Include all required extensions in the 8.x tree.
authorPat Thoyts <patthoyts@users.sourceforge.net>
Sun, 11 Jul 2010 00:36:04 +0000 (01:36 +0100)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Sun, 11 Jul 2010 00:36:04 +0000 (01:36 +0100)
From henceforth all the necessary extensions will be included in the git
repository. They can be updated intermittently from the various cvs/svn or
release tarballs as appropriate.
This patch incorporates zlib 1.2.5 from the recently released tarball.
This commit also marks a shift to github.

Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
1058 files changed:
.gitignore [new file with mode: 0644]
8.x/itcl/.cvsignore [new file with mode: 0644]
8.x/itcl/Makefile.in [new file with mode: 0644]
8.x/itcl/aclocal.m4 [new file with mode: 0644]
8.x/itcl/configure [new file with mode: 0755]
8.x/itcl/configure.in [new file with mode: 0644]
8.x/itcl/doc/Class.3 [new file with mode: 0644]
8.x/itcl/doc/List.3 [new file with mode: 0644]
8.x/itcl/doc/Object.3 [new file with mode: 0644]
8.x/itcl/doc/Preserve.3 [new file with mode: 0644]
8.x/itcl/doc/RegisterC.3 [new file with mode: 0644]
8.x/itcl/doc/Stack.3 [new file with mode: 0644]
8.x/itcl/doc/body.n [new file with mode: 0644]
8.x/itcl/doc/class.n [new file with mode: 0644]
8.x/itcl/doc/code.n [new file with mode: 0644]
8.x/itcl/doc/configbody.n [new file with mode: 0644]
8.x/itcl/doc/delete.n [new file with mode: 0644]
8.x/itcl/doc/ensemble.n [new file with mode: 0644]
8.x/itcl/doc/find.n [new file with mode: 0644]
8.x/itcl/doc/is.n [new file with mode: 0644]
8.x/itcl/doc/itcl.n [new file with mode: 0644]
8.x/itcl/doc/itclvars.n [new file with mode: 0644]
8.x/itcl/doc/license.terms [new file with mode: 0644]
8.x/itcl/doc/local.n [new file with mode: 0644]
8.x/itcl/doc/man.macros [new file with mode: 0644]
8.x/itcl/doc/scope.n [new file with mode: 0644]
8.x/itcl/generic/itcl.decls [new file with mode: 0644]
8.x/itcl/generic/itcl.h [new file with mode: 0644]
8.x/itcl/generic/itclDecls.h [new file with mode: 0644]
8.x/itcl/generic/itclInt.decls [new file with mode: 0644]
8.x/itcl/generic/itclInt.h [new file with mode: 0644]
8.x/itcl/generic/itclIntDecls.h [new file with mode: 0644]
8.x/itcl/generic/itclStubInit.c [new file with mode: 0644]
8.x/itcl/generic/itclStubLib.c [new file with mode: 0644]
8.x/itcl/generic/itcl_bicmds.c [new file with mode: 0644]
8.x/itcl/generic/itcl_class.c [new file with mode: 0644]
8.x/itcl/generic/itcl_cmds.c [new file with mode: 0644]
8.x/itcl/generic/itcl_ensemble.c [new file with mode: 0644]
8.x/itcl/generic/itcl_linkage.c [new file with mode: 0644]
8.x/itcl/generic/itcl_methods.c [new file with mode: 0644]
8.x/itcl/generic/itcl_migrate.c [new file with mode: 0644]
8.x/itcl/generic/itcl_objects.c [new file with mode: 0644]
8.x/itcl/generic/itcl_parse.c [new file with mode: 0644]
8.x/itcl/generic/itcl_util.c [new file with mode: 0644]
8.x/itcl/itclConfig.sh.in [new file with mode: 0644]
8.x/itcl/library/itcl.tcl [new file with mode: 0644]
8.x/itcl/license.terms [new file with mode: 0644]
8.x/itcl/pkgIndex.tcl.in [new file with mode: 0644]
8.x/itcl/tclconfig/install-sh [new file with mode: 0755]
8.x/itcl/tclconfig/tcl.m4 [new file with mode: 0644]
8.x/itcl/tests/all.tcl [new file with mode: 0755]
8.x/itcl/tests/basic.test [new file with mode: 0644]
8.x/itcl/tests/body.test [new file with mode: 0644]
8.x/itcl/tests/chain.test [new file with mode: 0644]
8.x/itcl/tests/delete.test [new file with mode: 0644]
8.x/itcl/tests/ensemble.test [new file with mode: 0644]
8.x/itcl/tests/import.test [new file with mode: 0644]
8.x/itcl/tests/info.test [new file with mode: 0644]
8.x/itcl/tests/inherit.test [new file with mode: 0644]
8.x/itcl/tests/interp.test [new file with mode: 0644]
8.x/itcl/tests/local.test [new file with mode: 0644]
8.x/itcl/tests/methods.test [new file with mode: 0644]
8.x/itcl/tests/mkindex.itcl [new file with mode: 0644]
8.x/itcl/tests/mkindex.test [new file with mode: 0644]
8.x/itcl/tests/namespace.test [new file with mode: 0644]
8.x/itcl/tests/old/AAA.test [new file with mode: 0644]
8.x/itcl/tests/old/Bar.tcl [new file with mode: 0644]
8.x/itcl/tests/old/BarFoo.tcl [new file with mode: 0644]
8.x/itcl/tests/old/Baz.tcl [new file with mode: 0644]
8.x/itcl/tests/old/Foo.tcl [new file with mode: 0644]
8.x/itcl/tests/old/FooBar.tcl [new file with mode: 0644]
8.x/itcl/tests/old/Geek.tcl [new file with mode: 0644]
8.x/itcl/tests/old/Mongrel.tcl [new file with mode: 0644]
8.x/itcl/tests/old/VirtualErr.tcl [new file with mode: 0644]
8.x/itcl/tests/old/all [new file with mode: 0644]
8.x/itcl/tests/old/basic.test [new file with mode: 0644]
8.x/itcl/tests/old/inherit.test [new file with mode: 0644]
8.x/itcl/tests/old/tclIndex [new file with mode: 0644]
8.x/itcl/tests/old/testlib.tcl [new file with mode: 0644]
8.x/itcl/tests/old/toaster.test [new file with mode: 0644]
8.x/itcl/tests/old/toasters/Appliance.tcl [new file with mode: 0644]
8.x/itcl/tests/old/toasters/Hazard.tcl [new file with mode: 0644]
8.x/itcl/tests/old/toasters/Outlet.tcl [new file with mode: 0644]
8.x/itcl/tests/old/toasters/SmartToaster.tcl [new file with mode: 0644]
8.x/itcl/tests/old/toasters/Toaster.tcl [new file with mode: 0644]
8.x/itcl/tests/old/toasters/tclIndex [new file with mode: 0644]
8.x/itcl/tests/old/toasters/usualway.tcl [new file with mode: 0644]
8.x/itcl/tests/old/uplevel.test [new file with mode: 0644]
8.x/itcl/tests/old/upvar.test [new file with mode: 0644]
8.x/itcl/tests/protection.test [new file with mode: 0644]
8.x/itcl/tests/scope.test [new file with mode: 0644]
8.x/itcl/tests/tclIndex [new file with mode: 0644]
8.x/itcl/win/.cvsignore [new file with mode: 0644]
8.x/itcl/win/dllEntryPoint.c [new file with mode: 0644]
8.x/itcl/win/makefile.vc [new file with mode: 0644]
8.x/itcl/win/nmakehlp.c [new file with mode: 0644]
8.x/itcl/win/rc/itcl.rc [new file with mode: 0644]
8.x/itcl/win/toaster.bmp [new file with mode: 0644]
8.x/mk/CHANGES [new file with mode: 0755]
8.x/mk/NOTES-2.3.4 [new file with mode: 0644]
8.x/mk/README [new file with mode: 0755]
8.x/mk/builds/!keepme.txt [new file with mode: 0644]
8.x/mk/demos/demo.cpp [new file with mode: 0755]
8.x/mk/demos/dump.cpp [new file with mode: 0755]
8.x/mk/demos/myio.cpp [new file with mode: 0755]
8.x/mk/demos/struct.cpp [new file with mode: 0755]
8.x/mk/doc/api/c4_Bytes.html [new file with mode: 0644]
8.x/mk/doc/api/c4_BytesProp.html [new file with mode: 0644]
8.x/mk/doc/api/c4_BytesProp_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_BytesProp_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_BytesRef.html [new file with mode: 0644]
8.x/mk/doc/api/c4_BytesRef_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_BytesRef_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Bytes___NONAME.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Bytes___NONAME_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Bytes___NONAME_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Bytes_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Bytes_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Cursor.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Cursor_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Cursor_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_CustomViewer.html [new file with mode: 0644]
8.x/mk/doc/api/c4_CustomViewer_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_CustomViewer_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_DoubleProp.html [new file with mode: 0644]
8.x/mk/doc/api/c4_DoubleProp_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_DoubleProp_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_DoubleRef.html [new file with mode: 0644]
8.x/mk/doc/api/c4_DoubleRef_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_DoubleRef_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_FloatProp.html [new file with mode: 0644]
8.x/mk/doc/api/c4_FloatProp_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_FloatProp_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_FloatRef.html [new file with mode: 0644]
8.x/mk/doc/api/c4_FloatRef_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_FloatRef_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_IntProp.html [new file with mode: 0644]
8.x/mk/doc/api/c4_IntProp_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_IntProp_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_IntRef.html [new file with mode: 0644]
8.x/mk/doc/api/c4_IntRef_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_IntRef_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_MemoProp.html [new file with mode: 0644]
8.x/mk/doc/api/c4_MemoProp_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_MemoProp_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_MemoRef.html [new file with mode: 0644]
8.x/mk/doc/api/c4_MemoRef_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_MemoRef_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Property.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Property_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Property_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Reference.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Reference_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Reference_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Row.html [new file with mode: 0644]
8.x/mk/doc/api/c4_RowRef.html [new file with mode: 0644]
8.x/mk/doc/api/c4_RowRef_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_RowRef_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Row_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Row_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Sequence.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Sequence_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Sequence_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Storage.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Storage_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Storage_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Strategy.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Strategy_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Strategy_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Stream.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Stream_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_Stream_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_StringProp.html [new file with mode: 0644]
8.x/mk/doc/api/c4_StringProp_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_StringProp_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_StringRef.html [new file with mode: 0644]
8.x/mk/doc/api/c4_StringRef_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_StringRef_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_View.html [new file with mode: 0644]
8.x/mk/doc/api/c4_ViewProp.html [new file with mode: 0644]
8.x/mk/doc/api/c4_ViewProp_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_ViewProp_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_ViewRef.html [new file with mode: 0644]
8.x/mk/doc/api/c4_ViewRef_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_ViewRef_info.html [new file with mode: 0644]
8.x/mk/doc/api/c4_View_desc.html [new file with mode: 0644]
8.x/mk/doc/api/c4_View_info.html [new file with mode: 0644]
8.x/mk/doc/api/classes.html [new file with mode: 0644]
8.x/mk/doc/api/doc_catfish.html [new file with mode: 0644]
8.x/mk/doc/api/doc_catrecv.html [new file with mode: 0644]
8.x/mk/doc/api/doc_catsend.html [new file with mode: 0644]
8.x/mk/doc/api/doc_dbf2mk.html [new file with mode: 0644]
8.x/mk/doc/api/doc_demo.html [new file with mode: 0644]
8.x/mk/doc/api/doc_discat.html [new file with mode: 0644]
8.x/mk/doc/api/doc_dump.html [new file with mode: 0644]
8.x/mk/doc/api/doc_ftpcat.html [new file with mode: 0644]
8.x/mk/doc/api/doc_kbind.html [new file with mode: 0644]
8.x/mk/doc/api/doc_mkoptim.html [new file with mode: 0644]
8.x/mk/doc/api/doc_myio.html [new file with mode: 0644]
8.x/mk/doc/api/doc_struct.html [new file with mode: 0644]
8.x/mk/doc/api/index.html [new file with mode: 0644]
8.x/mk/doc/api/navbar.html [new file with mode: 0644]
8.x/mk/doc/api/roadmap.html [new file with mode: 0644]
8.x/mk/doc/api/samples.html [new file with mode: 0644]
8.x/mk/doc/api/tips.html [new file with mode: 0644]
8.x/mk/doc/e4s.gif [new file with mode: 0755]
8.x/mk/doc/format.html [new file with mode: 0755]
8.x/mk/doc/metakit.png [new file with mode: 0644]
8.x/mk/doc/python.html [new file with mode: 0755]
8.x/mk/doc/python.jpg [new file with mode: 0755]
8.x/mk/doc/tcl.gif [new file with mode: 0755]
8.x/mk/doc/tcl.html [new file with mode: 0755]
8.x/mk/examples/README [new file with mode: 0644]
8.x/mk/examples/aside.py [new file with mode: 0644]
8.x/mk/examples/bigblock.tcl [new file with mode: 0644]
8.x/mk/examples/blockdels.tcl [new file with mode: 0644]
8.x/mk/examples/case.py [new file with mode: 0644]
8.x/mk/examples/demo.py [new file with mode: 0644]
8.x/mk/examples/demo.tcl [new file with mode: 0644]
8.x/mk/examples/demold.tcl [new file with mode: 0644]
8.x/mk/examples/derived.py [new file with mode: 0644]
8.x/mk/examples/find.py [new file with mode: 0644]
8.x/mk/examples/mapped.tcl [new file with mode: 0644]
8.x/mk/examples/millions.py [new file with mode: 0755]
8.x/mk/examples/mkbug.cpp [new file with mode: 0755]
8.x/mk/examples/mkhash.cpp [new file with mode: 0644]
8.x/mk/examples/mkmemoio.py [new file with mode: 0755]
8.x/mk/examples/pair.py [new file with mode: 0644]
8.x/mk/examples/random.tcl [new file with mode: 0644]
8.x/mk/examples/remap.py [new file with mode: 0644]
8.x/mk/examples/selfref.py [new file with mode: 0644]
8.x/mk/examples/selmap.tcl [new file with mode: 0644]
8.x/mk/examples/slow.tcl [new file with mode: 0644]
8.x/mk/examples/sort.tcl [new file with mode: 0644]
8.x/mk/examples/wrap.py [new file with mode: 0644]
8.x/mk/include/mk4.h [new file with mode: 0755]
8.x/mk/include/mk4.inl [new file with mode: 0755]
8.x/mk/include/mk4dll.h [new file with mode: 0755]
8.x/mk/include/mk4io.h [new file with mode: 0755]
8.x/mk/include/mk4str.h [new file with mode: 0755]
8.x/mk/include/mk4str.inl [new file with mode: 0755]
8.x/mk/license.terms [new file with mode: 0644]
8.x/mk/python/.cvsignore [new file with mode: 0644]
8.x/mk/python/PyHead.h [new file with mode: 0755]
8.x/mk/python/PyProperty.cpp [new file with mode: 0755]
8.x/mk/python/PyProperty.h [new file with mode: 0755]
8.x/mk/python/PyRowRef.cpp [new file with mode: 0755]
8.x/mk/python/PyRowRef.h [new file with mode: 0755]
8.x/mk/python/PyStorage.cpp [new file with mode: 0755]
8.x/mk/python/PyStorage.h [new file with mode: 0755]
8.x/mk/python/PyView.cpp [new file with mode: 0755]
8.x/mk/python/PyView.h [new file with mode: 0755]
8.x/mk/python/README-dmn [new file with mode: 0644]
8.x/mk/python/metakit.py [new file with mode: 0644]
8.x/mk/python/scxx/PWOBase.h [new file with mode: 0755]
8.x/mk/python/scxx/PWOCallable.h [new file with mode: 0644]
8.x/mk/python/scxx/PWOImp.cpp [new file with mode: 0755]
8.x/mk/python/scxx/PWOMSequence.h [new file with mode: 0755]
8.x/mk/python/scxx/PWOMapping.h [new file with mode: 0755]
8.x/mk/python/scxx/PWONumber.h [new file with mode: 0755]
8.x/mk/python/scxx/PWOSequence.h [new file with mode: 0755]
8.x/mk/python/scxx/README.txt [new file with mode: 0755]
8.x/mk/python/setup.py [new file with mode: 0755]
8.x/mk/python/test/.cvsignore [new file with mode: 0644]
8.x/mk/python/test/all.py [new file with mode: 0644]
8.x/mk/python/test/mktestsupport.py [new file with mode: 0644]
8.x/mk/python/test/test_hash.py [new file with mode: 0644]
8.x/mk/python/test/test_inttypes.py [new file with mode: 0644]
8.x/mk/python/test/test_stringtype.py [new file with mode: 0644]
8.x/mk/python/test/test_unittest.py [new file with mode: 0644]
8.x/mk/src/borc.h [new file with mode: 0755]
8.x/mk/src/column.cpp [new file with mode: 0755]
8.x/mk/src/column.h [new file with mode: 0755]
8.x/mk/src/column.inl [new file with mode: 0755]
8.x/mk/src/custom.cpp [new file with mode: 0755]
8.x/mk/src/custom.h [new file with mode: 0755]
8.x/mk/src/derived.cpp [new file with mode: 0755]
8.x/mk/src/derived.h [new file with mode: 0755]
8.x/mk/src/doxy.h [new file with mode: 0644]
8.x/mk/src/field.cpp [new file with mode: 0755]
8.x/mk/src/field.h [new file with mode: 0755]
8.x/mk/src/field.inl [new file with mode: 0755]
8.x/mk/src/fileio.cpp [new file with mode: 0755]
8.x/mk/src/format.cpp [new file with mode: 0755]
8.x/mk/src/format.h [new file with mode: 0755]
8.x/mk/src/gnuc.h [new file with mode: 0755]
8.x/mk/src/handler.cpp [new file with mode: 0755]
8.x/mk/src/handler.h [new file with mode: 0755]
8.x/mk/src/handler.inl [new file with mode: 0755]
8.x/mk/src/header.h [new file with mode: 0755]
8.x/mk/src/mfc.h [new file with mode: 0755]
8.x/mk/src/msvc.h [new file with mode: 0755]
8.x/mk/src/mwcw.h [new file with mode: 0755]
8.x/mk/src/persist.cpp [new file with mode: 0755]
8.x/mk/src/persist.h [new file with mode: 0755]
8.x/mk/src/remap.cpp [new file with mode: 0755]
8.x/mk/src/remap.h [new file with mode: 0644]
8.x/mk/src/std.cpp [new file with mode: 0755]
8.x/mk/src/std.h [new file with mode: 0755]
8.x/mk/src/store.cpp [new file with mode: 0755]
8.x/mk/src/store.h [new file with mode: 0755]
8.x/mk/src/store.inl [new file with mode: 0755]
8.x/mk/src/string.cpp [new file with mode: 0755]
8.x/mk/src/table.cpp [new file with mode: 0755]
8.x/mk/src/univ.cpp [new file with mode: 0755]
8.x/mk/src/univ.h [new file with mode: 0755]
8.x/mk/src/univ.inl [new file with mode: 0755]
8.x/mk/src/view.cpp [new file with mode: 0755]
8.x/mk/src/viewx.cpp [new file with mode: 0755]
8.x/mk/src/win.h [new file with mode: 0755]
8.x/mk/tcl/Makefile.in [new file with mode: 0755]
8.x/mk/tcl/aclocal.m4 [new file with mode: 0755]
8.x/mk/tcl/config.h.in [new file with mode: 0755]
8.x/mk/tcl/configure [new file with mode: 0755]
8.x/mk/tcl/configure.in [new file with mode: 0755]
8.x/mk/tcl/mk4tcl.cpp [new file with mode: 0755]
8.x/mk/tcl/mk4tcl.h [new file with mode: 0644]
8.x/mk/tcl/mk4too.cpp [new file with mode: 0644]
8.x/mk/tcl/mkshow.tcl [new file with mode: 0755]
8.x/mk/tcl/pkgIndex.tcl.in [new file with mode: 0644]
8.x/mk/tcl/stubtcl.h [new file with mode: 0644]
8.x/mk/tcl/tclconfig/README.txt [new file with mode: 0644]
8.x/mk/tcl/tclconfig/install-sh [new file with mode: 0755]
8.x/mk/tcl/tclconfig/tcl.m4 [new file with mode: 0644]
8.x/mk/tcl/tequila/README [new file with mode: 0644]
8.x/mk/tcl/tequila/proxy.tcl [new file with mode: 0755]
8.x/mk/tcl/tequila/tequical.tcl [new file with mode: 0644]
8.x/mk/tcl/tequila/tequila.tcl [new file with mode: 0644]
8.x/mk/tcl/tequila/tequilas.tcl [new file with mode: 0644]
8.x/mk/tcl/tests/all.tcl [new file with mode: 0755]
8.x/mk/tcl/tests/basic.test [new file with mode: 0755]
8.x/mk/tcl/tests/commit.test [new file with mode: 0755]
8.x/mk/tcl/tests/fixed.test [new file with mode: 0755]
8.x/mk/tcl/tests/initests.tcl [new file with mode: 0644]
8.x/mk/tcl/tests/limit.test [new file with mode: 0755]
8.x/mk/tcl/tests/object.test [new file with mode: 0755]
8.x/mk/tests/ok/b00.txt [new file with mode: 0644]
8.x/mk/tests/ok/b01.txt [new file with mode: 0644]
8.x/mk/tests/ok/b02.txt [new file with mode: 0644]
8.x/mk/tests/ok/b03.txt [new file with mode: 0644]
8.x/mk/tests/ok/b04.txt [new file with mode: 0644]
8.x/mk/tests/ok/b05.txt [new file with mode: 0644]
8.x/mk/tests/ok/b06.txt [new file with mode: 0644]
8.x/mk/tests/ok/b07.txt [new file with mode: 0644]
8.x/mk/tests/ok/b08.txt [new file with mode: 0644]
8.x/mk/tests/ok/b09.txt [new file with mode: 0644]
8.x/mk/tests/ok/b10.txt [new file with mode: 0644]
8.x/mk/tests/ok/b11.txt [new file with mode: 0644]
8.x/mk/tests/ok/b12.txt [new file with mode: 0644]
8.x/mk/tests/ok/b13.txt [new file with mode: 0644]
8.x/mk/tests/ok/b14.txt [new file with mode: 0644]
8.x/mk/tests/ok/b15.txt [new file with mode: 0644]
8.x/mk/tests/ok/b16.txt [new file with mode: 0644]
8.x/mk/tests/ok/b17.txt [new file with mode: 0644]
8.x/mk/tests/ok/b18.txt [new file with mode: 0644]
8.x/mk/tests/ok/b19.txt [new file with mode: 0644]
8.x/mk/tests/ok/b20.txt [new file with mode: 0644]
8.x/mk/tests/ok/b21.txt [new file with mode: 0644]
8.x/mk/tests/ok/b22.txt [new file with mode: 0644]
8.x/mk/tests/ok/b23.txt [new file with mode: 0755]
8.x/mk/tests/ok/b24.txt [new file with mode: 0755]
8.x/mk/tests/ok/b25.txt [new file with mode: 0755]
8.x/mk/tests/ok/b26.txt [new file with mode: 0644]
8.x/mk/tests/ok/b27.txt [new file with mode: 0644]
8.x/mk/tests/ok/c01.txt [new file with mode: 0644]
8.x/mk/tests/ok/c02.txt [new file with mode: 0644]
8.x/mk/tests/ok/c03.txt [new file with mode: 0644]
8.x/mk/tests/ok/c04.txt [new file with mode: 0644]
8.x/mk/tests/ok/c05.txt [new file with mode: 0644]
8.x/mk/tests/ok/c06.txt [new file with mode: 0644]
8.x/mk/tests/ok/c07.txt [new file with mode: 0644]
8.x/mk/tests/ok/c08.txt [new file with mode: 0644]
8.x/mk/tests/ok/c09.txt [new file with mode: 0644]
8.x/mk/tests/ok/c10.txt [new file with mode: 0644]
8.x/mk/tests/ok/c11.txt [new file with mode: 0644]
8.x/mk/tests/ok/c12.txt [new file with mode: 0644]
8.x/mk/tests/ok/c13.txt [new file with mode: 0644]
8.x/mk/tests/ok/c14.txt [new file with mode: 0644]
8.x/mk/tests/ok/c15.txt [new file with mode: 0755]
8.x/mk/tests/ok/c16.txt [new file with mode: 0644]
8.x/mk/tests/ok/c17.txt [new file with mode: 0644]
8.x/mk/tests/ok/c18.txt [new file with mode: 0755]
8.x/mk/tests/ok/c19.txt [new file with mode: 0755]
8.x/mk/tests/ok/c20.txt [new file with mode: 0644]
8.x/mk/tests/ok/c21.txt [new file with mode: 0644]
8.x/mk/tests/ok/c22.txt [new file with mode: 0644]
8.x/mk/tests/ok/d01.txt [new file with mode: 0644]
8.x/mk/tests/ok/d01a.txt [new file with mode: 0644]
8.x/mk/tests/ok/d01b.txt [new file with mode: 0644]
8.x/mk/tests/ok/e01.txt [new file with mode: 0644]
8.x/mk/tests/ok/e01a.txt [new file with mode: 0644]
8.x/mk/tests/ok/e02.txt [new file with mode: 0644]
8.x/mk/tests/ok/e02a.txt [new file with mode: 0644]
8.x/mk/tests/ok/e03.txt [new file with mode: 0644]
8.x/mk/tests/ok/e03a.txt [new file with mode: 0644]
8.x/mk/tests/ok/e04.txt [new file with mode: 0644]
8.x/mk/tests/ok/e04a.txt [new file with mode: 0644]
8.x/mk/tests/ok/e05.txt [new file with mode: 0644]
8.x/mk/tests/ok/e05a.txt [new file with mode: 0644]
8.x/mk/tests/ok/e06.txt [new file with mode: 0644]
8.x/mk/tests/ok/e06a.txt [new file with mode: 0644]
8.x/mk/tests/ok/f01.txt [new file with mode: 0644]
8.x/mk/tests/ok/f01a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f02.txt [new file with mode: 0644]
8.x/mk/tests/ok/f02a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f03.txt [new file with mode: 0644]
8.x/mk/tests/ok/f03a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f04.txt [new file with mode: 0644]
8.x/mk/tests/ok/f04a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f05.txt [new file with mode: 0644]
8.x/mk/tests/ok/f05a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f06.txt [new file with mode: 0644]
8.x/mk/tests/ok/f07.txt [new file with mode: 0644]
8.x/mk/tests/ok/f07a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f08.txt [new file with mode: 0644]
8.x/mk/tests/ok/f08a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f09.txt [new file with mode: 0644]
8.x/mk/tests/ok/f09a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f10.txt [new file with mode: 0644]
8.x/mk/tests/ok/f10a.txt [new file with mode: 0755]
8.x/mk/tests/ok/f11.txt [new file with mode: 0755]
8.x/mk/tests/ok/f11a.txt [new file with mode: 0755]
8.x/mk/tests/ok/l00.txt [new file with mode: 0644]
8.x/mk/tests/ok/l00a.txt [new file with mode: 0755]
8.x/mk/tests/ok/l01.txt [new file with mode: 0644]
8.x/mk/tests/ok/l01a.txt [new file with mode: 0755]
8.x/mk/tests/ok/l02.txt [new file with mode: 0644]
8.x/mk/tests/ok/l02a.txt [new file with mode: 0755]
8.x/mk/tests/ok/l03.txt [new file with mode: 0644]
8.x/mk/tests/ok/l03a.txt [new file with mode: 0755]
8.x/mk/tests/ok/l03b.txt [new file with mode: 0755]
8.x/mk/tests/ok/l04.txt [new file with mode: 0644]
8.x/mk/tests/ok/l04a.txt [new file with mode: 0755]
8.x/mk/tests/ok/l05.txt [new file with mode: 0644]
8.x/mk/tests/ok/l05a.txt [new file with mode: 0755]
8.x/mk/tests/ok/l06.txt [new file with mode: 0644]
8.x/mk/tests/ok/l06a.txt [new file with mode: 0755]
8.x/mk/tests/ok/l07.txt [new file with mode: 0755]
8.x/mk/tests/ok/l07a.txt [new file with mode: 0755]
8.x/mk/tests/ok/m01.txt [new file with mode: 0644]
8.x/mk/tests/ok/m02.txt [new file with mode: 0644]
8.x/mk/tests/ok/m02a.txt [new file with mode: 0644]
8.x/mk/tests/ok/m03.txt [new file with mode: 0644]
8.x/mk/tests/ok/m03a.txt [new file with mode: 0644]
8.x/mk/tests/ok/m04.txt [new file with mode: 0644]
8.x/mk/tests/ok/m04a.txt [new file with mode: 0644]
8.x/mk/tests/ok/m05.txt [new file with mode: 0644]
8.x/mk/tests/ok/m05a.txt [new file with mode: 0644]
8.x/mk/tests/ok/m06.txt [new file with mode: 0644]
8.x/mk/tests/ok/m06a.txt [new file with mode: 0644]
8.x/mk/tests/ok/m07.txt [new file with mode: 0644]
8.x/mk/tests/ok/n01.txt [new file with mode: 0644]
8.x/mk/tests/ok/n02.txt [new file with mode: 0644]
8.x/mk/tests/ok/n03.txt [new file with mode: 0644]
8.x/mk/tests/ok/n04.txt [new file with mode: 0644]
8.x/mk/tests/ok/n05.txt [new file with mode: 0644]
8.x/mk/tests/ok/n06.txt [new file with mode: 0644]
8.x/mk/tests/ok/n07.txt [new file with mode: 0644]
8.x/mk/tests/ok/n08.txt [new file with mode: 0644]
8.x/mk/tests/ok/n09.txt [new file with mode: 0644]
8.x/mk/tests/ok/n10.txt [new file with mode: 0644]
8.x/mk/tests/ok/n11.txt [new file with mode: 0644]
8.x/mk/tests/ok/n12.txt [new file with mode: 0644]
8.x/mk/tests/ok/n13.txt [new file with mode: 0755]
8.x/mk/tests/ok/n14.txt [new file with mode: 0644]
8.x/mk/tests/ok/n14a.txt [new file with mode: 0644]
8.x/mk/tests/ok/r00.txt [new file with mode: 0644]
8.x/mk/tests/ok/r00a.txt [new file with mode: 0755]
8.x/mk/tests/ok/r01.txt [new file with mode: 0644]
8.x/mk/tests/ok/r01a.txt [new file with mode: 0755]
8.x/mk/tests/ok/r02.txt [new file with mode: 0644]
8.x/mk/tests/ok/r02a.txt [new file with mode: 0755]
8.x/mk/tests/ok/r03.txt [new file with mode: 0644]
8.x/mk/tests/ok/r03a.txt [new file with mode: 0755]
8.x/mk/tests/ok/r04.txt [new file with mode: 0644]
8.x/mk/tests/ok/r04a.txt [new file with mode: 0755]
8.x/mk/tests/ok/reversed.txt [new file with mode: 0755]
8.x/mk/tests/ok/s00.txt [new file with mode: 0644]
8.x/mk/tests/ok/s00a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s01.txt [new file with mode: 0644]
8.x/mk/tests/ok/s01a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s02.txt [new file with mode: 0644]
8.x/mk/tests/ok/s02a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s03.txt [new file with mode: 0644]
8.x/mk/tests/ok/s03a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s04.txt [new file with mode: 0644]
8.x/mk/tests/ok/s04a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s05.txt [new file with mode: 0644]
8.x/mk/tests/ok/s05a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s06.txt [new file with mode: 0644]
8.x/mk/tests/ok/s06a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s07.txt [new file with mode: 0644]
8.x/mk/tests/ok/s07a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s08.txt [new file with mode: 0644]
8.x/mk/tests/ok/s08a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s09.txt [new file with mode: 0644]
8.x/mk/tests/ok/s09a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s09b.txt [new file with mode: 0755]
8.x/mk/tests/ok/s10.txt [new file with mode: 0644]
8.x/mk/tests/ok/s10a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s10b.txt [new file with mode: 0755]
8.x/mk/tests/ok/s10c.txt [new file with mode: 0755]
8.x/mk/tests/ok/s11.txt [new file with mode: 0644]
8.x/mk/tests/ok/s11a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s12.txt [new file with mode: 0644]
8.x/mk/tests/ok/s12a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s13.txt [new file with mode: 0644]
8.x/mk/tests/ok/s13a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s14.txt [new file with mode: 0644]
8.x/mk/tests/ok/s14a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s15.txt [new file with mode: 0644]
8.x/mk/tests/ok/s15a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s16.txt [new file with mode: 0644]
8.x/mk/tests/ok/s16a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s17.txt [new file with mode: 0644]
8.x/mk/tests/ok/s17a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s18.txt [new file with mode: 0644]
8.x/mk/tests/ok/s18a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s19.txt [new file with mode: 0644]
8.x/mk/tests/ok/s19a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s20.txt [new file with mode: 0644]
8.x/mk/tests/ok/s20a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s21.txt [new file with mode: 0644]
8.x/mk/tests/ok/s21a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s22.txt [new file with mode: 0644]
8.x/mk/tests/ok/s22a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s23.txt [new file with mode: 0644]
8.x/mk/tests/ok/s23a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s24.txt [new file with mode: 0644]
8.x/mk/tests/ok/s24a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s25.txt [new file with mode: 0644]
8.x/mk/tests/ok/s25a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s26.txt [new file with mode: 0644]
8.x/mk/tests/ok/s26a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s27.txt [new file with mode: 0644]
8.x/mk/tests/ok/s27a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s28.txt [new file with mode: 0644]
8.x/mk/tests/ok/s28a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s29.txt [new file with mode: 0644]
8.x/mk/tests/ok/s29a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s30.txt [new file with mode: 0644]
8.x/mk/tests/ok/s30a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s31.txt [new file with mode: 0755]
8.x/mk/tests/ok/s31a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s32.txt [new file with mode: 0755]
8.x/mk/tests/ok/s32a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s33.txt [new file with mode: 0755]
8.x/mk/tests/ok/s33a.txt [new file with mode: 0755]
8.x/mk/tests/ok/s33b.txt [new file with mode: 0755]
8.x/mk/tests/ok/s33c.txt [new file with mode: 0755]
8.x/mk/tests/ok/s34.txt [new file with mode: 0644]
8.x/mk/tests/ok/s34a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s35.txt [new file with mode: 0644]
8.x/mk/tests/ok/s35a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s36.txt [new file with mode: 0644]
8.x/mk/tests/ok/s36a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s36b.txt [new file with mode: 0644]
8.x/mk/tests/ok/s37.txt [new file with mode: 0644]
8.x/mk/tests/ok/s37a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s38.txt [new file with mode: 0644]
8.x/mk/tests/ok/s38a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s39.txt [new file with mode: 0644]
8.x/mk/tests/ok/s39a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s40.txt [new file with mode: 0644]
8.x/mk/tests/ok/s40a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s41.txt [new file with mode: 0644]
8.x/mk/tests/ok/s41a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s42.txt [new file with mode: 0644]
8.x/mk/tests/ok/s43.txt [new file with mode: 0644]
8.x/mk/tests/ok/s43a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s44.txt [new file with mode: 0644]
8.x/mk/tests/ok/s44a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s45.txt [new file with mode: 0644]
8.x/mk/tests/ok/s45a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s46.txt [new file with mode: 0644]
8.x/mk/tests/ok/s46a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s47.txt [new file with mode: 0644]
8.x/mk/tests/ok/s48.txt [new file with mode: 0644]
8.x/mk/tests/ok/s48a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s48b.txt [new file with mode: 0644]
8.x/mk/tests/ok/s49.txt [new file with mode: 0644]
8.x/mk/tests/ok/s49a.txt [new file with mode: 0644]
8.x/mk/tests/ok/s50.txt [new file with mode: 0644]
8.x/mk/tests/ok/s50a.txt [new file with mode: 0644]
8.x/mk/tests/regress.cpp [new file with mode: 0755]
8.x/mk/tests/regress.h [new file with mode: 0755]
8.x/mk/tests/tbasic1.cpp [new file with mode: 0644]
8.x/mk/tests/tbasic2.cpp [new file with mode: 0644]
8.x/mk/tests/tcusto1.cpp [new file with mode: 0755]
8.x/mk/tests/tcusto2.cpp [new file with mode: 0755]
8.x/mk/tests/tdiffer.cpp [new file with mode: 0644]
8.x/mk/tests/textend.cpp [new file with mode: 0644]
8.x/mk/tests/tformat.cpp [new file with mode: 0755]
8.x/mk/tests/tlimits.cpp [new file with mode: 0755]
8.x/mk/tests/tmapped.cpp [new file with mode: 0644]
8.x/mk/tests/tnotify.cpp [new file with mode: 0755]
8.x/mk/tests/tresize.cpp [new file with mode: 0755]
8.x/mk/tests/tstore1.cpp [new file with mode: 0755]
8.x/mk/tests/tstore2.cpp [new file with mode: 0755]
8.x/mk/tests/tstore3.cpp [new file with mode: 0755]
8.x/mk/tests/tstore4.cpp [new file with mode: 0755]
8.x/mk/tests/tstore5.cpp [new file with mode: 0644]
8.x/mk/unix/Doxyfile [new file with mode: 0644]
8.x/mk/unix/Doxytail.html [new file with mode: 0644]
8.x/mk/unix/Makefile.in [new file with mode: 0755]
8.x/mk/unix/README [new file with mode: 0644]
8.x/mk/unix/config.h.in [new file with mode: 0755]
8.x/mk/unix/configure [new file with mode: 0755]
8.x/mk/unix/configure.in [new file with mode: 0755]
8.x/mk/unix/cpprt0_stubs.s [new file with mode: 0644]
8.x/mk/unix/metakit.spec [new file with mode: 0644]
8.x/mk/unix/reversed [new file with mode: 0644]
8.x/mk/unix/scripts/config.guess [new file with mode: 0755]
8.x/mk/unix/scripts/config.sub [new file with mode: 0755]
8.x/mk/unix/scripts/install-sh [new file with mode: 0755]
8.x/mk/win/config.h [new file with mode: 0755]
8.x/mk/win/msvc60/mkbug.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mkdemo.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mkdist.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mkdll.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mkdump.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mkhash.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mklib.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mkpython.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mksrc.dsw [new file with mode: 0755]
8.x/mk/win/msvc60/mktcl.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/mktest.dsp [new file with mode: 0755]
8.x/mk/win/msvc60/reversed [new file with mode: 0644]
8.x/mk/win/msvc70/mkbug.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mkdemo.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mkdist.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mkdll.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mkdump.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mkhash.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mklib.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mkpython.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mksrc.sln [new file with mode: 0755]
8.x/mk/win/msvc70/mktcl.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/mktest.vcproj [new file with mode: 0755]
8.x/mk/win/msvc70/reversed [new file with mode: 0644]
8.x/mk/win/msvc70/tests/!keepme.txt [new file with mode: 0644]
8.x/tclvfs/ChangeLog [new file with mode: 0644]
8.x/tclvfs/DESCRIPTION.txt [new file with mode: 0644]
8.x/tclvfs/Makefile.in [new file with mode: 0644]
8.x/tclvfs/README.cygwin [new file with mode: 0644]
8.x/tclvfs/Readme.txt [new file with mode: 0644]
8.x/tclvfs/aclocal.m4 [new file with mode: 0644]
8.x/tclvfs/configure [new file with mode: 0755]
8.x/tclvfs/configure.in [new file with mode: 0644]
8.x/tclvfs/doc/vfs-filesystems.man [new file with mode: 0644]
8.x/tclvfs/doc/vfs-fsapi.man [new file with mode: 0644]
8.x/tclvfs/doc/vfs.man [new file with mode: 0644]
8.x/tclvfs/doc/vfs.n [new file with mode: 0644]
8.x/tclvfs/doc/vfslib.n [new file with mode: 0644]
8.x/tclvfs/examples/simpleExamples.tcl [new file with mode: 0644]
8.x/tclvfs/generic/vfs.c [new file with mode: 0644]
8.x/tclvfs/http2.6/http.n [new file with mode: 0644]
8.x/tclvfs/http2.6/http.tcl [new file with mode: 0644]
8.x/tclvfs/http2.6/pkgIndex.tcl [new file with mode: 0644]
8.x/tclvfs/library/ftpvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/httpvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/mk4vfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/starkit.tcl [new file with mode: 0644]
8.x/tclvfs/library/tarvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/tclprocvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/chrootvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/collatevfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/deltavfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/fishvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/globfind.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/quotavfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/tclIndex [new file with mode: 0644]
8.x/tclvfs/library/template/tdelta.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/templatevfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/template/versionvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/testvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/tkvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/vfs.tcl.in [new file with mode: 0644]
8.x/tclvfs/library/vfsUrl.tcl [new file with mode: 0644]
8.x/tclvfs/library/vfsUtils.tcl [new file with mode: 0644]
8.x/tclvfs/library/vfslib.tcl [new file with mode: 0644]
8.x/tclvfs/library/webdavvfs.tcl [new file with mode: 0644]
8.x/tclvfs/library/zipvfs.tcl [new file with mode: 0644]
8.x/tclvfs/license.terms [new file with mode: 0644]
8.x/tclvfs/make55.tcl [new file with mode: 0644]
8.x/tclvfs/pkgIndex.tcl.in [new file with mode: 0644]
8.x/tclvfs/tclconfig/README.txt [new file with mode: 0644]
8.x/tclvfs/tclconfig/install-sh [new file with mode: 0755]
8.x/tclvfs/tclconfig/tcl.m4 [new file with mode: 0644]
8.x/tclvfs/tests/all.tcl [new file with mode: 0644]
8.x/tclvfs/tests/vfs.test [new file with mode: 0644]
8.x/tclvfs/tests/vfsArchive.test [new file with mode: 0644]
8.x/tclvfs/tests/vfsFtp.test [new file with mode: 0644]
8.x/tclvfs/tests/vfsTar.test [new file with mode: 0644]
8.x/tclvfs/tests/vfsUrl.test [new file with mode: 0644]
8.x/tclvfs/tests/vfsZip.test [new file with mode: 0644]
8.x/tclvfs/win/makefile.vc [new file with mode: 0644]
8.x/tclvfs/win/nmakehlp.c [new file with mode: 0644]
8.x/tclvfs/win/rules.vc [new file with mode: 0644]
8.x/tclvfs/win/tclvfs.rc [new file with mode: 0644]
8.x/thread/.cvsignore [new file with mode: 0644]
8.x/thread/ChangeLog [new file with mode: 0644]
8.x/thread/Makefile.in [new file with mode: 0644]
8.x/thread/README [new file with mode: 0644]
8.x/thread/aclocal.m4 [new file with mode: 0644]
8.x/thread/aolserver.m4 [new file with mode: 0644]
8.x/thread/configure [new file with mode: 0755]
8.x/thread/configure.in [new file with mode: 0644]
8.x/thread/doc/format.tcl [new file with mode: 0644]
8.x/thread/doc/html/thread.html [new file with mode: 0644]
8.x/thread/doc/html/tpool.html [new file with mode: 0644]
8.x/thread/doc/html/tsv.html [new file with mode: 0644]
8.x/thread/doc/html/ttrace.html [new file with mode: 0644]
8.x/thread/doc/man.macros [new file with mode: 0644]
8.x/thread/doc/man/thread.n [new file with mode: 0644]
8.x/thread/doc/man/tpool.n [new file with mode: 0644]
8.x/thread/doc/man/tsv.n [new file with mode: 0644]
8.x/thread/doc/man/ttrace.n [new file with mode: 0644]
8.x/thread/doc/thread.man [new file with mode: 0644]
8.x/thread/doc/tpool.man [new file with mode: 0644]
8.x/thread/doc/tsv.man [new file with mode: 0644]
8.x/thread/doc/ttrace.man [new file with mode: 0644]
8.x/thread/generic/aolstub.cpp [new file with mode: 0644]
8.x/thread/generic/psGdbm.c [new file with mode: 0644]
8.x/thread/generic/psGdbm.h [new file with mode: 0644]
8.x/thread/generic/tclThread.h [new file with mode: 0644]
8.x/thread/generic/tclXkeylist.c [new file with mode: 0644]
8.x/thread/generic/tclXkeylist.h [new file with mode: 0644]
8.x/thread/generic/threadCmd.c [new file with mode: 0644]
8.x/thread/generic/threadPoolCmd.c [new file with mode: 0644]
8.x/thread/generic/threadSpCmd.c [new file with mode: 0644]
8.x/thread/generic/threadSpCmd.h [new file with mode: 0644]
8.x/thread/generic/threadSvCmd.c [new file with mode: 0644]
8.x/thread/generic/threadSvCmd.h [new file with mode: 0644]
8.x/thread/generic/threadSvKeylistCmd.c [new file with mode: 0644]
8.x/thread/generic/threadSvKeylistCmd.h [new file with mode: 0644]
8.x/thread/generic/threadSvListCmd.c [new file with mode: 0644]
8.x/thread/generic/threadSvListCmd.h [new file with mode: 0644]
8.x/thread/lib/ttrace.tcl [new file with mode: 0644]
8.x/thread/license.terms [new file with mode: 0644]
8.x/thread/pkgIndex.tcl.in [new file with mode: 0755]
8.x/thread/tcl/README [new file with mode: 0644]
8.x/thread/tcl/cmdsrv/cmdsrv.tcl [new file with mode: 0644]
8.x/thread/tcl/phttpd/index.htm [new file with mode: 0644]
8.x/thread/tcl/phttpd/phttpd.tcl [new file with mode: 0644]
8.x/thread/tcl/phttpd/uhttpd.tcl [new file with mode: 0644]
8.x/thread/tcl/tpool/tpool.tcl [new file with mode: 0644]
8.x/thread/tclconfig/ChangeLog [new file with mode: 0644]
8.x/thread/tclconfig/README.txt [new file with mode: 0644]
8.x/thread/tclconfig/install-sh [new file with mode: 0755]
8.x/thread/tclconfig/tcl.m4 [new file with mode: 0644]
8.x/thread/tests/all.tcl [new file with mode: 0644]
8.x/thread/tests/thread.test [new file with mode: 0644]
8.x/thread/tests/tpool.test [new file with mode: 0644]
8.x/thread/tests/tsv.test [new file with mode: 0644]
8.x/thread/tests/ttrace.test [new file with mode: 0644]
8.x/thread/unix/CONFIG [new file with mode: 0644]
8.x/thread/unix/README [new file with mode: 0644]
8.x/thread/unix/threadUnix.c [new file with mode: 0644]
8.x/thread/win/CONFIG [new file with mode: 0644]
8.x/thread/win/README.txt [new file with mode: 0644]
8.x/thread/win/thread.rc [new file with mode: 0644]
8.x/thread/win/threadWin.c [new file with mode: 0644]
8.x/thread/win/vc/.cvsignore [new file with mode: 0644]
8.x/thread/win/vc/README.txt [new file with mode: 0644]
8.x/thread/win/vc/makefile.vc [new file with mode: 0644]
8.x/thread/win/vc/nmakehlp.c [new file with mode: 0644]
8.x/thread/win/vc/nmakehlp.exe [new file with mode: 0644]
8.x/thread/win/vc/nmakehlp.obj [new file with mode: 0644]
8.x/thread/win/vc/pkg.vc [new file with mode: 0644]
8.x/thread/win/vc/rules.vc [new file with mode: 0644]
8.x/thread/win/vc/thread_win.dsp [new file with mode: 0644]
8.x/thread/win/vc/thread_win.dsw [new file with mode: 0644]
8.x/vqtcl/ChangeLog [new file with mode: 0644]
8.x/vqtcl/Makefile.in [new file with mode: 0644]
8.x/vqtcl/README [new file with mode: 0644]
8.x/vqtcl/aclocal.m4 [new file with mode: 0644]
8.x/vqtcl/configure [new file with mode: 0755]
8.x/vqtcl/configure.in [new file with mode: 0644]
8.x/vqtcl/data/gtest.db [new file with mode: 0644]
8.x/vqtcl/data/lkit-be.db [new file with mode: 0644]
8.x/vqtcl/data/lkit-le.db [new file with mode: 0644]
8.x/vqtcl/data/mkblk.db [new file with mode: 0644]
8.x/vqtcl/doc/ratcl.html [new file with mode: 0644]
8.x/vqtcl/doc/ratcl.man [new file with mode: 0644]
8.x/vqtcl/doc/ratcl.n [new file with mode: 0644]
8.x/vqtcl/doc/vlerq.html [new file with mode: 0644]
8.x/vqtcl/doc/vlerq.man [new file with mode: 0644]
8.x/vqtcl/doc/vlerq.n [new file with mode: 0644]
8.x/vqtcl/generic/vlerq.c [new file with mode: 0644]
8.x/vqtcl/library/m2mvfs.tcl [new file with mode: 0644]
8.x/vqtcl/library/mkclvfs.tcl [new file with mode: 0644]
8.x/vqtcl/library/mklite.tcl [new file with mode: 0644]
8.x/vqtcl/library/ratcl.tcl [new file with mode: 0644]
8.x/vqtcl/license.terms [new file with mode: 0644]
8.x/vqtcl/pkgIndex.tcl.in [new file with mode: 0644]
8.x/vqtcl/tclconfig/install-sh [new file with mode: 0755]
8.x/vqtcl/tclconfig/tcl.m4 [new file with mode: 0644]
8.x/vqtcl/tests/all.tcl [new file with mode: 0755]
8.x/vqtcl/tests/basic.test [new file with mode: 0755]
8.x/vqtcl/tests/bits.test [new file with mode: 0755]
8.x/vqtcl/tests/blocked.test [new file with mode: 0755]
8.x/vqtcl/tests/column.test [new file with mode: 0755]
8.x/vqtcl/tests/commit.test [new file with mode: 0755]
8.x/vqtcl/tests/emit.test [new file with mode: 0755]
8.x/vqtcl/tests/error.test [new file with mode: 0755]
8.x/vqtcl/tests/file.test [new file with mode: 0755]
8.x/vqtcl/tests/get.test [new file with mode: 0755]
8.x/vqtcl/tests/hash.test [new file with mode: 0755]
8.x/vqtcl/tests/indirect.test [new file with mode: 0755]
8.x/vqtcl/tests/initests.tcl [new file with mode: 0644]
8.x/vqtcl/tests/kitten.test [new file with mode: 0755]
8.x/vqtcl/tests/l.large.test [new file with mode: 0755]
8.x/vqtcl/tests/l.leaks.test [new file with mode: 0644]
8.x/vqtcl/tests/loop.test [new file with mode: 0755]
8.x/vqtcl/tests/m2m.test [new file with mode: 0755]
8.x/vqtcl/tests/mkcl.test [new file with mode: 0755]
8.x/vqtcl/tests/mklite.test [new file with mode: 0755]
8.x/vqtcl/tests/mutable.test [new file with mode: 0755]
8.x/vqtcl/tests/ops.test [new file with mode: 0755]
8.x/vqtcl/tests/ratcl.test [new file with mode: 0755]
8.x/vqtcl/tests/ref.test [new file with mode: 0755]
8.x/vqtcl/tests/sorted.test [new file with mode: 0755]
8.x/vqtcl/tests/view.test [new file with mode: 0755]
8.x/vqtcl/win/makefile.vc [new file with mode: 0644]
8.x/vqtcl/win/nmakehlp.c [new file with mode: 0644]
8.x/vqtcl/win/rules.vc [new file with mode: 0644]
8.x/vqtcl/win/unistd.h [new file with mode: 0644]
8.x/zlib/CMakeLists.txt [new file with mode: 0644]
8.x/zlib/ChangeLog [new file with mode: 0644]
8.x/zlib/FAQ [new file with mode: 0644]
8.x/zlib/INDEX [new file with mode: 0644]
8.x/zlib/Makefile [new file with mode: 0644]
8.x/zlib/Makefile.in [new file with mode: 0644]
8.x/zlib/README [new file with mode: 0644]
8.x/zlib/adler32.c [new file with mode: 0644]
8.x/zlib/amiga/Makefile.pup [new file with mode: 0644]
8.x/zlib/amiga/Makefile.sas [new file with mode: 0644]
8.x/zlib/compress.c [new file with mode: 0644]
8.x/zlib/configure [new file with mode: 0755]
8.x/zlib/contrib/README.contrib [new file with mode: 0644]
8.x/zlib/contrib/ada/buffer_demo.adb [new file with mode: 0644]
8.x/zlib/contrib/ada/mtest.adb [new file with mode: 0644]
8.x/zlib/contrib/ada/read.adb [new file with mode: 0644]
8.x/zlib/contrib/ada/readme.txt [new file with mode: 0644]
8.x/zlib/contrib/ada/test.adb [new file with mode: 0644]
8.x/zlib/contrib/ada/zlib-streams.adb [new file with mode: 0644]
8.x/zlib/contrib/ada/zlib-streams.ads [new file with mode: 0644]
8.x/zlib/contrib/ada/zlib-thin.adb [new file with mode: 0644]
8.x/zlib/contrib/ada/zlib-thin.ads [new file with mode: 0644]
8.x/zlib/contrib/ada/zlib.adb [new file with mode: 0644]
8.x/zlib/contrib/ada/zlib.ads [new file with mode: 0644]
8.x/zlib/contrib/ada/zlib.gpr [new file with mode: 0644]
8.x/zlib/contrib/amd64/amd64-match.S [new file with mode: 0644]
8.x/zlib/contrib/asm686/README.686 [new file with mode: 0644]
8.x/zlib/contrib/asm686/match.S [new file with mode: 0644]
8.x/zlib/contrib/blast/Makefile [new file with mode: 0644]
8.x/zlib/contrib/blast/README [new file with mode: 0644]
8.x/zlib/contrib/blast/blast.c [new file with mode: 0644]
8.x/zlib/contrib/blast/blast.h [new file with mode: 0644]
8.x/zlib/contrib/blast/test.pk [new file with mode: 0644]
8.x/zlib/contrib/blast/test.txt [new file with mode: 0644]
8.x/zlib/contrib/delphi/ZLib.pas [new file with mode: 0644]
8.x/zlib/contrib/delphi/ZLibConst.pas [new file with mode: 0644]
8.x/zlib/contrib/delphi/readme.txt [new file with mode: 0644]
8.x/zlib/contrib/delphi/zlibd32.mak [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib.build [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib.chm [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib.sln [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/CodecBase.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/Deflater.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/DotZLib.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/GZipStream.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/Inflater.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/DotZLib/UnitTests.cs [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/LICENSE_1_0.txt [new file with mode: 0644]
8.x/zlib/contrib/dotzlib/readme.txt [new file with mode: 0644]
8.x/zlib/contrib/gcc_gvmat64/gvmat64.S [new file with mode: 0644]
8.x/zlib/contrib/infback9/README [new file with mode: 0644]
8.x/zlib/contrib/infback9/infback9.c [new file with mode: 0644]
8.x/zlib/contrib/infback9/infback9.h [new file with mode: 0644]
8.x/zlib/contrib/infback9/inffix9.h [new file with mode: 0644]
8.x/zlib/contrib/infback9/inflate9.h [new file with mode: 0644]
8.x/zlib/contrib/infback9/inftree9.c [new file with mode: 0644]
8.x/zlib/contrib/infback9/inftree9.h [new file with mode: 0644]
8.x/zlib/contrib/inflate86/inffas86.c [new file with mode: 0644]
8.x/zlib/contrib/inflate86/inffast.S [new file with mode: 0644]
8.x/zlib/contrib/iostream/test.cpp [new file with mode: 0644]
8.x/zlib/contrib/iostream/zfstream.cpp [new file with mode: 0644]
8.x/zlib/contrib/iostream/zfstream.h [new file with mode: 0644]
8.x/zlib/contrib/iostream2/zstream.h [new file with mode: 0644]
8.x/zlib/contrib/iostream2/zstream_test.cpp [new file with mode: 0644]
8.x/zlib/contrib/iostream3/README [new file with mode: 0644]
8.x/zlib/contrib/iostream3/TODO [new file with mode: 0644]
8.x/zlib/contrib/iostream3/test.cc [new file with mode: 0644]
8.x/zlib/contrib/iostream3/zfstream.cc [new file with mode: 0644]
8.x/zlib/contrib/iostream3/zfstream.h [new file with mode: 0644]
8.x/zlib/contrib/masmx64/bld_ml64.bat [new file with mode: 0644]
8.x/zlib/contrib/masmx64/gvmat64.asm [new file with mode: 0644]
8.x/zlib/contrib/masmx64/inffas8664.c [new file with mode: 0644]
8.x/zlib/contrib/masmx64/inffasx64.asm [new file with mode: 0644]
8.x/zlib/contrib/masmx64/readme.txt [new file with mode: 0644]
8.x/zlib/contrib/masmx86/bld_ml32.bat [new file with mode: 0644]
8.x/zlib/contrib/masmx86/inffas32.asm [new file with mode: 0644]
8.x/zlib/contrib/masmx86/match686.asm [new file with mode: 0644]
8.x/zlib/contrib/masmx86/readme.txt [new file with mode: 0644]
8.x/zlib/contrib/minizip/Makefile [new file with mode: 0644]
8.x/zlib/contrib/minizip/MiniZip64_Changes.txt [new file with mode: 0644]
8.x/zlib/contrib/minizip/MiniZip64_info.txt [new file with mode: 0644]
8.x/zlib/contrib/minizip/crypt.h [new file with mode: 0644]
8.x/zlib/contrib/minizip/ioapi.c [new file with mode: 0644]
8.x/zlib/contrib/minizip/ioapi.h [new file with mode: 0644]
8.x/zlib/contrib/minizip/iowin32.c [new file with mode: 0644]
8.x/zlib/contrib/minizip/iowin32.h [new file with mode: 0644]
8.x/zlib/contrib/minizip/make_vms.com [new file with mode: 0644]
8.x/zlib/contrib/minizip/miniunz.c [new file with mode: 0644]
8.x/zlib/contrib/minizip/minizip.c [new file with mode: 0644]
8.x/zlib/contrib/minizip/mztools.c [new file with mode: 0644]
8.x/zlib/contrib/minizip/mztools.h [new file with mode: 0644]
8.x/zlib/contrib/minizip/unzip.c [new file with mode: 0644]
8.x/zlib/contrib/minizip/unzip.h [new file with mode: 0644]
8.x/zlib/contrib/minizip/zip.c [new file with mode: 0644]
8.x/zlib/contrib/minizip/zip.h [new file with mode: 0644]
8.x/zlib/contrib/pascal/example.pas [new file with mode: 0644]
8.x/zlib/contrib/pascal/readme.txt [new file with mode: 0644]
8.x/zlib/contrib/pascal/zlibd32.mak [new file with mode: 0644]
8.x/zlib/contrib/pascal/zlibpas.pas [new file with mode: 0644]
8.x/zlib/contrib/puff/Makefile [new file with mode: 0644]
8.x/zlib/contrib/puff/README [new file with mode: 0644]
8.x/zlib/contrib/puff/puff.c [new file with mode: 0644]
8.x/zlib/contrib/puff/puff.h [new file with mode: 0644]
8.x/zlib/contrib/puff/zeros.raw [new file with mode: 0644]
8.x/zlib/contrib/testzlib/testzlib.c [new file with mode: 0644]
8.x/zlib/contrib/testzlib/testzlib.txt [new file with mode: 0644]
8.x/zlib/contrib/untgz/Makefile [new file with mode: 0644]
8.x/zlib/contrib/untgz/Makefile.msc [new file with mode: 0644]
8.x/zlib/contrib/untgz/untgz.c [new file with mode: 0644]
8.x/zlib/contrib/vstudio/readme.txt [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj.user [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj.user [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj.user [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.user [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlib.rc [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.user [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlibvc.def [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlibvc.sln [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.user [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/miniunz.vcproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/minizip.vcproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/testzlib.vcproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/testzlibdll.vcproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/zlib.rc [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/zlibstat.vcproj [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/zlibvc.def [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/zlibvc.sln [new file with mode: 0644]
8.x/zlib/contrib/vstudio/vc9/zlibvc.vcproj [new file with mode: 0644]
8.x/zlib/crc32.c [new file with mode: 0644]
8.x/zlib/crc32.h [new file with mode: 0644]
8.x/zlib/deflate.c [new file with mode: 0644]
8.x/zlib/deflate.h [new file with mode: 0644]
8.x/zlib/doc/algorithm.txt [new file with mode: 0644]
8.x/zlib/doc/rfc1950.txt [new file with mode: 0644]
8.x/zlib/doc/rfc1951.txt [new file with mode: 0644]
8.x/zlib/doc/rfc1952.txt [new file with mode: 0644]
8.x/zlib/doc/txtvsbin.txt [new file with mode: 0644]
8.x/zlib/example.c [new file with mode: 0644]
8.x/zlib/examples/README.examples [new file with mode: 0644]
8.x/zlib/examples/enough.c [new file with mode: 0644]
8.x/zlib/examples/fitblk.c [new file with mode: 0644]
8.x/zlib/examples/gun.c [new file with mode: 0644]
8.x/zlib/examples/gzappend.c [new file with mode: 0644]
8.x/zlib/examples/gzjoin.c [new file with mode: 0644]
8.x/zlib/examples/gzlog.c [new file with mode: 0644]
8.x/zlib/examples/gzlog.h [new file with mode: 0644]
8.x/zlib/examples/zlib_how.html [new file with mode: 0644]
8.x/zlib/examples/zpipe.c [new file with mode: 0644]
8.x/zlib/examples/zran.c [new file with mode: 0644]
8.x/zlib/gzclose.c [new file with mode: 0644]
8.x/zlib/gzguts.h [new file with mode: 0644]
8.x/zlib/gzlib.c [new file with mode: 0644]
8.x/zlib/gzread.c [new file with mode: 0644]
8.x/zlib/gzwrite.c [new file with mode: 0644]
8.x/zlib/infback.c [new file with mode: 0644]
8.x/zlib/inffast.c [new file with mode: 0644]
8.x/zlib/inffast.h [new file with mode: 0644]
8.x/zlib/inffixed.h [new file with mode: 0644]
8.x/zlib/inflate.c [new file with mode: 0644]
8.x/zlib/inflate.h [new file with mode: 0644]
8.x/zlib/inftrees.c [new file with mode: 0644]
8.x/zlib/inftrees.h [new file with mode: 0644]
8.x/zlib/make_vms.com [new file with mode: 0644]
8.x/zlib/minigzip.c [new file with mode: 0644]
8.x/zlib/msdos/Makefile.bor [new file with mode: 0644]
8.x/zlib/msdos/Makefile.dj2 [new file with mode: 0644]
8.x/zlib/msdos/Makefile.emx [new file with mode: 0644]
8.x/zlib/msdos/Makefile.msc [new file with mode: 0644]
8.x/zlib/msdos/Makefile.tc [new file with mode: 0644]
8.x/zlib/nintendods/Makefile [new file with mode: 0644]
8.x/zlib/nintendods/README [new file with mode: 0644]
8.x/zlib/old/Makefile.riscos [new file with mode: 0644]
8.x/zlib/old/README [new file with mode: 0644]
8.x/zlib/old/as400/bndsrc [new file with mode: 0644]
8.x/zlib/old/as400/compile.clp [new file with mode: 0644]
8.x/zlib/old/as400/readme.txt [new file with mode: 0644]
8.x/zlib/old/as400/zlib.inc [new file with mode: 0644]
8.x/zlib/old/descrip.mms [new file with mode: 0644]
8.x/zlib/old/os2/Makefile.os2 [new file with mode: 0644]
8.x/zlib/old/os2/zlib.def [new file with mode: 0644]
8.x/zlib/old/visual-basic.txt [new file with mode: 0644]
8.x/zlib/old/visualc6/README.txt [new file with mode: 0644]
8.x/zlib/old/visualc6/example.dsp [new file with mode: 0644]
8.x/zlib/old/visualc6/minigzip.dsp [new file with mode: 0644]
8.x/zlib/old/visualc6/zlib.dsp [new file with mode: 0644]
8.x/zlib/old/visualc6/zlib.dsw [new file with mode: 0644]
8.x/zlib/qnx/package.qpg [new file with mode: 0644]
8.x/zlib/treebuild.xml [new file with mode: 0644]
8.x/zlib/trees.c [new file with mode: 0644]
8.x/zlib/trees.h [new file with mode: 0644]
8.x/zlib/uncompr.c [new file with mode: 0644]
8.x/zlib/watcom/watcom_f.mak [new file with mode: 0644]
8.x/zlib/watcom/watcom_l.mak [new file with mode: 0644]
8.x/zlib/win32/DLL_FAQ.txt [new file with mode: 0644]
8.x/zlib/win32/Makefile.bor [new file with mode: 0644]
8.x/zlib/win32/Makefile.emx [new file with mode: 0644]
8.x/zlib/win32/Makefile.gcc [new file with mode: 0644]
8.x/zlib/win32/Makefile.msc [new file with mode: 0644]
8.x/zlib/win32/README-WIN32.txt [new file with mode: 0644]
8.x/zlib/win32/VisualC.txt [new file with mode: 0644]
8.x/zlib/win32/zlib.def [new file with mode: 0644]
8.x/zlib/win32/zlib1.rc [new file with mode: 0644]
8.x/zlib/zconf.h [new file with mode: 0644]
8.x/zlib/zconf.h.cmakein [new file with mode: 0644]
8.x/zlib/zconf.h.in [new file with mode: 0644]
8.x/zlib/zlib.3 [new file with mode: 0644]
8.x/zlib/zlib.3.pdf [new file with mode: 0644]
8.x/zlib/zlib.h [new file with mode: 0644]
8.x/zlib/zlib.map [new file with mode: 0644]
8.x/zlib/zlib.pc.in [new file with mode: 0644]
8.x/zlib/zlib2ansi [new file with mode: 0755]
8.x/zlib/zutil.c [new file with mode: 0644]
8.x/zlib/zutil.h [new file with mode: 0644]
makefile.include

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..ee59f99
--- /dev/null
@@ -0,0 +1,8 @@
+# Ignore directories created by the tools
+/sources
+/downloads
+/sources
+
+# Ignore the build directories but not the 8.x extensions directory
+/8.*/
+!/8.x
diff --git a/8.x/itcl/.cvsignore b/8.x/itcl/.cvsignore
new file mode 100644 (file)
index 0000000..3dfe125
--- /dev/null
@@ -0,0 +1,3 @@
+Makefile
+config.log
+confdefs.h
diff --git a/8.x/itcl/Makefile.in b/8.x/itcl/Makefile.in
new file mode 100644 (file)
index 0000000..a00ebbc
--- /dev/null
@@ -0,0 +1,412 @@
+# Makefile.in --
+#
+#      This file is a Makefile for Sample TEA Extension.  If it has the name
+#      "Makefile.in" then it is a template for a Makefile;  to generate the
+#      actual Makefile, run "./configure", which is a configuration script
+#      generated by the "autoconf" program (constructs like "@foo@" will get
+#      replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+# Copyright (c) 2002-2004 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: Makefile.in,v 1.30 2008/12/15 20:02:58 andreas_kupries Exp $
+
+#========================================================================
+# The names of the source files is defined in the configure script.
+# The object files are used for linking into the final library.
+# This will be used when a dist target is added to the Makefile.
+# It is not important to specify the directory, as long as it is the
+# $(srcdir) or in the generic, win or unix subdirectory.
+#========================================================================
+
+PKG_SOURCES    = @PKG_SOURCES@
+PKG_OBJECTS    = @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+#========================================================================
+# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
+# this package that need to be installed, if any.
+#========================================================================
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+
+#========================================================================
+# This is a list of header files to be installed
+# itk.h includes itclInt.h, which needs itclIntDecls.h,
+# so we must install them.
+#========================================================================
+
+PKG_HEADERS    = @PKG_HEADERS@
+
+#========================================================================
+# Nothing of the variables below this line need to be changed.  Please
+# check the TARGETS section below to make sure the make targets are
+# correct.
+#========================================================================
+
+#========================================================================
+# Change the name of the variable "exampleA_LIB_FILE" to match the one
+# used in the configure script.  This is the parameterized name of the
+# library that we are building.
+#========================================================================
+
+PKG_LIB_FILE   = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES   = $(PKG_LIB_FILE) $(PKG_STUB_LIB_FILE)
+BINARIES       = $(lib_BINARIES)
+
+SHELL          = @SHELL@
+
+srcdir         = @srcdir@
+prefix         = @prefix@
+exec_prefix    = @exec_prefix@
+
+bindir         = @bindir@
+libdir         = @libdir@
+datadir                = @datadir@
+mandir         = @mandir@
+includedir     = @includedir@
+
+DESTDIR                =
+
+PKG_DIR                = $(PACKAGE_NAME)$(PACKAGE_VERSION)
+pkgdatadir     = $(datadir)/$(PKG_DIR)
+pkglibdir      = $(libdir)/$(PKG_DIR)
+pkgincludedir  = $(includedir)/$(PKG_DIR)
+
+top_builddir   = .
+
+INSTALL                = @INSTALL@
+INSTALL_PROGRAM        = @INSTALL_PROGRAM@
+INSTALL_DATA   = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+PACKAGE_NAME   = @PACKAGE_NAME@
+PACKAGE_VERSION        = @PACKAGE_VERSION@
+CC             = @CC@
+CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+CLEANFILES     = @CLEANFILES@
+EXEEXT         = @EXEEXT@
+LDFLAGS_DEFAULT        = @LDFLAGS_DEFAULT@
+MAKE_LIB       = @MAKE_LIB@
+MAKE_SHARED_LIB        = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB        = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB  = @MAKE_STUB_LIB@
+OBJEXT         = @OBJEXT@
+RANLIB         = @RANLIB@
+RANLIB_STUB    = @RANLIB_STUB@
+SHLIB_CFLAGS   = @SHLIB_CFLAGS@
+SHLIB_LD       = @SHLIB_LD@
+SHLIB_LD_FLAGS = @SHLIB_LD_FLAGS@
+SHLIB_LD_LIBS  = @SHLIB_LD_LIBS@
+STLIB_LD       = @STLIB_LD@
+TCL_DEFS       = @TCL_DEFS@
+TCL_BIN_DIR    = @TCL_BIN_DIR@
+TCL_SRC_DIR    = @TCL_SRC_DIR@
+# This is necessary for packages that use private Tcl headers
+TCL_TOP_DIR_NATIVE = @TCL_TOP_DIR_NATIVE@
+
+# Not used, but retained for reference of what libs Tcl required
+TCL_LIBS       = @TCL_LIBS@
+
+#========================================================================
+# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
+# package without installing.  The other environment variables allow us
+# to test against an uninstalled Tcl.  Add special env vars that you
+# require for testing here (like TCLX_LIBRARY).
+#========================================================================
+
+EXTRA_PATH     = $(top_builddir):$(TCL_BIN_DIR)
+TCLSH_ENV      = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
+PKG_ENV                = ITCL_LIBRARY=`@CYGPATH@ $(srcdir)/library` \
+                 @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+                 PATH="$(EXTRA_PATH):$(PATH)" \
+                 TCLLIBPATH="$(top_builddir)"
+TCLSH_PROG     = $(TCLSH_ENV) @TCLSH_PROG@
+TCLSH          = $(PKG_ENV) $(TCLSH_PROG)
+SHARED_BUILD   = @SHARED_BUILD@
+
+INCLUDES       = @PKG_INCLUDES@ @TCL_INCLUDES@
+
+PKG_CFLAGS     = @PKG_CFLAGS@
+
+DEFS           = @DEFS@ $(PKG_CFLAGS) \
+                 -DITCL_LIBRARY=\"$(pkglibdir)\" -DUSE_NON_CONST
+
+CONFIG_CLEAN_FILES = @CONFIG_CLEAN_FILES@ Makefile itclConfig.sh pkgIndex.tcl
+
+CPPFLAGS       = @CPPFLAGS@
+LIBS           = @PKG_LIBS@ @LIBS@
+AR             = @AR@
+CFLAGS         = @CFLAGS@
+COMPILE                = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+#========================================================================
+# Start of user-definable TARGETS section
+#========================================================================
+
+#========================================================================
+# TEA TARGETS.  Please note that the "libraries:" target refers to platform
+# independent files, and the "binaries:" target inclues executable programs and
+# platform-dependent libraries.  Modify these targets so that they install
+# the various pieces of your package.  The make and install rules
+# for the BINARIES that you specified above have already been done.
+#========================================================================
+
+all: binaries libraries doc
+
+#========================================================================
+# The binaries target builds executable programs, Windows .dll's, unix
+# shared/static libraries, and any other platform-dependent files.
+# The list of targets to build for "binaries:" is specified at the top
+# of the Makefile, in the "BINARIES" variable.
+#========================================================================
+
+binaries: $(BINARIES)
+
+libraries:
+
+doc:
+
+install: all install-binaries install-libraries install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+
+#========================================================================
+# This rule installs platform-independent files, such as header files.
+#========================================================================
+
+install-libraries: libraries
+       @mkdir -p $(DESTDIR)$(includedir)
+       @echo "Installing header files in $(DESTDIR)$(includedir)"
+       @list='$(PKG_HEADERS)'; for i in $$list; do \
+           echo "Installing $(srcdir)/$$i" ; \
+           $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+       done;
+
+#========================================================================
+# Install documentation.  Unix manpages should go in the $(mandir)
+# directory.
+#========================================================================
+
+install-doc: doc
+       @mkdir -p $(DESTDIR)$(mandir)/mann
+       @echo "Installing man pages in $(DESTDIR)$(mandir)"
+       @cd $(srcdir)/doc; for i in *.n; do \
+           echo "Installing $$i"; \
+           rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
+           sed -e '/man\.macros/r man.macros' -e '/man\.macros/d' \
+               $$i > $(DESTDIR)$(mandir)/mann/$$i; \
+           chmod 444 $(DESTDIR)$(mandir)/mann/$$i; \
+       done
+
+test: binaries libraries
+       $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` -load "package require Itcl" $(TESTFLAGS)
+
+shell: binaries libraries
+       @$(TCLSH) $(SCRIPT)
+
+gdb:
+       $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+#========================================================================
+# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
+# mentioned above.  That will ensure that this target is built when you
+# run "make binaries".
+#
+# The $(PKG_OBJECTS) objects are created and linked into the final
+# library.  In most cases these object files will correspond to the
+# source files above.
+#========================================================================
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+       -rm -f $(PKG_LIB_FILE)
+       ${MAKE_LIB}
+       $(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+       -rm -f $(PKG_STUB_LIB_FILE)
+       ${MAKE_STUB_LIB}
+       $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#========================================================================
+# We need to enumerate the list of .c to .o lines here.
+#
+# In the following lines, $(srcdir) refers to the toplevel directory
+# containing your extension.  If your sources are in a subdirectory,
+# you will have to modify the paths to reflect this:
+#
+# exampleA.$(OBJEXT): $(srcdir)/generic/exampleA.c
+#      $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/exampleA.c` -o $@
+#
+# Setting the VPATH variable to a list of paths will cause the makefile
+# to look into these paths when resolving .c to .obj dependencies.
+# As necessary, add $(srcdir):$(srcdir)/compat:....
+#========================================================================
+
+VPATH = $(srcdir)/unix:$(srcdir)/generic:$(srcdir)/win
+
+.c.$(OBJEXT):
+       $(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#========================================================================
+# Distribution creation
+# You may need to tweak this target to make it work correctly.
+#========================================================================
+
+TAR            = tar
+#COMPRESS       = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS        = $(TAR) zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT       = /tmp/dist
+DIST_DIR        = $(DIST_ROOT)/$(PKG_DIR)
+
+dist-clean:
+       rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
+
+dist: dist-clean doc
+       mkdir -p $(DIST_DIR)
+       cp -p $(srcdir)/license* $(srcdir)/aclocal.m4 $(srcdir)/configure \
+               $(srcdir)/*.in  $(DIST_DIR)/
+       chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
+       chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
+
+       mkdir $(DIST_DIR)/tclconfig
+       cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
+               $(DIST_DIR)/tclconfig/
+       chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
+       chmod +x $(DIST_DIR)/tclconfig/install-sh
+
+       list='doc generic library tests win win/rc'; \
+       for p in $$list; do \
+           if test -d $(srcdir)/$$p ; then \
+               mkdir $(DIST_DIR)/$$p; \
+               for q in $(srcdir)/$$p/*; do \
+                   if test -f $$q ; then \
+                       cp -p $$q $(DIST_DIR)/$$p/; \
+                   fi; \
+               done; \
+           fi; \
+       done
+
+       list='CHANGES ChangeLog INCOMPATIBLE README TODO'; \
+       for p in $$list; do \
+           if test -f $(srcdir)/../$$p ; then \
+               cp -p $(srcdir)/../$$p $(DIST_DIR)/; \
+           fi; \
+       done
+
+       (cd $(DIST_ROOT); $(COMPRESS);)
+
+#========================================================================
+# End of user-definable section
+#========================================================================
+
+#========================================================================
+# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
+# variable in configure.in
+#========================================================================
+
+clean:  
+       -test -z "$(BINARIES)" || rm -f $(BINARIES)
+       -rm -f *.o core *.core
+       -rm -f *.$(OBJEXT)
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+       -rm -f *.tab.c
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log config.status
+
+#========================================================================
+# Install binary object libraries.  On Windows this includes both .dll and
+# .lib files.  Because the .lib files are not explicitly listed anywhere,
+# we need to deduce their existence from the .dll file of the same name.
+# Additionally, the .dll files go into the bin directory, but the .lib
+# files go into the lib directory.  On Unix platforms, all library files
+# go into the lib directory.  In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh8.2 shell)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-lib-binaries:
+       @mkdir -p $(DESTDIR)$(pkglibdir)
+       @list='$(lib_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+           stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
+           if test "x$$stub" = "xstub"; then \
+               echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
+           else \
+               echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
+           fi; \
+           ext=`echo $$p|sed -e "s/.*\.//"`; \
+           if test "x$$ext" = "xdll"; then \
+               lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+               if test -f $$lib; then \
+                   echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
+                   $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+               fi; \
+           fi; \
+         fi; \
+       done
+       @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         if test -f $(srcdir)/$$p; then \
+           destp=`basename $$p`; \
+           echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
+           $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
+         fi; \
+       done
+       $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir)
+       $(INSTALL_DATA) itclConfig.sh $(DESTDIR)$(libdir)
+
+#========================================================================
+# Install binary executables (e.g. .exe files)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-bin-binaries:
+       @mkdir -p $(DESTDIR)$(bindir)
+       @list='$(bin_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+         fi; \
+       done
+
+.SUFFIXES: .c .$(OBJEXT)
+
+#Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+#      cd $(top_builddir) \
+#        && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+       list='$(lib_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         p=`basename $$p`; \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(bin_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/$$p; \
+       done
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/8.x/itcl/aclocal.m4 b/8.x/itcl/aclocal.m4
new file mode 100644 (file)
index 0000000..0f09fb8
--- /dev/null
@@ -0,0 +1 @@
+builtin(include,tclconfig/tcl.m4)
diff --git a/8.x/itcl/configure b/8.x/itcl/configure
new file mode 100755 (executable)
index 0000000..317dfb8
--- /dev/null
@@ -0,0 +1,10503 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for itcl 3.4.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='itcl'
+PACKAGE_TARNAME='itcl'
+PACKAGE_VERSION='3.4'
+PACKAGE_STRING='itcl 3.4'
+PACKAGE_BUGREPORT=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS LN_S CONFIG_CLEAN_FILES TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS PKG_SOURCES PKG_OBJECTS CLEANFILES TCL_TOP_DIR_NATIVE TCL_GENERIC_DIR_NATIVE TCL_UNIX_DIR_NATIVE TCL_WIN_DIR_NATIVE TCL_BMAP_DIR_NATIVE TCL_TOOL_DIR_NATIVE TCL_PLATFORM_DIR_NATIVE TCL_INCLUDES SHARED_BUILD AR CELIB_DIR LIBOBJS DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS LD_LIBRARY_PATH_VAR TCL_DBGX CFLAGS_DEFAULT LDFLAGS_DEFAULT MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB itcl_STUB_LIB_FILE itcl_LIB_FILE TCLSH_PROG itcl_BUILD_LIB_SPEC itcl_LIB_SPEC itcl_BUILD_STUB_LIB_SPEC itcl_STUB_LIB_SPEC itcl_BUILD_STUB_LIB_PATH itcl_STUB_LIB_PATH itcl_SRC_DIR LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures itcl 3.4 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of itcl 3.4:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-shared         build and link with shared libraries (default: on)
+  --enable-64bit          enable 64bit support (default: off)
+  --enable-64bit-vis      enable 64bit Sparc VIS support (default: off)
+  --enable-wince          enable Win/CE support (where applicable)
+  --enable-load           allow dynamic loading and "load" command (default:
+                          on)
+  --enable-symbols        build with debugging symbols (default: off)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-tcl              directory containing tcl configuration
+                          (tclConfig.sh)
+  --with-celib=DIR        use Windows/CE support library from DIR
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+itcl configure 3.4
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by itcl $as_me 3.4, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.6"
+
+    echo "$as_me:$LINENO: checking for correct TEA configuration" >&5
+echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6
+    if test x"${PACKAGE_NAME}" = x ; then
+       { { echo "$as_me:$LINENO: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5
+echo "$as_me: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test x"3.6" = x ; then
+       { { echo "$as_me:$LINENO: error:
+TEA version not specified." >&5
+echo "$as_me: error:
+TEA version not specified." >&2;}
+   { (exit 1); exit 1; }; }
+    elif test "3.6" != "${TEA_VERSION}" ; then
+       echo "$as_me:$LINENO: result: warning: requested TEA version \"3.6\", have \"${TEA_VERSION}\"" >&5
+echo "${ECHO_T}warning: requested TEA version \"3.6\", have \"${TEA_VERSION}\"" >&6
+    else
+       echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5
+echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+           # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CYGPATH+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CYGPATH"; then
+  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CYGPATH="cygpath -w"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+  echo "$as_me:$LINENO: result: $CYGPATH" >&5
+echo "${ECHO_T}$CYGPATH" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+
+
+
+    # This package name must be replaced statically for AC_SUBST to work
+
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+
+
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+CONFIG_CLEAN_FILES=
+if test ! -d $srcdir/tclconfig ; then
+    if test -d $srcdir/../tclconfig ; then
+       $LN_S $srcdir/../tclconfig tclconfig
+       CONFIG_CLEAN_FILES=tclconfig
+    fi
+fi
+
+
+ac_aux_dir=
+for ac_dir in tclconfig $srcdir/tclconfig; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+
+
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+
+# Check whether --with-tcl or --without-tcl was given.
+if test "${with_tcl+set}" = set; then
+  withval="$with_tcl"
+  with_tclconfig=${withval}
+fi;
+       echo "$as_me:$LINENO: checking for Tcl configuration" >&5
+echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6
+       if test "${ac_cv_c_tclconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
+echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5
+echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+
+fi
+
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           { echo "$as_me:$LINENO: WARNING: Can't find Tcl configuration definitions" >&5
+echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;}
+           exit 0
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6
+       fi
+    fi
+
+
+    echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        echo "$as_me:$LINENO: result: loading" >&5
+echo "${ECHO_T}loading" >&6
+       . ${TCL_BIN_DIR}/tclConfig.sh
+    else
+        echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f ${TCL_BIN_DIR}/Makefile ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f ${TCL_BIN_DIR}/${TCL_LIB_FILE}; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
+echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
+           prefix=${TCL_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5
+echo "$as_me: --prefix defaulting to /usr/local" >&6;}
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
+echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5
+echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;}
+           exec_prefix=$prefix
+       fi
+    fi
+
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
+# the basic setup necessary to compile executables.
+#-----------------------------------------------------------------------
+
+
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+    # Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5
+echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6
+if test "${tcl_cv_cc_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_pipe=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_pipe=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5
+echo "${ECHO_T}$tcl_cv_cc_pipe" >&6
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+    if test "${TEA_PLATFORM}" = "unix" ; then
+
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking for sin" >&5
+echo $ECHO_N "checking for sin... $ECHO_C" >&6
+if test "${ac_cv_func_sin+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define sin to an innocuous variant, in case <limits.h> declares sin.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define sin innocuous_sin
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char sin (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef sin
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char sin ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_sin) || defined (__stub___sin)
+choke me
+#else
+char (*f) () = sin;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != sin;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_sin=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_sin=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5
+echo "${ECHO_T}$ac_cv_func_sin" >&6
+if test $ac_cv_func_sin = yes; then
+  MATH_LIBS=""
+else
+  MATH_LIBS="-lm"
+fi
+
+    echo "$as_me:$LINENO: checking for main in -lieee" >&5
+echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6
+if test "${ac_cv_lib_ieee_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lieee  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ieee_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ieee_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5
+echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6
+if test $ac_cv_lib_ieee_main = yes; then
+  MATH_LIBS="-lieee $MATH_LIBS"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking for main in -linet" >&5
+echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6
+if test "${ac_cv_lib_inet_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5
+echo "${ECHO_T}$ac_cv_lib_inet_main" >&6
+if test $ac_cv_lib_inet_main = yes; then
+  LIBS="$LIBS -linet"
+fi
+
+    if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking net/errno.h usability" >&5
+echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <net/errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking net/errno.h presence" >&5
+echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <net/errno.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: net/errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_net_errno_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
+
+fi
+if test $ac_cv_header_net_errno_h = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NET_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+if test $ac_cv_func_connect = yes; then
+  tcl_checkSocket=0
+else
+  tcl_checkSocket=1
+fi
+
+    if test "$tcl_checkSocket" = 1; then
+       echo "$as_me:$LINENO: checking for setsockopt" >&5
+echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6
+if test "${ac_cv_func_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define setsockopt to an innocuous variant, in case <limits.h> declares setsockopt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define setsockopt innocuous_setsockopt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char setsockopt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef setsockopt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char setsockopt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_setsockopt) || defined (__stub___setsockopt)
+choke me
+#else
+char (*f) () = setsockopt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != setsockopt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_setsockopt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_func_setsockopt" >&6
+if test $ac_cv_func_setsockopt = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5
+echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char setsockopt ();
+int
+main ()
+{
+setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_setsockopt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6
+if test $ac_cv_lib_socket_setsockopt = yes; then
+  LIBS="$LIBS -lsocket"
+else
+  tcl_checkBoth=1
+fi
+
+fi
+
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       echo "$as_me:$LINENO: checking for accept" >&5
+echo $ECHO_N "checking for accept... $ECHO_C" >&6
+if test "${ac_cv_func_accept+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define accept to an innocuous variant, in case <limits.h> declares accept.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define accept innocuous_accept
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char accept (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef accept
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char accept ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_accept) || defined (__stub___accept)
+choke me
+#else
+char (*f) () = accept;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != accept;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_accept=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_accept=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5
+echo "${ECHO_T}$ac_cv_func_accept" >&6
+if test $ac_cv_func_accept = yes; then
+  tcl_checkNsl=0
+else
+  LIBS=$tk_oldLibs
+fi
+
+    fi
+    echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+char (*f) () = gethostbyname;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != gethostbyname;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
+if test $ac_cv_func_gethostbyname = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  LIBS="$LIBS -lnsl"
+fi
+
+fi
+
+
+    # Don't perform the eval of the libraries here because DL_LIBS
+    # won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+
+
+
+
+    echo "$as_me:$LINENO: checking dirent.h" >&5
+echo $ECHO_N "checking dirent.h... $ECHO_C" >&6
+if test "${tcl_cv_dirent_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_dirent_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_dirent_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5
+echo "${ECHO_T}$tcl_cv_dirent_h" >&6
+
+    if test $tcl_cv_dirent_h = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DIRENT_H 1
+_ACEOF
+
+    fi
+
+    if test "${ac_cv_header_errno_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking errno.h usability" >&5
+echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking errno.h presence" >&5
+echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <errno.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_errno_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+
+fi
+if test $ac_cv_header_errno_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_float_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking float.h usability" >&5
+echo $ECHO_N "checking float.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <float.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking float.h presence" >&5
+echo $ECHO_N "checking float.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <float.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: float.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_float_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6
+
+fi
+if test $ac_cv_header_float_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_FLOAT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_values_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking values.h usability" >&5
+echo $ECHO_N "checking values.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <values.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking values.h presence" >&5
+echo $ECHO_N "checking values.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <values.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: values.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_values_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6
+
+fi
+if test $ac_cv_header_values_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_VALUES_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_limits_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking limits.h usability" >&5
+echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <limits.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking limits.h presence" >&5
+echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <limits.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: limits.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_limits_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6
+
+fi
+if test $ac_cv_header_limits_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIMITS_H 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_LIMITS_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking stdlib.h usability" >&5
+echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <stdlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking stdlib.h presence" >&5
+echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: stdlib.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_stdlib_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
+
+fi
+if test $ac_cv_header_stdlib_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtol" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtoul" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtod" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STDLIB_H 1
+_ACEOF
+
+    fi
+    if test "${ac_cv_header_string_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking string.h usability" >&5
+echo $ECHO_N "checking string.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <string.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking string.h presence" >&5
+echo $ECHO_N "checking string.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: string.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_string_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6
+
+fi
+if test $ac_cv_header_string_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strstr" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strerror" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STRING_H 1
+_ACEOF
+
+    fi
+
+    if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/wait.h usability" >&5
+echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <sys/wait.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/wait.h presence" >&5
+echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/wait.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_wait_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+
+fi
+if test $ac_cv_header_sys_wait_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking dlfcn.h usability" >&5
+echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <dlfcn.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking dlfcn.h presence" >&5
+echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <dlfcn.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_dlfcn_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+
+fi
+if test $ac_cv_header_dlfcn_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DLFCN_H 1
+_ACEOF
+
+fi
+
+
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+
+for ac_header in sys/param.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the itcl lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+
+    vars="itclStubInit.c
+               itcl_bicmds.c
+               itcl_class.c
+               itcl_cmds.c
+               itcl_ensemble.c
+               itcl_linkage.c
+               itcl_methods.c
+               itcl_migrate.c
+               itcl_objects.c
+               itcl_parse.c
+               itcl_util.c"
+    for i in $vars; do
+       case $i in
+           \$*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5
+echo "$as_me: error: could not find source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+
+
+
+
+    vars="generic/itcl.h
+               generic/itclDecls.h
+               generic/itclInt.h
+               generic/itclIntDecls.h"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+
+
+
+    vars="-I\"`${CYGPATH} ${srcdir}/generic`\""
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+
+
+
+    vars=""
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+
+    PKG_CFLAGS="$PKG_CFLAGS "
+
+
+
+    vars="itclStubLib.c"
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5
+echo "$as_me: error: could not find stub source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+
+
+
+
+    vars="library/itcl.tcl"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+
+
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_itcl in this case) so
+# that we create the export library with the dll.  See sha1.h on how
+# to use this.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
+# These will be appended to the current set of compiler flags for
+# your system.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    cat >>confdefs.h <<\_ACEOF
+#define BUILD_itcl 1
+_ACEOF
+
+    CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+
+    vars="dllEntryPoint.c"
+    for i in $vars; do
+       case $i in
+           \$*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5
+echo "$as_me: error: could not find source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+
+
+
+else
+    CLEANFILES=
+    #TEA_ADD_SOURCES([])
+fi
+
+
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This must be done AFTER calling TEA_PATH_TCLCONFIG/TEA_LOAD_TCLCONFIG
+# so that we can extract TCL_SRC_DIR from the config file (in the case
+# of private headers
+#--------------------------------------------------------------------
+
+#TEA_PUBLIC_TCL_HEADERS
+
+    echo "$as_me:$LINENO: checking for Tcl private include files" >&5
+echo $ECHO_N "checking for Tcl private include files... $ECHO_C" >&6
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+    TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+    TCL_UNIX_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+    TCL_WIN_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+    TCL_BMAP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/bitmaps\"
+    TCL_TOOL_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/tools\"
+    TCL_COMPAT_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/compat\"
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       TCL_PLATFORM_DIR_NATIVE=${TCL_WIN_DIR_NATIVE}
+    else
+       TCL_PLATFORM_DIR_NATIVE=${TCL_UNIX_DIR_NATIVE}
+    fi
+    # We want to ensure these are substituted so as not to require
+    # any *_NATIVE vars be defined in the Makefile
+    TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+    if test "`uname -s`" = "Darwin"; then
+        # If Tcl was built as a framework, attempt to use
+        # the framework's Headers and PrivateHeaders directories
+        case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -d "${TCL_BIN_DIR}/Headers" -a -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+               TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"; else
+               TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"; fi
+               ;;
+       esac
+    else
+       if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+           { { echo "$as_me:$LINENO: error: Cannot find private header tclInt.h in ${TCL_SRC_DIR}" >&5
+echo "$as_me: error: Cannot find private header tclInt.h in ${TCL_SRC_DIR}" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+    fi
+
+
+
+
+
+
+
+
+
+
+
+    echo "$as_me:$LINENO: result: Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}" >&5
+echo "${ECHO_T}Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}" >&6
+
+
+#--------------------------------------------------------------------
+# We need to enable the threading macros found in tcl.h and tclInt.h.
+# The use of the threading features is determined by the core the
+# extension is loaded into, but we need to compile with these macros
+# turned on.
+#--------------------------------------------------------------------
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_THREADS 1
+_ACEOF
+
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+#TEA_ENABLE_THREADS
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+
+    echo "$as_me:$LINENO: checking how to build libraries" >&5
+echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6
+    # Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       echo "$as_me:$LINENO: result: shared" >&5
+echo "${ECHO_T}shared" >&6
+       SHARED_BUILD=1
+    else
+       echo "$as_me:$LINENO: result: static" >&5
+echo "${ECHO_T}static" >&6
+       SHARED_BUILD=0
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_BUILD 1
+_ACEOF
+
+    fi
+
+
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+
+
+
+    # Step 0.a: Enable 64 bit support?
+
+    echo "$as_me:$LINENO: checking if 64bit support is requested" >&5
+echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6
+    # Check whether --enable-64bit or --disable-64bit was given.
+if test "${enable_64bit+set}" = set; then
+  enableval="$enable_64bit"
+  do64bit=$enableval
+else
+  do64bit=no
+fi;
+    echo "$as_me:$LINENO: result: $do64bit" >&5
+echo "${ECHO_T}$do64bit" >&6
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5
+echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6
+    # Check whether --enable-64bit-vis or --disable-64bit-vis was given.
+if test "${enable_64bit_vis+set}" = set; then
+  enableval="$enable_64bit_vis"
+  do64bitVIS=$enableval
+else
+  do64bitVIS=no
+fi;
+    echo "$as_me:$LINENO: result: $do64bitVIS" >&5
+echo "${ECHO_T}$do64bitVIS" >&6
+
+    if test "$do64bitVIS" = "yes"; then
+       # Force 64bit on with VIS
+       do64bit=yes
+    fi
+
+    # Step 0.c: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5
+echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6
+       # Check whether --enable-wince or --disable-wince was given.
+if test "${enable_wince+set}" = set; then
+  enableval="$enable_wince"
+  doWince=$enableval
+else
+  doWince=no
+fi;
+       echo "$as_me:$LINENO: result: $doWince" >&5
+echo "${ECHO_T}$doWince" >&6
+    fi
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+
+    echo "$as_me:$LINENO: checking system version" >&5
+echo $ECHO_N "checking system version... $ECHO_C" >&6
+if test "${tcl_cv_sys_version+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5
+echo "$as_me: WARNING: can't find uname command" >&2;}
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $3}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5
+echo "${ECHO_T}$tcl_cv_sys_version" >&6
+    system=$tcl_cv_sys_version
+
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  have_dl=yes
+else
+  have_dl=no
+fi
+
+
+    # Require ranlib early so we can override it in special cases below.
+
+
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    if test "$GCC" = "yes" ; then
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall -Wno-implicit-int"
+    else
+       CFLAGS_WARNING=""
+    fi
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+    # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    case $system in
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+                   { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5
+echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+                   do64bit="no"
+               else
+                   echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
+echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5
+echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               if test "$GCC" = "yes" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5
+echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+
+# Check whether --with-celib or --without-celib was given.
+if test "${with_celib+set}" = set; then
+  withval="$with_celib"
+  with_celibconfig=${withval}
+fi;
+       echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
+echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6
+       if test "${ac_cv_c_celibconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5
+echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+fi
+
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5
+echo "$as_me: error: Cannot find celib support library directory" >&2;}
+   { (exit 1); exit 1; }; }
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5
+echo "${ECHO_T}found $CELIB_DIR" >&6
+       fi
+    fi
+
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
+           if ($1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
+           if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
+           if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5
+echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;}
+   { (exit 1); exit 1; }; }
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+
+    vars="bufferoverflowU.lib"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower($0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+
+cat >>confdefs.h <<_ACEOF
+#define $i 1
+_ACEOF
+
+                   done
+
+cat >>confdefs.h <<_ACEOF
+#define _WIN32_WCE $CEVERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNDER_CE $CEVERSION
+_ACEOF
+
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r)
+                       # ok ...
+                       ;;
+                   *)
+                       CC=${CC}_r
+                       ;;
+               esac
+               echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5
+echo "${ECHO_T}Using $CC for compiling with threads" >&6
+           fi
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
+               if test "$GCC" = "yes" ; then
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+               fi
+           fi
+
+           if test "`uname -m`" = "ia64" ; then
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               if test "$GCC" = "yes" ; then
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               else
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+               fi
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           else
+               if test "$GCC" = "yes" ; then
+                   SHLIB_LD="gcc -shared"
+               else
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+               fi
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+           fi
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
+               case $LIBOBJS in
+    "tclLoadAix.$ac_objext"   | \
+  *" tclLoadAix.$ac_objext"   | \
+    "tclLoadAix.$ac_objext "* | \
+  *" tclLoadAix.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;;
+esac
+
+               DL_LIBS="-lld"
+           fi
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5
+echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6
+if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gettimeofday ();
+int
+main ()
+{
+gettimeofday ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bsd_gettimeofday=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bsd_gettimeofday=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5
+echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6
+if test $ac_cv_lib_bsd_gettimeofday = yes; then
+  libbsd=yes
+else
+  libbsd=no
+fi
+
+           if test $libbsd = yes; then
+               MATH_LIBS="$MATH_LIBS -lbsd"
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_DELTA_FOR_TZ 1
+_ACEOF
+
+           fi
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -nostart"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5
+echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6
+if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbind  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_ntoa ();
+int
+main ()
+{
+inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bind_inet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bind_inet_ntoa=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6
+if test $ac_cv_lib_bind_inet_ntoa = yes; then
+  LIBS="$LIBS -lbind -lsocket"
+fi
+
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD="cc -shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+
+cat >>confdefs.h <<\_ACEOF
+#define _XOPEN_SOURCE_EXTENDED 1
+_ACEOF
+
+           # Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           if test "`uname -m`" = "ia64" ; then
+               SHLIB_SUFFIX=".so"
+           else
+               SHLIB_SUFFIX=".sl"
+           fi
+           echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="gcc -shared"
+               SHLIB_LD_LIBS='${LIBS}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+
+           # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+           #CFLAGS="$CFLAGS +DAportable"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   hpux_arch=`${CC} -dumpmachine`
+                   case $hpux_arch in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD="${CC} -shared"
+                           SHLIB_LD_LIBS='${LIBS}'
+                           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+                           ;;
+                   esac
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+               fi
+           fi
+           ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+           else
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+           fi
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5
+echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
+               else
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               fi
+           fi
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           if test $do64bit = yes; then
+               echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_m64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_m64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_m64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                   CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5
+echo "${ECHO_T}$tcl_cv_cc_m64" >&6
+               if test $tcl_cv_cc_m64 = yes; then
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+               fi
+           fi
+
+           # The combo of gcc + glibc has a bug related
+           # to inlining of functions like strtod(). The
+           # -fno-builtin flag should address this problem
+           # but it does not work. The -fno-inline flag
+           # is kind of overkill but it works.
+           # Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+           if test x"${USE_COMPAT}" != x ; then
+               CFLAGS="$CFLAGS -fno-inline"
+           fi
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD="${CC} -shared"
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD="${CC} -shared "
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-*|FreeBSD-[1-2].*)
+           # NetBSD/SPARC needs -fPIC, -fpic will not do.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6
+           if test $tcl_cv_ld_elf = yes; then
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+           else
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           fi
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
+           case `machine` in
+           sparc|sparc64)
+               SHLIB_CFLAGS="-fPIC";;
+           *)
+               SHLIB_CFLAGS="-fpic";;
+           esac
+           SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6
+           if test $tcl_cv_ld_elf = yes; then
+               LDFLAGS=-Wl,-export-dynamic
+           else
+               LDFLAGS=""
+           fi
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       FreeBSD-*)
+           # FreeBSD 3.* and greater have ELF.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "${TCL_THREADS}" = "1" ; then
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+           fi
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           # To avoid discrepancies between what headers configure sees during
+           # preprocessing tests and compiling tests, move any -isysroot and
+           # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+           CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
+           CFLAGS="`echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
+           if test $do64bit = yes; then
+               case `arch` in
+                   ppc)
+                       echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_arch_ppc64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_arch_ppc64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_arch_ppc64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6
+                       if test $tcl_cv_cc_arch_ppc64 = yes; then
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+                       fi;;
+                   i386)
+                       echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_arch_x86_64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_arch_x86_64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_arch_x86_64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6
+                       if test $tcl_cv_cc_arch_x86_64 = yes; then
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+                       fi;;
+                   *)
+                       { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
+               esac
+           else
+               # Check for combined 32-bit and 64-bit fat build
+               echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
+                   echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
+                   fat_32_64=yes
+           fi
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5
+echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_single_module+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_single_module=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_single_module=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5
+echo "${ECHO_T}$tcl_cv_ld_single_module" >&6
+           if test $tcl_cv_ld_single_module = yes; then
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+           fi
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
+               "`echo "${CFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4 && \
+               LDFLAGS="$LDFLAGS -prebind"
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5
+echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_search_paths_first+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_search_paths_first=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_search_paths_first=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5
+echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6
+           if test $tcl_cv_ld_search_paths_first = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+
+           # TEA specific: for Tk extensions, remove 64-bit arch flags from
+           # CFLAGS for combined 32-bit and 64-bit fat builds as neither TkAqua
+           # nor TkX11 can be built for 64-bit at present.
+           test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}" && \
+               CFLAGS="`echo "$CFLAGS " | sed -e 's/-arch ppc64 / /g' -e 's/-arch x86_64 / /g'`"
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="cc -nostdlib -r"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+
+cat >>confdefs.h <<\_ACEOF
+#define _OE_SOCKETS 1
+_ACEOF
+
+           ;;
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export :'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD="ld -shared"
+           else
+               SHLIB_LD="ld -non_shared"
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+           else
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mieee"
+            else
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+           fi
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           if test "${TCL_THREADS}" = "1" ; then
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               if test "$GCC" = "yes" ; then
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+               else
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+               fi
+           fi
+
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           if test "$GCC" = "yes" ; then
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+           else
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+           fi
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[0-6])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               arch=`isainfo`
+               if test "$arch" = "sparcv9 sparc" ; then
+                       if test "$GCC" = "yes" ; then
+                           if test "`gcc -dumpversion | awk -F. '{print $1}'`" -lt "3" ; then
+                               { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
+                           else
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                               LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                               SHLIB_CFLAGS="-fPIC"
+                           fi
+                       else
+                           do64bit_ok=yes
+                           if test "$do64bitVIS" = "yes" ; then
+                               CFLAGS="$CFLAGS -xarch=v9a"
+                               LDFLAGS_ARCH="-xarch=v9a"
+                           else
+                               CFLAGS="$CFLAGS -xarch=v9"
+                               LDFLAGS_ARCH="-xarch=v9"
+                           fi
+                           # Solaris 64 uses this as well
+                           #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+                       fi
+               elif test "$arch" = "amd64 i386" ; then
+                   if test "$GCC" = "yes" ; then
+                       { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+                   else
+                       do64bit_ok=yes
+                       CFLAGS="$CFLAGS -xarch=amd64"
+                       LDFLAGS="$LDFLAGS -xarch=amd64"
+                   fi
+               else
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5
+echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+               fi
+           fi
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               if test "$do64bit_ok" = "yes" ; then
+                   # We need to specify -static-libgcc or we need to
+                   # add the path to the sparv9 libgcc.
+                   # JH: static-libgcc is necessary for core Tcl, but may
+                   # not be necessary for extensions.
+                   SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                   # for finding sparcv9 libgcc, get the regular libgcc
+                   # path, remove so name and append 'sparcv9'
+                   #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                   #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+               fi
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           fi
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5
+echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_Bexport+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_Bexport=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_Bexport=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5
+echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6
+           if test $tcl_cv_ld_Bexport = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
+       { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+    fi
+
+
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    # Check whether --enable-load or --disable-load was given.
+if test "${enable_load+set}" = set; then
+  enableval="$enable_load"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+    if test "$tcl_ok" = "no"; then
+       DL_OBJS=""
+    fi
+
+    if test "x$DL_OBJS" != "x" ; then
+       BUILD_DLTEST="\$(DLTEST_TARGETS)"
+    else
+       echo "Can't figure out how to do dynamic loading or shared libraries"
+       echo "on this system."
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+    fi
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$DL_OBJS" != "tclLoadNone.o" ; then
+       if test "$GCC" = "yes" ; then
+           case $system in
+               AIX-*)
+                   ;;
+               BSD/OS*)
+                   ;;
+               IRIX*)
+                   ;;
+               NetBSD-*|FreeBSD-*)
+                   ;;
+               Darwin-*)
+                   ;;
+               SCO_SV-3.2*)
+                   ;;
+               windows)
+                   ;;
+               *)
+                   SHLIB_CFLAGS="-fPIC"
+                   ;;
+           esac
+       fi
+    fi
+
+    if test "$SHARED_LIB_SUFFIX" = "" ; then
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+    fi
+    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+    fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+
+    echo "$as_me:$LINENO: checking for required early compiler flags" >&5
+echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6
+    tcl_flags=""
+
+    if test "${tcl_cv_flag__isoc99_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__isoc99_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__isoc99_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__isoc99_source=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _ISOC99_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _ISOC99_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile64_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile64_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE64_SOURCE 1
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile64_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__largefile64_source=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE64_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile_source64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile_source64=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE_SOURCE64 1
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile_source64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__largefile_source64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE_SOURCE64 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
+    fi
+
+    if test "x${tcl_flags}" = "x" ; then
+       echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+    else
+       echo "$as_me:$LINENO: result: ${tcl_flags}" >&5
+echo "${ECHO_T}${tcl_flags}" >&6
+    fi
+
+
+    echo "$as_me:$LINENO: checking for 64-bit integer type" >&5
+echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6
+    if test "${tcl_cv_type_64bit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__int64 value = (__int64) 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_type_64bit=__int64
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_type_64bit="long long"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+switch (0) {
+            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+        }
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_type_64bit=${tcl_type_64bit}
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "${tcl_cv_type_64bit}" = none ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_WIDE_INT_IS_LONG 1
+_ACEOF
+
+       echo "$as_me:$LINENO: result: using long" >&5
+echo "${ECHO_T}using long" >&6
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # We actually want to use the default tcl.h checks in this
+       # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       echo "$as_me:$LINENO: result: using Tcl header defaults" >&5
+echo "${ECHO_T}using Tcl header defaults" >&6
+    else
+
+cat >>confdefs.h <<_ACEOF
+#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
+_ACEOF
+
+       echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5
+echo "${ECHO_T}${tcl_cv_type_64bit}" >&6
+
+       # Now check for auxiliary declarations
+       echo "$as_me:$LINENO: checking for struct dirent64" >&5
+echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6
+if test "${tcl_cv_struct_dirent64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/dirent.h>
+int
+main ()
+{
+struct dirent64 p;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_struct_dirent64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_struct_dirent64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5
+echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_DIRENT64 1
+_ACEOF
+
+       fi
+
+       echo "$as_me:$LINENO: checking for struct stat64" >&5
+echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6
+if test "${tcl_cv_struct_stat64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 p;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_struct_stat64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_struct_stat64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5
+echo "${ECHO_T}$tcl_cv_struct_stat64" >&6
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_STAT64 1
+_ACEOF
+
+       fi
+
+
+
+for ac_func in open64 lseek64
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+       echo "$as_me:$LINENO: checking for off64_t" >&5
+echo $ECHO_N "checking for off64_t... $ECHO_C" >&6
+       if test "${tcl_cv_type_off64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+off64_t offset;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_type_off64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_type_off64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+                       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TYPE_OFF64_T 1
+_ACEOF
+
+           echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+           echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+       fi
+    fi
+
+
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols
+# option.
+#--------------------------------------------------------------------
+
+
+
+    echo "$as_me:$LINENO: checking for build with symbols" >&5
+echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6
+    # Check whether --enable-symbols or --disable-symbols was given.
+if test "${enable_symbols+set}" = set; then
+  enableval="$enable_symbols"
+  tcl_ok=$enableval
+else
+  tcl_ok=no
+fi;
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
+echo "${ECHO_T}yes (standard debugging)" >&6
+       fi
+    fi
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+
+
+
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_MEM_DEBUG 1
+_ACEOF
+
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5
+echo "${ECHO_T}enabled symbols mem debugging" >&6
+       else
+           echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
+echo "${ECHO_T}enabled $tcl_ok debugging" >&6
+       fi
+    fi
+
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.
+#--------------------------------------------------------------------
+
+if test "${SHARED_BUILD}" = "1" ; then
+    cat >>confdefs.h <<\_ACEOF
+#define USE_TCL_STUBS 1
+_ACEOF
+
+fi
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Change the name from exampeA_LIB_FILE to match your package name.
+# Use the stub_LIB_FILE substitution if your package creates a stub
+# library.
+#--------------------------------------------------------------------
+
+itcl_STUB_LIB_FILE=${PKG_STUB_LIB_FILE}
+itcl_LIB_FILE=${PKG_LIB_FILE}
+
+
+
+#--------------------------------------------------------------------
+# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
+# file during the install process.  Don't run the TCLSH_PROG through
+# ${CYGPATH} because it's being used directly by make.
+# Require that we use a tclsh shell version 8.2 or later since earlier
+# versions have bugs in the pkg_mkIndex routine.
+#--------------------------------------------------------------------
+
+
+    echo "$as_me:$LINENO: checking for tclsh" >&5
+echo $ECHO_N "checking for tclsh... $ECHO_C" >&6
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}"
+    fi
+    echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5
+echo "${ECHO_T}${TCLSH_PROG}" >&6
+
+
+
+#--------------------------------------------------------------------
+# These are for itclConfig.sh
+#--------------------------------------------------------------------
+
+# pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
+eval pkglibdir="${libdir}/${PACKAGE_NAME}${PACKAGE_VERSION}"
+if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+    eval itcl_LIB_FLAG="-litcl${PACKAGE_VERSION}${DBGX}"
+    eval itcl_STUB_LIB_FLAG="-litclstub${PACKAGE_VERSION}${DBGX}"
+else
+    eval itcl_LIB_FLAG="-litcl`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+    eval itcl_STUB_LIB_FLAG="-litclstub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+fi
+itcl_BUILD_LIB_SPEC="-L`pwd` ${itcl_LIB_FLAG}"
+itcl_LIB_SPEC="-L${pkglibdir} ${itcl_LIB_FLAG}"
+
+itcl_BUILD_STUB_LIB_SPEC="-L`pwd` ${itcl_STUB_LIB_FLAG}"
+itcl_STUB_LIB_SPEC="-L${pkglibdir} ${itcl_STUB_LIB_FLAG}"
+itcl_BUILD_STUB_LIB_PATH="`pwd`/${itcl_STUB_LIB_FILE}"
+itcl_STUB_LIB_PATH="${pkglibdir}/${itcl_STUB_LIB_FILE}"
+
+
+
+
+
+
+
+
+# itcl_SRC_DIR must be a fully qualified path
+eval itcl_SRC_DIR="$srcdir"
+itcl_SRC_DIR=`cd "${itcl_SRC_DIR}"; pwd`
+
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+#--------------------------------------------------------------------
+
+                              ac_config_files="$ac_config_files Makefile pkgIndex.tcl itclConfig.sh"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by itcl $as_me 3.4, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+itcl config.status 3.4
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "pkgIndex.tcl" ) CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;;
+  "itclConfig.sh" ) CONFIG_FILES="$CONFIG_FILES itclConfig.sh" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CYGPATH@,$CYGPATH,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t
+s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t
+s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t
+s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t
+s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t
+s,@PKG_HEADERS@,$PKG_HEADERS,;t t
+s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t
+s,@PKG_LIBS@,$PKG_LIBS,;t t
+s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t
+s,@LN_S@,$LN_S,;t t
+s,@CONFIG_CLEAN_FILES@,$CONFIG_CLEAN_FILES,;t t
+s,@TCL_VERSION@,$TCL_VERSION,;t t
+s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
+s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t
+s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t
+s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t
+s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t
+s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t
+s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t
+s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t
+s,@TCL_LIBS@,$TCL_LIBS,;t t
+s,@TCL_DEFS@,$TCL_DEFS,;t t
+s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t
+s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t
+s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@EGREP@,$EGREP,;t t
+s,@MATH_LIBS@,$MATH_LIBS,;t t
+s,@PKG_SOURCES@,$PKG_SOURCES,;t t
+s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t
+s,@CLEANFILES@,$CLEANFILES,;t t
+s,@TCL_TOP_DIR_NATIVE@,$TCL_TOP_DIR_NATIVE,;t t
+s,@TCL_GENERIC_DIR_NATIVE@,$TCL_GENERIC_DIR_NATIVE,;t t
+s,@TCL_UNIX_DIR_NATIVE@,$TCL_UNIX_DIR_NATIVE,;t t
+s,@TCL_WIN_DIR_NATIVE@,$TCL_WIN_DIR_NATIVE,;t t
+s,@TCL_BMAP_DIR_NATIVE@,$TCL_BMAP_DIR_NATIVE,;t t
+s,@TCL_TOOL_DIR_NATIVE@,$TCL_TOOL_DIR_NATIVE,;t t
+s,@TCL_PLATFORM_DIR_NATIVE@,$TCL_PLATFORM_DIR_NATIVE,;t t
+s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t
+s,@SHARED_BUILD@,$SHARED_BUILD,;t t
+s,@AR@,$AR,;t t
+s,@CELIB_DIR@,$CELIB_DIR,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@DL_LIBS@,$DL_LIBS,;t t
+s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t
+s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t
+s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
+s,@STLIB_LD@,$STLIB_LD,;t t
+s,@SHLIB_LD@,$SHLIB_LD,;t t
+s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t
+s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t
+s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t
+s,@TCL_DBGX@,$TCL_DBGX,;t t
+s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t
+s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t
+s,@MAKE_LIB@,$MAKE_LIB,;t t
+s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t
+s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t
+s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t
+s,@RANLIB_STUB@,$RANLIB_STUB,;t t
+s,@itcl_STUB_LIB_FILE@,$itcl_STUB_LIB_FILE,;t t
+s,@itcl_LIB_FILE@,$itcl_LIB_FILE,;t t
+s,@TCLSH_PROG@,$TCLSH_PROG,;t t
+s,@itcl_BUILD_LIB_SPEC@,$itcl_BUILD_LIB_SPEC,;t t
+s,@itcl_LIB_SPEC@,$itcl_LIB_SPEC,;t t
+s,@itcl_BUILD_STUB_LIB_SPEC@,$itcl_BUILD_STUB_LIB_SPEC,;t t
+s,@itcl_STUB_LIB_SPEC@,$itcl_STUB_LIB_SPEC,;t t
+s,@itcl_BUILD_STUB_LIB_PATH@,$itcl_BUILD_STUB_LIB_PATH,;t t
+s,@itcl_STUB_LIB_PATH@,$itcl_STUB_LIB_PATH,;t t
+s,@itcl_SRC_DIR@,$itcl_SRC_DIR,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/8.x/itcl/configure.in b/8.x/itcl/configure.in
new file mode 100644 (file)
index 0000000..fbb04f6
--- /dev/null
@@ -0,0 +1,247 @@
+#!/bin/bash -norc
+#--------------------------------------------------------------------
+# Sample configure.in for Tcl Extensions.  The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#--------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
+# set as provided.  These will also be added as -D defs in your Makefile
+# so you can encode the package version directly into the source files.
+#-----------------------------------------------------------------------
+
+AC_INIT([itcl], [3.4])
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+TEA_INIT([3.6])
+
+AC_PROG_LN_S
+CONFIG_CLEAN_FILES=
+if test ! -d $srcdir/tclconfig ; then
+    if test -d $srcdir/../tclconfig ; then
+       $LN_S $srcdir/../tclconfig tclconfig
+       CONFIG_CLEAN_FILES=tclconfig
+    fi
+fi
+AC_SUBST(CONFIG_CLEAN_FILES)
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+TEA_PREFIX
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
+# the basic setup necessary to compile executables.
+#-----------------------------------------------------------------------
+
+TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+TEA_ADD_SOURCES([itclStubInit.c
+               itcl_bicmds.c
+               itcl_class.c
+               itcl_cmds.c
+               itcl_ensemble.c
+               itcl_linkage.c
+               itcl_methods.c
+               itcl_migrate.c
+               itcl_objects.c
+               itcl_parse.c
+               itcl_util.c])
+TEA_ADD_HEADERS([generic/itcl.h
+               generic/itclDecls.h
+               generic/itclInt.h
+               generic/itclIntDecls.h])
+TEA_ADD_INCLUDES([-I\"`${CYGPATH} ${srcdir}/generic`\"])
+TEA_ADD_LIBS([])
+TEA_ADD_CFLAGS([])
+TEA_ADD_STUB_SOURCES([itclStubLib.c])
+TEA_ADD_TCL_SOURCES([library/itcl.tcl])
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_itcl in this case) so
+# that we create the export library with the dll.  See sha1.h on how
+# to use this.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
+# These will be appended to the current set of compiler flags for
+# your system.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    AC_DEFINE(BUILD_itcl)
+    CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+    TEA_ADD_SOURCES([dllEntryPoint.c])
+else
+    CLEANFILES=
+    #TEA_ADD_SOURCES([])
+fi
+
+AC_SUBST(CLEANFILES)
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This must be done AFTER calling TEA_PATH_TCLCONFIG/TEA_LOAD_TCLCONFIG
+# so that we can extract TCL_SRC_DIR from the config file (in the case
+# of private headers
+#--------------------------------------------------------------------
+
+#TEA_PUBLIC_TCL_HEADERS
+TEA_PRIVATE_TCL_HEADERS
+
+#--------------------------------------------------------------------
+# We need to enable the threading macros found in tcl.h and tclInt.h.
+# The use of the threading features is determined by the core the
+# extension is loaded into, but we need to compile with these macros
+# turned on.
+#--------------------------------------------------------------------
+
+AC_DEFINE(TCL_THREADS)
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+#TEA_ENABLE_THREADS
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SHARED
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+TEA_CONFIG_CFLAGS
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols 
+# option.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SYMBOLS
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.
+#--------------------------------------------------------------------
+
+if test "${SHARED_BUILD}" = "1" ; then
+    AC_DEFINE(USE_TCL_STUBS)
+fi
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+TEA_MAKE_LIB
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Change the name from exampeA_LIB_FILE to match your package name.
+# Use the stub_LIB_FILE substitution if your package creates a stub
+# library.
+#--------------------------------------------------------------------
+
+itcl_STUB_LIB_FILE=${PKG_STUB_LIB_FILE}
+itcl_LIB_FILE=${PKG_LIB_FILE}
+AC_SUBST(itcl_STUB_LIB_FILE)
+AC_SUBST(itcl_LIB_FILE)
+
+#--------------------------------------------------------------------
+# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
+# file during the install process.  Don't run the TCLSH_PROG through
+# ${CYGPATH} because it's being used directly by make.
+# Require that we use a tclsh shell version 8.2 or later since earlier
+# versions have bugs in the pkg_mkIndex routine.
+#--------------------------------------------------------------------
+
+TEA_PROG_TCLSH
+
+#--------------------------------------------------------------------
+# These are for itclConfig.sh
+#--------------------------------------------------------------------
+
+# pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
+eval pkglibdir="${libdir}/${PACKAGE_NAME}${PACKAGE_VERSION}"
+if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+    eval itcl_LIB_FLAG="-litcl${PACKAGE_VERSION}${DBGX}"
+    eval itcl_STUB_LIB_FLAG="-litclstub${PACKAGE_VERSION}${DBGX}"
+else
+    eval itcl_LIB_FLAG="-litcl`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+    eval itcl_STUB_LIB_FLAG="-litclstub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+fi
+itcl_BUILD_LIB_SPEC="-L`pwd` ${itcl_LIB_FLAG}"
+itcl_LIB_SPEC="-L${pkglibdir} ${itcl_LIB_FLAG}"
+
+itcl_BUILD_STUB_LIB_SPEC="-L`pwd` ${itcl_STUB_LIB_FLAG}"
+itcl_STUB_LIB_SPEC="-L${pkglibdir} ${itcl_STUB_LIB_FLAG}"
+itcl_BUILD_STUB_LIB_PATH="`pwd`/${itcl_STUB_LIB_FILE}"
+itcl_STUB_LIB_PATH="${pkglibdir}/${itcl_STUB_LIB_FILE}"
+
+AC_SUBST(itcl_BUILD_LIB_SPEC)
+AC_SUBST(itcl_LIB_SPEC)
+AC_SUBST(itcl_BUILD_STUB_LIB_SPEC)
+AC_SUBST(itcl_STUB_LIB_SPEC)
+AC_SUBST(itcl_BUILD_STUB_LIB_PATH)
+AC_SUBST(itcl_STUB_LIB_PATH)
+
+# itcl_SRC_DIR must be a fully qualified path
+eval itcl_SRC_DIR="$srcdir"
+itcl_SRC_DIR=`cd "${itcl_SRC_DIR}"; pwd`
+AC_SUBST(itcl_SRC_DIR)
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+#--------------------------------------------------------------------
+
+AC_OUTPUT([Makefile pkgIndex.tcl itclConfig.sh])
diff --git a/8.x/itcl/doc/Class.3 b/8.x/itcl/doc/Class.3
new file mode 100644 (file)
index 0000000..1ab32e4
--- /dev/null
@@ -0,0 +1,57 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: Class.3,v 1.1 2007/09/06 21:48:31 davygrvy Exp $
+'\"
+.so man.macros
+.TH Itcl_CreateClass 3 3.0 itcl "[incr\ Tcl] Library Procedures"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Itcl_CreateClass, Itcl_DeleteClass, Itcl_FindClass, Itcl_IsClass, Itcl_IsClassNamespace \- Manipulate classes.
+.SH SYNOPSIS
+.nf
+\fB#include <itclInt.h>\fR
+.sp
+int
+\fBItcl_CreateClass\fR(\fIinterp, path, info, rPtr\fR)
+.sp
+int
+\fBItcl_DeleteClass\fR(\fIinterp, cdefnPtr\fR)
+.sp
+ItclClass *
+\fBItcl_FindClass\fR(\fIinterp, path, autoload\fR)
+.sp
+int
+\fBItcl_IsClass\fR(\fIcmd\fR)
+.sp
+int
+\fBItcl_IsClassNamespace\fR(\fInamesp\fR)
+.SH ARGUMENTS
+.AP Tcl_Interp *interp in
+Interpreter to modify.
+.AP "CONST char" *path in
+Path of the class.
+.AP ItclObjectInfo *info in
+TODO.
+.AP ItclClass **rPtr in/out
+The address of the pointer to modify.
+.AP ItclClass *cdefnPtr in
+Pointer to class info struct.
+.AP int autoload in
+Flag value for if the class should be autoloaded
+.AP Tcl_Command cmd in
+Command to check.
+.AP Tcl_Namespace *namesp in
+Namespace to check.
+.BE
+
+.SH DESCRIPTION
+.PP
+
+.SH KEYWORDS
+class, find
+
diff --git a/8.x/itcl/doc/List.3 b/8.x/itcl/doc/List.3
new file mode 100644 (file)
index 0000000..3b009a2
--- /dev/null
@@ -0,0 +1,59 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: List.3,v 1.1 2007/09/06 21:45:52 davygrvy Exp $
+'\"
+.so man.macros
+.TH Itcl_InitList 3 3.0 itcl "[incr\ Tcl] Library Procedures"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Itcl_InitList, Itcl_DeleteList, Itcl_CreateListElem, Itcl_DeleteListElem, Itcl_InsertList, Itcl_InsertListElem, Itcl_AppendList, Itcl_AppendListElem, Itcl_SetListValue \- Manipulate an Itcl list object.
+.SH SYNOPSIS
+.nf
+\fB#include <itcl.h>\fR
+.sp
+void
+\fBItcl_InitList\fR(\fIlist\fR)
+.sp
+void
+\fBItcl_DeleteList\fR(\fIlist\fR)
+.sp
+Itcl_ListElem *
+\fBItcl_CreateListElem\fR(\fIlist\fR)
+.sp
+Itcl_ListElem *
+\fBItcl_DeleteListElem\fR(\fIelem\fR)
+.sp
+Itcl_ListElem *
+\fBItcl_InsertList\fR(\fIlist, clientData\fR)
+.sp
+Itcl_ListElem *
+\fBItcl_InsertListElem\fR(\fIelem, clientData\fR)
+.sp
+Itcl_ListElem *
+\fBItcl_AppendList\fR(\fIlist, clientData\fR)
+.sp
+Itcl_ListElem *
+\fBItcl_AppendListElem\fR(\fIelem, clientData\fR)
+.sp
+void
+\fBItcl_SetListValue\fR(\fIelem, clientData\fR)
+.SH ARGUMENTS
+.AP Itcl_List *list in
+List info structure.
+.AP Itcl_ListElem *elem in
+List element info structure.
+.AP ClientData clientData in
+Arbitrary one-word value to save in the list.
+.BE
+
+.SH DESCRIPTION
+.PP
+
+.SH KEYWORDS
+list
+
diff --git a/8.x/itcl/doc/Object.3 b/8.x/itcl/doc/Object.3
new file mode 100644 (file)
index 0000000..04d90a2
--- /dev/null
@@ -0,0 +1,39 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: Object.3,v 1.1 2007/09/06 21:45:52 davygrvy Exp $
+'\"
+.so man.macros
+.TH Itcl_CreateObject 3 3.0 itcl "[incr\ Tcl] Library Procedures"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Itcl_CreateObject, Itcl_DeleteObject, Itcl_FindObject, Itcl_IsObject, Itcl_IsObjectIsa \- Manipulate an class instance.
+.SH SYNOPSIS
+.nf
+\fB#include <itclInt.h>\fR
+.sp
+void
+\fBItcl_PreserveData\fR(\fIcdata\fR)
+.sp
+void
+\fBItcl_ReleaseData\fR(\fIcdata\fR)
+.sp
+void
+\fBItcl_EventuallyFree\fR(\fIcdata, fproc\fR)
+.SH ARGUMENTS
+.AP Tcl_FreeProc *fproc in
+Address of function to call when the block is to be freed.
+.AP ClientData clientData in
+Arbitrary one-word value.
+.BE
+
+.SH DESCRIPTION
+.PP
+
+.SH KEYWORDS
+free, memory
+
diff --git a/8.x/itcl/doc/Preserve.3 b/8.x/itcl/doc/Preserve.3
new file mode 100644 (file)
index 0000000..bbb4d81
--- /dev/null
@@ -0,0 +1,39 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: Preserve.3,v 1.1 2007/09/06 21:45:52 davygrvy Exp $
+'\"
+.so man.macros
+.TH Itcl_PreserveData 3 3.0 itcl "[incr\ Tcl] Library Procedures"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Itcl_PreserveData, Itcl_ReleaseData, Itcl_EventuallyFree \- Manipulate an Itcl list object.
+.SH SYNOPSIS
+.nf
+\fB#include <itcl.h>\fR
+.sp
+void
+\fBItcl_PreserveData\fR(\fIcdata\fR)
+.sp
+void
+\fBItcl_ReleaseData\fR(\fIcdata\fR)
+.sp
+void
+\fBItcl_EventuallyFree\fR(\fIcdata, fproc\fR)
+.SH ARGUMENTS
+.AP Tcl_FreeProc *fproc in
+Address of function to call when the block is to be freed.
+.AP ClientData clientData in
+Arbitrary one-word value.
+.BE
+
+.SH DESCRIPTION
+.PP
+
+.SH KEYWORDS
+free, memory
+
diff --git a/8.x/itcl/doc/RegisterC.3 b/8.x/itcl/doc/RegisterC.3
new file mode 100644 (file)
index 0000000..9864589
--- /dev/null
@@ -0,0 +1,124 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: RegisterC.3,v 1.5 2004/09/27 05:17:11 davygrvy Exp $
+'\"
+.so man.macros
+.TH Itcl_RegisterC 3 3.0 itcl "[incr\ Tcl] Library Procedures"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Itcl_RegisterC, Itcl_RegisterObjC, Itcl_FindC \- Associate a symbolic name with a C procedure.
+.SH SYNOPSIS
+.nf
+\fB#include <itcl.h>\fR
+.sp
+int
+\fBItcl_RegisterC\fR(\fIinterp, cmdName, argProc, clientData, deleteProc\fR)
+.sp
+int
+\fBItcl_RegisterObjC\fR(\fIinterp, cmdName, objProc, clientData, deleteProc\fR)
+.sp
+int
+\fBItcl_FindC\fR(\fIinterp, cmdName, argProcPtr, objProcPtr, cDataPtr\fR)
+.SH ARGUMENTS
+.AP Tcl_Interp *interp in
+Interpreter in which to create new command.
+.VS 8.4
+.AP "CONST char" *cmdName in
+.VE
+Name of command.
+.AP Tcl_CmdProc *argProc in
+Implementation of new command:  \fIargProc\fR will be called whenever
+.AP Tcl_CmdProc **argProcPtr in/out
+The Tcl_CmdProc * to receive the pointer.
+.AP Tcl_ObjCmdProc *objProc in
+Implementation of the new command: \fIobjProc\fR will be called whenever
+.AP Tcl_ObjCmdProc **objProcPtr in/out
+The Tcl_ObjCmdProc * to receive the pointer.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR and \fIdeleteProc\fR.
+.AP ClientData *cDataPtr in/out
+The ClientData to receive the pointer.
+.AP Tcl_CmdDeleteProc *deleteProc in
+Procedure to call before \fIcmdName\fR is deleted from the interpreter;
+allows for command-specific cleanup.  If NULL, then no procedure is
+called before the command is deleted.
+.BE
+
+.SH DESCRIPTION
+.PP
+Used to associate a symbolic name with an (argc,argv) C procedure
+that handles a Tcl command.  Procedures that are registered in this
+manner can be referenced in the body of an [incr Tcl] class
+definition to specify C procedures to acting as methods/procs.
+Usually invoked in an initialization routine for an extension,
+called out in Tcl_AppInit() at the start of an application.
+.PP
+Each symbolic procedure can have an arbitrary client data value
+associated with it.  This value is passed into the command
+handler whenever it is invoked.
+.PP
+A symbolic procedure name can be used only once for a given style
+(arg/obj) handler.  If the name is defined with an arg-style
+handler, it can be redefined with an obj-style handler; or if
+the name is defined with an obj-style handler, it can be redefined
+with an arg-style handler.  In either case, any previous client
+data is discarded and the new client data is remembered.  However,
+if a name is redefined to a different handler of the same style,
+this procedure returns an error.
+.PP
+Returns TCL_OK on success, or TCL_ERROR (along with an error message
+in interp->result) if anything goes wrong.
+.PP
+C procedures can be integrated into an \fB[incr\ Tcl]\fR class
+definition to implement methods, procs, and the "config" code
+for public variables.  Any body that starts with "\fB@\fR"
+is treated as the symbolic name for a C procedure.
+.PP
+Symbolic names are established by registering procedures via
+\fBItcl_RegisterC()\fR.  This is usually done in the \fBTcl_AppInit()\fR
+procedure, which is automatically called when the interpreter starts up.
+In the following example, the procedure \fCMy_FooCmd()\fR is registered
+with the symbolic name "foo".  This procedure can be referenced in
+the \fBbody\fR command as "\fC@foo\fR".
+.CS
+int
+Tcl_AppInit(interp)
+    Tcl_Interp *interp;     /* Interpreter for application. */
+{
+    if (Itcl_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+
+    if (Itcl_RegisterC(interp, "foo", My_FooCmd) != TCL_OK) {
+        return TCL_ERROR;
+    }
+}
+.CE
+C procedures are implemented just like ordinary Tcl commands.
+See the \fBCrtCommand\fR man page for details.  Within the procedure,
+class data members can be accessed like ordinary variables
+using \fBTcl_SetVar()\fR, \fBTcl_GetVar()\fR, \fBTcl_TraceVar()\fR,
+etc.  Class methods and procs can be executed like ordinary commands
+using \fBTcl_Eval()\fR.  \fB[incr\ Tcl]\fR makes this possible by
+automatically setting up the context before executing the C procedure.
+.PP
+This scheme provides a natural migration path for code development.
+Classes can be developed quickly using Tcl code to implement the
+bodies.  An entire application can be built and tested.  When
+necessary, individual bodies can be implemented with C code to
+improve performance.
+.PP
+See the Archetype class in \fB[incr\ Tk]\fR for an example of how this
+C linking method is used.
+
+.SH "SEE ALSO"
+Tcl_CreateCommand, Tcl_CreateObjCommand
+
+.SH KEYWORDS
+class, object
+
diff --git a/8.x/itcl/doc/Stack.3 b/8.x/itcl/doc/Stack.3
new file mode 100644 (file)
index 0000000..98e686a
--- /dev/null
@@ -0,0 +1,60 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: Stack.3,v 1.2 2004/09/26 00:51:55 davygrvy Exp $
+'\"
+.so man.macros
+.TH Itcl_InitStack 3 3.0 itcl "[incr\ Tcl] Library Procedures"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Itcl_InitStack, Itcl_DeleteStack, Itcl_PushStack, Itcl_PopStack, Itcl_PeekStack, Itcl_GetStackValue, Itcl_GetStackSize \- Manipulate an Itcl stack object.
+.SH SYNOPSIS
+.nf
+\fB#include <itcl.h>\fR
+.sp
+int
+\fBItcl_InitStack\fR(\fIstack\fR)
+.sp
+int
+\fBItcl_DeleteStack\fR(\fIstack\fR)
+.sp
+int
+\fBItcl_PushStack\fR(\fIcdata, stack\fR)
+.sp
+ClientData
+\fBItcl_PopStack\fR(\fIstack\fR)
+.sp
+ClientData
+\fBItcl_PeekStack\fR(\fIstack\fR)
+.sp
+ClientData
+\fBItcl_GetStackValue\fR(\fIstack, pos\fR)
+.sp
+int
+\fBItcl_GetStackSize\fR(\fIstack\fR)
+.SH ARGUMENTS
+.AP Itcl_Stack *stack in
+Stack info structure.
+.AP int pos in
+position in stack order from the top.
+.AP ClientData clientData in
+Arbitrary one-word value to save in the stack.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBItcl_InitStack\fR initializes a stack structure and \fBItcl_DeleteStack\fR
+deletes it. \fBItcl_PushStack\fR pushes the \fIcdata\fR value onto the stack.
+\fBItcl_PopStack\fR removes and returns the top most \fIcdata\fR value.
+\fBItcl_PeekStack\fR returns the top most value, but does not remove it.
+\fBItcl_GetStackValue\fR gets a value at some index within the stack.  Index
+"0" is the first value pushed onto the stack. \fBItcl_GetStackSize\fR
+returns the count of entries on the stack.
+
+.SH KEYWORDS
+stack
+
diff --git a/8.x/itcl/doc/body.n b/8.x/itcl/doc/body.n
new file mode 100644 (file)
index 0000000..4b09355
--- /dev/null
@@ -0,0 +1,124 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: body.n,v 1.4 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH body n 3.0 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+body \- change the body for a class method/proc
+.SH SYNOPSIS
+\fBitcl::body \fIclassName\fB::\fIfunction args body\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBbody\fR command is used outside of an \fB[incr\ Tcl]\fR
+class definition to define or redefine the body of a class
+method or proc.  This facility allows a class definition
+to have separate "interface" and "implementation" parts.
+The "interface" part is a \fBclass\fR command with declarations
+for methods, procs, instance variables and common variables.
+The "implementation" part is a series of \fBbody\fR and
+\fBconfigbody\fR commands.  If the "implementation" part
+is kept in a separate file, it can be sourced again and
+again as bugs are fixed, to support interactive development.
+When using the "tcl" mode in the \fBemacs\fR editor, the
+"interface" and "implementation" parts can be kept in the
+same file; as bugs are fixed, individual bodies can be
+highlighted and sent to the test application.
+.PP
+The name "\fIclassName\fB::\fIfunction\fR"
+identifies the method/proc being changed.
+.PP
+If an \fIargs\fR list was specified when the \fIfunction\fR was
+defined in the class definition, the \fIargs\fR list for the
+\fBbody\fR command must match in meaning.  Variable names
+can change, but the argument lists must have the same required
+arguments and the same default values for optional arguments.
+The special \fBargs\fR argument acts as a wildcard when included
+in the \fIargs\fR list in the class definition; it will match
+zero or more arguments of any type when the body is redefined.
+.PP
+If the \fIbody\fR string starts with "\fB@\fR", it is treated
+as the symbolic name for a C procedure.  The \fIargs\fR list
+has little meaning for the C procedure, except to document
+the expected usage.  (The C procedure is not guaranteed to
+use arguments in this manner.)  If \fIbody\fR does not start
+with "\fB@\fR", it is treated as a Tcl command script.  When
+the function is invoked, command line arguments are matched
+against the \fIargs\fR list, and local variables are created
+to represent each argument.  This is the usual behavior for
+a Tcl-style proc.
+.PP
+Symbolic names for C procedures are established by registering
+procedures via \fBItcl_RegisterC()\fR.  This is usually done
+in the \fBTcl_AppInit()\fR procedure, which is automatically called
+when the interpreter starts up.  In the following example,
+the procedure \fCMy_FooCmd()\fR is registered with the
+symbolic name "foo".  This procedure can be referenced in
+the \fBbody\fR command as "\fC@foo\fR".
+.CS
+int
+Tcl_AppInit(interp)
+    Tcl_Interp *interp;     /* Interpreter for application. */
+{
+    if (Itcl_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+
+    if (Itcl_RegisterC(interp, "foo", My_FooCmd) != TCL_OK) {
+        return TCL_ERROR;
+    }
+}
+.CE
+
+.SH EXAMPLE
+In the following example, a "File" class is defined to represent
+open files.  The method bodies are included below the class
+definition via the \fBbody\fR command.  Note that the bodies
+of the constructor/destructor must be included in the class
+definition, but they can be redefined via the \fBbody\fR command
+as well.
+.CS
+itcl::class File {
+    private variable fid ""
+    constructor {name access} {
+        set fid [open $name $access]
+    }
+    destructor {
+        close $fid
+    }
+
+    method get {}
+    method put {line}
+    method eof {}
+}
+
+itcl::body File::get {} {
+    return [gets $fid]
+}
+itcl::body File::put {line} {
+    puts $fid $line
+}
+itcl::body File::eof {} {
+    return [::eof $fid]
+}
+
+#
+# See the File class in action:
+#
+File x /etc/passwd "r"
+while {![x eof]} {
+    puts "=> [x get]"
+}
+itcl::delete object x
+.CE
+
+.SH KEYWORDS
+class, object, procedure
diff --git a/8.x/itcl/doc/class.n b/8.x/itcl/doc/class.n
new file mode 100644 (file)
index 0000000..5eb5d62
--- /dev/null
@@ -0,0 +1,490 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: class.n,v 1.5 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH class n "" itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+class \- create a class of objects
+.SH SYNOPSIS
+\fBitcl::class \fIclassName\fR \fB{
+.br
+    \fBinherit \fIbaseClass\fR ?\fIbaseClass\fR...?
+.br
+    \fBconstructor \fIargs\fR ?\fIinit\fR? \fIbody\fR
+.br
+    \fBdestructor \fIbody\fR
+.br
+    \fBmethod \fIname\fR ?\fIargs\fR? ?\fIbody\fR?
+.br
+    \fBproc \fIname ?\fIargs\fR? ?\fIbody\fR?
+.br
+    \fBvariable \fIvarName\fR ?\fIinit\fR? ?\fIconfig\fR?
+.br
+    \fBcommon \fIvarName\fR ?\fIinit\fR?
+.sp
+    \fBpublic \fIcommand\fR ?\fIarg arg ...\fR?
+.br
+    \fBprotected \fIcommand\fR ?\fIarg arg ...\fR?
+.br
+    \fBprivate \fIcommand\fR ?\fIarg arg ...\fR?
+.sp
+    \fBset \fIvarName\fR ?\fIvalue\fR?
+.br
+    \fBarray \fIoption\fR ?\fIarg arg ...\fR?
+.br
+\fB}\fR
+.sp
+\fIclassName objName\fR ?\fIarg arg ...\fR?
+.sp
+\fIobjName method\fR ?\fIarg arg ...\fR?
+.sp
+\fIclassName::proc ?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The fundamental construct in \fB[incr\ Tcl]\fR is the class definition.
+Each class acts as a template for actual objects that can be created.
+The class itself is a namespace which contains things common to all
+objects.  Each object has its own unique bundle of data which contains
+instances of the "variables" defined in the class definition.  Each
+object also has a built-in variable named "this", which contains the
+name of the object.  Classes can also have "common" data members that
+are shared by all objects in a class.
+.PP
+Two types of functions can be included in the class definition.
+"Methods" are functions which operate on a specific object, and
+therefore have access to both "variables" and "common" data members.
+"Procs" are ordinary procedures in the class namespace, and only
+have access to "common" data members.
+.PP
+If the body of any method or proc starts with "\fB@\fR", it is treated
+as the symbolic name for a C procedure.  Otherwise, it is treated as
+a Tcl code script.  See below for details on registering and using
+C procedures.
+.PP
+A class can only be defined once, although the bodies of class
+methods and procs can be defined again and again for interactive
+debugging.  See the \fBbody\fR and \fBconfigbody\fR commands for
+details.
+.PP
+Each namespace can have its own collection of objects and classes.
+The list of classes available in the current context can be queried
+using the "\fBitcl::find classes\fR" command, and the list of objects,
+with the "\fBitcl::find objects\fR" command.
+.PP
+A class can be deleted using the "\fBdelete class\fR" command.
+Individual objects can be deleted using the "\fBdelete object\fR"
+command.
+
+.SH CLASS DEFINITIONS
+.TP
+\fBclass \fIclassName definition\fR
+Provides the definition for a class named \fIclassName\fR.  If
+the class \fIclassName\fR already exists, or if a command called
+\fIclassName\fR exists in the current namespace context, this
+command returns an error.  If the class definition is successfully
+parsed, \fIclassName\fR becomes a command in the current context,
+handling the creation of objects for this class.
+.PP
+The class \fIdefinition\fR is evaluated as a series of Tcl
+statements that define elements within the class.  The following
+class definition commands are recognized:
+.RS
+.TP
+\fBinherit \fIbaseClass\fR ?\fIbaseClass\fR...?
+Causes the current class to inherit characteristics from one or
+more base classes.  Classes must have been defined by a previous
+\fBclass\fR command, or must be available to the auto-loading
+facility (see "AUTO-LOADING" below).  A single class definition
+can contain no more than one \fBinherit\fR command.
+.sp
+The order of \fIbaseClass\fR names in the \fBinherit\fR list
+affects the name resolution for class members.  When the same
+member name appears in two or more base classes, the base class
+that appears first in the \fBinherit\fR list takes precedence.
+For example, if classes "Foo" and "Bar" both contain the member
+"x", and if another class has the "\fBinherit\fR" statement:
+.CS
+inherit Foo Bar
+.CE
+then the name "x" means "Foo::x".  Other inherited members named
+"x" must be referenced with their explicit name, like "Bar::x".
+.TP
+\fBconstructor \fIargs\fR ?\fIinit\fR? \fIbody\fR
+Declares the \fIargs\fR argument list and \fIbody\fR used for
+the constructor, which is automatically invoked whenever an
+object is created.
+.sp
+Before the \fIbody\fR is executed, the
+optional \fIinit\fR statement is used to invoke any base class
+constructors that require arguments.  Variables in the \fIargs\fR
+specification can be accessed in the \fIinit\fR code fragment,
+and passed to base class constructors.  After evaluating the
+\fIinit\fR statement, any base class constructors that have
+not been executed are invoked automatically without arguments.
+This ensures that all base classes are fully constructed before
+the constructor \fIbody\fR is executed.  By default, this
+scheme causes constructors to be invoked in order from least-
+to most-specific.  This is exactly the opposite of the order
+that classes are reported by the \fBinfo heritage\fR command.
+.sp
+If construction is successful, the constructor always returns
+the object name\-regardless of how the \fIbody\fR is defined\-and
+the object name becomes a command in the current namespace context.
+If construction fails, an error message is returned.
+.TP
+\fBdestructor \fIbody\fR
+Declares the \fIbody\fR used for the destructor, which is automatically
+invoked when an object is deleted.  If the destructor is successful,
+the object data is destroyed and the object name is removed as a command
+from the interpreter.  If destruction fails, an error message is returned
+and the object remains.
+.sp
+When an object is destroyed, all destructors in its class hierarchy
+are invoked in order from most- to least-specific.  This is the
+order that the classes are reported by the "\fBinfo heritage\fR"
+command, and it is exactly the opposite of the default constructor
+order.
+.TP
+\fBmethod \fIname\fR ?\fIargs\fR? ?\fIbody\fR?
+Declares a method called \fIname\fR.  When the method \fIbody\fR is
+executed, it will have automatic access to object-specific variables
+and common data members.
+.sp
+If the \fIargs\fR list is specified, it establishes the usage
+information for this method.  The \fBbody\fR command can be used
+to redefine the method body, but the \fIargs\fR list must match
+this specification.
+.sp
+Within the body of another class method, a method can be invoked
+like any other command\-simply by using its name.  Outside of the
+class context, the method name must be prefaced an object name,
+which provides the context for the data that it manipulates.
+Methods in a base class that are redefined in the current class,
+or hidden by another base class, can be qualified using the
+"\fIclassName\fR::\fImethod\fR" syntax.
+.TP
+\fBproc \fIname\fR ?\fIargs\fR? ?\fIbody\fR?
+Declares a proc called \fIname\fR.  A proc is an ordinary procedure
+within the class namespace.  Unlike a method, a proc is invoked
+without referring to a specific object.  When the proc \fIbody\fR is
+executed, it will have automatic access only to common data members.
+.sp
+If the \fIargs\fR list is specified, it establishes the usage
+information for this proc.  The \fBbody\fR command can be used
+to redefine the proc body, but the \fIargs\fR list must match
+this specification.
+.sp
+Within the body of another class method or proc, a proc can be
+invoked like any other command\-simply by using its name.
+In any other namespace context, the proc is invoked using a
+qualified name like "\fIclassName\fB::\fIproc\fR".  Procs in
+a base class that are redefined in the current class, or hidden
+by another base class, can also be accessed via their qualified
+name.
+.TP
+\fBvariable \fIvarName\fR ?\fIinit\fR? ?\fIconfig\fR?
+Defines an object-specific variable named \fIvarName\fR.  All
+object-specific variables are automatically available in class
+methods.  They need not be declared with anything like the
+\fBglobal\fR command.
+.sp
+If the optional \fIinit\fR string is specified, it is used as the
+initial value of the variable when a new object is created.
+Initialization forces the variable to be a simple scalar
+value; uninitialized variables, on the other hand, can be set
+within the constructor and used as arrays.
+.sp
+The optional \fIconfig\fR script is only allowed for public variables.
+If specified, this code fragment is executed whenever a public
+variable is modified by the built-in "configure" method.  The
+\fIconfig\fR script can also be specified outside of the class
+definition using the \fBconfigbody\fR command.
+.TP
+\fBcommon \fIvarName\fR ?\fIinit\fR?
+Declares a common variable named \fIvarName\fR.  Common variables
+reside in the class namespace and are shared by all objects belonging
+to the class.  They are just like global variables, except that
+they need not be declared with the usual \fBglobal\fR command.
+They are automatically visible in all class methods and procs.
+.sp
+If the optional \fIinit\fR string is specified, it is used as the
+initial value of the variable.  Initialization forces the variable
+to be a simple scalar value; uninitialized variables, on the other
+hand, can be set with subsequent \fBset\fR and \fBarray\fR commands
+and used as arrays.
+.sp
+Once a common data member has been defined, it can be set using
+\fBset\fR and \fBarray\fR commands within the class definition.
+This allows common data members to be initialized as arrays.
+For example:
+.CS
+itcl::class Foo {
+    common boolean
+    set boolean(true) 1
+    set boolean(false) 0
+}
+.CE
+Note that if common data members are initialized within the
+constructor, they get initialized again and again whenever new
+objects are created.
+.TP
+\fBpublic \fIcommand\fR ?\fIarg arg ...\fR?
+.TP
+\fBprotected \fIcommand\fR ?\fIarg arg ...\fR?
+.TP
+\fBprivate \fIcommand\fR ?\fIarg arg ...\fR?
+These commands are used to set the protection level for class
+members that are created when \fIcommand\fR is evaluated.
+The \fIcommand\fR is usually \fBmethod\fR, \fBproc\fR,
+\fBvariable\fR or\fBcommon\fR, and the remaining \fIarg\fR's
+complete the member definition.  However, \fIcommand\fR can
+also be a script containing many different member definitions,
+and the protection level will apply to all of the members
+that are created.
+
+.SH CLASS USAGE
+.PP
+Once a class has been defined, the class name can be used as a
+command to create new objects belonging to the class.
+.TP
+\fIclassName objName\fR ?\fIargs...\fR?
+Creates a new object in class \fIclassName\fR with the name \fIobjName\fR.
+Remaining arguments are passed to the constructor of the most-specific
+class.  This in turn passes arguments to base class constructors before
+invoking its own body of commands.  If construction is successful, a
+command called \fIobjName\fR is created in the current namespace context,
+and \fIobjName\fR is returned as the result of this operation.
+If an error is encountered during construction, the destructors are
+automatically invoked to free any resources that have been allocated,
+the object is deleted, and an error is returned.
+.sp
+If \fIobjName\fR contains the string "\fB#auto\fR", that string is
+replaced with an automatically generated name.  Names have the
+form \fIclassName<number>\fR, where the \fIclassName\fR part is
+modified to start with a lowercase letter.  In class "Toaster",
+for example, the "\fB#auto\fR" specification would produce names
+like toaster0, toaster1, etc.  Note that "\fB#auto\fR" can be
+also be buried within an object name:
+.CS
+fileselectiondialog .foo.bar.#auto -background red
+.CE
+This would generate an object named ".foo.bar.fileselectiondialog0".
+
+.SH OBJECT USAGE
+Once an object has been created, the object name can be used
+as a command to invoke methods that operate on the object.
+.TP
+\fIobjName method\fR ?\fIargs...\fR?
+Invokes a method named \fImethod\fR on an object named \fIobjName\fR.
+Remaining arguments are passed to the argument list for the
+method.  The method name can be "constructor", "destructor",
+any method name appearing in the class definition, or any of
+the following built-in methods.
+.SH BUILT-IN METHODS
+.TP
+\fIobjName\fR \fBcget option\fR
+Provides access to public variables as configuration options.  This
+mimics the behavior of the usual "cget" operation for Tk widgets.
+The \fIoption\fR argument is a string of the form "\fB-\fIvarName\fR",
+and this method returns the current value of the public variable
+\fIvarName\fR.
+.TP
+\fIobjName\fR \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
+Provides access to public variables as configuration options.  This
+mimics the behavior of the usual "configure" operation for Tk widgets.
+With no arguments, this method returns a list of lists describing
+all of the public variables.  Each list has three elements:  the
+variable name, its initial value and its current value.
+.sp
+If a single \fIoption\fR of the form "\fB-\fIvarName\fR" is specified,
+then this method returns the information for that one variable.
+.sp
+Otherwise, the arguments are treated as \fIoption\fR/\fIvalue\fR
+pairs assigning new values to public variables.  Each variable
+is assigned its new value, and if it has any "config" code associated
+with it, it is executed in the context of the class where it was
+defined.  If the "config" code generates an error, the variable
+is set back to its previous value, and the \fBconfigure\fR method
+returns an error.
+.TP
+\fIobjName\fR \fBisa \fIclassName\fR
+Returns non-zero if the given \fIclassName\fR can be found in the
+object's heritage, and zero otherwise.
+.TP
+\fIobjName\fR \fBinfo \fIoption\fR ?\fIargs...\fR?
+Returns information related to a particular object named
+\fIobjName\fR, or to its class definition.  The \fIoption\fR
+parameter includes the following things, as well as the options
+recognized by the usual Tcl "info" command:
+.RS
+.TP
+\fIobjName\fR \fBinfo class\fR
+Returns the name of the most-specific class for object \fIobjName\fR.
+.TP
+\fIobjName\fR \fBinfo inherit\fR
+Returns the list of base classes as they were defined in the
+"\fBinherit\fR" command, or an empty string if this class
+has no base classes.
+.TP
+\fIobjName\fR \fBinfo heritage\fR
+Returns the current class name and the entire list of base classes
+in the order that they are traversed for member lookup and object
+destruction.
+.TP
+\fIobjName\fR \fBinfo function\fR ?\fIcmdName\fR? ?\fB-protection\fR? ?\fB-type\fR? ?\fB-name\fR? ?\fB-args\fR? ?\fB-body\fR?
+With no arguments, this command returns a list of all class methods
+and procs.  If \fIcmdName\fR is specified, it returns information
+for a specific method or proc.  If no flags are specified, this
+command returns a list with the following elements:  the protection
+level, the type (method/proc), the qualified name, the argument list
+and the body.  Flags can be used to request specific elements from
+this list.
+.TP
+\fIobjName\fR \fBinfo variable\fR ?\fIvarName\fR? ?\fB-protection\fR? ?\fB-type\fR? ?\fB-name\fR? ?\fB-init\fR? ?\fB-value\fR? ?\fB-config\fR?
+With no arguments, this command returns a list of all object-specific
+variables and common data members.  If \fIvarName\fR is specified, it
+returns information for a specific data member.  If no flags are
+specified, this command returns a list with the following elements:  the
+protection level, the type (variable/common), the qualified name, the
+initial value, and the current value.  If \fIvarName\fR is a public
+variable, the "config" code is included on this list.  Flags can be
+used to request specific elements from this list.
+
+.SH CHAINING METHODS/PROCS
+Sometimes a base class has a method or proc that is redefined with
+the same name in a derived class.  This is a way of making the
+derived class handle the same operations as the base class, but
+with its own specialized behavior.  For example, suppose we have
+a Toaster class that looks like this:
+.CS
+itcl::class Toaster {
+    variable crumbs 0
+    method toast {nslices} {
+        if {$crumbs > 50} {
+            error "== FIRE! FIRE! =="
+        }
+        set crumbs [expr $crumbs+4*$nslices]
+    }
+    method clean {} {
+        set crumbs 0
+    }
+}
+.CE
+We might create another class like SmartToaster that redefines
+the "toast" method.  If we want to access the base class method,
+we can qualify it with the base class name, to avoid ambiguity:
+.CS
+itcl::class SmartToaster {
+    inherit Toaster
+    method toast {nslices} {
+        if {$crumbs > 40} {
+            clean
+        }
+        return [Toaster::toast $nslices]
+    }
+}
+.CE
+Instead of hard-coding the base class name, we can use the
+"chain" command like this:
+.CS
+itcl::class SmartToaster {
+    inherit Toaster
+    method toast {nslices} {
+        if {$crumbs > 40} {
+            clean
+        }
+        return [chain $nslices]
+    }
+}
+.CE
+The chain command searches through the class hierarchy for
+a slightly more generic (base class) implementation of a method
+or proc, and invokes it with the specified arguments.  It starts
+at the current class context and searches through base classes
+in the order that they are reported by the "info heritage" command.
+If another implementation is not found, this command does nothing
+and returns the null string.
+
+.SH AUTO-LOADING
+.PP
+Class definitions need not be loaded explicitly; they can be loaded as
+needed by the usual Tcl auto-loading facility.  Each directory containing
+class definition files should have an accompanying "tclIndex" file.
+Each line in this file identifies a Tcl procedure or \fB[incr\ Tcl]\fR
+class definition and the file where the definition can be found.
+.PP
+For example, suppose a directory contains the definitions for classes
+"Toaster" and "SmartToaster".  Then the "tclIndex" file for this
+directory would look like:
+.CS
+# Tcl autoload index file, version 2.0 for [incr Tcl]
+# This file is generated by the "auto_mkindex" command
+# and sourced to set up indexing information for one or
+# more commands.  Typically each line is a command that
+# sets an element in the auto_index array, where the
+# element name is the name of a command and the value is
+# a script that loads the command.
+
+set auto_index(::Toaster) "source $dir/Toaster.itcl"
+set auto_index(::SmartToaster) "source $dir/SmartToaster.itcl"
+.PP
+The \fBauto_mkindex\fR command is used to automatically
+generate "tclIndex" files.
+.CE
+The auto-loader must be made aware of this directory by appending
+the directory name to the "auto_path" variable.  When this is in
+place, classes will be auto-loaded as needed when used in an
+application.
+
+.SH C PROCEDURES
+.PP
+C procedures can be integrated into an \fB[incr\ Tcl]\fR class
+definition to implement methods, procs, and the "config" code
+for public variables.  Any body that starts with "\fB@\fR"
+is treated as the symbolic name for a C procedure.
+.PP
+Symbolic names are established by registering procedures via
+\fBItcl_RegisterC()\fR.  This is usually done in the \fBTcl_AppInit()\fR
+procedure, which is automatically called when the interpreter starts up.
+In the following example, the procedure \fCMy_FooCmd()\fR is registered
+with the symbolic name "foo".  This procedure can be referenced in
+the \fBbody\fR command as "\fC@foo\fR".
+.CS
+int
+Tcl_AppInit(interp)
+    Tcl_Interp *interp;     /* Interpreter for application. */
+{
+    if (Itcl_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+
+    if (Itcl_RegisterC(interp, "foo", My_FooCmd) != TCL_OK) {
+        return TCL_ERROR;
+    }
+}
+.CE
+C procedures are implemented just like ordinary Tcl commands.
+See the \fBCrtCommand\fR man page for details.  Within the procedure,
+class data members can be accessed like ordinary variables
+using \fBTcl_SetVar()\fR, \fBTcl_GetVar()\fR, \fBTcl_TraceVar()\fR,
+etc.  Class methods and procs can be executed like ordinary commands
+using \fBTcl_Eval()\fR.  \fB[incr\ Tcl]\fR makes this possible by
+automatically setting up the context before executing the C procedure.
+.PP
+This scheme provides a natural migration path for code development.
+Classes can be developed quickly using Tcl code to implement the
+bodies.  An entire application can be built and tested.  When
+necessary, individual bodies can be implemented with C code to
+improve performance.
+
+.SH KEYWORDS
+class, object, object-oriented
diff --git a/8.x/itcl/doc/code.n b/8.x/itcl/doc/code.n
new file mode 100644 (file)
index 0000000..027917e
--- /dev/null
@@ -0,0 +1,96 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: code.n,v 1.3 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH code n 3.0 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+code \- capture the namespace context for a code fragment
+.SH SYNOPSIS
+\fBitcl::code \fR?\fB-namespace \fIname\fR? \fIcommand \fR?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+Creates a scoped value for the specified \fIcommand\fR and its
+associated \fIarg\fR arguments.  A scoped value is a list with three
+elements:  the "\fC@scope\fR" keyword, a namespace context,
+and a value string.  For example, the command
+.CS
+namespace foo {
+    code puts "Hello World!"
+}
+.CE
+produces the scoped value:
+.CS
+@scope ::foo {puts {Hello World!}}
+.CE
+Note that the \fBcode\fR command captures the current namespace
+context.  If the \fB-namespace\fR flag is specified, then the
+current context is ignored, and the \fIname\fR string is used
+as the namespace context.
+.PP
+Extensions like Tk execute ordinary code fragments in the global
+namespace.  A scoped value captures a code fragment together with
+its namespace context in a way that allows it to be executed
+properly later.  It is needed, for example, to wrap up code fragments
+when a Tk widget is used within a namespace:
+.CS
+namespace foo {
+    private proc report {mesg} {
+        puts "click: $mesg"
+    }
+
+    button .b1 -text "Push Me" \
+        -command [code report "Hello World!"]
+    pack .b1
+}
+.CE
+The code fragment associated with button \fC.b1\fR only makes
+sense in the context of namespace "foo".  Furthermore, the
+"report" procedure is private, and can only be accessed within
+that namespace.  The \fBcode\fR command wraps up the code
+fragment in a way that allows it to be executed properly
+when the button is pressed.
+.PP
+Also, note that the \fBcode\fR command preserves the integrity
+of arguments on the command line.  This makes it a natural replacement
+for the \fBlist\fR command, which is often used to format Tcl code
+fragments.  In other words, instead of using the \fBlist\fR command
+like this:
+.CS
+after 1000 [list puts "Hello $name!"]
+.CE
+use the \fBcode\fR command like this:
+.CS
+after 1000 [code puts "Hello $name!"]
+.CE
+This not only formats the command correctly, but also captures
+its namespace context.
+.PP
+Scoped commands can be invoked like ordinary code fragments, with
+or without the \fBeval\fR command.  For example, the following
+statements work properly:
+.CS
+set cmd {@scope ::foo .b1}
+$cmd configure -background red
+
+set opts {-bg blue -fg white}
+eval $cmd configure $opts
+.CE
+Note that scoped commands by-pass the usual protection mechanisms;
+the command:
+.CS
+@scope ::foo {report {Hello World!}}
+.CE
+can be used to access the "foo::report" proc from any namespace
+context, even though it is private.
+
+.SH KEYWORDS
+scope, callback, namespace, public, protected, private
diff --git a/8.x/itcl/doc/configbody.n b/8.x/itcl/doc/configbody.n
new file mode 100644 (file)
index 0000000..b2db88c
--- /dev/null
@@ -0,0 +1,129 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: configbody.n,v 1.4 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH configbody n 3.0 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+configbody \- change the "config" code for a public variable
+.SH SYNOPSIS
+\fBitcl::configbody \fIclassName\fB::\fIvarName body\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBconfigbody\fR command is used outside of an \fB[incr\ Tcl]\fR
+class definition to define or redefine the configuration code
+associated with a public variable.  Public variables act like
+configuration options for an object.  They can be modified
+outside the class scope using the built-in \fBconfigure\fR method.
+Each variable can have a bit of "config" code associate with it
+that is automatically executed when the variable is configured.
+The \fBconfigbody\fR command can be used to define or redefine
+this body of code.
+.PP
+Like the \fBbody\fR command, this facility allows a class definition
+to have separate "interface" and "implementation" parts.
+The "interface" part is a \fBclass\fR command with declarations
+for methods, procs, instance variables and common variables.
+The "implementation" part is a series of \fBbody\fR and
+\fBconfigbody\fR commands.  If the "implementation" part
+is kept in a separate file, it can be sourced again and
+again as bugs are fixed, to support interactive development.
+When using the "tcl" mode in the \fBemacs\fR editor, the
+"interface" and "implementation" parts can be kept in the
+same file; as bugs are fixed, individual bodies can be
+highlighted and sent to the test application.
+.PP
+The name "\fIclassName\fB::\fIvarName\fR"
+identifies the public variable being updated.
+If the \fIbody\fR string starts with "\fB@\fR", it is treated
+as the symbolic name for a C procedure.  Otherwise, it is
+treated as a Tcl command script.
+.PP
+Symbolic names for C procedures are established by registering
+procedures via \fBItcl_RegisterC()\fR.  This is usually done
+in the \fBTcl_AppInit()\fR procedure, which is automatically called
+when the interpreter starts up.  In the following example,
+the procedure \fCMy_FooCmd()\fR is registered with the
+symbolic name "foo".  This procedure can be referenced in
+the \fBconfigbody\fR command as "\fC@foo\fR".
+.CS
+int
+Tcl_AppInit(interp)
+    Tcl_Interp *interp;     /* Interpreter for application. */
+{
+    if (Itcl_Init(interp) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+
+    if (Itcl_RegisterC(interp, "foo", My_FooCmd) != TCL_OK) {
+        return TCL_ERROR;
+    }
+}
+.CE
+
+.SH EXAMPLE
+In the following example, a "File" class is defined to represent
+open files.  Whenever the "-name" option is configured, the
+existing file is closed, and a new file is opened.  Note that
+the "config" code for a public variable is optional.  The "-access"
+option, for example, does not have it.
+.CS
+itcl::class File {
+    private variable fid ""
+
+    public variable name ""
+    public variable access "r"
+
+    constructor {args} {
+        eval configure $args
+    }
+    destructor {
+        if {$fid != ""} {
+            close $fid
+        }
+    }
+
+    method get {}
+    method put {line}
+    method eof {}
+}
+
+itcl::body File::get {} {
+    return [gets $fid]
+}
+itcl::body File::put {line} {
+    puts $fid $line
+}
+itcl::body File::eof {} {
+    return [::eof $fid]
+}
+
+itcl::configbody File::name {
+    if {$fid != ""} {
+        close $fid
+    }
+    set fid [open $name $access]
+}
+
+#
+# See the File class in action:
+#
+File x
+
+x configure -name /etc/passwd
+while {![x eof]} {
+    puts "=> [x get]"
+}
+itcl::delete object x
+.CE
+
+.SH KEYWORDS
+class, object, variable, configure
diff --git a/8.x/itcl/doc/delete.n b/8.x/itcl/doc/delete.n
new file mode 100644 (file)
index 0000000..206bcbe
--- /dev/null
@@ -0,0 +1,64 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: delete.n,v 1.4 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH delete n 3.0 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+delete \- delete things in the interpreter
+.SH SYNOPSIS
+\fBitcl::delete \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBdelete\fR command is used to delete things in the interpreter.
+It is implemented as an ensemble, so extensions can add their own
+options and extend the behavior of this command.  By default, the
+\fBdelete\fR command handles the destruction of namespaces.
+.PP
+The \fIoption\fR argument determines what action is carried out
+by the command.  The legal \fIoptions\fR (which may be abbreviated)
+are:
+.TP
+\fBdelete class \fIname\fR ?\fIname...\fR?
+Deletes one or more \fB[incr\ Tcl]\fR classes called \fIname\fR.
+This deletes all objects in the class, and all derived classes
+as well.
+.sp
+If an error is encountered while destructing an object, it will
+prevent the destruction of the class and any remaining objects.
+To destroy the entire class without regard for errors, use the
+"\fBdelete namespace\fR" command.
+.TP
+\fBdelete object \fIname\fR ?\fIname...\fR?
+Deletes one or more \fB[incr\ Tcl]\fR objects called \fIname\fR.
+An object is deleted by invoking all destructors in its class
+hierarchy, in order from most- to least-specific.  If all destructors
+are successful, data associated with the object is deleted and
+the \fIname\fR is removed as a command from the interpreter.
+.sp
+If the access command for an object resides in another namespace,
+then its qualified name can be used:
+.CS
+itcl::delete object foo::bar::x
+.CE
+If an error is encountered while destructing an object, the
+\fBdelete\fR command is aborted and the object remains alive.
+To destroy an object without regard for errors, use the
+"\fBrename\fR" command to destroy the object access command.
+.TP
+\fBdelete namespace \fIname\fR ?\fIname...\fR?
+Deletes one or more namespaces called \fIname\fR.  This deletes
+all commands and variables in the namespace, and deletes all
+child namespaces as well.  When a namespace is deleted, it is
+automatically removed from the import lists of all other namespaces.
+
+.SH KEYWORDS
+namespace, proc, variable, ensemble
diff --git a/8.x/itcl/doc/ensemble.n b/8.x/itcl/doc/ensemble.n
new file mode 100644 (file)
index 0000000..247689b
--- /dev/null
@@ -0,0 +1,173 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+'\" RCS: $Id: ensemble.n,v 1.4 2004/09/25 22:50:43 davygrvy Exp $
+'\" 
+.so man.macros
+.TH ensemble n 3.0 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+ensemble \- create or modify a composite command
+.SH SYNOPSIS
+\fBitcl::ensemble \fIensName\fR ?\fIcommand arg arg...\fR?
+.br
+or
+.br
+\fBensemble \fIensName\fR {
+.br
+    \fBpart \fIpartName args body\fR
+.br
+    \fI...\fR
+.br
+    \fBensemble \fIpartName\fR {
+.br
+        \fBpart \fIsubPartName args body\fR
+.br
+        \fBpart \fIsubPartName args body\fR
+.br
+    \fI...\fR
+    }
+.br
+}
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBensemble\fR command is used to create or modify a composite
+command.  See the section \fBWHAT IS AN ENSEMBLE?\fR below for a
+brief overview of ensembles.
+.PP
+If the \fBensemble\fR command finds an existing ensemble called
+\fIensName\fR, it updates that ensemble.  Otherwise, it creates an
+ensemble called \fIensName\fR.  If the \fIensName\fR is a simple name
+like "foo", then an ensemble command named "foo" is added to the
+current namespace context.  If a command named "foo" already exists
+in that context, then it is deleted.  If the \fIensName\fR contains
+namespace qualifiers like "a::b::foo", then the namespace path is
+resolved, and the ensemble command is added that namespace context.
+Parent namespaces like "a" and "b" are created automatically, as needed.
+.PP
+If the \fIensName\fR contains spaces like "a::b::foo bar baz", then
+additional words like "bar" and "baz" are treated as sub-ensembles.
+Sub-ensembles are merely parts within an ensemble; they do not have
+a Tcl command associated with them.  An ensemble like "foo" can
+have a sub-ensemble called "foo bar", which in turn can have a
+sub-ensemble called "foo bar baz".  In this case, the sub-ensemble
+"foo bar" must be created before the sub-ensemble "foo bar baz"
+that resides within it.
+.PP
+If there are any arguments following \fIensName\fR, then they are
+treated as commands, and they are executed to update the ensemble.
+The following commands are recognized in this context:  \fBpart\fR
+and \fBensemble\fR.
+.PP
+The \fBpart\fR command defines a new part for the ensemble.
+Its syntax is identical to the usual \fBproc\fR command, but
+it defines a part within an ensemble, instead of a Tcl command.
+If a part called \fIpartName\fR already exists within the ensemble,
+then the \fBpart\fR command returns an error.
+.PP
+The \fBensemble\fR command can be nested inside another \fBensemble\fR
+command to define a sub-ensemble.
+
+.SH "WHAT IS AN ENSEMBLE?"
+The usual "info" command is a composite command--the command name
+\fBinfo\fR must be followed by a sub-command like \fBbody\fR or \fBglobals\fR.
+We will refer to a command like \fBinfo\fR as an \fIensemble\fR, and to
+sub-commands like \fBbody\fR or \fBglobals\fR as its \fIparts\fR.
+.PP
+Ensembles can be nested.  For example, the \fBinfo\fR command has
+an ensemble \fBinfo namespace\fR within it.  This ensemble has parts
+like \fBinfo namespace all\fR and \fBinfo namespace children\fR.
+.PP
+With ensembles, composite commands can be created and extended
+in an automatic way.  Any package can find an existing ensemble
+and add new parts to it.  So extension writers can add their
+own parts, for example, to the \fBinfo\fR command.
+.PP
+The ensemble facility manages all of the part names and keeps
+track of unique abbreviations.  Normally, you can abbreviate
+\fBinfo complete\fR to \fBinfo comp\fR.  But if an extension adds the
+part \fBinfo complexity\fR, the minimum abbreviation for \fBinfo complete\fR
+becomes \fBinfo complet\fR.
+.PP
+The ensemble facility not only automates the construction of
+composite commands, but it automates the error handling as well.
+If you invoke an ensemble command without specifying a part name,
+you get an automatically generated error message that summarizes
+the usage information.  For example, when the \fBinfo\fR command
+is invoked without any arguments, it produces the following error
+message:
+.CS
+wrong # args: should be one of...
+  info args procname
+  info body procname
+  info cmdcount
+  info commands ?pattern?
+  info complete command
+  info context
+  info default procname arg varname
+  info exists varName
+  info globals ?pattern?
+  info level ?number?
+  info library
+  info locals ?pattern?
+  info namespace option ?arg arg ...?
+  info patchlevel
+  info procs ?pattern?
+  info protection ?-command? ?-variable? name
+  info script
+  info tclversion
+  info vars ?pattern?
+  info which ?-command? ?-variable? ?-namespace? name\fR
+.CE
+You can also customize the way an ensemble responds to errors.
+When an ensemble encounters an unspecified or ambiguous part
+name, it looks for a part called \fB@error\fR.  If it exists,
+then it is used to handle the error.  This part will receive all
+of the arguments on the command line starting with the offending
+part name.  It can find another way of resolving the command,
+or generate its own error message.
+
+.SH EXAMPLE
+We could use an ensemble to clean up the syntax of the various
+"wait" commands in Tcl/Tk.  Instead of using a series of
+strange commands like this:
+.CS
+vwait x
+tkwait visibility .top
+tkwait window .
+.CE
+we could use commands with a uniform syntax, like this:
+.CS
+wait variable x
+wait visibility .top
+wait window .
+.CE
+The Tcl package could define the following ensemble:
+.CS
+itcl::ensemble wait part variable {name} {
+    uplevel vwait $name
+}
+.CE
+The Tk package could add some options to this ensemble, with a
+command like this:
+.CS
+itcl::ensemble wait {
+    part visibility {name} {
+        tkwait visibility $name
+    }
+    part window {name} {
+        tkwait window $name
+    }
+}
+.CE
+Other extensions could add their own parts to the \fBwait\fR command
+too.
+
+.SH KEYWORDS
+ensemble, part, info
diff --git a/8.x/itcl/doc/find.n b/8.x/itcl/doc/find.n
new file mode 100644 (file)
index 0000000..f0d5c25
--- /dev/null
@@ -0,0 +1,72 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: find.n,v 1.5 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH find n 3.0 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+find \- search for classes and objects
+.SH SYNOPSIS
+\fBitcl::find \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBfind\fR command is used to find classes and objects
+that are available in the current interpreter.  Classes and objects
+are reported first in the active namespace, then in all other
+namespaces in the interpreter.
+.PP
+The \fIoption\fR argument determines what action is carried out
+by the command.  The legal \fIoptions\fR (which may be abbreviated)
+are:
+.TP
+\fBfind classes ?\fIpattern\fR?
+Returns a list of [incr Tcl] classes.  Classes in the current
+namespace are listed first, followed by classes in all other
+namespaces in the interpreter.  If the optional \fIpattern\fR
+is specified, then the reported names are compared using the rules
+of the "\fBstring match\fR" command, and only matching names are
+reported.
+.sp
+If a class resides in the current namespace context, this command
+reports its simple name--without any qualifiers.  However, if the
+\fIpattern\fR contains \fB::\fR qualifiers, or if the class resides
+in another context, this command reports its fully-qualified name.
+Therefore, you can use the following command to obtain a list where
+all names are fully-qualified:
+.CS
+itcl::find classes ::*
+.CE
+.TP
+\fBfind objects ?\fIpattern\fR? ?\fB-class \fIclassName\fR? ?\fB-isa \fIclassName\fR?
+Returns a list of [incr Tcl] objects.  Objects in the current
+namespace are listed first, followed by objects in all other
+namespaces in the interpreter.  If the optional \fIpattern\fR is
+specified, then the reported names are compared using the rules
+of the "\fBstring match\fR" command, and only matching names are
+reported.
+If the optional "\fB-class\fR" parameter is specified, this list is
+restricted to objects whose most-specific class is \fIclassName\fR.
+If the optional "\fB-isa\fR" parameter is specified, this list is
+further restricted to objects having the given \fIclassName\fR
+anywhere in their heritage.
+.sp
+If an object resides in the current namespace context, this command
+reports its simple name--without any qualifiers.  However, if the
+\fIpattern\fR contains \fB::\fR qualifiers, or if the object resides
+in another context, this command reports its fully-qualified name.
+Therefore, you can use the following command to obtain a list where
+all names are fully-qualified:
+.CS
+itcl::find objects ::*
+.CE
+
+.SH KEYWORDS
+class, object, search, import
diff --git a/8.x/itcl/doc/is.n b/8.x/itcl/doc/is.n
new file mode 100644 (file)
index 0000000..cd2c2ae
--- /dev/null
@@ -0,0 +1,66 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: is.n,v 1.6 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH is n 3.3 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+is \- test argument to see if it is a class or an object
+.SH SYNOPSIS
+\fBitcl::is \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBis\fR command is used to check if the argument given is
+a class or an object; depending on the option given. If the argument
+if a class or object, then 1 is returned. Otherwise, 0 is returned.
+The \fBis\fR command also recognizes the commands wrapped in the
+itcl \fBcode command.
+.PP
+The \fIoption\fR argument determines what action is carried out
+by the command.  The legal \fIoptions\fR (which may be abbreviated)
+are:
+.TP
+\fBis class \fIcommand\fR
+Returns 1 if command is a class, and returns 0 otherwise.
+.sp
+The fully qualified name of the class needs to be given as the \fIcommand\fR
+argument. So, if a class resides in a namespace, then the namespace needs to
+be specified as well. So, if a class \fBC resides in a namespace \fBN, then 
+the command should be called like:
+.CS
+\fBis N::C\fR
+    or
+\fBis ::N::C\fR
+.CE
+.TP
+\fBis\fR object ?\fB-class \fIclassName\fR? \fIcommand\fR
+Returns 1 if \fIcommand\fR is an object, and returns 0 otherwise.
+.sp
+If the optional "\fB-class\fR" parameter is specified, then the
+\fIcommand\fR will be checked within the context of the class
+given. Note that \fIclassName\fR has to exist. If not, then an
+error will be given. So, if \fIclassName\fR is uncertain to be
+a class, then the programmer will need to check it's existance
+beforehand, or wrap it in a catch statement.
+.sp
+So, if \fBc\fR is an object in the class \fBC\fR, in namespace N then
+these are the possibilities (all return 1):
+.CS
+set obj [N::C c]
+itcl::is object N::c
+itcl::is object c
+itcl::is object $obj
+itcl::is object [itcl::code c]
+.CE
+
+.SH KEYWORDS
+class, object
+
diff --git a/8.x/itcl/doc/itcl.n b/8.x/itcl/doc/itcl.n
new file mode 100644 (file)
index 0000000..3854186
--- /dev/null
@@ -0,0 +1,147 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: itcl.n,v 1.3 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH itcl n 3.0 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+itcl \- object-oriented extensions to Tcl
+.BE
+
+.SH DESCRIPTION
+.PP
+\fB[incr\ Tcl]\fR provides object-oriented extensions to Tcl, much as
+C++ provides object-oriented extensions to C.  The emphasis of this
+work, however, is not to create a whiz-bang object-oriented
+programming environment.  Rather, it is to support more structured
+programming practices in Tcl without changing the flavor of the language.
+More than anything else, \fB[incr\ Tcl]\fR provides a means of
+encapsulating related procedures together with their shared data
+in a namespace that is hidden from the outside world.
+It encourages better programming by promoting the object-oriented
+"library" mindset.  It also allows for code re-use through inheritance.
+
+.SH CLASSES
+.PP
+The fundamental construct in \fB[incr\ Tcl]\fR is the class definition.
+Each class acts as a template for actual objects that can be created.
+Each object has its own unique bundle of data, which contains instances
+of the "variables" defined in the class.  Special procedures called
+"methods" are used to manipulate individual objects.  Methods are just
+like the operations that are used to manipulate Tk widgets.  The
+"\fBbutton\fR" widget, for example, has methods such as "flash" and
+"invoke" that cause a particular button to blink and invoke its command.
+.PP
+Within the body of a method, the "variables" defined in the class
+are automatically available.  They need not be declared with anything
+like the \fBglobal\fR command.  Within another class method, a method
+can be invoked like any other command\-simply by using its name.
+From any other context, the method name must be prefaced by an object
+name, which provides a context for the data that the method can access.
+.PP
+Each class has its own namespace containing things that are common
+to all objects which belong to the class.  For example, "common" data
+members are shared by all objects in the class.  They are global
+variables that exist in the class namespace, but since they are
+included in the class definition, they need not be declared using
+the \fBglobal\fR command; they are automatically available to any
+code executing in the class context.  A class can also create
+ordinary global variables, but these must be declared using the
+\fBglobal\fR command each time they are used.
+.PP
+Classes can also have ordinary procedures declared as "procs".
+Within another class method or proc, a proc can be invoked like
+any other command\-simply by using its name.  From any other context,
+the procedure name should be qualified with the class namespace
+like "\fIclassName\fB::\fIproc\fR".  Class procs execute in the
+class context, and therefore have automatic access to all "common"
+data members.  However, they cannot access object-specific "variables",
+since they are invoked without reference to any specific object.
+They are usually used to perform generic operations which affect
+all objects belonging to the class.
+.PP
+Each of the elements in a class can be declared "public", "protected"
+or "private".  Public elements can be accessed by the class, by
+derived classes (other classes that inherit this class), and by
+external clients that use the class.  Protected elements can be
+accessed by the class, and by derived classes.  Private elements
+are only accessible in the class where they are defined.
+.PP
+The "public" elements within a class define its interface to the
+external world.  Public methods define the operations that can
+be used to manipulate an object.  Public variables are recognized
+as configuration options by the "configure" and "cget" methods
+that are built into each class.  The public interface says
+\fIwhat\fR an object will do but not \fIhow\fR it will do it.
+Protected and private members, along with the bodies of class
+methods and procs, provide the implementation details.  Insulating
+the application developer from these details leaves the class designer
+free to change them at any time, without warning, and without affecting
+programs that rely on the class.  It is precisely this encapsulation
+that makes object-oriented programs easier to understand and maintain.
+.PP
+The fact that \fB[incr\ Tcl]\fR objects look like Tk widgets is
+no accident.  \fB[incr\ Tcl]\fR was designed this way, to blend
+naturally into a Tcl/Tk application.  But \fB[incr\ Tcl]\fR
+extends the Tk paradigm from being merely object-based to being
+fully object-oriented.  An object-oriented system supports
+inheritance, allowing classes to share common behaviors by
+inheriting them from an ancestor or base class.  Having a base
+class as a common abstraction allows a programmer to treat
+related classes in a similar manner.  For example, a toaster
+and a blender perform different (specialized) functions, but
+both share the abstraction of being appliances.  By abstracting
+common behaviors into a base class, code can be \fIshared\fR rather
+than \fIcopied\fR.  The resulting application is easier to
+understand and maintain, and derived classes (e.g., specialized
+appliances) can be added or removed more easily.
+.PP
+This description was merely a brief overview of object-oriented
+programming and \fB[incr\ Tcl]\fR.  A more tutorial introduction is
+presented in the paper included with this distribution.  See the
+\fBclass\fR command for more details on creating and using classes.
+
+.SH NAMESPACES
+.PP
+\fB[incr\ Tcl]\fR now includes a complete namespace facility.
+A namespace is a collection of commands and global variables that
+is kept apart from the usual global scope.  This allows Tcl code
+libraries to be packaged in a well-defined manner, and prevents
+unwanted interactions with other libraries.  A namespace can also
+have child namespaces within it, so one library can contain its
+own private copy of many other libraries.  A namespace can also
+be used to wrap up a group of related classes.  The global scope
+(named "\fC::\fR") is the root namespace for an interpreter; all
+other namespaces are contained within it.
+.PP
+See the \fBnamespace\fR command for details on creating and
+using namespaces.
+
+.SH MEGA-WIDGETS
+.PP
+Mega-widgets are high-level widgets that are constructed using
+Tk widgets as component parts, usually without any C code.  A
+fileselectionbox, for example, may have a few listboxes, some
+entry widgets and some control buttons.  These individual widgets
+are put together in a way that makes them act like one big
+widget.
+.PP
+\fB[incr\ Tk]\fR is a framework for building mega-widgets.  It
+uses \fB[incr\ Tcl]\fR to support the object paradigm, and adds
+base classes which provide default widget behaviors.  See the
+\fBitk\fR man page for more details.
+.PP
+\fB[incr\ Widgets]\fR is a library of mega-widgets built using
+\fB[incr\ Tk]\fR.  It contains more than 30 different widget
+classes that can be used right out of the box to build Tcl/Tk
+applications.  Each widget class has its own man page describing
+the features available.
+
+.SH KEYWORDS
+class, object, object-oriented, namespace, mega-widget
diff --git a/8.x/itcl/doc/itclvars.n b/8.x/itcl/doc/itclvars.n
new file mode 100644 (file)
index 0000000..486c79e
--- /dev/null
@@ -0,0 +1,96 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: itclvars.n,v 1.3 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH itclvars n 3.0 itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+itclvars \- variables used by [incr\ Tcl]
+.BE
+
+.SH DESCRIPTION
+.PP
+The following global variables are created and managed automatically
+by the \fB[incr\ Tcl]\fR library.  Except where noted below, these
+variables should normally be treated as read-only by application-specific
+code and by users.
+.TP
+\fBitcl::library\fR
+When an interpreter is created, \fB[incr\ Tcl]\fR initializes this variable
+to hold the name of a directory containing the system library of
+\fB[incr\ Tcl]\fR scripts.  The initial value of \fBitcl::library\fR
+is set from the ITCL_LIBRARY environment variable if it exists,
+or from a compiled-in value otherwise.
+.TP
+\fBitcl::patchLevel\fR
+When an interpreter is created, \fB[incr\ Tcl]\fR initializes this
+variable to hold the current patch level for \fB[incr\ Tcl]\fR.
+For example, the value "\fB2.0p1\fR" indicates \fB[incr\ Tcl]\fR
+version 2.0 with the first set of patches applied.
+.TP
+\fBitcl::purist\fR
+When an interpreter is created containing Tcl/Tk and the
+\fB[incr\ Tcl]\fR namespace facility, this variable controls
+a "backward-compatibility" mode for widget access.
+.sp
+In vanilla Tcl/Tk, there is a single pool of commands, so the
+access command for a widget is the same as the window name.
+When a widget is created within a namespace, however, its access
+command is installed in that namespace, and should be accessed
+outside of the namespace using a qualified name.  For example,
+.CS
+namespace foo {
+    namespace bar {
+        button .b -text "Testing"
+    }
+}
+foo::bar::.b configure -background red
+pack .b
+.CE
+Note that the window name "\fC.b\fR" is still used in conjunction
+with commands like \fBpack\fR and \fBdestroy\fR.  However, the
+access command for the widget (i.e., name that appears as the
+\fIfirst\fR argument on a command line) must be more specific.
+.sp
+The "\fBwinfo command\fR" command can be used to query the
+fully-qualified access command for any widget, so one can write:
+.CS
+[winfo command .b] configure -background red
+.CE
+and this is good practice when writing library procedures.  Also,
+in conjunction with the \fBbind\fR command, the "%q" field can be
+used in place of "%W" as the access command:
+.CS
+bind Button <Key-Return> {%q flash; %q invoke}
+.CE
+While this behavior makes sense from the standpoint of encapsulation,
+it causes problems with existing Tcl/Tk applications.  Many existing
+applications are written with bindings that use "%W".  Many
+library procedures assume that the window name is the access
+command.
+.sp
+The \fBitcl::purist\fR variable controls a backward-compatibility
+mode.  By default, this variable is "0", and the window name
+can be used as an access command in any context.  Whenever the
+\fBunknown\fR procedure stumbles across a widget name, it simply
+uses "\fBwinfo command\fR" to determine the appropriate command
+name.  If this variable is set to "1", this backward-compatibility
+mode is disabled.  This gives better encapsulation, but using the
+window name as the access command may lead to "invalid command"
+errors.
+.TP
+\fBitcl::version\fR
+When an interpreter is created, \fB[incr\ Tcl]\fR initializes this
+variable to hold the version number of the form \fIx.y\fR.
+Changes to \fIx\fR represent major changes with probable
+incompatibilities and changes to \fIy\fR represent small enhancements
+and bug fixes that retain backward compatibility.
+
+.SH KEYWORDS
+itcl, variables
diff --git a/8.x/itcl/doc/license.terms b/8.x/itcl/doc/license.terms
new file mode 100644 (file)
index 0000000..5ad5643
--- /dev/null
@@ -0,0 +1,27 @@
+------------------------------------------------------------------------
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [incr Tcl] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ AUTHOR:  Michael J. McLennan
+          Bell Labs Innovations for Lucent Technologies
+          mmclennan@lucent.com
+          http://www.tcltk.com/itcl
+========================================================================
+             Copyright (c) 1993-1996  Lucent Technologies
+========================================================================
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that the copyright notice and warranty disclaimer appear in
+supporting documentation, and that the names of Lucent Technologies
+any of their entities not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+Lucent Technologies disclaims all warranties with regard to this
+software, including all implied warranties of merchantability and
+fitness.  In no event shall Lucent be liable for any special, indirect
+or consequential damages or any damages whatsoever resulting from loss
+of use, data or profits, whether in an action of contract, negligence
+or other tortuous action, arising out of or in connection with the use
+or performance of this software.
+========================================================================
diff --git a/8.x/itcl/doc/local.n b/8.x/itcl/doc/local.n
new file mode 100644 (file)
index 0000000..f24b71c
--- /dev/null
@@ -0,0 +1,75 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: local.n,v 1.4 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH local n "" itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+local \- create an object local to a procedure
+.SH SYNOPSIS
+\fBitcl::local \fIclassName objName\fR ?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBlocal\fR command creates an \fB[incr\ Tcl]\fR object that
+is local to the current call frame.  When the call frame goes away,
+the object is automatically deleted.  This command is useful for
+creating objects that are local to a procedure.
+.PP
+As a side effect, this command creates a variable named
+"\fCitcl-local-\fIxxx\fR", where \fIxxx\fR is the name of
+the object that is created.  This variable detects when the
+call frame is destroyed and automatically deletes the
+associated object.
+
+.SH EXAMPLE
+In the following example, a simple "counter" object is used
+within the procedure "test".  The counter is created as a
+local object, so it is automatically deleted each time the
+procedure exits.  The \fBputs\fR statements included in the
+constructor/destructor show the object coming and going
+as the procedure is called.
+.CS
+itcl::class counter {
+    private variable count 0
+    constructor {} {
+        puts "created: $this"
+    }
+    destructor {
+        puts "deleted: $this"
+    }
+
+    method bump {{by 1}} {
+        incr count $by
+    }
+    method get {} {
+        return $count
+    }
+}
+
+proc test {val} {
+    local counter x
+    for {set i 0} {$i < $val} {incr i} {
+        x bump
+    }
+    return [x get]
+}
+
+set result [test 5]
+puts "test: $result"
+
+set result [test 10]
+puts "test: $result"
+
+puts "objects: [itcl::find objects *]"
+.CE
+
+.SH KEYWORDS
+class, object, procedure
diff --git a/8.x/itcl/doc/man.macros b/8.x/itcl/doc/man.macros
new file mode 100644 (file)
index 0000000..3af2da9
--- /dev/null
@@ -0,0 +1,236 @@
+'\" The definitions below are for supplemental macros used in Tcl/Tk
+'\" manual entries.
+'\"
+'\" .AP type name in/out ?indent?
+'\"    Start paragraph describing an argument to a library procedure.
+'\"    type is type of argument (int, etc.), in/out is either "in", "out",
+'\"    or "in/out" to describe whether procedure reads or modifies arg,
+'\"    and indent is equivalent to second arg of .IP (shouldn't ever be
+'\"    needed;  use .AS below instead)
+'\"
+'\" .AS ?type? ?name?
+'\"    Give maximum sizes of arguments for setting tab stops.  Type and
+'\"    name are examples of largest possible arguments that will be passed
+'\"    to .AP later.  If args are omitted, default tab stops are used.
+'\"
+'\" .BS
+'\"    Start box enclosure.  From here until next .BE, everything will be
+'\"    enclosed in one large box.
+'\"
+'\" .BE
+'\"    End of box enclosure.
+'\"
+'\" .CS
+'\"    Begin code excerpt.
+'\"
+'\" .CE
+'\"    End code excerpt.
+'\"
+'\" .VS ?version? ?br?
+'\"    Begin vertical sidebar, for use in marking newly-changed parts
+'\"    of man pages.  The first argument is ignored and used for recording
+'\"    the version when the .VS was added, so that the sidebars can be
+'\"    found and removed when they reach a certain age.  If another argument
+'\"    is present, then a line break is forced before starting the sidebar.
+'\"
+'\" .VE
+'\"    End of vertical sidebar.
+'\"
+'\" .DS
+'\"    Begin an indented unfilled display.
+'\"
+'\" .DE
+'\"    End of indented unfilled display.
+'\"
+'\" .SO
+'\"    Start of list of standard options for a Tk widget.  The
+'\"    options follow on successive lines, in four columns separated
+'\"    by tabs.
+'\"
+'\" .SE
+'\"    End of list of standard options for a Tk widget.
+'\"
+'\" .OP cmdName dbName dbClass
+'\"    Start of description of a specific option.  cmdName gives the
+'\"    option's name as specified in the class command, dbName gives
+'\"    the option's name in the option database, and dbClass gives
+'\"    the option's class in the option database.
+'\"
+'\" .UL arg1 arg2
+'\"    Print arg1 underlined, then print arg2 normally.
+'\"
+'\" SCCS: @(#) man.macros 1.9 97/08/22 18:50:59
+'\"
+'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+'\"    # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ie !"\\$3"" \{\
+.ta \\n()Au \\n()Bu
+\&\\$1 \\fI\\$2\\fP    (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"    # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+'\"    # BS - start boxed text
+'\"    # ^y = starting y location
+'\"    # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"    # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"    Draw four-sided box normally, but don't draw top of
+.\"    box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"    # VS - start vertical sidebar
+'\"    # ^Y = starting y location
+'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"    # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"    # Special macro to handle page bottom:  finish off current
+'\"    # box/sidebar if in box/sidebar mode, then invoked standard
+'\"    # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"    Draw three-sided box if this is the box's first page,
+.\"    draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"    # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"    # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+'\"    # SO - start of list of standard options
+.de SO
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 4c 8c 12c
+.ft B
+..
+'\"    # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\fBoptions\\fR manual entry for details on the standard options.
+..
+'\"    # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name:     \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class:        \\fB\\$3\\fR
+.fi
+.IP
+..
+'\"    # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+..
+'\"    # CE - end code excerpt
+.de CE
+.fi
+.RE
+..
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
diff --git a/8.x/itcl/doc/scope.n b/8.x/itcl/doc/scope.n
new file mode 100644 (file)
index 0000000..576c6f0
--- /dev/null
@@ -0,0 +1,77 @@
+'\"
+'\" Copyright (c) 1993-1998  Lucent Technologies, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: $Id: scope.n,v 1.7 2004/09/25 22:50:43 davygrvy Exp $
+'\"
+.so man.macros
+.TH scope n "" itcl "[incr\ Tcl]"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+scope \- capture the namespace context for a variable
+.SH SYNOPSIS
+\fBitcl::scope \fIname\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+Creates a scoped value for the specified \fIname\fR, which must
+be a variable name.  If the \fIname\fR is an instance variable,
+then the scope command returns a string of the following form:
+.CS
+@itcl \fIobject varName\fP
+.CE
+This is recognized in any context as an instance variable belonging
+to \fIobject\fR.  So with itcl3.0 and beyond, it is possible to use
+instance variables in conjunction with widgets.  For example, if you
+have an object with a private variable \fCx\fR, and you can use
+\fCx\fR in conjunction with the \fC-textvariable\fR option of an
+entry widget.  Before itcl3.0, only common variables could be used
+in this manner.
+.PP
+If the \fIname\fR is not an instance variable, then it must be
+a common variable or a global variable.  In that case, the scope
+command returns the fully qualified name of the variable, e.g.,
+\fC::foo::bar::x\fR.
+.PP
+If the \fIname\fR is not recognized as a variable, the scope
+command returns an error.
+.PP
+Ordinary variable names refer to variables in the global namespace.
+A scoped value captures a variable name together with its namespace
+context in a way that allows it to be referenced properly later.
+It is needed, for example, to wrap up variable names when a Tk
+widget is used within a namespace:
+.CS
+namespace foo {
+    private variable mode 1
+
+    radiobutton .rb1 -text "Mode #1" \
+        -variable [scope mode] -value 1
+    pack .rb1
+
+    radiobutton .rb2 -text "Mode #2" \
+        -variable [scope mode] -value 2
+    pack .rb2
+}
+.CE
+Radiobuttons \fC.rb1\fR and \fC.rb2\fR interact via the variable
+"mode" contained in the namespace "foo".  The \fBscope\fR command
+guarantees this by returning the fully qualified variable name
+\fC::foo::mode\fR.
+.PP
+You should never use the \fC@itcl\fR syntax directly.  For example,
+it is a bad idea to write code like this:
+.CS
+set {@itcl ::fred x} 3
+puts "value = ${@itcl ::fred x}"
+.CE
+Instead, you should always use the scope command to generate the
+variable name dynamically.  Then, you can pass that name to a widget
+or to any other bit of code in your program.
+
+.SH KEYWORDS
+code, namespace, variable
diff --git a/8.x/itcl/generic/itcl.decls b/8.x/itcl/generic/itcl.decls
new file mode 100644 (file)
index 0000000..0c29022
--- /dev/null
@@ -0,0 +1,112 @@
+# itcl.decls --
+#
+#      This file contains the declarations for all supported public
+#      functions that are exported by the Itcl library via the stubs table.
+#      This file is used to generate the itclDecls.h, itclPlatDecls.h,
+#      itclStub.c, and itclPlatStub.c files.
+#      
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# RCS: $Id: itcl.decls,v 1.3 2003/12/17 02:25:37 davygrvy Exp $
+
+library itcl
+
+# Define the itcl interface with several sub interfaces:
+#     itclPlat  - platform specific public
+#     itclInt   - generic private
+#     itclPlatInt - platform specific private
+
+interface itcl
+hooks {itclInt}
+
+# Declare each of the functions in the public Tcl interface.  Note that
+# the an index should never be reused for a different function in order
+# to preserve backwards compatibility.
+
+declare 0 generic {
+    int Itcl_Init(Tcl_Interp *interp)
+}
+declare 1 generic {
+    int Itcl_SafeInit(Tcl_Interp *interp)
+}
+declare 2 generic {
+    int Itcl_RegisterC(Tcl_Interp *interp, CONST char *name, \
+        Tcl_CmdProc *proc, ClientData clientData, \
+        Tcl_CmdDeleteProc *deleteProc)
+}
+declare 3 generic {
+    int Itcl_RegisterObjC (Tcl_Interp *interp, CONST char *name, \
+        Tcl_ObjCmdProc *proc, ClientData clientData, \
+        Tcl_CmdDeleteProc *deleteProc)
+}
+declare 4 generic {
+    int Itcl_FindC(Tcl_Interp *interp, CONST char *name, \
+       Tcl_CmdProc **argProcPtr, Tcl_ObjCmdProc **objProcPtr, \
+       ClientData *cDataPtr)
+}
+declare 5 generic {
+    void Itcl_InitStack(Itcl_Stack *stack)
+}
+declare 6 generic {
+    void Itcl_DeleteStack(Itcl_Stack *stack)
+}
+declare 7 generic {
+    void Itcl_PushStack(ClientData cdata, Itcl_Stack *stack)
+}
+declare 8 generic {
+    ClientData Itcl_PopStack(Itcl_Stack *stack)
+}
+declare 9 generic {
+    ClientData Itcl_PeekStack(Itcl_Stack *stack)
+}
+declare 10 generic {
+    ClientData Itcl_GetStackValue(Itcl_Stack *stack, int pos)
+}
+declare 11 generic {
+    void Itcl_InitList(Itcl_List *listPtr)
+}
+declare 12 generic {
+    void Itcl_DeleteList(Itcl_List *listPtr)
+}
+declare 13 generic {
+    Itcl_ListElem* Itcl_CreateListElem(Itcl_List *listPtr)
+}
+declare 14 generic {
+    Itcl_ListElem* Itcl_DeleteListElem(Itcl_ListElem *elemPtr)
+}
+declare 15 generic {
+    Itcl_ListElem* Itcl_InsertList(Itcl_List *listPtr, ClientData val)
+}
+declare 16 generic {
+    Itcl_ListElem* Itcl_InsertListElem (Itcl_ListElem *pos, ClientData val)
+}
+declare 17 generic {
+    Itcl_ListElem* Itcl_AppendList(Itcl_List *listPtr, ClientData val)
+}
+declare 18 generic {
+    Itcl_ListElem* Itcl_AppendListElem(Itcl_ListElem *pos, ClientData val)
+}
+declare 19 generic {
+    void Itcl_SetListValue(Itcl_ListElem *elemPtr, ClientData val)
+}
+declare 20 generic {
+    void Itcl_EventuallyFree(ClientData cdata, Tcl_FreeProc *fproc)
+}
+declare 21 generic {
+    void Itcl_PreserveData(ClientData cdata)
+}
+declare 22 generic {
+    void Itcl_ReleaseData(ClientData cdata)
+}
+declare 23 generic {
+    Itcl_InterpState Itcl_SaveInterpState(Tcl_Interp* interp, int status)
+}
+declare 24 generic {
+    int Itcl_RestoreInterpState(Tcl_Interp* interp, Itcl_InterpState state)
+}
+declare 25 generic {
+    void Itcl_DiscardInterpState(Itcl_InterpState state)
+}
diff --git a/8.x/itcl/generic/itcl.h b/8.x/itcl/generic/itcl.h
new file mode 100644 (file)
index 0000000..89f39e7
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *  
+ *  ADDING [incr Tcl] TO A Tcl-BASED APPLICATION:
+ *
+ *    To add [incr Tcl] facilities to a Tcl application, modify the
+ *    Tcl_AppInit() routine as follows:
+ *
+ *    1) Include this header file near the top of the file containing
+ *       Tcl_AppInit():
+ *
+ *         #include "itcl.h"
+ *
+ *    2) Within the body of Tcl_AppInit(), add the following lines:
+ *
+ *         if (Itcl_Init(interp) == TCL_ERROR) {
+ *             return TCL_ERROR;
+ *         }
+ * 
+ *    3) Link your application with libitcl.a
+ *
+ *    NOTE:  An example file "tclAppInit.c" containing the changes shown
+ *           above is included in this distribution.
+ *  
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl.h,v 1.31 2007/05/24 22:15:41 hobbs Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#ifndef ITCL_H
+#define ITCL_H
+
+#include "tcl.h"
+
+#ifndef TCL_ALPHA_RELEASE
+#   define TCL_ALPHA_RELEASE   0
+#endif
+#ifndef TCL_BETA_RELEASE
+#   define TCL_BETA_RELEASE    1
+#endif
+#ifndef TCL_FINAL_RELEASE
+#   define TCL_FINAL_RELEASE   2
+#endif
+
+
+#define ITCL_MAJOR_VERSION     3
+#define ITCL_MINOR_VERSION     4
+#define ITCL_RELEASE_LEVEL     TCL_FINAL_RELEASE
+#define ITCL_RELEASE_SERIAL    0
+
+#define ITCL_VERSION           "3.4"
+#define ITCL_PATCH_LEVEL       "3.4.0"
+
+/* 
+ * A special definition used to allow this header file to be included 
+ * in resource files so that they can get obtain version information from
+ * this file.  Resource compilers don't like all the C stuff, like typedefs
+ * and procedure declarations, that occur below.
+ */
+
+#ifndef RC_INVOKED
+
+#undef TCL_STORAGE_CLASS
+#ifdef BUILD_itcl
+#   define TCL_STORAGE_CLASS DLLEXPORT
+#else
+#   ifdef USE_ITCL_STUBS
+#      define TCL_STORAGE_CLASS
+#   else
+#      define TCL_STORAGE_CLASS DLLIMPORT
+#   endif
+#endif
+
+/*
+ * Fix the Borland bug that's in the EXTERN macro from tcl.h.
+ */
+#ifndef TCL_EXTERN
+#   undef DLLIMPORT
+#   undef DLLEXPORT
+#   ifdef __cplusplus
+#      define TCL_EXTERNC extern "C"
+#   else
+#      define TCL_EXTERNC extern
+#   endif
+#   if defined(STATIC_BUILD)
+#      define DLLIMPORT
+#      define DLLEXPORT
+#      define TCL_EXTERN(RTYPE) TCL_EXTERNC RTYPE
+#   elif (defined(__WIN32__) && ( \
+           defined(_MSC_VER) || (__BORLANDC__ >= 0x0550) || \
+           defined(__LCC__) || defined(__WATCOMC__) || \
+           (defined(__GNUC__) && defined(__declspec)) \
+       )) || (defined(MAC_TCL) && FUNCTION_DECLSPEC)
+#      define DLLIMPORT __declspec(dllimport)
+#      define DLLEXPORT __declspec(dllexport)
+#      define TCL_EXTERN(RTYPE) TCL_EXTERNC TCL_STORAGE_CLASS RTYPE
+#   elif defined(__BORLANDC__)
+#      define DLLIMPORT __import
+#      define DLLEXPORT __export
+       /* Pre-5.5 Borland requires the attributes be placed after the */
+       /* return type instead. */
+#      define TCL_EXTERN(RTYPE) TCL_EXTERNC RTYPE TCL_STORAGE_CLASS
+#   else
+#      define DLLIMPORT
+#      define DLLEXPORT
+#      define TCL_EXTERN(RTYPE) TCL_EXTERNC TCL_STORAGE_CLASS RTYPE
+#   endif
+#endif
+
+
+/*
+ * Starting from the 8.4 core, Tcl API is CONST'ified.  Our API is always
+ * CONST, but we need to build with Tcl when it isn't CONST and fake it
+ * when needed with <= 8.3
+ *
+ * http://wiki.tcl.tk/3669
+ */
+
+#ifndef CONST84
+#   define CONST84
+#endif
+
+
+/*
+ * Protection levels:
+ *
+ * ITCL_PUBLIC    - accessible from any namespace
+ * ITCL_PROTECTED - accessible from namespace that imports in "protected" mode
+ * ITCL_PRIVATE   - accessible only within the namespace that contains it
+ */
+#define ITCL_PUBLIC           1
+#define ITCL_PROTECTED        2
+#define ITCL_PRIVATE          3
+#define ITCL_DEFAULT_PROTECT  4
+
+
+/*
+ *  Generic stack.
+ */
+typedef struct Itcl_Stack {
+    ClientData *values;          /* values on stack */
+    int len;                     /* number of values on stack */
+    int max;                     /* maximum size of stack */
+    ClientData space[5];         /* initial space for stack data */
+} Itcl_Stack;
+
+#define Itcl_GetStackSize(stackPtr) ((stackPtr)->len)
+
+/*
+ *  Generic linked list.
+ */
+struct Itcl_List;
+typedef struct Itcl_ListElem {
+    struct Itcl_List* owner;     /* list containing this element */
+    ClientData value;            /* value associated with this element */
+    struct Itcl_ListElem *prev;  /* previous element in linked list */
+    struct Itcl_ListElem *next;  /* next element in linked list */
+} Itcl_ListElem;
+
+typedef struct Itcl_List {
+    int validate;                /* validation stamp */
+    int num;                     /* number of elements */
+    struct Itcl_ListElem *head;  /* previous element in linked list */
+    struct Itcl_ListElem *tail;  /* next element in linked list */
+} Itcl_List;
+
+#define Itcl_FirstListElem(listPtr) ((listPtr)->head)
+#define Itcl_LastListElem(listPtr)  ((listPtr)->tail)
+#define Itcl_NextListElem(elemPtr)  ((elemPtr)->next)
+#define Itcl_PrevListElem(elemPtr)  ((elemPtr)->prev)
+#define Itcl_GetListLength(listPtr) ((listPtr)->num)
+#define Itcl_GetListValue(elemPtr)  ((elemPtr)->value)
+
+/*
+ *  Token representing the state of an interpreter.
+ */
+typedef struct Itcl_InterpState_ *Itcl_InterpState;
+
+
+/*
+ * Include the public function declarations that are accessible via
+ * the stubs table.
+ */
+
+#include "itclDecls.h"
+
+
+/*
+ * Itcl_InitStubs is used by extensions like Itk that can be linked
+ * against the itcl stubs library.  If we are not using stubs
+ * then this reduces to package require.
+ */
+
+#ifdef USE_ITCL_STUBS
+
+TCL_EXTERNC CONST char *
+       Itcl_InitStubs _ANSI_ARGS_((Tcl_Interp *interp,
+                           CONST char *version, int exact));
+#else
+#define Itcl_InitStubs(interp, version, exact) \
+      Tcl_PkgRequire(interp, "Itcl", version, exact)
+#endif
+
+/*
+ * Public functions that are not accessible via the stubs table.
+ */
+
+
+#endif /* RC_INVOKED */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
+#endif /* ITCL_H */
diff --git a/8.x/itcl/generic/itclDecls.h b/8.x/itcl/generic/itclDecls.h
new file mode 100644 (file)
index 0000000..fe49ec8
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * itclDecls.h --
+ *
+ *     Declarations of functions in the platform independent public Itcl API.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: $Id: itclDecls.h,v 1.9 2003/12/23 05:22:45 davygrvy Exp $
+ */
+
+#ifndef _ITCLDECLS
+#define _ITCLDECLS
+
+/*
+ * WARNING: This file is automatically generated by the tools/genStubs.tcl
+ * script.  Any modifications to the function declarations below should be made
+ * in the itcl/generic/tcl.decls script.
+ */
+
+/* !BEGIN!: Do not edit below this line. */
+
+/*
+ * Exported function declarations:
+ */
+
+#ifndef Itcl_Init_TCL_DECLARED
+#define Itcl_Init_TCL_DECLARED
+/* 0 */
+TCL_EXTERN(int)                Itcl_Init _ANSI_ARGS_((Tcl_Interp * interp));
+#endif
+#ifndef Itcl_SafeInit_TCL_DECLARED
+#define Itcl_SafeInit_TCL_DECLARED
+/* 1 */
+TCL_EXTERN(int)                Itcl_SafeInit _ANSI_ARGS_((Tcl_Interp * interp));
+#endif
+#ifndef Itcl_RegisterC_TCL_DECLARED
+#define Itcl_RegisterC_TCL_DECLARED
+/* 2 */
+TCL_EXTERN(int)                Itcl_RegisterC _ANSI_ARGS_((Tcl_Interp * interp, 
+                               CONST char * name, Tcl_CmdProc * proc, 
+                               ClientData clientData, 
+                               Tcl_CmdDeleteProc * deleteProc));
+#endif
+#ifndef Itcl_RegisterObjC_TCL_DECLARED
+#define Itcl_RegisterObjC_TCL_DECLARED
+/* 3 */
+TCL_EXTERN(int)                Itcl_RegisterObjC _ANSI_ARGS_((Tcl_Interp * interp, 
+                               CONST char * name, Tcl_ObjCmdProc * proc, 
+                               ClientData clientData, 
+                               Tcl_CmdDeleteProc * deleteProc));
+#endif
+#ifndef Itcl_FindC_TCL_DECLARED
+#define Itcl_FindC_TCL_DECLARED
+/* 4 */
+TCL_EXTERN(int)                Itcl_FindC _ANSI_ARGS_((Tcl_Interp * interp, 
+                               CONST char * name, Tcl_CmdProc ** argProcPtr, 
+                               Tcl_ObjCmdProc ** objProcPtr, 
+                               ClientData * cDataPtr));
+#endif
+#ifndef Itcl_InitStack_TCL_DECLARED
+#define Itcl_InitStack_TCL_DECLARED
+/* 5 */
+TCL_EXTERN(void)       Itcl_InitStack _ANSI_ARGS_((Itcl_Stack * stack));
+#endif
+#ifndef Itcl_DeleteStack_TCL_DECLARED
+#define Itcl_DeleteStack_TCL_DECLARED
+/* 6 */
+TCL_EXTERN(void)       Itcl_DeleteStack _ANSI_ARGS_((Itcl_Stack * stack));
+#endif
+#ifndef Itcl_PushStack_TCL_DECLARED
+#define Itcl_PushStack_TCL_DECLARED
+/* 7 */
+TCL_EXTERN(void)       Itcl_PushStack _ANSI_ARGS_((ClientData cdata, 
+                               Itcl_Stack * stack));
+#endif
+#ifndef Itcl_PopStack_TCL_DECLARED
+#define Itcl_PopStack_TCL_DECLARED
+/* 8 */
+TCL_EXTERN(ClientData) Itcl_PopStack _ANSI_ARGS_((Itcl_Stack * stack));
+#endif
+#ifndef Itcl_PeekStack_TCL_DECLARED
+#define Itcl_PeekStack_TCL_DECLARED
+/* 9 */
+TCL_EXTERN(ClientData) Itcl_PeekStack _ANSI_ARGS_((Itcl_Stack * stack));
+#endif
+#ifndef Itcl_GetStackValue_TCL_DECLARED
+#define Itcl_GetStackValue_TCL_DECLARED
+/* 10 */
+TCL_EXTERN(ClientData) Itcl_GetStackValue _ANSI_ARGS_((Itcl_Stack * stack, 
+                               int pos));
+#endif
+#ifndef Itcl_InitList_TCL_DECLARED
+#define Itcl_InitList_TCL_DECLARED
+/* 11 */
+TCL_EXTERN(void)       Itcl_InitList _ANSI_ARGS_((Itcl_List * listPtr));
+#endif
+#ifndef Itcl_DeleteList_TCL_DECLARED
+#define Itcl_DeleteList_TCL_DECLARED
+/* 12 */
+TCL_EXTERN(void)       Itcl_DeleteList _ANSI_ARGS_((Itcl_List * listPtr));
+#endif
+#ifndef Itcl_CreateListElem_TCL_DECLARED
+#define Itcl_CreateListElem_TCL_DECLARED
+/* 13 */
+TCL_EXTERN(Itcl_ListElem*) Itcl_CreateListElem _ANSI_ARGS_((
+                               Itcl_List * listPtr));
+#endif
+#ifndef Itcl_DeleteListElem_TCL_DECLARED
+#define Itcl_DeleteListElem_TCL_DECLARED
+/* 14 */
+TCL_EXTERN(Itcl_ListElem*) Itcl_DeleteListElem _ANSI_ARGS_((
+                               Itcl_ListElem * elemPtr));
+#endif
+#ifndef Itcl_InsertList_TCL_DECLARED
+#define Itcl_InsertList_TCL_DECLARED
+/* 15 */
+TCL_EXTERN(Itcl_ListElem*) Itcl_InsertList _ANSI_ARGS_((Itcl_List * listPtr, 
+                               ClientData val));
+#endif
+#ifndef Itcl_InsertListElem_TCL_DECLARED
+#define Itcl_InsertListElem_TCL_DECLARED
+/* 16 */
+TCL_EXTERN(Itcl_ListElem*) Itcl_InsertListElem _ANSI_ARGS_((
+                               Itcl_ListElem * pos, ClientData val));
+#endif
+#ifndef Itcl_AppendList_TCL_DECLARED
+#define Itcl_AppendList_TCL_DECLARED
+/* 17 */
+TCL_EXTERN(Itcl_ListElem*) Itcl_AppendList _ANSI_ARGS_((Itcl_List * listPtr, 
+                               ClientData val));
+#endif
+#ifndef Itcl_AppendListElem_TCL_DECLARED
+#define Itcl_AppendListElem_TCL_DECLARED
+/* 18 */
+TCL_EXTERN(Itcl_ListElem*) Itcl_AppendListElem _ANSI_ARGS_((
+                               Itcl_ListElem * pos, ClientData val));
+#endif
+#ifndef Itcl_SetListValue_TCL_DECLARED
+#define Itcl_SetListValue_TCL_DECLARED
+/* 19 */
+TCL_EXTERN(void)       Itcl_SetListValue _ANSI_ARGS_((
+                               Itcl_ListElem * elemPtr, ClientData val));
+#endif
+#ifndef Itcl_EventuallyFree_TCL_DECLARED
+#define Itcl_EventuallyFree_TCL_DECLARED
+/* 20 */
+TCL_EXTERN(void)       Itcl_EventuallyFree _ANSI_ARGS_((ClientData cdata, 
+                               Tcl_FreeProc * fproc));
+#endif
+#ifndef Itcl_PreserveData_TCL_DECLARED
+#define Itcl_PreserveData_TCL_DECLARED
+/* 21 */
+TCL_EXTERN(void)       Itcl_PreserveData _ANSI_ARGS_((ClientData cdata));
+#endif
+#ifndef Itcl_ReleaseData_TCL_DECLARED
+#define Itcl_ReleaseData_TCL_DECLARED
+/* 22 */
+TCL_EXTERN(void)       Itcl_ReleaseData _ANSI_ARGS_((ClientData cdata));
+#endif
+#ifndef Itcl_SaveInterpState_TCL_DECLARED
+#define Itcl_SaveInterpState_TCL_DECLARED
+/* 23 */
+TCL_EXTERN(Itcl_InterpState) Itcl_SaveInterpState _ANSI_ARGS_((
+                               Tcl_Interp* interp, int status));
+#endif
+#ifndef Itcl_RestoreInterpState_TCL_DECLARED
+#define Itcl_RestoreInterpState_TCL_DECLARED
+/* 24 */
+TCL_EXTERN(int)                Itcl_RestoreInterpState _ANSI_ARGS_((
+                               Tcl_Interp* interp, Itcl_InterpState state));
+#endif
+#ifndef Itcl_DiscardInterpState_TCL_DECLARED
+#define Itcl_DiscardInterpState_TCL_DECLARED
+/* 25 */
+TCL_EXTERN(void)       Itcl_DiscardInterpState _ANSI_ARGS_((
+                               Itcl_InterpState state));
+#endif
+
+typedef struct ItclStubHooks {
+    struct ItclIntStubs *itclIntStubs;
+} ItclStubHooks;
+
+typedef struct ItclStubs {
+    int magic;
+    struct ItclStubHooks *hooks;
+
+    int (*itcl_Init) _ANSI_ARGS_((Tcl_Interp * interp)); /* 0 */
+    int (*itcl_SafeInit) _ANSI_ARGS_((Tcl_Interp * interp)); /* 1 */
+    int (*itcl_RegisterC) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, Tcl_CmdProc * proc, ClientData clientData, Tcl_CmdDeleteProc * deleteProc)); /* 2 */
+    int (*itcl_RegisterObjC) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, Tcl_ObjCmdProc * proc, ClientData clientData, Tcl_CmdDeleteProc * deleteProc)); /* 3 */
+    int (*itcl_FindC) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, Tcl_CmdProc ** argProcPtr, Tcl_ObjCmdProc ** objProcPtr, ClientData * cDataPtr)); /* 4 */
+    void (*itcl_InitStack) _ANSI_ARGS_((Itcl_Stack * stack)); /* 5 */
+    void (*itcl_DeleteStack) _ANSI_ARGS_((Itcl_Stack * stack)); /* 6 */
+    void (*itcl_PushStack) _ANSI_ARGS_((ClientData cdata, Itcl_Stack * stack)); /* 7 */
+    ClientData (*itcl_PopStack) _ANSI_ARGS_((Itcl_Stack * stack)); /* 8 */
+    ClientData (*itcl_PeekStack) _ANSI_ARGS_((Itcl_Stack * stack)); /* 9 */
+    ClientData (*itcl_GetStackValue) _ANSI_ARGS_((Itcl_Stack * stack, int pos)); /* 10 */
+    void (*itcl_InitList) _ANSI_ARGS_((Itcl_List * listPtr)); /* 11 */
+    void (*itcl_DeleteList) _ANSI_ARGS_((Itcl_List * listPtr)); /* 12 */
+    Itcl_ListElem* (*itcl_CreateListElem) _ANSI_ARGS_((Itcl_List * listPtr)); /* 13 */
+    Itcl_ListElem* (*itcl_DeleteListElem) _ANSI_ARGS_((Itcl_ListElem * elemPtr)); /* 14 */
+    Itcl_ListElem* (*itcl_InsertList) _ANSI_ARGS_((Itcl_List * listPtr, ClientData val)); /* 15 */
+    Itcl_ListElem* (*itcl_InsertListElem) _ANSI_ARGS_((Itcl_ListElem * pos, ClientData val)); /* 16 */
+    Itcl_ListElem* (*itcl_AppendList) _ANSI_ARGS_((Itcl_List * listPtr, ClientData val)); /* 17 */
+    Itcl_ListElem* (*itcl_AppendListElem) _ANSI_ARGS_((Itcl_ListElem * pos, ClientData val)); /* 18 */
+    void (*itcl_SetListValue) _ANSI_ARGS_((Itcl_ListElem * elemPtr, ClientData val)); /* 19 */
+    void (*itcl_EventuallyFree) _ANSI_ARGS_((ClientData cdata, Tcl_FreeProc * fproc)); /* 20 */
+    void (*itcl_PreserveData) _ANSI_ARGS_((ClientData cdata)); /* 21 */
+    void (*itcl_ReleaseData) _ANSI_ARGS_((ClientData cdata)); /* 22 */
+    Itcl_InterpState (*itcl_SaveInterpState) _ANSI_ARGS_((Tcl_Interp* interp, int status)); /* 23 */
+    int (*itcl_RestoreInterpState) _ANSI_ARGS_((Tcl_Interp* interp, Itcl_InterpState state)); /* 24 */
+    void (*itcl_DiscardInterpState) _ANSI_ARGS_((Itcl_InterpState state)); /* 25 */
+} ItclStubs;
+
+TCL_EXTERNC ItclStubs *itclStubsPtr;
+
+#if defined(USE_ITCL_STUBS) && !defined(USE_ITCL_STUB_PROCS)
+
+/*
+ * Inline function declarations:
+ */
+
+#ifndef Itcl_Init
+#define Itcl_Init \
+       (itclStubsPtr->itcl_Init) /* 0 */
+#endif
+#ifndef Itcl_SafeInit
+#define Itcl_SafeInit \
+       (itclStubsPtr->itcl_SafeInit) /* 1 */
+#endif
+#ifndef Itcl_RegisterC
+#define Itcl_RegisterC \
+       (itclStubsPtr->itcl_RegisterC) /* 2 */
+#endif
+#ifndef Itcl_RegisterObjC
+#define Itcl_RegisterObjC \
+       (itclStubsPtr->itcl_RegisterObjC) /* 3 */
+#endif
+#ifndef Itcl_FindC
+#define Itcl_FindC \
+       (itclStubsPtr->itcl_FindC) /* 4 */
+#endif
+#ifndef Itcl_InitStack
+#define Itcl_InitStack \
+       (itclStubsPtr->itcl_InitStack) /* 5 */
+#endif
+#ifndef Itcl_DeleteStack
+#define Itcl_DeleteStack \
+       (itclStubsPtr->itcl_DeleteStack) /* 6 */
+#endif
+#ifndef Itcl_PushStack
+#define Itcl_PushStack \
+       (itclStubsPtr->itcl_PushStack) /* 7 */
+#endif
+#ifndef Itcl_PopStack
+#define Itcl_PopStack \
+       (itclStubsPtr->itcl_PopStack) /* 8 */
+#endif
+#ifndef Itcl_PeekStack
+#define Itcl_PeekStack \
+       (itclStubsPtr->itcl_PeekStack) /* 9 */
+#endif
+#ifndef Itcl_GetStackValue
+#define Itcl_GetStackValue \
+       (itclStubsPtr->itcl_GetStackValue) /* 10 */
+#endif
+#ifndef Itcl_InitList
+#define Itcl_InitList \
+       (itclStubsPtr->itcl_InitList) /* 11 */
+#endif
+#ifndef Itcl_DeleteList
+#define Itcl_DeleteList \
+       (itclStubsPtr->itcl_DeleteList) /* 12 */
+#endif
+#ifndef Itcl_CreateListElem
+#define Itcl_CreateListElem \
+       (itclStubsPtr->itcl_CreateListElem) /* 13 */
+#endif
+#ifndef Itcl_DeleteListElem
+#define Itcl_DeleteListElem \
+       (itclStubsPtr->itcl_DeleteListElem) /* 14 */
+#endif
+#ifndef Itcl_InsertList
+#define Itcl_InsertList \
+       (itclStubsPtr->itcl_InsertList) /* 15 */
+#endif
+#ifndef Itcl_InsertListElem
+#define Itcl_InsertListElem \
+       (itclStubsPtr->itcl_InsertListElem) /* 16 */
+#endif
+#ifndef Itcl_AppendList
+#define Itcl_AppendList \
+       (itclStubsPtr->itcl_AppendList) /* 17 */
+#endif
+#ifndef Itcl_AppendListElem
+#define Itcl_AppendListElem \
+       (itclStubsPtr->itcl_AppendListElem) /* 18 */
+#endif
+#ifndef Itcl_SetListValue
+#define Itcl_SetListValue \
+       (itclStubsPtr->itcl_SetListValue) /* 19 */
+#endif
+#ifndef Itcl_EventuallyFree
+#define Itcl_EventuallyFree \
+       (itclStubsPtr->itcl_EventuallyFree) /* 20 */
+#endif
+#ifndef Itcl_PreserveData
+#define Itcl_PreserveData \
+       (itclStubsPtr->itcl_PreserveData) /* 21 */
+#endif
+#ifndef Itcl_ReleaseData
+#define Itcl_ReleaseData \
+       (itclStubsPtr->itcl_ReleaseData) /* 22 */
+#endif
+#ifndef Itcl_SaveInterpState
+#define Itcl_SaveInterpState \
+       (itclStubsPtr->itcl_SaveInterpState) /* 23 */
+#endif
+#ifndef Itcl_RestoreInterpState
+#define Itcl_RestoreInterpState \
+       (itclStubsPtr->itcl_RestoreInterpState) /* 24 */
+#endif
+#ifndef Itcl_DiscardInterpState
+#define Itcl_DiscardInterpState \
+       (itclStubsPtr->itcl_DiscardInterpState) /* 25 */
+#endif
+
+#endif /* defined(USE_ITCL_STUBS) && !defined(USE_ITCL_STUB_PROCS) */
+
+/* !END!: Do not edit above this line. */
+
+#endif /* _ITCLDECLS */
+
diff --git a/8.x/itcl/generic/itclInt.decls b/8.x/itcl/generic/itclInt.decls
new file mode 100644 (file)
index 0000000..bcb8dce
--- /dev/null
@@ -0,0 +1,513 @@
+# itclInt.decls --
+#
+#      This file contains the declarations for all unsupported
+#      functions that are exported by the Itcl library.
+#
+#      By "unsupported", it should be noted that due to Tcl's hiding
+#      of the data types used, we inherit this hidden-ness ourselves,
+#      too, unfortunately.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# RCS: @(#) $Id: itclInt.decls,v 1.9 2007/05/24 21:40:23 hobbs Exp $
+
+library itcl
+
+# Define the unsupported generic interfaces.
+
+interface itclInt
+
+
+#
+# Functions used within the package, but not considered "public"
+#
+
+declare 0 generic {
+    int Itcl_IsClassNamespace(Tcl_Namespace *namesp)
+}
+declare 1 generic {
+    int Itcl_IsClass (Tcl_Command cmd)
+}
+declare 2 generic {
+    ItclClass* Itcl_FindClass (Tcl_Interp* interp, CONST char* path, int autoload)
+}
+declare 3 generic {
+    int Itcl_FindObject (Tcl_Interp *interp, CONST char *name, ItclObject **roPtr)
+}
+declare 4 generic {   
+    int Itcl_IsObject (Tcl_Command cmd)
+}
+declare 5 generic {
+    int Itcl_ObjectIsa (ItclObject *contextObj, ItclClass *cdefn)
+}
+declare 6 generic {
+    int Itcl_Protection (Tcl_Interp *interp, int newLevel)
+}
+declare 7 generic {
+    char* Itcl_ProtectionStr (int pLevel)
+}
+declare 8 generic {
+    int Itcl_CanAccess (ItclMember* memberPtr, Tcl_Namespace* fromNsPtr)
+}
+declare 9 generic {
+    int Itcl_CanAccessFunc (ItclMemberFunc* mfunc, Tcl_Namespace* fromNsPtr)
+}
+declare 10 generic {
+    Tcl_Namespace* Itcl_GetTrueNamespace (Tcl_Interp *interp, \
+        ItclObjectInfo *info)
+}
+declare 11 generic {
+    void Itcl_ParseNamespPath (CONST char *name, Tcl_DString *buffer, \
+        char **head, char **tail)
+}
+declare 12 generic {
+    int Itcl_DecodeScopedCommand (Tcl_Interp *interp, CONST char *name, \
+        Tcl_Namespace **rNsPtr, char **rCmdPtr)
+}
+declare 13 generic {
+    int Itcl_EvalArgs (Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+}
+declare 14 generic {
+    Tcl_Obj* Itcl_CreateArgs (Tcl_Interp *interp, CONST char *string, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 15 generic {
+    int Itcl_PushContext (Tcl_Interp *interp, ItclMember *member, \
+        ItclClass *contextClass, ItclObject *contextObj, \
+        ItclContext *contextPtr)
+}
+declare 16 generic {
+    void Itcl_PopContext (Tcl_Interp *interp, ItclContext *contextPtr)
+}
+declare 17 generic {
+    int Itcl_GetContext (Tcl_Interp *interp, ItclClass **cdefnPtr, \
+        ItclObject **odefnPtr)
+}
+declare 18 generic {
+    void Itcl_InitHierIter (ItclHierIter *iter, ItclClass *cdefn)
+}
+declare 19 generic {
+    void Itcl_DeleteHierIter (ItclHierIter *iter)
+}
+declare 20 generic {
+    ItclClass* Itcl_AdvanceHierIter (ItclHierIter *iter)
+}
+declare 21 generic {
+    int Itcl_FindClassesCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 22 generic {
+    int Itcl_FindObjectsCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 23 generic {
+    int Itcl_ProtectionCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 24 generic {
+    int Itcl_DelClassCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 25 generic {
+    int Itcl_DelObjectCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 26 generic {
+    int Itcl_ScopeCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 27 generic {
+    int Itcl_CodeCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 28 generic {   
+    int Itcl_StubCreateCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 29 generic {
+    int Itcl_StubExistsCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 30 generic {
+    int Itcl_IsStub (Tcl_Command cmd)
+}
+
+
+#
+#  Functions for manipulating classes
+#
+
+declare 31 generic {
+    int Itcl_CreateClass (Tcl_Interp* interp, CONST char* path, \
+        ItclObjectInfo *info, ItclClass **rPtr)
+}
+declare 32 generic {
+    int Itcl_DeleteClass (Tcl_Interp *interp, ItclClass *cdefnPtr)
+}
+declare 33 generic {
+    Tcl_Namespace* Itcl_FindClassNamespace (Tcl_Interp* interp, CONST char* path)
+}
+declare 34 generic {
+    int Itcl_HandleClass (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 35 generic {
+    int Itcl_ClassCmdResolver (Tcl_Interp *interp, CONST char* name, \
+        Tcl_Namespace *context, int flags, Tcl_Command *rPtr)
+}
+declare 36 generic {
+    int Itcl_ClassVarResolver (Tcl_Interp *interp, CONST char* name, \
+        Tcl_Namespace *context, int flags, Tcl_Var *rPtr)
+}
+declare 37 generic {
+    int Itcl_ClassCompiledVarResolver (Tcl_Interp *interp, CONST char* name, \
+        int length, Tcl_Namespace *context, Tcl_ResolvedVarInfo **rPtr)
+}
+declare 38 generic {
+    void Itcl_BuildVirtualTables (ItclClass* cdefnPtr)
+}
+declare 39 generic {
+    int Itcl_CreateVarDefn (Tcl_Interp *interp, ItclClass* cdefn, \
+        char* name, char* init, char* config, ItclVarDefn** vdefnPtr)
+}
+declare 40 generic {
+    void Itcl_DeleteVarDefn (ItclVarDefn *vdefn)
+}
+declare 41 generic {
+    CONST char* Itcl_GetCommonVar (Tcl_Interp *interp, CONST char *name, \
+        ItclClass *contextClass)
+}
+declare 42 generic {
+    ItclMember* Itcl_CreateMember (Tcl_Interp* interp, ItclClass *cdefn, \
+        CONST char* name)
+}
+declare 43 generic {
+    void Itcl_DeleteMember (ItclMember *memPtr)
+}
+
+
+#
+#  Functions for manipulating objects
+#
+
+declare 44 generic {
+    int Itcl_CreateObject (Tcl_Interp *interp, CONST char* name, ItclClass *cdefn, \
+        int objc, Tcl_Obj *CONST objv[], ItclObject **roPtr)
+}
+declare 45 generic {
+    int Itcl_DeleteObject (Tcl_Interp *interp, ItclObject *contextObj)
+}
+declare 46 generic {
+    int Itcl_DestructObject (Tcl_Interp *interp, ItclObject *contextObj, \
+        int flags)
+}
+declare 47 generic {
+    int Itcl_HandleInstance (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 48 generic {
+    CONST char* Itcl_GetInstanceVar (Tcl_Interp *interp, CONST char *name, \
+        ItclObject *contextObj, ItclClass *contextClass)
+}
+declare 49 generic {
+    int Itcl_ScopedVarResolver (Tcl_Interp *interp, CONST char *name, \
+        Tcl_Namespace *contextNs, int flags, Tcl_Var *rPtr)
+}
+
+
+#
+#  Functions for manipulating methods and procs
+#
+
+declare 50 generic {
+    int Itcl_BodyCmd (ClientData dummy, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 51 generic {
+    int Itcl_ConfigBodyCmd (ClientData dummy, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 52 generic {
+    int Itcl_CreateMethod (Tcl_Interp* interp, ItclClass *cdefn,
+       CONST char* name, CONST char* arglist, CONST char* body)
+}
+declare 53 generic {
+    int Itcl_CreateProc (Tcl_Interp* interp, ItclClass *cdefn,
+       CONST char* name, CONST char* arglist, CONST char* body)
+}
+declare 54 generic {
+    int Itcl_CreateMemberFunc (Tcl_Interp* interp, ItclClass *cdefn, \
+        CONST char* name, CONST char* arglist, CONST char* body, \
+       ItclMemberFunc** mfuncPtr)
+}
+declare 55 generic {
+    int Itcl_ChangeMemberFunc (Tcl_Interp* interp, ItclMemberFunc* mfunc, \
+        CONST char* arglist, CONST char* body)
+}
+declare 56 generic {
+    void Itcl_DeleteMemberFunc (CONST char* cdata)
+}
+declare 57 generic {
+    int Itcl_CreateMemberCode (Tcl_Interp* interp, ItclClass *cdefn, \
+        CONST char* arglist, CONST char* body, ItclMemberCode** mcodePtr)
+}
+declare 58 generic {
+    void Itcl_DeleteMemberCode (CONST char* cdata)
+}
+declare 59 generic {
+    int Itcl_GetMemberCode (Tcl_Interp* interp, ItclMember* member)
+}
+#declare 60 generic {
+#    int Itcl_CompileMemberCodeBody (Tcl_Interp *interp, ItclMember *member, \
+#        char *desc, Tcl_Obj *bodyPtr)
+#}
+declare 61 generic {
+    int Itcl_EvalMemberCode (Tcl_Interp *interp, ItclMemberFunc *mfunc, \
+        ItclMember *member, ItclObject *contextObj, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 62 generic {
+    int Itcl_CreateArgList (Tcl_Interp* interp, CONST char* decl, int* argcPtr, \
+        CompiledLocal** argPtr)
+}
+declare 63 generic {
+    CompiledLocal* Itcl_CreateArg (CONST char* name, CONST char* init)
+}
+declare 64 generic {
+    void Itcl_DeleteArgList (CompiledLocal *arglist)
+}
+declare 65 generic {
+    Tcl_Obj* Itcl_ArgList (int argc, CompiledLocal* arglist)
+}
+declare 66 generic {
+    int Itcl_EquivArgLists (CompiledLocal* arg1, int arg1c, \
+        CompiledLocal* arg2, int arg2c)
+}
+declare 67 generic {
+    void Itcl_GetMemberFuncUsage (ItclMemberFunc *mfunc, \
+        ItclObject *contextObj, Tcl_Obj *objPtr)
+}
+declare 68 generic {
+    int Itcl_ExecMethod (ClientData clientData, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 69 generic {
+    int Itcl_ExecProc (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 70 generic {
+    int Itcl_AssignArgs (Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], \
+        ItclMemberFunc *mfunc)
+}
+declare 71 generic {
+    int Itcl_ConstructBase (Tcl_Interp *interp, ItclObject *contextObj, \
+        ItclClass *contextClass)
+}
+declare 72 generic {
+    int Itcl_InvokeMethodIfExists (Tcl_Interp *interp, CONST char *name, \
+        ItclClass *contextClass, ItclObject *contextObj, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+#declare 73 generic {
+#    int Itcl_EvalBody (Tcl_Interp *interp, Tcl_Obj *bodyPtr)
+#}
+declare 74 generic {
+    int Itcl_ReportFuncErrors (Tcl_Interp* interp, ItclMemberFunc *mfunc, \
+        ItclObject *contextObj, int result)
+}
+
+
+#
+#  Commands for parsing class definitions
+#
+
+declare 75 generic {
+    int Itcl_ParseInit (Tcl_Interp *interp, ItclObjectInfo *info)
+}
+declare 76 generic {
+    int Itcl_ClassCmd (ClientData clientData, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 77 generic {
+    int Itcl_ClassInheritCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 78 generic {
+    int Itcl_ClassProtectionCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 79 generic {
+    int Itcl_ClassConstructorCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 80 generic {
+    int Itcl_ClassDestructorCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 81 generic {
+    int Itcl_ClassMethodCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 82 generic {
+    int Itcl_ClassProcCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 83 generic {
+    int Itcl_ClassVariableCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 84 generic {
+    int Itcl_ClassCommonCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 85 generic {
+    int Itcl_ParseVarResolver (Tcl_Interp *interp, CONST char* name, \
+        Tcl_Namespace *contextNs, int flags, Tcl_Var* rPtr)
+}
+
+
+#
+#  Commands in the "builtin" namespace
+#
+
+declare 86 generic {
+    int Itcl_BiInit (Tcl_Interp *interp)
+}
+declare 87 generic {
+    int Itcl_InstallBiMethods (Tcl_Interp *interp, ItclClass *cdefn)
+}
+declare 88 generic {
+    int Itcl_BiIsaCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 89 generic {
+    int Itcl_BiConfigureCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 90 generic {
+    int Itcl_BiCgetCmd (ClientData clientData, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 91 generic {
+    int Itcl_BiChainCmd (ClientData dummy, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 92 generic {
+    int Itcl_BiInfoClassCmd (ClientData dummy, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 93 generic {
+    int Itcl_BiInfoInheritCmd (ClientData dummy, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 94 generic {
+    int Itcl_BiInfoHeritageCmd (ClientData dummy, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 95 generic {
+    int Itcl_BiInfoFunctionCmd (ClientData dummy, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 96 generic {
+    int Itcl_BiInfoVariableCmd (ClientData dummy, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+declare 97 generic {
+    int Itcl_BiInfoBodyCmd (ClientData dummy, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 98 generic {
+    int Itcl_BiInfoArgsCmd (ClientData dummy, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 99 generic {
+    int Itcl_DefaultInfoCmd (ClientData dummy, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+
+
+#
+#  Ensembles
+#
+
+declare 100 generic {
+    int Itcl_EnsembleInit (Tcl_Interp *interp)
+}
+declare 101 generic {
+    int Itcl_CreateEnsemble (Tcl_Interp *interp, CONST char* ensName)
+}
+declare 102 generic {
+    int Itcl_AddEnsemblePart (Tcl_Interp *interp, CONST char* ensName, \
+        CONST char* partName, CONST char* usageInfo, Tcl_ObjCmdProc *objProc, \
+        ClientData clientData, Tcl_CmdDeleteProc *deleteProc)
+}
+declare 103 generic {
+    int Itcl_GetEnsemblePart (Tcl_Interp *interp, CONST char *ensName, \
+        CONST char *partName, Tcl_CmdInfo *infoPtr)
+}
+declare 104 generic {
+    int Itcl_IsEnsemble (Tcl_CmdInfo* infoPtr)
+}
+declare 105 generic {
+    int Itcl_GetEnsembleUsage (Tcl_Interp *interp, CONST char *ensName, \
+        Tcl_Obj *objPtr)
+}
+declare 106 generic {
+    int Itcl_GetEnsembleUsageForObj (Tcl_Interp *interp, Tcl_Obj *ensObjPtr, \
+        Tcl_Obj *objPtr)
+}
+declare 107 generic {
+    int Itcl_EnsembleCmd (ClientData clientData, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 108 generic {
+    int Itcl_EnsPartCmd (ClientData clientData, Tcl_Interp *interp, int objc, \
+        Tcl_Obj *CONST objv[])
+}
+declare 109 generic {
+    int Itcl_EnsembleErrorCmd (ClientData clientData, Tcl_Interp *interp, \
+        int objc, Tcl_Obj *CONST objv[])
+}
+
+
+#
+#  Commands provided for backward compatibility
+#
+
+# not used anymore (3.3)
+#declare 110 generic {
+#    int Itcl_OldInit (Tcl_Interp* interp, ItclObjectInfo* info)
+#}
+#declare 111 generic {
+#    int Itcl_InstallOldBiMethods (Tcl_Interp *interp, ItclClass *cdefn)
+#}
+
+
+#
+#  Things that should be in the Tcl core.
+#
+
+declare 112 generic {
+    Itcl_CallFrame* _Tcl_GetCallFrame (Tcl_Interp *interp, int level)
+}
+declare 113 generic {
+    Itcl_CallFrame* _Tcl_ActivateCallFrame (Tcl_Interp *interp, \
+        Itcl_CallFrame *framePtr)
+}
+declare 114 generic {
+    Var* _TclNewVar (void)
+}
+declare 115 generic {
+    void Itcl_Assert (CONST char *testExpr, CONST char *fileName, int lineNum)
+}
+
+declare 116 generic {
+    int Itcl_IsObjectCmd (ClientData clientData, Tcl_Interp *interp, \
+    int objc, Tcl_Obj *CONST objv[])
+}
+declare 117 generic {
+    int Itcl_IsClassCmd (ClientData clientData, Tcl_Interp *interp, \
+    int objc, Tcl_Obj *CONST objv[])
+}
diff --git a/8.x/itcl/generic/itclInt.h b/8.x/itcl/generic/itclInt.h
new file mode 100644 (file)
index 0000000..b245f13
--- /dev/null
@@ -0,0 +1,514 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *  
+ *  ADDING [incr Tcl] TO A Tcl-BASED APPLICATION:
+ *
+ *    To add [incr Tcl] facilities to a Tcl application, modify the
+ *    Tcl_AppInit() routine as follows:
+ *
+ *    1) Include this header file near the top of the file containing
+ *       Tcl_AppInit():
+ *
+ *         #include "itcl.h"
+ *
+ *    2) Within the body of Tcl_AppInit(), add the following lines:
+ *
+ *         if (Itcl_Init(interp) == TCL_ERROR) {
+ *             return TCL_ERROR;
+ *         }
+ * 
+ *    3) Link your application with libitcl.a
+ *
+ *    NOTE:  An example file "tclAppInit.c" containing the changes shown
+ *           above is included in this distribution.
+ *  
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itclInt.h,v 1.19 2008/12/15 20:02:58 andreas_kupries Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#ifndef ITCLINT_H
+#define ITCLINT_H
+
+#include "tclInt.h"
+#include "itcl.h"
+
+#ifdef BUILD_itcl
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLEXPORT
+#endif
+
+/*
+ * Handle hiding of errorLine in 8.6
+ */
+#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
+#define ERRORLINE(interp) ((interp)->errorLine)
+#else
+#define ERRORLINE(interp) (Tcl_GetErrorLine(interp))
+#endif
+
+#define ITCL_TCL_PRE_8_5 (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 5)
+
+#if !ITCL_TCL_PRE_8_5
+#if defined(USE_TCL_STUBS)
+
+/*
+ * Fix Tcl bug #803489 the right way.  We need to always use the old Stub
+ * slot positions, not the new broken ones part of TIP 127.  I do like
+ * that these functions have moved to the public space (about time), but
+ * the slot change is the killer and is the painful side affect.
+ */
+
+#   undef Tcl_CreateNamespace
+#   define Tcl_CreateNamespace \
+       (tclIntStubsPtr->tcl_CreateNamespace)
+#   undef Tcl_DeleteNamespace
+#   define Tcl_DeleteNamespace \
+       (tclIntStubsPtr->tcl_DeleteNamespace)
+#   undef Tcl_AppendExportList
+#   define Tcl_AppendExportList \
+       (tclIntStubsPtr->tcl_AppendExportList)
+#   undef Tcl_Export
+#   define Tcl_Export \
+       (tclIntStubsPtr->tcl_Export)
+#   undef Tcl_Import
+#   define Tcl_Import \
+       (tclIntStubsPtr->tcl_Import)
+#   undef Tcl_ForgetImport
+#   define Tcl_ForgetImport \
+       (tclIntStubsPtr->tcl_ForgetImport)
+#   undef Tcl_GetCurrentNamespace
+#   define Tcl_GetCurrentNamespace \
+       (tclIntStubsPtr->tcl_GetCurrentNamespace)
+#   undef Tcl_GetGlobalNamespace
+#   define Tcl_GetGlobalNamespace \
+       (tclIntStubsPtr->tcl_GetGlobalNamespace)
+#   undef Tcl_FindNamespace
+#   define Tcl_FindNamespace \
+       (tclIntStubsPtr->tcl_FindNamespace)
+#   undef Tcl_FindCommand
+#   define Tcl_FindCommand \
+       (tclIntStubsPtr->tcl_FindCommand)
+#   undef Tcl_GetCommandFromObj
+#   define Tcl_GetCommandFromObj \
+       (tclIntStubsPtr->tcl_GetCommandFromObj)
+#   undef Tcl_GetCommandFullName
+#   define Tcl_GetCommandFullName \
+       (tclIntStubsPtr->tcl_GetCommandFullName)
+#endif /* use stubs */
+
+/*
+ * Use 8.5+ CallFrame
+ */
+
+#define ItclCallFrame CallFrame
+#define Itcl_CallFrame Tcl_CallFrame
+
+#define ItclInitVarFlags(varPtr) \
+    (varPtr)->flags = 0
+
+#define ItclInitVarArgument(varPtr) \
+   (varPtr)->flags = VAR_ARGUMENT 
+
+#define ItclVarHashCreateVar(tablePtr, key, newPtr) \
+    TclVarHashCreateVar((tablePtr), (key), (newPtr))
+
+#define ItclVarRefCount(varPtr) VarHashRefCount(varPtr)
+
+#define ItclClearVarUndefined(varPtr)
+
+#define ItclNextLocal(varPtr) ((varPtr)++)
+
+#define ItclVarObjValue(varPtr) ((varPtr)->value.objPtr)
+
+#define itclVarInHashSize sizeof(VarInHash)
+#define itclVarLocalSize  sizeof(Var)
+
+#else /* Compiling on Tcl8.x, x<5 */ 
+
+/*
+ * Redefine CallFrame to account for extra ClientData in 8.5.
+ * Make sure that standard CallFrame comes first.
+ */
+
+typedef struct ItclCallFrame {
+    Namespace *nsPtr;
+    int isProcCallFrame;
+    int objc;
+    Tcl_Obj *CONST *objv;
+    struct CallFrame *callerPtr;
+    struct CallFrame *callerVarPtr;
+    int level;
+    Proc *procPtr;
+    Tcl_HashTable *varTablePtr;
+    int numCompiledLocals;
+    Var* compiledLocals;
+    ClientData clientData;
+    struct localCache *localCachePtr;
+} ItclCallFrame;
+
+typedef struct Itcl_CallFrame {
+    Tcl_Namespace *nsPtr;
+    int dummy1;
+    int dummy2;
+    char *dummy3;
+    char *dummy4;
+    char *dummy5;
+    int dummy6;
+    char *dummy7;
+    char *dummy8;
+    int dummy9;
+    char *dummy10;
+    char *dummy11;
+    char *dummy12;
+} Itcl_CallFrame;
+
+/*
+ * Definition of runtime behaviour to be able to run irrespective of the Tcl
+ * version.
+ */
+
+#define VarInHash Var
+
+#define TclVarHashTable Tcl_HashTable
+
+typedef struct ItclShortVar {
+    int flags;
+    union {
+       Tcl_Obj *objPtr;
+       TclVarHashTable *tablePtr;
+       struct Var *linkPtr;
+    } value;
+} ItclShortVar;
+
+typedef struct ItclVarInHash {
+    ItclShortVar var;
+    int refCount;
+    Tcl_HashEntry entry;
+} ItclVarInHash;
+
+#define ItclOffset(type, field) ((int) ((char *) &((type *) 0)->field))
+
+#define itclOldRuntime (itclVarFlagOffset!=0)
+
+extern int itclVarFlagOffset; 
+extern int itclVarRefCountOffset;
+extern int itclVarInHashSize;
+extern int itclVarLocalSize;
+extern int itclVarValueOffset;
+
+/*
+ * VarReform related macros: provide access to the Var fields with offsets
+ * determined at load time, so that the same code copes with the different
+ * structs in Tcl8.5 and previous Tcl.
+ */
+
+#define ItclNextLocal(varPtr) \
+    ((varPtr) = (Var *) (((char *)(varPtr))+itclVarLocalSize))
+
+#define ItclVarObjValue(varPtr) \
+    (*((Tcl_Obj **) (((char *)(varPtr))+itclVarValueOffset)))
+
+#define ItclVarRefCount(varPtr) \
+    (*((int *) (((char *)(varPtr))+itclVarRefCountOffset)))
+
+#define ItclVarFlags(varPtr) \
+    (*((int *)(((char *)(varPtr))+itclVarFlagOffset)))
+
+/* Note that itclVarFlagOffset==0 exactly when we are running in Tcl8.5 */
+#define ItclInitVarFlags(varPtr) \
+    if (itclOldRuntime) { \
+       (varPtr)->flags = (VAR_SCALAR | VAR_UNDEFINED | VAR_IN_HASHTABLE);\
+    } else { \
+        ((ItclShortVar *)(varPtr))->flags = 0;\
+    }
+
+/* This is used for CompiledLocal, not for Var & Co. That struct did not
+ * change, but the correct flag init did! The flags bits themselves are
+ * unchanged */
+
+#define ItclInitVarArgument(varPtr) \
+    if (itclOldRuntime) { \
+       (varPtr)->flags = (VAR_SCALAR | VAR_ARGUMENT);\
+    } else { \
+       (varPtr)->flags = VAR_ARGUMENT;\
+    }
+
+#define TclIsVarNamespaceVar(varPtr) \
+    (ItclVarFlags(varPtr) & VAR_NAMESPACE_VAR)
+
+#define TclSetVarNamespaceVar(varPtr) \
+    if (!TclIsVarNamespaceVar(varPtr)) {\
+        ItclVarFlags(varPtr) |= VAR_NAMESPACE_VAR;\
+        ItclVarRefCount(varPtr)++;\
+    }
+
+#define ItclClearVarUndefined(varPtr) \
+    if (itclOldRuntime) { \
+       ItclVarFlags(varPtr) &= ~VAR_UNDEFINED;\
+    }
+
+#ifndef MODULE_SCOPE
+#define MODULE_SCOPE
+#endif
+
+MODULE_SCOPE Var * ItclVarHashCreateVar (TclVarHashTable * tablePtr, 
+                               const char * key, int * newPtr);
+
+#endif /* Version dependent defs and macros */
+
+
+#define ItclVarHashFindVar(tablePtr, key) \
+    ItclVarHashCreateVar((tablePtr), (key), NULL)
+
+
+/*
+ * Some backward compatability adjustments.
+ */
+
+#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0
+#   define Tcl_GetString(obj)  Tcl_GetStringFromObj((obj), NULL)
+#   define TCL_DECLARE_MUTEX(mutexVar)
+#   define Tcl_MutexLock(mutexVar)
+#   define Tcl_MutexUnlock(mutexVar)
+#   define Tcl_Panic panic
+#endif
+
+#define TCL_DOES_STUBS \
+    (TCL_MAJOR_VERSION > 8 || TCL_MAJOR_VERSION == 8 && (TCL_MINOR_VERSION > 1 || \
+    (TCL_MINOR_VERSION == 1 && TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE)))
+
+
+/*
+ *  Common info for managing all known objects.
+ *  Each interpreter has one of these data structures stored as
+ *  clientData in the "itcl" namespace.  It is also accessible
+ *  as associated data via the key ITCL_INTERP_DATA.
+ */
+struct ItclObject;
+typedef struct ItclObjectInfo {
+    Tcl_Interp *interp;             /* interpreter that manages this info */
+    Tcl_HashTable objects;          /* list of all known objects */
+
+    Itcl_Stack transparentFrames;   /* stack of call frames that should be
+                                     * treated transparently.  When
+                                     * Itcl_EvalMemberCode is invoked in
+                                     * one of these contexts, it does an
+                                     * "uplevel" to get past the transparent
+                                     * frame and back to the calling context. */
+    Tcl_HashTable contextFrames;    /* object contexts for active call frames */
+
+    int protection;                 /* protection level currently in effect */
+
+    Itcl_Stack cdefnStack;          /* stack of class definitions currently
+                                     * being parsed */
+} ItclObjectInfo;
+
+#define ITCL_INTERP_DATA "itcl_data"
+
+/*
+ *  Representation for each [incr Tcl] class.
+ */
+typedef struct ItclClass {
+    char *name;                   /* class name */
+    char *fullname;               /* fully qualified class name */
+    Tcl_Interp *interp;           /* interpreter that manages this info */
+    Tcl_Namespace *namesp;        /* namespace representing class scope */
+    Tcl_Command accessCmd;        /* access command for creating instances */
+
+    struct ItclObjectInfo *info;  /* info about all known objects */
+    Itcl_List bases;              /* list of base classes */
+    Itcl_List derived;            /* list of all derived classes */
+    Tcl_HashTable heritage;       /* table of all base classes.  Look up
+                                   * by pointer to class definition.  This
+                                   * provides fast lookup for inheritance
+                                   * tests. */
+    Tcl_Obj *initCode;            /* initialization code for new objs */
+    Tcl_HashTable variables;      /* definitions for all data members
+                                     in this class.  Look up simple string
+                                     names and get back ItclVarDefn* ptrs */
+    Tcl_HashTable functions;      /* definitions for all member functions
+                                     in this class.  Look up simple string
+                                     names and get back ItclMemberFunc* ptrs */
+    int numInstanceVars;          /* number of instance vars in variables
+                                     table */
+    Tcl_HashTable resolveVars;    /* all possible names for variables in
+                                   * this class (e.g., x, foo::x, etc.) */
+    Tcl_HashTable resolveCmds;    /* all possible names for functions in
+                                   * this class (e.g., x, foo::x, etc.) */
+    int unique;                   /* unique number for #auto generation */
+    int flags;                    /* maintains class status */
+} ItclClass;
+
+typedef struct ItclHierIter {
+    ItclClass *current;           /* current position in hierarchy */
+    Itcl_Stack stack;             /* stack used for traversal */
+} ItclHierIter;
+
+/*
+ *  Representation for each [incr Tcl] object.
+ */
+typedef struct ItclObject {
+    ItclClass *classDefn;        /* most-specific class */
+    Tcl_Command accessCmd;       /* object access command */
+
+    int dataSize;                /* number of elements in data array */
+    Var** data;                  /* all object-specific data members */
+    Tcl_HashTable* constructed;  /* temp storage used during construction */
+    Tcl_HashTable* destructed;   /* temp storage used during destruction */
+} ItclObject;
+
+#define ITCL_IGNORE_ERRS  0x002  /* useful for construction/destruction */
+
+/*
+ *  Implementation for any code body in an [incr Tcl] class.
+ */
+typedef struct ItclMemberCode {
+    int flags;                  /* flags describing implementation */
+    CompiledLocal *arglist;     /* list of arg names and initial values */
+    int argcount;               /* number of args in arglist */
+    Proc *procPtr;              /* Tcl proc representation (needed to
+                                 * handle compiled locals) */
+    union {
+        Tcl_CmdProc *argCmd;    /* (argc,argv) C implementation */
+        Tcl_ObjCmdProc *objCmd; /* (objc,objv) C implementation */
+    } cfunc;
+
+    ClientData clientData;      /* client data for C implementations */
+
+} ItclMemberCode;
+
+#define Itcl_IsMemberCodeImplemented(mcode) \
+    (((mcode)->flags & ITCL_IMPLEMENT_NONE) == 0)
+
+/*
+ *  Basic representation for class members (commands/variables)
+ */
+typedef struct ItclMember {
+    Tcl_Interp* interp;         /* interpreter containing the class */
+    ItclClass* classDefn;       /* class containing this member */
+    char* name;                 /* member name */
+    char* fullname;             /* member name with "class::" qualifier */
+    int protection;             /* protection level */
+    int flags;                  /* flags describing member (see below) */
+    ItclMemberCode *code;       /* code associated with member */
+} ItclMember;
+
+/*
+ *  Flag bits for ItclMemberCode and ItclMember:
+ */
+#define ITCL_IMPLEMENT_NONE    0x001  /* no implementation */
+#define ITCL_IMPLEMENT_TCL     0x002  /* Tcl implementation */
+#define ITCL_IMPLEMENT_ARGCMD  0x004  /* (argc,argv) C implementation */
+#define ITCL_IMPLEMENT_OBJCMD  0x008  /* (objc,objv) C implementation */
+#define ITCL_IMPLEMENT_C       0x00c  /* either kind of C implementation */
+#define ITCL_CONSTRUCTOR       0x010  /* non-zero => is a constructor */
+#define ITCL_DESTRUCTOR        0x020  /* non-zero => is a destructor */
+#define ITCL_COMMON            0x040  /* non-zero => is a "proc" */
+#define ITCL_ARG_SPEC          0x080  /* non-zero => has an argument spec */
+
+#define ITCL_OLD_STYLE         0x100  /* non-zero => old-style method
+                                       * (process "config" argument) */
+
+#define ITCL_THIS_VAR          0x200  /* non-zero => built-in "this" variable */
+
+/*
+ *  Representation of member functions in an [incr Tcl] class.
+ */
+typedef struct ItclMemberFunc {
+    ItclMember *member;          /* basic member info */
+    Tcl_Command accessCmd;       /* Tcl command installed for this function */
+    CompiledLocal *arglist;      /* list of arg names and initial values */
+    int argcount;                /* number of args in arglist */
+} ItclMemberFunc;
+
+/*
+ *  Instance variables.
+ */
+typedef struct ItclVarDefn {
+    ItclMember *member;          /* basic member info */
+    char* init;                  /* initial value */
+} ItclVarDefn;
+
+/*
+ *  Instance variable lookup entry.
+ */
+typedef struct ItclVarLookup {
+    ItclVarDefn* vdefn;       /* variable definition */
+    int usage;                /* number of uses for this record */
+    int accessible;           /* non-zero => accessible from class with
+                               * this lookup record in its resolveVars */
+    char *leastQualName;      /* simplist name for this variable, with
+                               * the fewest qualifiers.  This string is
+                               * taken from the resolveVars table, so
+                               * it shouldn't be freed. */
+    union {
+        int index;            /* index into virtual table (instance data) */
+        Tcl_Var common;       /* variable (common data) */
+    } var;
+} ItclVarLookup;
+
+/*
+ *  Representation for the context in which a body of [incr Tcl]
+ *  code executes.  In ordinary Tcl, this is a CallFrame.  But for
+ *  [incr Tcl] code bodies, we must be careful to set up the
+ *  CallFrame properly, to plug in instance variables before
+ *  executing the code body.
+ */
+typedef struct ItclContext {
+    ItclClass *classDefn;     /* class definition */
+    ItclCallFrame frame;      /* call frame for object context */
+    Var *compiledLocals;      /* points to storage for compiled locals */
+    Var localStorage[20];     /* default storage for compiled locals */
+} ItclContext;
+
+/*
+ *  Compatibility flags.  Used to support small "hacks".  These are stored
+ *  in the global variable named itclCompatFlags.
+ */
+
+extern int itclCompatFlags;
+
+#define ITCL_COMPAT_USECMDFLAGS 0x0001 /* Tcl8.4a1 introduced a different Command
+                                        * structure, and we need to adapt
+                                        * dynamically */
+#define ITCL_COMPAT_USE_ISTATE_API 0x2  /* Tcl 8.5a2 added interp state APIs */
+
+#include "itclIntDecls.h"
+
+/*
+ * Since the Tcl/Tk distribution doesn't perform any asserts,
+ * dynamic loading can fail to find the __assert function.
+ * As a workaround, we'll include our own.
+ */
+
+#undef  assert
+#ifndef  DEBUG
+#define assert(EX) ((void)0)
+#else
+#define assert(EX) (void)((EX) || (Itcl_Assert(STRINGIFY(EX), __FILE__, __LINE__), 0))
+#endif  /* DEBUG */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
+#endif /* ITCLINT_H */
diff --git a/8.x/itcl/generic/itclIntDecls.h b/8.x/itcl/generic/itclIntDecls.h
new file mode 100644 (file)
index 0000000..c19df29
--- /dev/null
@@ -0,0 +1,1393 @@
+/*
+ * itclIntDecls.h --
+ *
+ *     This file contains the declarations for all unsupported
+ *     functions that are exported by the Tcl library.  These
+ *     interfaces are not guaranteed to remain the same between
+ *     versions.  Use at your own risk.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: $Id: itclIntDecls.h,v 1.13 2007/05/24 21:40:23 hobbs Exp $
+ */
+
+#ifndef _ITCLINTDECLS
+#define _ITCLINTDECLS
+
+/*
+ * WARNING: This file is automatically generated by the tools/genStubs.tcl
+ * script.  Any modifications to the function declarations below should be made
+ * in the itcl/generic/tclInt.decls script.
+ */
+
+/* !BEGIN!: Do not edit below this line. */
+
+/*
+ * Exported function declarations:
+ */
+
+#ifndef Itcl_IsClassNamespace_TCL_DECLARED
+#define Itcl_IsClassNamespace_TCL_DECLARED
+/* 0 */
+TCL_EXTERN(int)                Itcl_IsClassNamespace _ANSI_ARGS_((
+                               Tcl_Namespace * namesp));
+#endif
+#ifndef Itcl_IsClass_TCL_DECLARED
+#define Itcl_IsClass_TCL_DECLARED
+/* 1 */
+TCL_EXTERN(int)                Itcl_IsClass _ANSI_ARGS_((Tcl_Command cmd));
+#endif
+#ifndef Itcl_FindClass_TCL_DECLARED
+#define Itcl_FindClass_TCL_DECLARED
+/* 2 */
+TCL_EXTERN(ItclClass*) Itcl_FindClass _ANSI_ARGS_((Tcl_Interp* interp, 
+                               CONST char* path, int autoload));
+#endif
+#ifndef Itcl_FindObject_TCL_DECLARED
+#define Itcl_FindObject_TCL_DECLARED
+/* 3 */
+TCL_EXTERN(int)                Itcl_FindObject _ANSI_ARGS_((Tcl_Interp * interp, 
+                               CONST char * name, ItclObject ** roPtr));
+#endif
+#ifndef Itcl_IsObject_TCL_DECLARED
+#define Itcl_IsObject_TCL_DECLARED
+/* 4 */
+TCL_EXTERN(int)                Itcl_IsObject _ANSI_ARGS_((Tcl_Command cmd));
+#endif
+#ifndef Itcl_ObjectIsa_TCL_DECLARED
+#define Itcl_ObjectIsa_TCL_DECLARED
+/* 5 */
+TCL_EXTERN(int)                Itcl_ObjectIsa _ANSI_ARGS_((ItclObject * contextObj, 
+                               ItclClass * cdefn));
+#endif
+#ifndef Itcl_Protection_TCL_DECLARED
+#define Itcl_Protection_TCL_DECLARED
+/* 6 */
+TCL_EXTERN(int)                Itcl_Protection _ANSI_ARGS_((Tcl_Interp * interp, 
+                               int newLevel));
+#endif
+#ifndef Itcl_ProtectionStr_TCL_DECLARED
+#define Itcl_ProtectionStr_TCL_DECLARED
+/* 7 */
+TCL_EXTERN(char*)      Itcl_ProtectionStr _ANSI_ARGS_((int pLevel));
+#endif
+#ifndef Itcl_CanAccess_TCL_DECLARED
+#define Itcl_CanAccess_TCL_DECLARED
+/* 8 */
+TCL_EXTERN(int)                Itcl_CanAccess _ANSI_ARGS_((ItclMember* memberPtr, 
+                               Tcl_Namespace* fromNsPtr));
+#endif
+#ifndef Itcl_CanAccessFunc_TCL_DECLARED
+#define Itcl_CanAccessFunc_TCL_DECLARED
+/* 9 */
+TCL_EXTERN(int)                Itcl_CanAccessFunc _ANSI_ARGS_((
+                               ItclMemberFunc* mfunc, 
+                               Tcl_Namespace* fromNsPtr));
+#endif
+#ifndef Itcl_GetTrueNamespace_TCL_DECLARED
+#define Itcl_GetTrueNamespace_TCL_DECLARED
+/* 10 */
+TCL_EXTERN(Tcl_Namespace*) Itcl_GetTrueNamespace _ANSI_ARGS_((
+                               Tcl_Interp * interp, ItclObjectInfo * info));
+#endif
+#ifndef Itcl_ParseNamespPath_TCL_DECLARED
+#define Itcl_ParseNamespPath_TCL_DECLARED
+/* 11 */
+TCL_EXTERN(void)       Itcl_ParseNamespPath _ANSI_ARGS_((CONST char * name, 
+                               Tcl_DString * buffer, char ** head, 
+                               char ** tail));
+#endif
+#ifndef Itcl_DecodeScopedCommand_TCL_DECLARED
+#define Itcl_DecodeScopedCommand_TCL_DECLARED
+/* 12 */
+TCL_EXTERN(int)                Itcl_DecodeScopedCommand _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char * name, 
+                               Tcl_Namespace ** rNsPtr, char ** rCmdPtr));
+#endif
+#ifndef Itcl_EvalArgs_TCL_DECLARED
+#define Itcl_EvalArgs_TCL_DECLARED
+/* 13 */
+TCL_EXTERN(int)                Itcl_EvalArgs _ANSI_ARGS_((Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_CreateArgs_TCL_DECLARED
+#define Itcl_CreateArgs_TCL_DECLARED
+/* 14 */
+TCL_EXTERN(Tcl_Obj*)   Itcl_CreateArgs _ANSI_ARGS_((Tcl_Interp * interp, 
+                               CONST char * string, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_PushContext_TCL_DECLARED
+#define Itcl_PushContext_TCL_DECLARED
+/* 15 */
+TCL_EXTERN(int)                Itcl_PushContext _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclMember * member, 
+                               ItclClass * contextClass, 
+                               ItclObject * contextObj, 
+                               ItclContext * contextPtr));
+#endif
+#ifndef Itcl_PopContext_TCL_DECLARED
+#define Itcl_PopContext_TCL_DECLARED
+/* 16 */
+TCL_EXTERN(void)       Itcl_PopContext _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclContext * contextPtr));
+#endif
+#ifndef Itcl_GetContext_TCL_DECLARED
+#define Itcl_GetContext_TCL_DECLARED
+/* 17 */
+TCL_EXTERN(int)                Itcl_GetContext _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclClass ** cdefnPtr, 
+                               ItclObject ** odefnPtr));
+#endif
+#ifndef Itcl_InitHierIter_TCL_DECLARED
+#define Itcl_InitHierIter_TCL_DECLARED
+/* 18 */
+TCL_EXTERN(void)       Itcl_InitHierIter _ANSI_ARGS_((ItclHierIter * iter, 
+                               ItclClass * cdefn));
+#endif
+#ifndef Itcl_DeleteHierIter_TCL_DECLARED
+#define Itcl_DeleteHierIter_TCL_DECLARED
+/* 19 */
+TCL_EXTERN(void)       Itcl_DeleteHierIter _ANSI_ARGS_((ItclHierIter * iter));
+#endif
+#ifndef Itcl_AdvanceHierIter_TCL_DECLARED
+#define Itcl_AdvanceHierIter_TCL_DECLARED
+/* 20 */
+TCL_EXTERN(ItclClass*) Itcl_AdvanceHierIter _ANSI_ARGS_((
+                               ItclHierIter * iter));
+#endif
+#ifndef Itcl_FindClassesCmd_TCL_DECLARED
+#define Itcl_FindClassesCmd_TCL_DECLARED
+/* 21 */
+TCL_EXTERN(int)                Itcl_FindClassesCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_FindObjectsCmd_TCL_DECLARED
+#define Itcl_FindObjectsCmd_TCL_DECLARED
+/* 22 */
+TCL_EXTERN(int)                Itcl_FindObjectsCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ProtectionCmd_TCL_DECLARED
+#define Itcl_ProtectionCmd_TCL_DECLARED
+/* 23 */
+TCL_EXTERN(int)                Itcl_ProtectionCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_DelClassCmd_TCL_DECLARED
+#define Itcl_DelClassCmd_TCL_DECLARED
+/* 24 */
+TCL_EXTERN(int)                Itcl_DelClassCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_DelObjectCmd_TCL_DECLARED
+#define Itcl_DelObjectCmd_TCL_DECLARED
+/* 25 */
+TCL_EXTERN(int)                Itcl_DelObjectCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ScopeCmd_TCL_DECLARED
+#define Itcl_ScopeCmd_TCL_DECLARED
+/* 26 */
+TCL_EXTERN(int)                Itcl_ScopeCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_CodeCmd_TCL_DECLARED
+#define Itcl_CodeCmd_TCL_DECLARED
+/* 27 */
+TCL_EXTERN(int)                Itcl_CodeCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_StubCreateCmd_TCL_DECLARED
+#define Itcl_StubCreateCmd_TCL_DECLARED
+/* 28 */
+TCL_EXTERN(int)                Itcl_StubCreateCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_StubExistsCmd_TCL_DECLARED
+#define Itcl_StubExistsCmd_TCL_DECLARED
+/* 29 */
+TCL_EXTERN(int)                Itcl_StubExistsCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_IsStub_TCL_DECLARED
+#define Itcl_IsStub_TCL_DECLARED
+/* 30 */
+TCL_EXTERN(int)                Itcl_IsStub _ANSI_ARGS_((Tcl_Command cmd));
+#endif
+#ifndef Itcl_CreateClass_TCL_DECLARED
+#define Itcl_CreateClass_TCL_DECLARED
+/* 31 */
+TCL_EXTERN(int)                Itcl_CreateClass _ANSI_ARGS_((Tcl_Interp* interp, 
+                               CONST char* path, ItclObjectInfo * info, 
+                               ItclClass ** rPtr));
+#endif
+#ifndef Itcl_DeleteClass_TCL_DECLARED
+#define Itcl_DeleteClass_TCL_DECLARED
+/* 32 */
+TCL_EXTERN(int)                Itcl_DeleteClass _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclClass * cdefnPtr));
+#endif
+#ifndef Itcl_FindClassNamespace_TCL_DECLARED
+#define Itcl_FindClassNamespace_TCL_DECLARED
+/* 33 */
+TCL_EXTERN(Tcl_Namespace*) Itcl_FindClassNamespace _ANSI_ARGS_((
+                               Tcl_Interp* interp, CONST char* path));
+#endif
+#ifndef Itcl_HandleClass_TCL_DECLARED
+#define Itcl_HandleClass_TCL_DECLARED
+/* 34 */
+TCL_EXTERN(int)                Itcl_HandleClass _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassCmdResolver_TCL_DECLARED
+#define Itcl_ClassCmdResolver_TCL_DECLARED
+/* 35 */
+TCL_EXTERN(int)                Itcl_ClassCmdResolver _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char* name, 
+                               Tcl_Namespace * context, int flags, 
+                               Tcl_Command * rPtr));
+#endif
+#ifndef Itcl_ClassVarResolver_TCL_DECLARED
+#define Itcl_ClassVarResolver_TCL_DECLARED
+/* 36 */
+TCL_EXTERN(int)                Itcl_ClassVarResolver _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char* name, 
+                               Tcl_Namespace * context, int flags, 
+                               Tcl_Var * rPtr));
+#endif
+#ifndef Itcl_ClassCompiledVarResolver_TCL_DECLARED
+#define Itcl_ClassCompiledVarResolver_TCL_DECLARED
+/* 37 */
+TCL_EXTERN(int)                Itcl_ClassCompiledVarResolver _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char* name, 
+                               int length, Tcl_Namespace * context, 
+                               Tcl_ResolvedVarInfo ** rPtr));
+#endif
+#ifndef Itcl_BuildVirtualTables_TCL_DECLARED
+#define Itcl_BuildVirtualTables_TCL_DECLARED
+/* 38 */
+TCL_EXTERN(void)       Itcl_BuildVirtualTables _ANSI_ARGS_((
+                               ItclClass* cdefnPtr));
+#endif
+#ifndef Itcl_CreateVarDefn_TCL_DECLARED
+#define Itcl_CreateVarDefn_TCL_DECLARED
+/* 39 */
+TCL_EXTERN(int)                Itcl_CreateVarDefn _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclClass* cdefn, char* name, char* init, 
+                               char* config, ItclVarDefn** vdefnPtr));
+#endif
+#ifndef Itcl_DeleteVarDefn_TCL_DECLARED
+#define Itcl_DeleteVarDefn_TCL_DECLARED
+/* 40 */
+TCL_EXTERN(void)       Itcl_DeleteVarDefn _ANSI_ARGS_((ItclVarDefn * vdefn));
+#endif
+#ifndef Itcl_GetCommonVar_TCL_DECLARED
+#define Itcl_GetCommonVar_TCL_DECLARED
+/* 41 */
+TCL_EXTERN(CONST char*)         Itcl_GetCommonVar _ANSI_ARGS_((Tcl_Interp * interp, 
+                               CONST char * name, ItclClass * contextClass));
+#endif
+#ifndef Itcl_CreateMember_TCL_DECLARED
+#define Itcl_CreateMember_TCL_DECLARED
+/* 42 */
+TCL_EXTERN(ItclMember*)         Itcl_CreateMember _ANSI_ARGS_((Tcl_Interp* interp, 
+                               ItclClass * cdefn, CONST char* name));
+#endif
+#ifndef Itcl_DeleteMember_TCL_DECLARED
+#define Itcl_DeleteMember_TCL_DECLARED
+/* 43 */
+TCL_EXTERN(void)       Itcl_DeleteMember _ANSI_ARGS_((ItclMember * memPtr));
+#endif
+#ifndef Itcl_CreateObject_TCL_DECLARED
+#define Itcl_CreateObject_TCL_DECLARED
+/* 44 */
+TCL_EXTERN(int)                Itcl_CreateObject _ANSI_ARGS_((Tcl_Interp * interp, 
+                               CONST char* name, ItclClass * cdefn, 
+                               int objc, Tcl_Obj *CONST objv[], 
+                               ItclObject ** roPtr));
+#endif
+#ifndef Itcl_DeleteObject_TCL_DECLARED
+#define Itcl_DeleteObject_TCL_DECLARED
+/* 45 */
+TCL_EXTERN(int)                Itcl_DeleteObject _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclObject * contextObj));
+#endif
+#ifndef Itcl_DestructObject_TCL_DECLARED
+#define Itcl_DestructObject_TCL_DECLARED
+/* 46 */
+TCL_EXTERN(int)                Itcl_DestructObject _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclObject * contextObj, int flags));
+#endif
+#ifndef Itcl_HandleInstance_TCL_DECLARED
+#define Itcl_HandleInstance_TCL_DECLARED
+/* 47 */
+TCL_EXTERN(int)                Itcl_HandleInstance _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_GetInstanceVar_TCL_DECLARED
+#define Itcl_GetInstanceVar_TCL_DECLARED
+/* 48 */
+TCL_EXTERN(CONST char*)         Itcl_GetInstanceVar _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char * name, 
+                               ItclObject * contextObj, 
+                               ItclClass * contextClass));
+#endif
+#ifndef Itcl_ScopedVarResolver_TCL_DECLARED
+#define Itcl_ScopedVarResolver_TCL_DECLARED
+/* 49 */
+TCL_EXTERN(int)                Itcl_ScopedVarResolver _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char * name, 
+                               Tcl_Namespace * contextNs, int flags, 
+                               Tcl_Var * rPtr));
+#endif
+#ifndef Itcl_BodyCmd_TCL_DECLARED
+#define Itcl_BodyCmd_TCL_DECLARED
+/* 50 */
+TCL_EXTERN(int)                Itcl_BodyCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ConfigBodyCmd_TCL_DECLARED
+#define Itcl_ConfigBodyCmd_TCL_DECLARED
+/* 51 */
+TCL_EXTERN(int)                Itcl_ConfigBodyCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_CreateMethod_TCL_DECLARED
+#define Itcl_CreateMethod_TCL_DECLARED
+/* 52 */
+TCL_EXTERN(int)                Itcl_CreateMethod _ANSI_ARGS_((Tcl_Interp* interp, 
+                               ItclClass * cdefn, CONST char* name, 
+                               CONST char* arglist, CONST char* body));
+#endif
+#ifndef Itcl_CreateProc_TCL_DECLARED
+#define Itcl_CreateProc_TCL_DECLARED
+/* 53 */
+TCL_EXTERN(int)                Itcl_CreateProc _ANSI_ARGS_((Tcl_Interp* interp, 
+                               ItclClass * cdefn, CONST char* name, 
+                               CONST char* arglist, CONST char* body));
+#endif
+#ifndef Itcl_CreateMemberFunc_TCL_DECLARED
+#define Itcl_CreateMemberFunc_TCL_DECLARED
+/* 54 */
+TCL_EXTERN(int)                Itcl_CreateMemberFunc _ANSI_ARGS_((
+                               Tcl_Interp* interp, ItclClass * cdefn, 
+                               CONST char* name, CONST char* arglist, 
+                               CONST char* body, ItclMemberFunc** mfuncPtr));
+#endif
+#ifndef Itcl_ChangeMemberFunc_TCL_DECLARED
+#define Itcl_ChangeMemberFunc_TCL_DECLARED
+/* 55 */
+TCL_EXTERN(int)                Itcl_ChangeMemberFunc _ANSI_ARGS_((
+                               Tcl_Interp* interp, ItclMemberFunc* mfunc, 
+                               CONST char* arglist, CONST char* body));
+#endif
+#ifndef Itcl_DeleteMemberFunc_TCL_DECLARED
+#define Itcl_DeleteMemberFunc_TCL_DECLARED
+/* 56 */
+TCL_EXTERN(void)       Itcl_DeleteMemberFunc _ANSI_ARGS_((CONST char* cdata));
+#endif
+#ifndef Itcl_CreateMemberCode_TCL_DECLARED
+#define Itcl_CreateMemberCode_TCL_DECLARED
+/* 57 */
+TCL_EXTERN(int)                Itcl_CreateMemberCode _ANSI_ARGS_((
+                               Tcl_Interp* interp, ItclClass * cdefn, 
+                               CONST char* arglist, CONST char* body, 
+                               ItclMemberCode** mcodePtr));
+#endif
+#ifndef Itcl_DeleteMemberCode_TCL_DECLARED
+#define Itcl_DeleteMemberCode_TCL_DECLARED
+/* 58 */
+TCL_EXTERN(void)       Itcl_DeleteMemberCode _ANSI_ARGS_((CONST char* cdata));
+#endif
+#ifndef Itcl_GetMemberCode_TCL_DECLARED
+#define Itcl_GetMemberCode_TCL_DECLARED
+/* 59 */
+TCL_EXTERN(int)                Itcl_GetMemberCode _ANSI_ARGS_((Tcl_Interp* interp, 
+                               ItclMember* member));
+#endif
+/* Slot 60 is reserved */
+#ifndef Itcl_EvalMemberCode_TCL_DECLARED
+#define Itcl_EvalMemberCode_TCL_DECLARED
+/* 61 */
+TCL_EXTERN(int)                Itcl_EvalMemberCode _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclMemberFunc * mfunc, ItclMember * member, 
+                               ItclObject * contextObj, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_CreateArgList_TCL_DECLARED
+#define Itcl_CreateArgList_TCL_DECLARED
+/* 62 */
+TCL_EXTERN(int)                Itcl_CreateArgList _ANSI_ARGS_((Tcl_Interp* interp, 
+                               CONST char* decl, int* argcPtr, 
+                               CompiledLocal** argPtr));
+#endif
+#ifndef Itcl_CreateArg_TCL_DECLARED
+#define Itcl_CreateArg_TCL_DECLARED
+/* 63 */
+TCL_EXTERN(CompiledLocal*) Itcl_CreateArg _ANSI_ARGS_((CONST char* name, 
+                               CONST char* init));
+#endif
+#ifndef Itcl_DeleteArgList_TCL_DECLARED
+#define Itcl_DeleteArgList_TCL_DECLARED
+/* 64 */
+TCL_EXTERN(void)       Itcl_DeleteArgList _ANSI_ARGS_((
+                               CompiledLocal * arglist));
+#endif
+#ifndef Itcl_ArgList_TCL_DECLARED
+#define Itcl_ArgList_TCL_DECLARED
+/* 65 */
+TCL_EXTERN(Tcl_Obj*)   Itcl_ArgList _ANSI_ARGS_((int argc, 
+                               CompiledLocal* arglist));
+#endif
+#ifndef Itcl_EquivArgLists_TCL_DECLARED
+#define Itcl_EquivArgLists_TCL_DECLARED
+/* 66 */
+TCL_EXTERN(int)                Itcl_EquivArgLists _ANSI_ARGS_((CompiledLocal* arg1, 
+                               int arg1c, CompiledLocal* arg2, int arg2c));
+#endif
+#ifndef Itcl_GetMemberFuncUsage_TCL_DECLARED
+#define Itcl_GetMemberFuncUsage_TCL_DECLARED
+/* 67 */
+TCL_EXTERN(void)       Itcl_GetMemberFuncUsage _ANSI_ARGS_((
+                               ItclMemberFunc * mfunc, 
+                               ItclObject * contextObj, Tcl_Obj * objPtr));
+#endif
+#ifndef Itcl_ExecMethod_TCL_DECLARED
+#define Itcl_ExecMethod_TCL_DECLARED
+/* 68 */
+TCL_EXTERN(int)                Itcl_ExecMethod _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ExecProc_TCL_DECLARED
+#define Itcl_ExecProc_TCL_DECLARED
+/* 69 */
+TCL_EXTERN(int)                Itcl_ExecProc _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_AssignArgs_TCL_DECLARED
+#define Itcl_AssignArgs_TCL_DECLARED
+/* 70 */
+TCL_EXTERN(int)                Itcl_AssignArgs _ANSI_ARGS_((Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[], 
+                               ItclMemberFunc * mfunc));
+#endif
+#ifndef Itcl_ConstructBase_TCL_DECLARED
+#define Itcl_ConstructBase_TCL_DECLARED
+/* 71 */
+TCL_EXTERN(int)                Itcl_ConstructBase _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclObject * contextObj, 
+                               ItclClass * contextClass));
+#endif
+#ifndef Itcl_InvokeMethodIfExists_TCL_DECLARED
+#define Itcl_InvokeMethodIfExists_TCL_DECLARED
+/* 72 */
+TCL_EXTERN(int)                Itcl_InvokeMethodIfExists _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char * name, 
+                               ItclClass * contextClass, 
+                               ItclObject * contextObj, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+/* Slot 73 is reserved */
+#ifndef Itcl_ReportFuncErrors_TCL_DECLARED
+#define Itcl_ReportFuncErrors_TCL_DECLARED
+/* 74 */
+TCL_EXTERN(int)                Itcl_ReportFuncErrors _ANSI_ARGS_((
+                               Tcl_Interp* interp, ItclMemberFunc * mfunc, 
+                               ItclObject * contextObj, int result));
+#endif
+#ifndef Itcl_ParseInit_TCL_DECLARED
+#define Itcl_ParseInit_TCL_DECLARED
+/* 75 */
+TCL_EXTERN(int)                Itcl_ParseInit _ANSI_ARGS_((Tcl_Interp * interp, 
+                               ItclObjectInfo * info));
+#endif
+#ifndef Itcl_ClassCmd_TCL_DECLARED
+#define Itcl_ClassCmd_TCL_DECLARED
+/* 76 */
+TCL_EXTERN(int)                Itcl_ClassCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassInheritCmd_TCL_DECLARED
+#define Itcl_ClassInheritCmd_TCL_DECLARED
+/* 77 */
+TCL_EXTERN(int)                Itcl_ClassInheritCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassProtectionCmd_TCL_DECLARED
+#define Itcl_ClassProtectionCmd_TCL_DECLARED
+/* 78 */
+TCL_EXTERN(int)                Itcl_ClassProtectionCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassConstructorCmd_TCL_DECLARED
+#define Itcl_ClassConstructorCmd_TCL_DECLARED
+/* 79 */
+TCL_EXTERN(int)                Itcl_ClassConstructorCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassDestructorCmd_TCL_DECLARED
+#define Itcl_ClassDestructorCmd_TCL_DECLARED
+/* 80 */
+TCL_EXTERN(int)                Itcl_ClassDestructorCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassMethodCmd_TCL_DECLARED
+#define Itcl_ClassMethodCmd_TCL_DECLARED
+/* 81 */
+TCL_EXTERN(int)                Itcl_ClassMethodCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassProcCmd_TCL_DECLARED
+#define Itcl_ClassProcCmd_TCL_DECLARED
+/* 82 */
+TCL_EXTERN(int)                Itcl_ClassProcCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassVariableCmd_TCL_DECLARED
+#define Itcl_ClassVariableCmd_TCL_DECLARED
+/* 83 */
+TCL_EXTERN(int)                Itcl_ClassVariableCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ClassCommonCmd_TCL_DECLARED
+#define Itcl_ClassCommonCmd_TCL_DECLARED
+/* 84 */
+TCL_EXTERN(int)                Itcl_ClassCommonCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_ParseVarResolver_TCL_DECLARED
+#define Itcl_ParseVarResolver_TCL_DECLARED
+/* 85 */
+TCL_EXTERN(int)                Itcl_ParseVarResolver _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char* name, 
+                               Tcl_Namespace * contextNs, int flags, 
+                               Tcl_Var* rPtr));
+#endif
+#ifndef Itcl_BiInit_TCL_DECLARED
+#define Itcl_BiInit_TCL_DECLARED
+/* 86 */
+TCL_EXTERN(int)                Itcl_BiInit _ANSI_ARGS_((Tcl_Interp * interp));
+#endif
+#ifndef Itcl_InstallBiMethods_TCL_DECLARED
+#define Itcl_InstallBiMethods_TCL_DECLARED
+/* 87 */
+TCL_EXTERN(int)                Itcl_InstallBiMethods _ANSI_ARGS_((
+                               Tcl_Interp * interp, ItclClass * cdefn));
+#endif
+#ifndef Itcl_BiIsaCmd_TCL_DECLARED
+#define Itcl_BiIsaCmd_TCL_DECLARED
+/* 88 */
+TCL_EXTERN(int)                Itcl_BiIsaCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiConfigureCmd_TCL_DECLARED
+#define Itcl_BiConfigureCmd_TCL_DECLARED
+/* 89 */
+TCL_EXTERN(int)                Itcl_BiConfigureCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiCgetCmd_TCL_DECLARED
+#define Itcl_BiCgetCmd_TCL_DECLARED
+/* 90 */
+TCL_EXTERN(int)                Itcl_BiCgetCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiChainCmd_TCL_DECLARED
+#define Itcl_BiChainCmd_TCL_DECLARED
+/* 91 */
+TCL_EXTERN(int)                Itcl_BiChainCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiInfoClassCmd_TCL_DECLARED
+#define Itcl_BiInfoClassCmd_TCL_DECLARED
+/* 92 */
+TCL_EXTERN(int)                Itcl_BiInfoClassCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiInfoInheritCmd_TCL_DECLARED
+#define Itcl_BiInfoInheritCmd_TCL_DECLARED
+/* 93 */
+TCL_EXTERN(int)                Itcl_BiInfoInheritCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiInfoHeritageCmd_TCL_DECLARED
+#define Itcl_BiInfoHeritageCmd_TCL_DECLARED
+/* 94 */
+TCL_EXTERN(int)                Itcl_BiInfoHeritageCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiInfoFunctionCmd_TCL_DECLARED
+#define Itcl_BiInfoFunctionCmd_TCL_DECLARED
+/* 95 */
+TCL_EXTERN(int)                Itcl_BiInfoFunctionCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiInfoVariableCmd_TCL_DECLARED
+#define Itcl_BiInfoVariableCmd_TCL_DECLARED
+/* 96 */
+TCL_EXTERN(int)                Itcl_BiInfoVariableCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiInfoBodyCmd_TCL_DECLARED
+#define Itcl_BiInfoBodyCmd_TCL_DECLARED
+/* 97 */
+TCL_EXTERN(int)                Itcl_BiInfoBodyCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_BiInfoArgsCmd_TCL_DECLARED
+#define Itcl_BiInfoArgsCmd_TCL_DECLARED
+/* 98 */
+TCL_EXTERN(int)                Itcl_BiInfoArgsCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_DefaultInfoCmd_TCL_DECLARED
+#define Itcl_DefaultInfoCmd_TCL_DECLARED
+/* 99 */
+TCL_EXTERN(int)                Itcl_DefaultInfoCmd _ANSI_ARGS_((ClientData dummy, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_EnsembleInit_TCL_DECLARED
+#define Itcl_EnsembleInit_TCL_DECLARED
+/* 100 */
+TCL_EXTERN(int)                Itcl_EnsembleInit _ANSI_ARGS_((Tcl_Interp * interp));
+#endif
+#ifndef Itcl_CreateEnsemble_TCL_DECLARED
+#define Itcl_CreateEnsemble_TCL_DECLARED
+/* 101 */
+TCL_EXTERN(int)                Itcl_CreateEnsemble _ANSI_ARGS_((Tcl_Interp * interp, 
+                               CONST char* ensName));
+#endif
+#ifndef Itcl_AddEnsemblePart_TCL_DECLARED
+#define Itcl_AddEnsemblePart_TCL_DECLARED
+/* 102 */
+TCL_EXTERN(int)                Itcl_AddEnsemblePart _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char* ensName, 
+                               CONST char* partName, CONST char* usageInfo, 
+                               Tcl_ObjCmdProc * objProc, 
+                               ClientData clientData, 
+                               Tcl_CmdDeleteProc * deleteProc));
+#endif
+#ifndef Itcl_GetEnsemblePart_TCL_DECLARED
+#define Itcl_GetEnsemblePart_TCL_DECLARED
+/* 103 */
+TCL_EXTERN(int)                Itcl_GetEnsemblePart _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char * ensName, 
+                               CONST char * partName, Tcl_CmdInfo * infoPtr));
+#endif
+#ifndef Itcl_IsEnsemble_TCL_DECLARED
+#define Itcl_IsEnsemble_TCL_DECLARED
+/* 104 */
+TCL_EXTERN(int)                Itcl_IsEnsemble _ANSI_ARGS_((Tcl_CmdInfo* infoPtr));
+#endif
+#ifndef Itcl_GetEnsembleUsage_TCL_DECLARED
+#define Itcl_GetEnsembleUsage_TCL_DECLARED
+/* 105 */
+TCL_EXTERN(int)                Itcl_GetEnsembleUsage _ANSI_ARGS_((
+                               Tcl_Interp * interp, CONST char * ensName, 
+                               Tcl_Obj * objPtr));
+#endif
+#ifndef Itcl_GetEnsembleUsageForObj_TCL_DECLARED
+#define Itcl_GetEnsembleUsageForObj_TCL_DECLARED
+/* 106 */
+TCL_EXTERN(int)                Itcl_GetEnsembleUsageForObj _ANSI_ARGS_((
+                               Tcl_Interp * interp, Tcl_Obj * ensObjPtr, 
+                               Tcl_Obj * objPtr));
+#endif
+#ifndef Itcl_EnsembleCmd_TCL_DECLARED
+#define Itcl_EnsembleCmd_TCL_DECLARED
+/* 107 */
+TCL_EXTERN(int)                Itcl_EnsembleCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_EnsPartCmd_TCL_DECLARED
+#define Itcl_EnsPartCmd_TCL_DECLARED
+/* 108 */
+TCL_EXTERN(int)                Itcl_EnsPartCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_EnsembleErrorCmd_TCL_DECLARED
+#define Itcl_EnsembleErrorCmd_TCL_DECLARED
+/* 109 */
+TCL_EXTERN(int)                Itcl_EnsembleErrorCmd _ANSI_ARGS_((
+                               ClientData clientData, Tcl_Interp * interp, 
+                               int objc, Tcl_Obj *CONST objv[]));
+#endif
+/* Slot 110 is reserved */
+/* Slot 111 is reserved */
+#ifndef _Tcl_GetCallFrame_TCL_DECLARED
+#define _Tcl_GetCallFrame_TCL_DECLARED
+/* 112 */
+TCL_EXTERN(Itcl_CallFrame*) _Tcl_GetCallFrame _ANSI_ARGS_((
+                               Tcl_Interp * interp, int level));
+#endif
+#ifndef _Tcl_ActivateCallFrame_TCL_DECLARED
+#define _Tcl_ActivateCallFrame_TCL_DECLARED
+/* 113 */
+TCL_EXTERN(Itcl_CallFrame*) _Tcl_ActivateCallFrame _ANSI_ARGS_((
+                               Tcl_Interp * interp, 
+                               Itcl_CallFrame * framePtr));
+#endif
+#ifndef _TclNewVar_TCL_DECLARED
+#define _TclNewVar_TCL_DECLARED
+/* 114 */
+TCL_EXTERN(Var*)       _TclNewVar _ANSI_ARGS_((void));
+#endif
+#ifndef Itcl_Assert_TCL_DECLARED
+#define Itcl_Assert_TCL_DECLARED
+/* 115 */
+TCL_EXTERN(void)       Itcl_Assert _ANSI_ARGS_((CONST char * testExpr, 
+                               CONST char * fileName, int lineNum));
+#endif
+#ifndef Itcl_IsObjectCmd_TCL_DECLARED
+#define Itcl_IsObjectCmd_TCL_DECLARED
+/* 116 */
+TCL_EXTERN(int)                Itcl_IsObjectCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+#ifndef Itcl_IsClassCmd_TCL_DECLARED
+#define Itcl_IsClassCmd_TCL_DECLARED
+/* 117 */
+TCL_EXTERN(int)                Itcl_IsClassCmd _ANSI_ARGS_((ClientData clientData, 
+                               Tcl_Interp * interp, int objc, 
+                               Tcl_Obj *CONST objv[]));
+#endif
+
+typedef struct ItclIntStubs {
+    int magic;
+    struct ItclIntStubHooks *hooks;
+
+    int (*itcl_IsClassNamespace) _ANSI_ARGS_((Tcl_Namespace * namesp)); /* 0 */
+    int (*itcl_IsClass) _ANSI_ARGS_((Tcl_Command cmd)); /* 1 */
+    ItclClass* (*itcl_FindClass) _ANSI_ARGS_((Tcl_Interp* interp, CONST char* path, int autoload)); /* 2 */
+    int (*itcl_FindObject) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, ItclObject ** roPtr)); /* 3 */
+    int (*itcl_IsObject) _ANSI_ARGS_((Tcl_Command cmd)); /* 4 */
+    int (*itcl_ObjectIsa) _ANSI_ARGS_((ItclObject * contextObj, ItclClass * cdefn)); /* 5 */
+    int (*itcl_Protection) _ANSI_ARGS_((Tcl_Interp * interp, int newLevel)); /* 6 */
+    char* (*itcl_ProtectionStr) _ANSI_ARGS_((int pLevel)); /* 7 */
+    int (*itcl_CanAccess) _ANSI_ARGS_((ItclMember* memberPtr, Tcl_Namespace* fromNsPtr)); /* 8 */
+    int (*itcl_CanAccessFunc) _ANSI_ARGS_((ItclMemberFunc* mfunc, Tcl_Namespace* fromNsPtr)); /* 9 */
+    Tcl_Namespace* (*itcl_GetTrueNamespace) _ANSI_ARGS_((Tcl_Interp * interp, ItclObjectInfo * info)); /* 10 */
+    void (*itcl_ParseNamespPath) _ANSI_ARGS_((CONST char * name, Tcl_DString * buffer, char ** head, char ** tail)); /* 11 */
+    int (*itcl_DecodeScopedCommand) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, Tcl_Namespace ** rNsPtr, char ** rCmdPtr)); /* 12 */
+    int (*itcl_EvalArgs) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 13 */
+    Tcl_Obj* (*itcl_CreateArgs) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * string, int objc, Tcl_Obj *CONST objv[])); /* 14 */
+    int (*itcl_PushContext) _ANSI_ARGS_((Tcl_Interp * interp, ItclMember * member, ItclClass * contextClass, ItclObject * contextObj, ItclContext * contextPtr)); /* 15 */
+    void (*itcl_PopContext) _ANSI_ARGS_((Tcl_Interp * interp, ItclContext * contextPtr)); /* 16 */
+    int (*itcl_GetContext) _ANSI_ARGS_((Tcl_Interp * interp, ItclClass ** cdefnPtr, ItclObject ** odefnPtr)); /* 17 */
+    void (*itcl_InitHierIter) _ANSI_ARGS_((ItclHierIter * iter, ItclClass * cdefn)); /* 18 */
+    void (*itcl_DeleteHierIter) _ANSI_ARGS_((ItclHierIter * iter)); /* 19 */
+    ItclClass* (*itcl_AdvanceHierIter) _ANSI_ARGS_((ItclHierIter * iter)); /* 20 */
+    int (*itcl_FindClassesCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 21 */
+    int (*itcl_FindObjectsCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 22 */
+    int (*itcl_ProtectionCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 23 */
+    int (*itcl_DelClassCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 24 */
+    int (*itcl_DelObjectCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 25 */
+    int (*itcl_ScopeCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 26 */
+    int (*itcl_CodeCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 27 */
+    int (*itcl_StubCreateCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 28 */
+    int (*itcl_StubExistsCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 29 */
+    int (*itcl_IsStub) _ANSI_ARGS_((Tcl_Command cmd)); /* 30 */
+    int (*itcl_CreateClass) _ANSI_ARGS_((Tcl_Interp* interp, CONST char* path, ItclObjectInfo * info, ItclClass ** rPtr)); /* 31 */
+    int (*itcl_DeleteClass) _ANSI_ARGS_((Tcl_Interp * interp, ItclClass * cdefnPtr)); /* 32 */
+    Tcl_Namespace* (*itcl_FindClassNamespace) _ANSI_ARGS_((Tcl_Interp* interp, CONST char* path)); /* 33 */
+    int (*itcl_HandleClass) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 34 */
+    int (*itcl_ClassCmdResolver) _ANSI_ARGS_((Tcl_Interp * interp, CONST char* name, Tcl_Namespace * context, int flags, Tcl_Command * rPtr)); /* 35 */
+    int (*itcl_ClassVarResolver) _ANSI_ARGS_((Tcl_Interp * interp, CONST char* name, Tcl_Namespace * context, int flags, Tcl_Var * rPtr)); /* 36 */
+    int (*itcl_ClassCompiledVarResolver) _ANSI_ARGS_((Tcl_Interp * interp, CONST char* name, int length, Tcl_Namespace * context, Tcl_ResolvedVarInfo ** rPtr)); /* 37 */
+    void (*itcl_BuildVirtualTables) _ANSI_ARGS_((ItclClass* cdefnPtr)); /* 38 */
+    int (*itcl_CreateVarDefn) _ANSI_ARGS_((Tcl_Interp * interp, ItclClass* cdefn, char* name, char* init, char* config, ItclVarDefn** vdefnPtr)); /* 39 */
+    void (*itcl_DeleteVarDefn) _ANSI_ARGS_((ItclVarDefn * vdefn)); /* 40 */
+    CONST char* (*itcl_GetCommonVar) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, ItclClass * contextClass)); /* 41 */
+    ItclMember* (*itcl_CreateMember) _ANSI_ARGS_((Tcl_Interp* interp, ItclClass * cdefn, CONST char* name)); /* 42 */
+    void (*itcl_DeleteMember) _ANSI_ARGS_((ItclMember * memPtr)); /* 43 */
+    int (*itcl_CreateObject) _ANSI_ARGS_((Tcl_Interp * interp, CONST char* name, ItclClass * cdefn, int objc, Tcl_Obj *CONST objv[], ItclObject ** roPtr)); /* 44 */
+    int (*itcl_DeleteObject) _ANSI_ARGS_((Tcl_Interp * interp, ItclObject * contextObj)); /* 45 */
+    int (*itcl_DestructObject) _ANSI_ARGS_((Tcl_Interp * interp, ItclObject * contextObj, int flags)); /* 46 */
+    int (*itcl_HandleInstance) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 47 */
+    CONST char* (*itcl_GetInstanceVar) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, ItclObject * contextObj, ItclClass * contextClass)); /* 48 */
+    int (*itcl_ScopedVarResolver) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, Tcl_Namespace * contextNs, int flags, Tcl_Var * rPtr)); /* 49 */
+    int (*itcl_BodyCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 50 */
+    int (*itcl_ConfigBodyCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 51 */
+    int (*itcl_CreateMethod) _ANSI_ARGS_((Tcl_Interp* interp, ItclClass * cdefn, CONST char* name, CONST char* arglist, CONST char* body)); /* 52 */
+    int (*itcl_CreateProc) _ANSI_ARGS_((Tcl_Interp* interp, ItclClass * cdefn, CONST char* name, CONST char* arglist, CONST char* body)); /* 53 */
+    int (*itcl_CreateMemberFunc) _ANSI_ARGS_((Tcl_Interp* interp, ItclClass * cdefn, CONST char* name, CONST char* arglist, CONST char* body, ItclMemberFunc** mfuncPtr)); /* 54 */
+    int (*itcl_ChangeMemberFunc) _ANSI_ARGS_((Tcl_Interp* interp, ItclMemberFunc* mfunc, CONST char* arglist, CONST char* body)); /* 55 */
+    void (*itcl_DeleteMemberFunc) _ANSI_ARGS_((CONST char* cdata)); /* 56 */
+    int (*itcl_CreateMemberCode) _ANSI_ARGS_((Tcl_Interp* interp, ItclClass * cdefn, CONST char* arglist, CONST char* body, ItclMemberCode** mcodePtr)); /* 57 */
+    void (*itcl_DeleteMemberCode) _ANSI_ARGS_((CONST char* cdata)); /* 58 */
+    int (*itcl_GetMemberCode) _ANSI_ARGS_((Tcl_Interp* interp, ItclMember* member)); /* 59 */
+    void *reserved60;
+    int (*itcl_EvalMemberCode) _ANSI_ARGS_((Tcl_Interp * interp, ItclMemberFunc * mfunc, ItclMember * member, ItclObject * contextObj, int objc, Tcl_Obj *CONST objv[])); /* 61 */
+    int (*itcl_CreateArgList) _ANSI_ARGS_((Tcl_Interp* interp, CONST char* decl, int* argcPtr, CompiledLocal** argPtr)); /* 62 */
+    CompiledLocal* (*itcl_CreateArg) _ANSI_ARGS_((CONST char* name, CONST char* init)); /* 63 */
+    void (*itcl_DeleteArgList) _ANSI_ARGS_((CompiledLocal * arglist)); /* 64 */
+    Tcl_Obj* (*itcl_ArgList) _ANSI_ARGS_((int argc, CompiledLocal* arglist)); /* 65 */
+    int (*itcl_EquivArgLists) _ANSI_ARGS_((CompiledLocal* arg1, int arg1c, CompiledLocal* arg2, int arg2c)); /* 66 */
+    void (*itcl_GetMemberFuncUsage) _ANSI_ARGS_((ItclMemberFunc * mfunc, ItclObject * contextObj, Tcl_Obj * objPtr)); /* 67 */
+    int (*itcl_ExecMethod) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 68 */
+    int (*itcl_ExecProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 69 */
+    int (*itcl_AssignArgs) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[], ItclMemberFunc * mfunc)); /* 70 */
+    int (*itcl_ConstructBase) _ANSI_ARGS_((Tcl_Interp * interp, ItclObject * contextObj, ItclClass * contextClass)); /* 71 */
+    int (*itcl_InvokeMethodIfExists) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, ItclClass * contextClass, ItclObject * contextObj, int objc, Tcl_Obj *CONST objv[])); /* 72 */
+    void *reserved73;
+    int (*itcl_ReportFuncErrors) _ANSI_ARGS_((Tcl_Interp* interp, ItclMemberFunc * mfunc, ItclObject * contextObj, int result)); /* 74 */
+    int (*itcl_ParseInit) _ANSI_ARGS_((Tcl_Interp * interp, ItclObjectInfo * info)); /* 75 */
+    int (*itcl_ClassCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 76 */
+    int (*itcl_ClassInheritCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 77 */
+    int (*itcl_ClassProtectionCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 78 */
+    int (*itcl_ClassConstructorCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 79 */
+    int (*itcl_ClassDestructorCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 80 */
+    int (*itcl_ClassMethodCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 81 */
+    int (*itcl_ClassProcCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 82 */
+    int (*itcl_ClassVariableCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 83 */
+    int (*itcl_ClassCommonCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 84 */
+    int (*itcl_ParseVarResolver) _ANSI_ARGS_((Tcl_Interp * interp, CONST char* name, Tcl_Namespace * contextNs, int flags, Tcl_Var* rPtr)); /* 85 */
+    int (*itcl_BiInit) _ANSI_ARGS_((Tcl_Interp * interp)); /* 86 */
+    int (*itcl_InstallBiMethods) _ANSI_ARGS_((Tcl_Interp * interp, ItclClass * cdefn)); /* 87 */
+    int (*itcl_BiIsaCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 88 */
+    int (*itcl_BiConfigureCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 89 */
+    int (*itcl_BiCgetCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 90 */
+    int (*itcl_BiChainCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 91 */
+    int (*itcl_BiInfoClassCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 92 */
+    int (*itcl_BiInfoInheritCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 93 */
+    int (*itcl_BiInfoHeritageCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 94 */
+    int (*itcl_BiInfoFunctionCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 95 */
+    int (*itcl_BiInfoVariableCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 96 */
+    int (*itcl_BiInfoBodyCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 97 */
+    int (*itcl_BiInfoArgsCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 98 */
+    int (*itcl_DefaultInfoCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 99 */
+    int (*itcl_EnsembleInit) _ANSI_ARGS_((Tcl_Interp * interp)); /* 100 */
+    int (*itcl_CreateEnsemble) _ANSI_ARGS_((Tcl_Interp * interp, CONST char* ensName)); /* 101 */
+    int (*itcl_AddEnsemblePart) _ANSI_ARGS_((Tcl_Interp * interp, CONST char* ensName, CONST char* partName, CONST char* usageInfo, Tcl_ObjCmdProc * objProc, ClientData clientData, Tcl_CmdDeleteProc * deleteProc)); /* 102 */
+    int (*itcl_GetEnsemblePart) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * ensName, CONST char * partName, Tcl_CmdInfo * infoPtr)); /* 103 */
+    int (*itcl_IsEnsemble) _ANSI_ARGS_((Tcl_CmdInfo* infoPtr)); /* 104 */
+    int (*itcl_GetEnsembleUsage) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * ensName, Tcl_Obj * objPtr)); /* 105 */
+    int (*itcl_GetEnsembleUsageForObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * ensObjPtr, Tcl_Obj * objPtr)); /* 106 */
+    int (*itcl_EnsembleCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 107 */
+    int (*itcl_EnsPartCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 108 */
+    int (*itcl_EnsembleErrorCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 109 */
+    void *reserved110;
+    void *reserved111;
+    Itcl_CallFrame* (*_Tcl_GetCallFrame) _ANSI_ARGS_((Tcl_Interp * interp, int level)); /* 112 */
+    Itcl_CallFrame* (*_Tcl_ActivateCallFrame) _ANSI_ARGS_((Tcl_Interp * interp, Itcl_CallFrame * framePtr)); /* 113 */
+    Var* (*_TclNewVar) _ANSI_ARGS_((void)); /* 114 */
+    void (*itcl_Assert) _ANSI_ARGS_((CONST char * testExpr, CONST char * fileName, int lineNum)); /* 115 */
+    int (*itcl_IsObjectCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 116 */
+    int (*itcl_IsClassCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 117 */
+} ItclIntStubs;
+
+TCL_EXTERNC ItclIntStubs *itclIntStubsPtr;
+
+#if defined(USE_ITCL_STUBS) && !defined(USE_ITCL_STUB_PROCS)
+
+/*
+ * Inline function declarations:
+ */
+
+#ifndef Itcl_IsClassNamespace
+#define Itcl_IsClassNamespace \
+       (itclIntStubsPtr->itcl_IsClassNamespace) /* 0 */
+#endif
+#ifndef Itcl_IsClass
+#define Itcl_IsClass \
+       (itclIntStubsPtr->itcl_IsClass) /* 1 */
+#endif
+#ifndef Itcl_FindClass
+#define Itcl_FindClass \
+       (itclIntStubsPtr->itcl_FindClass) /* 2 */
+#endif
+#ifndef Itcl_FindObject
+#define Itcl_FindObject \
+       (itclIntStubsPtr->itcl_FindObject) /* 3 */
+#endif
+#ifndef Itcl_IsObject
+#define Itcl_IsObject \
+       (itclIntStubsPtr->itcl_IsObject) /* 4 */
+#endif
+#ifndef Itcl_ObjectIsa
+#define Itcl_ObjectIsa \
+       (itclIntStubsPtr->itcl_ObjectIsa) /* 5 */
+#endif
+#ifndef Itcl_Protection
+#define Itcl_Protection \
+       (itclIntStubsPtr->itcl_Protection) /* 6 */
+#endif
+#ifndef Itcl_ProtectionStr
+#define Itcl_ProtectionStr \
+       (itclIntStubsPtr->itcl_ProtectionStr) /* 7 */
+#endif
+#ifndef Itcl_CanAccess
+#define Itcl_CanAccess \
+       (itclIntStubsPtr->itcl_CanAccess) /* 8 */
+#endif
+#ifndef Itcl_CanAccessFunc
+#define Itcl_CanAccessFunc \
+       (itclIntStubsPtr->itcl_CanAccessFunc) /* 9 */
+#endif
+#ifndef Itcl_GetTrueNamespace
+#define Itcl_GetTrueNamespace \
+       (itclIntStubsPtr->itcl_GetTrueNamespace) /* 10 */
+#endif
+#ifndef Itcl_ParseNamespPath
+#define Itcl_ParseNamespPath \
+       (itclIntStubsPtr->itcl_ParseNamespPath) /* 11 */
+#endif
+#ifndef Itcl_DecodeScopedCommand
+#define Itcl_DecodeScopedCommand \
+       (itclIntStubsPtr->itcl_DecodeScopedCommand) /* 12 */
+#endif
+#ifndef Itcl_EvalArgs
+#define Itcl_EvalArgs \
+       (itclIntStubsPtr->itcl_EvalArgs) /* 13 */
+#endif
+#ifndef Itcl_CreateArgs
+#define Itcl_CreateArgs \
+       (itclIntStubsPtr->itcl_CreateArgs) /* 14 */
+#endif
+#ifndef Itcl_PushContext
+#define Itcl_PushContext \
+       (itclIntStubsPtr->itcl_PushContext) /* 15 */
+#endif
+#ifndef Itcl_PopContext
+#define Itcl_PopContext \
+       (itclIntStubsPtr->itcl_PopContext) /* 16 */
+#endif
+#ifndef Itcl_GetContext
+#define Itcl_GetContext \
+       (itclIntStubsPtr->itcl_GetContext) /* 17 */
+#endif
+#ifndef Itcl_InitHierIter
+#define Itcl_InitHierIter \
+       (itclIntStubsPtr->itcl_InitHierIter) /* 18 */
+#endif
+#ifndef Itcl_DeleteHierIter
+#define Itcl_DeleteHierIter \
+       (itclIntStubsPtr->itcl_DeleteHierIter) /* 19 */
+#endif
+#ifndef Itcl_AdvanceHierIter
+#define Itcl_AdvanceHierIter \
+       (itclIntStubsPtr->itcl_AdvanceHierIter) /* 20 */
+#endif
+#ifndef Itcl_FindClassesCmd
+#define Itcl_FindClassesCmd \
+       (itclIntStubsPtr->itcl_FindClassesCmd) /* 21 */
+#endif
+#ifndef Itcl_FindObjectsCmd
+#define Itcl_FindObjectsCmd \
+       (itclIntStubsPtr->itcl_FindObjectsCmd) /* 22 */
+#endif
+#ifndef Itcl_ProtectionCmd
+#define Itcl_ProtectionCmd \
+       (itclIntStubsPtr->itcl_ProtectionCmd) /* 23 */
+#endif
+#ifndef Itcl_DelClassCmd
+#define Itcl_DelClassCmd \
+       (itclIntStubsPtr->itcl_DelClassCmd) /* 24 */
+#endif
+#ifndef Itcl_DelObjectCmd
+#define Itcl_DelObjectCmd \
+       (itclIntStubsPtr->itcl_DelObjectCmd) /* 25 */
+#endif
+#ifndef Itcl_ScopeCmd
+#define Itcl_ScopeCmd \
+       (itclIntStubsPtr->itcl_ScopeCmd) /* 26 */
+#endif
+#ifndef Itcl_CodeCmd
+#define Itcl_CodeCmd \
+       (itclIntStubsPtr->itcl_CodeCmd) /* 27 */
+#endif
+#ifndef Itcl_StubCreateCmd
+#define Itcl_StubCreateCmd \
+       (itclIntStubsPtr->itcl_StubCreateCmd) /* 28 */
+#endif
+#ifndef Itcl_StubExistsCmd
+#define Itcl_StubExistsCmd \
+       (itclIntStubsPtr->itcl_StubExistsCmd) /* 29 */
+#endif
+#ifndef Itcl_IsStub
+#define Itcl_IsStub \
+       (itclIntStubsPtr->itcl_IsStub) /* 30 */
+#endif
+#ifndef Itcl_CreateClass
+#define Itcl_CreateClass \
+       (itclIntStubsPtr->itcl_CreateClass) /* 31 */
+#endif
+#ifndef Itcl_DeleteClass
+#define Itcl_DeleteClass \
+       (itclIntStubsPtr->itcl_DeleteClass) /* 32 */
+#endif
+#ifndef Itcl_FindClassNamespace
+#define Itcl_FindClassNamespace \
+       (itclIntStubsPtr->itcl_FindClassNamespace) /* 33 */
+#endif
+#ifndef Itcl_HandleClass
+#define Itcl_HandleClass \
+       (itclIntStubsPtr->itcl_HandleClass) /* 34 */
+#endif
+#ifndef Itcl_ClassCmdResolver
+#define Itcl_ClassCmdResolver \
+       (itclIntStubsPtr->itcl_ClassCmdResolver) /* 35 */
+#endif
+#ifndef Itcl_ClassVarResolver
+#define Itcl_ClassVarResolver \
+       (itclIntStubsPtr->itcl_ClassVarResolver) /* 36 */
+#endif
+#ifndef Itcl_ClassCompiledVarResolver
+#define Itcl_ClassCompiledVarResolver \
+       (itclIntStubsPtr->itcl_ClassCompiledVarResolver) /* 37 */
+#endif
+#ifndef Itcl_BuildVirtualTables
+#define Itcl_BuildVirtualTables \
+       (itclIntStubsPtr->itcl_BuildVirtualTables) /* 38 */
+#endif
+#ifndef Itcl_CreateVarDefn
+#define Itcl_CreateVarDefn \
+       (itclIntStubsPtr->itcl_CreateVarDefn) /* 39 */
+#endif
+#ifndef Itcl_DeleteVarDefn
+#define Itcl_DeleteVarDefn \
+       (itclIntStubsPtr->itcl_DeleteVarDefn) /* 40 */
+#endif
+#ifndef Itcl_GetCommonVar
+#define Itcl_GetCommonVar \
+       (itclIntStubsPtr->itcl_GetCommonVar) /* 41 */
+#endif
+#ifndef Itcl_CreateMember
+#define Itcl_CreateMember \
+       (itclIntStubsPtr->itcl_CreateMember) /* 42 */
+#endif
+#ifndef Itcl_DeleteMember
+#define Itcl_DeleteMember \
+       (itclIntStubsPtr->itcl_DeleteMember) /* 43 */
+#endif
+#ifndef Itcl_CreateObject
+#define Itcl_CreateObject \
+       (itclIntStubsPtr->itcl_CreateObject) /* 44 */
+#endif
+#ifndef Itcl_DeleteObject
+#define Itcl_DeleteObject \
+       (itclIntStubsPtr->itcl_DeleteObject) /* 45 */
+#endif
+#ifndef Itcl_DestructObject
+#define Itcl_DestructObject \
+       (itclIntStubsPtr->itcl_DestructObject) /* 46 */
+#endif
+#ifndef Itcl_HandleInstance
+#define Itcl_HandleInstance \
+       (itclIntStubsPtr->itcl_HandleInstance) /* 47 */
+#endif
+#ifndef Itcl_GetInstanceVar
+#define Itcl_GetInstanceVar \
+       (itclIntStubsPtr->itcl_GetInstanceVar) /* 48 */
+#endif
+#ifndef Itcl_ScopedVarResolver
+#define Itcl_ScopedVarResolver \
+       (itclIntStubsPtr->itcl_ScopedVarResolver) /* 49 */
+#endif
+#ifndef Itcl_BodyCmd
+#define Itcl_BodyCmd \
+       (itclIntStubsPtr->itcl_BodyCmd) /* 50 */
+#endif
+#ifndef Itcl_ConfigBodyCmd
+#define Itcl_ConfigBodyCmd \
+       (itclIntStubsPtr->itcl_ConfigBodyCmd) /* 51 */
+#endif
+#ifndef Itcl_CreateMethod
+#define Itcl_CreateMethod \
+       (itclIntStubsPtr->itcl_CreateMethod) /* 52 */
+#endif
+#ifndef Itcl_CreateProc
+#define Itcl_CreateProc \
+       (itclIntStubsPtr->itcl_CreateProc) /* 53 */
+#endif
+#ifndef Itcl_CreateMemberFunc
+#define Itcl_CreateMemberFunc \
+       (itclIntStubsPtr->itcl_CreateMemberFunc) /* 54 */
+#endif
+#ifndef Itcl_ChangeMemberFunc
+#define Itcl_ChangeMemberFunc \
+       (itclIntStubsPtr->itcl_ChangeMemberFunc) /* 55 */
+#endif
+#ifndef Itcl_DeleteMemberFunc
+#define Itcl_DeleteMemberFunc \
+       (itclIntStubsPtr->itcl_DeleteMemberFunc) /* 56 */
+#endif
+#ifndef Itcl_CreateMemberCode
+#define Itcl_CreateMemberCode \
+       (itclIntStubsPtr->itcl_CreateMemberCode) /* 57 */
+#endif
+#ifndef Itcl_DeleteMemberCode
+#define Itcl_DeleteMemberCode \
+       (itclIntStubsPtr->itcl_DeleteMemberCode) /* 58 */
+#endif
+#ifndef Itcl_GetMemberCode
+#define Itcl_GetMemberCode \
+       (itclIntStubsPtr->itcl_GetMemberCode) /* 59 */
+#endif
+/* Slot 60 is reserved */
+#ifndef Itcl_EvalMemberCode
+#define Itcl_EvalMemberCode \
+       (itclIntStubsPtr->itcl_EvalMemberCode) /* 61 */
+#endif
+#ifndef Itcl_CreateArgList
+#define Itcl_CreateArgList \
+       (itclIntStubsPtr->itcl_CreateArgList) /* 62 */
+#endif
+#ifndef Itcl_CreateArg
+#define Itcl_CreateArg \
+       (itclIntStubsPtr->itcl_CreateArg) /* 63 */
+#endif
+#ifndef Itcl_DeleteArgList
+#define Itcl_DeleteArgList \
+       (itclIntStubsPtr->itcl_DeleteArgList) /* 64 */
+#endif
+#ifndef Itcl_ArgList
+#define Itcl_ArgList \
+       (itclIntStubsPtr->itcl_ArgList) /* 65 */
+#endif
+#ifndef Itcl_EquivArgLists
+#define Itcl_EquivArgLists \
+       (itclIntStubsPtr->itcl_EquivArgLists) /* 66 */
+#endif
+#ifndef Itcl_GetMemberFuncUsage
+#define Itcl_GetMemberFuncUsage \
+       (itclIntStubsPtr->itcl_GetMemberFuncUsage) /* 67 */
+#endif
+#ifndef Itcl_ExecMethod
+#define Itcl_ExecMethod \
+       (itclIntStubsPtr->itcl_ExecMethod) /* 68 */
+#endif
+#ifndef Itcl_ExecProc
+#define Itcl_ExecProc \
+       (itclIntStubsPtr->itcl_ExecProc) /* 69 */
+#endif
+#ifndef Itcl_AssignArgs
+#define Itcl_AssignArgs \
+       (itclIntStubsPtr->itcl_AssignArgs) /* 70 */
+#endif
+#ifndef Itcl_ConstructBase
+#define Itcl_ConstructBase \
+       (itclIntStubsPtr->itcl_ConstructBase) /* 71 */
+#endif
+#ifndef Itcl_InvokeMethodIfExists
+#define Itcl_InvokeMethodIfExists \
+       (itclIntStubsPtr->itcl_InvokeMethodIfExists) /* 72 */
+#endif
+/* Slot 73 is reserved */
+#ifndef Itcl_ReportFuncErrors
+#define Itcl_ReportFuncErrors \
+       (itclIntStubsPtr->itcl_ReportFuncErrors) /* 74 */
+#endif
+#ifndef Itcl_ParseInit
+#define Itcl_ParseInit \
+       (itclIntStubsPtr->itcl_ParseInit) /* 75 */
+#endif
+#ifndef Itcl_ClassCmd
+#define Itcl_ClassCmd \
+       (itclIntStubsPtr->itcl_ClassCmd) /* 76 */
+#endif
+#ifndef Itcl_ClassInheritCmd
+#define Itcl_ClassInheritCmd \
+       (itclIntStubsPtr->itcl_ClassInheritCmd) /* 77 */
+#endif
+#ifndef Itcl_ClassProtectionCmd
+#define Itcl_ClassProtectionCmd \
+       (itclIntStubsPtr->itcl_ClassProtectionCmd) /* 78 */
+#endif
+#ifndef Itcl_ClassConstructorCmd
+#define Itcl_ClassConstructorCmd \
+       (itclIntStubsPtr->itcl_ClassConstructorCmd) /* 79 */
+#endif
+#ifndef Itcl_ClassDestructorCmd
+#define Itcl_ClassDestructorCmd \
+       (itclIntStubsPtr->itcl_ClassDestructorCmd) /* 80 */
+#endif
+#ifndef Itcl_ClassMethodCmd
+#define Itcl_ClassMethodCmd \
+       (itclIntStubsPtr->itcl_ClassMethodCmd) /* 81 */
+#endif
+#ifndef Itcl_ClassProcCmd
+#define Itcl_ClassProcCmd \
+       (itclIntStubsPtr->itcl_ClassProcCmd) /* 82 */
+#endif
+#ifndef Itcl_ClassVariableCmd
+#define Itcl_ClassVariableCmd \
+       (itclIntStubsPtr->itcl_ClassVariableCmd) /* 83 */
+#endif
+#ifndef Itcl_ClassCommonCmd
+#define Itcl_ClassCommonCmd \
+       (itclIntStubsPtr->itcl_ClassCommonCmd) /* 84 */
+#endif
+#ifndef Itcl_ParseVarResolver
+#define Itcl_ParseVarResolver \
+       (itclIntStubsPtr->itcl_ParseVarResolver) /* 85 */
+#endif
+#ifndef Itcl_BiInit
+#define Itcl_BiInit \
+       (itclIntStubsPtr->itcl_BiInit) /* 86 */
+#endif
+#ifndef Itcl_InstallBiMethods
+#define Itcl_InstallBiMethods \
+       (itclIntStubsPtr->itcl_InstallBiMethods) /* 87 */
+#endif
+#ifndef Itcl_BiIsaCmd
+#define Itcl_BiIsaCmd \
+       (itclIntStubsPtr->itcl_BiIsaCmd) /* 88 */
+#endif
+#ifndef Itcl_BiConfigureCmd
+#define Itcl_BiConfigureCmd \
+       (itclIntStubsPtr->itcl_BiConfigureCmd) /* 89 */
+#endif
+#ifndef Itcl_BiCgetCmd
+#define Itcl_BiCgetCmd \
+       (itclIntStubsPtr->itcl_BiCgetCmd) /* 90 */
+#endif
+#ifndef Itcl_BiChainCmd
+#define Itcl_BiChainCmd \
+       (itclIntStubsPtr->itcl_BiChainCmd) /* 91 */
+#endif
+#ifndef Itcl_BiInfoClassCmd
+#define Itcl_BiInfoClassCmd \
+       (itclIntStubsPtr->itcl_BiInfoClassCmd) /* 92 */
+#endif
+#ifndef Itcl_BiInfoInheritCmd
+#define Itcl_BiInfoInheritCmd \
+       (itclIntStubsPtr->itcl_BiInfoInheritCmd) /* 93 */
+#endif
+#ifndef Itcl_BiInfoHeritageCmd
+#define Itcl_BiInfoHeritageCmd \
+       (itclIntStubsPtr->itcl_BiInfoHeritageCmd) /* 94 */
+#endif
+#ifndef Itcl_BiInfoFunctionCmd
+#define Itcl_BiInfoFunctionCmd \
+       (itclIntStubsPtr->itcl_BiInfoFunctionCmd) /* 95 */
+#endif
+#ifndef Itcl_BiInfoVariableCmd
+#define Itcl_BiInfoVariableCmd \
+       (itclIntStubsPtr->itcl_BiInfoVariableCmd) /* 96 */
+#endif
+#ifndef Itcl_BiInfoBodyCmd
+#define Itcl_BiInfoBodyCmd \
+       (itclIntStubsPtr->itcl_BiInfoBodyCmd) /* 97 */
+#endif
+#ifndef Itcl_BiInfoArgsCmd
+#define Itcl_BiInfoArgsCmd \
+       (itclIntStubsPtr->itcl_BiInfoArgsCmd) /* 98 */
+#endif
+#ifndef Itcl_DefaultInfoCmd
+#define Itcl_DefaultInfoCmd \
+       (itclIntStubsPtr->itcl_DefaultInfoCmd) /* 99 */
+#endif
+#ifndef Itcl_EnsembleInit
+#define Itcl_EnsembleInit \
+       (itclIntStubsPtr->itcl_EnsembleInit) /* 100 */
+#endif
+#ifndef Itcl_CreateEnsemble
+#define Itcl_CreateEnsemble \
+       (itclIntStubsPtr->itcl_CreateEnsemble) /* 101 */
+#endif
+#ifndef Itcl_AddEnsemblePart
+#define Itcl_AddEnsemblePart \
+       (itclIntStubsPtr->itcl_AddEnsemblePart) /* 102 */
+#endif
+#ifndef Itcl_GetEnsemblePart
+#define Itcl_GetEnsemblePart \
+       (itclIntStubsPtr->itcl_GetEnsemblePart) /* 103 */
+#endif
+#ifndef Itcl_IsEnsemble
+#define Itcl_IsEnsemble \
+       (itclIntStubsPtr->itcl_IsEnsemble) /* 104 */
+#endif
+#ifndef Itcl_GetEnsembleUsage
+#define Itcl_GetEnsembleUsage \
+       (itclIntStubsPtr->itcl_GetEnsembleUsage) /* 105 */
+#endif
+#ifndef Itcl_GetEnsembleUsageForObj
+#define Itcl_GetEnsembleUsageForObj \
+       (itclIntStubsPtr->itcl_GetEnsembleUsageForObj) /* 106 */
+#endif
+#ifndef Itcl_EnsembleCmd
+#define Itcl_EnsembleCmd \
+       (itclIntStubsPtr->itcl_EnsembleCmd) /* 107 */
+#endif
+#ifndef Itcl_EnsPartCmd
+#define Itcl_EnsPartCmd \
+       (itclIntStubsPtr->itcl_EnsPartCmd) /* 108 */
+#endif
+#ifndef Itcl_EnsembleErrorCmd
+#define Itcl_EnsembleErrorCmd \
+       (itclIntStubsPtr->itcl_EnsembleErrorCmd) /* 109 */
+#endif
+/* Slot 110 is reserved */
+/* Slot 111 is reserved */
+#ifndef _Tcl_GetCallFrame
+#define _Tcl_GetCallFrame \
+       (itclIntStubsPtr->_Tcl_GetCallFrame) /* 112 */
+#endif
+#ifndef _Tcl_ActivateCallFrame
+#define _Tcl_ActivateCallFrame \
+       (itclIntStubsPtr->_Tcl_ActivateCallFrame) /* 113 */
+#endif
+#ifndef _TclNewVar
+#define _TclNewVar \
+       (itclIntStubsPtr->_TclNewVar) /* 114 */
+#endif
+#ifndef Itcl_Assert
+#define Itcl_Assert \
+       (itclIntStubsPtr->itcl_Assert) /* 115 */
+#endif
+#ifndef Itcl_IsObjectCmd
+#define Itcl_IsObjectCmd \
+       (itclIntStubsPtr->itcl_IsObjectCmd) /* 116 */
+#endif
+#ifndef Itcl_IsClassCmd
+#define Itcl_IsClassCmd \
+       (itclIntStubsPtr->itcl_IsClassCmd) /* 117 */
+#endif
+
+#endif /* defined(USE_ITCL_STUBS) && !defined(USE_ITCL_STUB_PROCS) */
+
+/* !END!: Do not edit above this line. */
+
+#endif /* _ITCLINTDECLS */
diff --git a/8.x/itcl/generic/itclStubInit.c b/8.x/itcl/generic/itclStubInit.c
new file mode 100644 (file)
index 0000000..0ab730c
--- /dev/null
@@ -0,0 +1,187 @@
+/* 
+ * itclStubInit.c --
+ *
+ *     This file contains the initializers for the Itcl stub vectors.
+ *
+ * Copyright (c) 1998-1999 by XXX
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: $Id: itclStubInit.c,v 1.4 2002/08/11 03:43:46 davygrvy Exp $
+ */
+
+#include "itclInt.h"
+
+/*
+ * Remove macros that will interfere with the definitions below.
+ */
+
+
+/*
+ * WARNING: The contents of this file is automatically generated by the
+ * tools/genStubs.tcl script. Any modifications to the function declarations
+ * below should be made in the generic/tcl.decls script.
+ */
+
+/* !BEGIN!: Do not edit below this line. */
+
+ItclIntStubs itclIntStubs = {
+    TCL_STUB_MAGIC,
+    NULL,
+    Itcl_IsClassNamespace, /* 0 */
+    Itcl_IsClass, /* 1 */
+    Itcl_FindClass, /* 2 */
+    Itcl_FindObject, /* 3 */
+    Itcl_IsObject, /* 4 */
+    Itcl_ObjectIsa, /* 5 */
+    Itcl_Protection, /* 6 */
+    Itcl_ProtectionStr, /* 7 */
+    Itcl_CanAccess, /* 8 */
+    Itcl_CanAccessFunc, /* 9 */
+    Itcl_GetTrueNamespace, /* 10 */
+    Itcl_ParseNamespPath, /* 11 */
+    Itcl_DecodeScopedCommand, /* 12 */
+    Itcl_EvalArgs, /* 13 */
+    Itcl_CreateArgs, /* 14 */
+    Itcl_PushContext, /* 15 */
+    Itcl_PopContext, /* 16 */
+    Itcl_GetContext, /* 17 */
+    Itcl_InitHierIter, /* 18 */
+    Itcl_DeleteHierIter, /* 19 */
+    Itcl_AdvanceHierIter, /* 20 */
+    Itcl_FindClassesCmd, /* 21 */
+    Itcl_FindObjectsCmd, /* 22 */
+    Itcl_ProtectionCmd, /* 23 */
+    Itcl_DelClassCmd, /* 24 */
+    Itcl_DelObjectCmd, /* 25 */
+    Itcl_ScopeCmd, /* 26 */
+    Itcl_CodeCmd, /* 27 */
+    Itcl_StubCreateCmd, /* 28 */
+    Itcl_StubExistsCmd, /* 29 */
+    Itcl_IsStub, /* 30 */
+    Itcl_CreateClass, /* 31 */
+    Itcl_DeleteClass, /* 32 */
+    Itcl_FindClassNamespace, /* 33 */
+    Itcl_HandleClass, /* 34 */
+    Itcl_ClassCmdResolver, /* 35 */
+    Itcl_ClassVarResolver, /* 36 */
+    Itcl_ClassCompiledVarResolver, /* 37 */
+    Itcl_BuildVirtualTables, /* 38 */
+    Itcl_CreateVarDefn, /* 39 */
+    Itcl_DeleteVarDefn, /* 40 */
+    Itcl_GetCommonVar, /* 41 */
+    Itcl_CreateMember, /* 42 */
+    Itcl_DeleteMember, /* 43 */
+    Itcl_CreateObject, /* 44 */
+    Itcl_DeleteObject, /* 45 */
+    Itcl_DestructObject, /* 46 */
+    Itcl_HandleInstance, /* 47 */
+    Itcl_GetInstanceVar, /* 48 */
+    Itcl_ScopedVarResolver, /* 49 */
+    Itcl_BodyCmd, /* 50 */
+    Itcl_ConfigBodyCmd, /* 51 */
+    Itcl_CreateMethod, /* 52 */
+    Itcl_CreateProc, /* 53 */
+    Itcl_CreateMemberFunc, /* 54 */
+    Itcl_ChangeMemberFunc, /* 55 */
+    Itcl_DeleteMemberFunc, /* 56 */
+    Itcl_CreateMemberCode, /* 57 */
+    Itcl_DeleteMemberCode, /* 58 */
+    Itcl_GetMemberCode, /* 59 */
+    NULL, /* 60 */
+    Itcl_EvalMemberCode, /* 61 */
+    Itcl_CreateArgList, /* 62 */
+    Itcl_CreateArg, /* 63 */
+    Itcl_DeleteArgList, /* 64 */
+    Itcl_ArgList, /* 65 */
+    Itcl_EquivArgLists, /* 66 */
+    Itcl_GetMemberFuncUsage, /* 67 */
+    Itcl_ExecMethod, /* 68 */
+    Itcl_ExecProc, /* 69 */
+    Itcl_AssignArgs, /* 70 */
+    Itcl_ConstructBase, /* 71 */
+    Itcl_InvokeMethodIfExists, /* 72 */
+    NULL, /* 73 */
+    Itcl_ReportFuncErrors, /* 74 */
+    Itcl_ParseInit, /* 75 */
+    Itcl_ClassCmd, /* 76 */
+    Itcl_ClassInheritCmd, /* 77 */
+    Itcl_ClassProtectionCmd, /* 78 */
+    Itcl_ClassConstructorCmd, /* 79 */
+    Itcl_ClassDestructorCmd, /* 80 */
+    Itcl_ClassMethodCmd, /* 81 */
+    Itcl_ClassProcCmd, /* 82 */
+    Itcl_ClassVariableCmd, /* 83 */
+    Itcl_ClassCommonCmd, /* 84 */
+    Itcl_ParseVarResolver, /* 85 */
+    Itcl_BiInit, /* 86 */
+    Itcl_InstallBiMethods, /* 87 */
+    Itcl_BiIsaCmd, /* 88 */
+    Itcl_BiConfigureCmd, /* 89 */
+    Itcl_BiCgetCmd, /* 90 */
+    Itcl_BiChainCmd, /* 91 */
+    Itcl_BiInfoClassCmd, /* 92 */
+    Itcl_BiInfoInheritCmd, /* 93 */
+    Itcl_BiInfoHeritageCmd, /* 94 */
+    Itcl_BiInfoFunctionCmd, /* 95 */
+    Itcl_BiInfoVariableCmd, /* 96 */
+    Itcl_BiInfoBodyCmd, /* 97 */
+    Itcl_BiInfoArgsCmd, /* 98 */
+    Itcl_DefaultInfoCmd, /* 99 */
+    Itcl_EnsembleInit, /* 100 */
+    Itcl_CreateEnsemble, /* 101 */
+    Itcl_AddEnsemblePart, /* 102 */
+    Itcl_GetEnsemblePart, /* 103 */
+    Itcl_IsEnsemble, /* 104 */
+    Itcl_GetEnsembleUsage, /* 105 */
+    Itcl_GetEnsembleUsageForObj, /* 106 */
+    Itcl_EnsembleCmd, /* 107 */
+    Itcl_EnsPartCmd, /* 108 */
+    Itcl_EnsembleErrorCmd, /* 109 */
+    NULL, /* 110 */
+    NULL, /* 111 */
+    _Tcl_GetCallFrame, /* 112 */
+    _Tcl_ActivateCallFrame, /* 113 */
+    _TclNewVar, /* 114 */
+    Itcl_Assert, /* 115 */
+    Itcl_IsObjectCmd, /* 116 */
+    Itcl_IsClassCmd, /* 117 */
+};
+
+static ItclStubHooks itclStubHooks = {
+    &itclIntStubs
+};
+
+ItclStubs itclStubs = {
+    TCL_STUB_MAGIC,
+    &itclStubHooks,
+    Itcl_Init, /* 0 */
+    Itcl_SafeInit, /* 1 */
+    Itcl_RegisterC, /* 2 */
+    Itcl_RegisterObjC, /* 3 */
+    Itcl_FindC, /* 4 */
+    Itcl_InitStack, /* 5 */
+    Itcl_DeleteStack, /* 6 */
+    Itcl_PushStack, /* 7 */
+    Itcl_PopStack, /* 8 */
+    Itcl_PeekStack, /* 9 */
+    Itcl_GetStackValue, /* 10 */
+    Itcl_InitList, /* 11 */
+    Itcl_DeleteList, /* 12 */
+    Itcl_CreateListElem, /* 13 */
+    Itcl_DeleteListElem, /* 14 */
+    Itcl_InsertList, /* 15 */
+    Itcl_InsertListElem, /* 16 */
+    Itcl_AppendList, /* 17 */
+    Itcl_AppendListElem, /* 18 */
+    Itcl_SetListValue, /* 19 */
+    Itcl_EventuallyFree, /* 20 */
+    Itcl_PreserveData, /* 21 */
+    Itcl_ReleaseData, /* 22 */
+    Itcl_SaveInterpState, /* 23 */
+    Itcl_RestoreInterpState, /* 24 */
+    Itcl_DiscardInterpState, /* 25 */
+};
+
+/* !END!: Do not edit above this line. */
diff --git a/8.x/itcl/generic/itclStubLib.c b/8.x/itcl/generic/itclStubLib.c
new file mode 100644 (file)
index 0000000..49a6b57
--- /dev/null
@@ -0,0 +1,86 @@
+/* 
+ * itclStubLib.c --
+ *
+ *     Stub object that will be statically linked into extensions that wish
+ *     to access Itcl.
+ *
+ * Copyright (c) 1998 Paul Duffin.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: $Id: itclStubLib.c,v 1.9 2003/12/24 03:38:02 davygrvy Exp $
+ */
+
+/*
+ * We need to ensure that we use the stub macros so that this file contains
+ * no references to any of the stub functions.  This will make it possible
+ * to build an extension that references Tcl_InitStubs but doesn't end up
+ * including the rest of the stub functions.
+ */
+
+#ifndef USE_TCL_STUBS
+#define USE_TCL_STUBS
+#endif
+#undef USE_TCL_STUB_PROCS
+
+/*
+ * This ensures that the Itcl_InitStubs has a prototype in
+ * itcl.h and is not the macro that turns it into Tcl_PkgRequire
+ */
+
+#ifndef USE_ITCL_STUBS
+#define USE_ITCL_STUBS
+#endif
+
+#include "itclInt.h"
+
+ItclStubs *itclStubsPtr;
+ItclIntStubs *itclIntStubsPtr;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_InitStubs --
+ *
+ *     Tries to initialize the stub table pointers and ensures that
+ *     the correct version of Itcl is loaded.
+ *
+ * Results:
+ *     The actual version of Itcl that satisfies the request, or
+ *     NULL to indicate that an error occurred.
+ *
+ * Side effects:
+ *     Sets the stub table pointers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef Itcl_InitStubs
+#undef Itcl_InitStubs
+#endif
+
+CONST char *
+Itcl_InitStubs (interp, version, exact)
+    Tcl_Interp *interp;
+    CONST char *version;
+    int exact;
+{
+    CONST char *actualVersion;
+    
+    actualVersion = Tcl_PkgRequireEx(interp, "Itcl", (CONST84 char *)version, exact,
+        (ClientData *) &itclStubsPtr);
+
+    if (actualVersion == NULL) {
+       itclStubsPtr = NULL;
+       return NULL;
+    }
+
+    if (itclStubsPtr->hooks) {
+       itclIntStubsPtr = itclStubsPtr->hooks->itclIntStubs;
+    } else {
+       itclIntStubsPtr = NULL;
+    }
+    
+    return actualVersion;
+}
diff --git a/8.x/itcl/generic/itcl_bicmds.c b/8.x/itcl/generic/itcl_bicmds.c
new file mode 100644 (file)
index 0000000..d3ac5d2
--- /dev/null
@@ -0,0 +1,1703 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  These procedures handle built-in class methods, including the
+ *  "isa" method (to query hierarchy info) and the "info" method
+ *  (to query class/object data).
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_bicmds.c,v 1.12 2008/10/04 15:22:39 msofer Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ *  Standard list of built-in methods for all objects.
+ */
+typedef struct BiMethod {
+    char* name;              /* method name */
+    char* usage;             /* string describing usage */
+    char* registration;      /* registration name for C proc */
+    Tcl_ObjCmdProc *proc;    /* implementation C proc */
+} BiMethod;
+
+static BiMethod BiMethodList[] = {
+    { "cget",      "-option",
+                   "@itcl-builtin-cget",  Itcl_BiCgetCmd },
+    { "configure", "?-option? ?value -option value...?",
+                   "@itcl-builtin-configure",  Itcl_BiConfigureCmd },
+    { "isa",       "className",
+                   "@itcl-builtin-isa",  Itcl_BiIsaCmd },
+};
+static int BiMethodListLen = sizeof(BiMethodList)/sizeof(BiMethod);
+
+
+/*
+ *  FORWARD DECLARATIONS
+ */
+static Tcl_Obj* ItclReportPublicOpt _ANSI_ARGS_((Tcl_Interp *interp,
+    ItclVarDefn *vdefn, ItclObject *contextObj));
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiInit()
+ *
+ *  Creates a namespace full of built-in methods/procs for [incr Tcl]
+ *  classes.  This includes things like the "isa" method and "info"
+ *  for querying class info.  Usually invoked by Itcl_Init() when
+ *  [incr Tcl] is first installed into an interpreter.
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_BiInit(interp)
+    Tcl_Interp *interp;      /* current interpreter */
+{
+    int i;
+    Tcl_Namespace *itclBiNs;
+
+    /*
+     *  Declare all of the built-in methods as C procedures.
+     */
+    for (i=0; i < BiMethodListLen; i++) {
+        if (Itcl_RegisterObjC(interp,
+                BiMethodList[i].registration+1, BiMethodList[i].proc,
+                (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK) {
+
+            return TCL_ERROR;
+        }
+    }
+
+    /*
+     *  Create the "::itcl::builtin" namespace for built-in class
+     *  commands.  These commands are imported into each class
+     *  just before the class definition is parsed.
+     */
+    Tcl_CreateObjCommand(interp, "::itcl::builtin::chain", Itcl_BiChainCmd,
+        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
+
+    if (Itcl_CreateEnsemble(interp, "::itcl::builtin::info") != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    if (Itcl_AddEnsemblePart(interp, "::itcl::builtin::info",
+            "class", "",
+            Itcl_BiInfoClassCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL)
+            != TCL_OK ||
+        Itcl_AddEnsemblePart(interp, "::itcl::builtin::info",
+            "inherit", "",
+            Itcl_BiInfoInheritCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL)
+            != TCL_OK ||
+        Itcl_AddEnsemblePart(interp, "::itcl::builtin::info",
+            "heritage", "",
+            Itcl_BiInfoHeritageCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL)
+            != TCL_OK ||
+        Itcl_AddEnsemblePart(interp, "::itcl::builtin::info",
+            "function", "?name? ?-protection? ?-type? ?-name? ?-args? ?-body?",
+            Itcl_BiInfoFunctionCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL)
+            != TCL_OK ||
+        Itcl_AddEnsemblePart(interp, "::itcl::builtin::info",
+            "variable", "?name? ?-protection? ?-type? ?-name? ?-init? ?-value? ?-config?",
+            Itcl_BiInfoVariableCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL)
+            != TCL_OK ||
+        Itcl_AddEnsemblePart(interp, "::itcl::builtin::info",
+            "args", "procname",
+            Itcl_BiInfoArgsCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL)
+            != TCL_OK ||
+        Itcl_AddEnsemblePart(interp, "::itcl::builtin::info",
+            "body", "procname",
+            Itcl_BiInfoBodyCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL)
+            != TCL_OK
+    ) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Add an error handler to support all of the usual inquiries
+     *  for the "info" command in the global namespace.
+     */
+    if (Itcl_AddEnsemblePart(interp, "::itcl::builtin::info",
+            "@error", "",
+            Itcl_DefaultInfoCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL)
+            != TCL_OK
+    ) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Export all commands in the built-in namespace so we can
+     *  import them later on.
+     */
+    itclBiNs = Tcl_FindNamespace(interp, "::itcl::builtin",
+        (Tcl_Namespace*)NULL, TCL_LEAVE_ERR_MSG);
+
+    if (!itclBiNs ||
+        Tcl_Export(interp, itclBiNs, "*", /* resetListFirst */ 1) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_InstallBiMethods()
+ *
+ *  Invoked when a class is first created, just after the class
+ *  definition has been parsed, to add definitions for built-in
+ *  methods to the class.  If a method already exists in the class
+ *  with the same name as the built-in, then the built-in is skipped.
+ *  Otherwise, a method definition for the built-in method is added.
+ *
+ *  Returns TCL_OK if successful, or TCL_ERROR (along with an error
+ *  message in the interpreter) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_InstallBiMethods(interp, cdefn)
+    Tcl_Interp *interp;      /* current interpreter */
+    ItclClass *cdefn;        /* class definition to be updated */
+{
+    int result = TCL_OK;
+    Tcl_HashEntry *entry = NULL;
+
+    int i;
+    ItclHierIter hier;
+    ItclClass *cdPtr;
+
+    /*
+     *  Scan through all of the built-in methods and see if
+     *  that method already exists in the class.  If not, add
+     *  it in.
+     *
+     *  TRICKY NOTE:  The virtual tables haven't been built yet,
+     *    so look for existing methods the hard way--by scanning
+     *    through all classes.
+     */
+    for (i=0; i < BiMethodListLen; i++) {
+        Itcl_InitHierIter(&hier, cdefn);
+        cdPtr = Itcl_AdvanceHierIter(&hier);
+        while (cdPtr) {
+            entry = Tcl_FindHashEntry(&cdPtr->functions, BiMethodList[i].name);
+            if (entry) {
+                break;
+            }
+            cdPtr = Itcl_AdvanceHierIter(&hier);
+        }
+        Itcl_DeleteHierIter(&hier);
+
+        if (!entry) {
+            result = Itcl_CreateMethod(interp, cdefn, BiMethodList[i].name,
+                BiMethodList[i].usage, BiMethodList[i].registration);
+
+            if (result != TCL_OK) {
+                break;
+            }
+        }
+    }
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiIsaCmd()
+ *
+ *  Invoked whenever the user issues the "isa" method for an object.
+ *  Handles the following syntax:
+ *
+ *    <objName> isa <className>
+ *
+ *  Checks to see if the object has the given <className> anywhere
+ *  in its heritage.  Returns 1 if so, and 0 otherwise.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiIsaCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* class definition */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclClass *contextClass, *cdefn;
+    ItclObject *contextObj;
+    char *token;
+
+    /*
+     *  Make sure that this command is being invoked in the proper
+     *  context.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    if (!contextObj) {
+        Tcl_AppendResult(interp,
+            "improper usage: should be \"object isa className\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+    if (objc != 2) {
+        token = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_AppendResult(interp,
+            "wrong # args: should be \"object ", token, " className\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Look for the requested class.  If it is not found, then
+     *  try to autoload it.  If it absolutely cannot be found,
+     *  signal an error.
+     */
+    token = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    cdefn = Itcl_FindClass(interp, token, /* autoload */ 1);
+    if (cdefn == NULL) {
+        return TCL_ERROR;
+    }
+
+    if (Itcl_ObjectIsa(contextObj, cdefn)) {
+        Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
+    } else {
+        Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiConfigureCmd()
+ *
+ *  Invoked whenever the user issues the "configure" method for an object.
+ *  Handles the following syntax:
+ *
+ *    <objName> configure ?-<option>? ?<value> -<option> <value>...?
+ *
+ *  Allows access to public variables as if they were configuration
+ *  options.  With no arguments, this command returns the current
+ *  list of public variable options.  If -<option> is specified,
+ *  this returns the information for just one option:
+ *
+ *    -<optionName> <initVal> <currentVal>
+ *
+ *  Otherwise, the list of arguments is parsed, and values are
+ *  assigned to the various public variable options.  When each
+ *  option changes, a big of "config" code associated with the option
+ *  is executed, to bring the object up to date.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiConfigureCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* class definition */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+
+    int i, result;
+    CONST char *lastval;
+    char *token;
+    ItclClass *cdPtr;
+    Tcl_HashSearch place;
+    Tcl_HashEntry *entry;
+    ItclVarDefn *vdefn;
+    ItclVarLookup *vlookup;
+    ItclMember *member;
+    ItclMemberCode *mcode;
+    ItclHierIter hier;
+    Tcl_Obj *resultPtr, *objPtr;
+    Tcl_DString buffer;
+    ItclContext context;
+    Itcl_CallFrame *oldFramePtr, *uplevelFramePtr;
+
+    /*
+     *  Make sure that this command is being invoked in the proper
+     *  context.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    if (!contextObj) {
+        Tcl_AppendResult(interp,
+            "improper usage: should be ",
+            "\"object configure ?-option? ?value -option value...?\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  BE CAREFUL:  work in the virtual scope!
+     */
+    contextClass = contextObj->classDefn;
+
+    /*
+     *  HANDLE:  configure
+     */
+    if (objc == 1) {
+        resultPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+
+        Itcl_InitHierIter(&hier, contextClass);
+        while ((cdPtr=Itcl_AdvanceHierIter(&hier)) != NULL) {
+            entry = Tcl_FirstHashEntry(&cdPtr->variables, &place);
+            while (entry) {
+                vdefn = (ItclVarDefn*)Tcl_GetHashValue(entry);
+                if (vdefn->member->protection == ITCL_PUBLIC) {
+                    objPtr = ItclReportPublicOpt(interp, vdefn, contextObj);
+
+                    Tcl_ListObjAppendElement((Tcl_Interp*)NULL, resultPtr,
+                        objPtr);
+                }
+                entry = Tcl_NextHashEntry(&place);
+            }
+        }
+        Itcl_DeleteHierIter(&hier);
+
+        Tcl_SetObjResult(interp, resultPtr);
+        return TCL_OK;
+    }
+
+    /*
+     *  HANDLE:  configure -option
+     */
+    else if (objc == 2) {
+        token = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+        if (*token != '-') {
+            Tcl_AppendResult(interp,
+                "improper usage: should be ",
+                "\"object configure ?-option? ?value -option value...?\"",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+
+        vlookup = NULL;
+        entry = Tcl_FindHashEntry(&contextClass->resolveVars, token+1);
+        if (entry) {
+            vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+
+            if (vlookup->vdefn->member->protection != ITCL_PUBLIC) {
+                vlookup = NULL;
+            }
+        }
+
+        if (!vlookup) {
+            Tcl_AppendResult(interp,
+                "unknown option \"", token, "\"",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+
+        resultPtr = ItclReportPublicOpt(interp, vlookup->vdefn, contextObj);
+        Tcl_SetObjResult(interp, resultPtr);
+        return TCL_OK;
+    }
+
+    /*
+     *  HANDLE:  configure -option value -option value...
+     *
+     *  Be careful to work in the virtual scope.  If this "configure"
+     *  method was defined in a base class, the current namespace
+     *  (from Itcl_ExecMethod()) will be that base class.  Activate
+     *  the derived class namespace here, so that instance variables
+     *  are accessed properly.
+     */
+    result = TCL_OK;
+
+    if (Itcl_PushContext(interp, (ItclMember*)NULL, contextObj->classDefn,
+        contextObj, &context) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    Tcl_DStringInit(&buffer);
+
+    for (i=1; i < objc; i+=2) {
+        vlookup = NULL;
+        token = Tcl_GetStringFromObj(objv[i], (int*)NULL);
+        if (*token == '-') {
+            entry = Tcl_FindHashEntry(&contextClass->resolveVars, token+1);
+            if (entry) {
+                vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+            }
+        }
+
+        if (!vlookup || vlookup->vdefn->member->protection != ITCL_PUBLIC) {
+            Tcl_AppendResult(interp,
+                "unknown option \"", token, "\"",
+                (char*)NULL);
+            result = TCL_ERROR;
+            goto configureDone;
+        }
+        if (i == objc-1) {
+            Tcl_AppendResult(interp,
+                "value for \"", token, "\" missing",
+                (char*)NULL);
+            result = TCL_ERROR;
+            goto configureDone;
+        }
+
+        member = vlookup->vdefn->member;
+        lastval = Tcl_GetVar2(interp, member->fullname, (char*)NULL, 0);
+        Tcl_DStringSetLength(&buffer, 0);
+        Tcl_DStringAppend(&buffer, (lastval) ? lastval : "", -1);
+
+        token = Tcl_GetStringFromObj(objv[i+1], (int*)NULL);
+
+        if (Tcl_SetVar2(interp, member->fullname, (char*)NULL, token,
+            TCL_LEAVE_ERR_MSG) == NULL) {
+
+            char msg[256];
+            sprintf(msg, "\n    (error in configuration of public variable \"%.100s\")", member->fullname);
+            Tcl_AddErrorInfo(interp, msg);
+            result = TCL_ERROR;
+            goto configureDone;
+        }
+
+        /*
+         *  If this variable has some "config" code, invoke it now.
+         *
+         *  TRICKY NOTE:  Be careful to evaluate the code one level
+         *    up in the call stack, so that it's executed in the
+         *    calling context, and not in the context that we've
+         *    set up for public variable access.
+         */
+        mcode = member->code;
+        if (mcode && Itcl_IsMemberCodeImplemented(mcode)) {
+
+            uplevelFramePtr = _Tcl_GetCallFrame(interp, 1);
+            oldFramePtr = _Tcl_ActivateCallFrame(interp, uplevelFramePtr);
+
+            result = Itcl_EvalMemberCode(interp, (ItclMemberFunc*)NULL,
+                member, contextObj, 0, (Tcl_Obj**)NULL);
+
+            (void) _Tcl_ActivateCallFrame(interp, oldFramePtr);
+
+            if (result == TCL_OK) {
+                Tcl_ResetResult(interp);
+            } else {
+                char msg[256];
+                sprintf(msg, "\n    (error in configuration of public variable \"%.100s\")", member->fullname);
+                Tcl_AddErrorInfo(interp, msg);
+
+                Tcl_SetVar2(interp, member->fullname,(char*)NULL,
+                    Tcl_DStringValue(&buffer), 0);
+
+                goto configureDone;
+            }
+        }
+    }
+
+configureDone:
+    Itcl_PopContext(interp, &context);
+    Tcl_DStringFree(&buffer);
+
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiCgetCmd()
+ *
+ *  Invoked whenever the user issues the "cget" method for an object.
+ *  Handles the following syntax:
+ *
+ *    <objName> cget -<option>
+ *
+ *  Allows access to public variables as if they were configuration
+ *  options.  Mimics the behavior of the usual "cget" method for
+ *  Tk widgets.  Returns the current value of the public variable
+ *  with name <option>.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiCgetCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* class definition */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+
+    CONST char *name, *val;
+    ItclVarLookup *vlookup;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  Make sure that this command is being invoked in the proper
+     *  context.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (!contextObj || objc != 2) {
+        Tcl_AppendResult(interp,
+            "improper usage: should be \"object cget -option\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  BE CAREFUL:  work in the virtual scope!
+     */
+    contextClass = contextObj->classDefn;
+
+    name = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+
+    vlookup = NULL;
+    entry = Tcl_FindHashEntry(&contextClass->resolveVars, name+1);
+    if (entry) {
+        vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+    }
+
+    if (!vlookup || vlookup->vdefn->member->protection != ITCL_PUBLIC) {
+        Tcl_AppendResult(interp,
+            "unknown option \"", name, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    val = Itcl_GetInstanceVar(interp, vlookup->vdefn->member->fullname,
+        contextObj, contextObj->classDefn);
+
+    if (val) {
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(val, -1));
+    } else {
+        Tcl_SetObjResult(interp, Tcl_NewStringObj("<undefined>", -1));
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclReportPublicOpt()
+ *
+ *  Returns information about a public variable formatted as a
+ *  configuration option:
+ *
+ *    -<varName> <initVal> <currentVal>
+ *
+ *  Used by Itcl_BiConfigureCmd() to report configuration options.
+ *  Returns a Tcl_Obj containing the information.
+ * ------------------------------------------------------------------------
+ */
+static Tcl_Obj*
+ItclReportPublicOpt(interp, vdefn, contextObj)
+    Tcl_Interp *interp;      /* interpreter containing the object */
+    ItclVarDefn *vdefn;      /* public variable to be reported */
+    ItclObject *contextObj;  /* object containing this variable */
+{
+    CONST char *val;
+    ItclClass *cdefnPtr;
+    Tcl_HashEntry *entry;
+    ItclVarLookup *vlookup;
+    Tcl_DString optName;
+    Tcl_Obj *listPtr, *objPtr;
+
+    listPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+
+    /*
+     *  Determine how the option name should be reported.
+     *  If the simple name can be used to find it in the virtual
+     *  data table, then use the simple name.  Otherwise, this
+     *  is a shadowed variable; use the full name.
+     */
+    Tcl_DStringInit(&optName);
+    Tcl_DStringAppend(&optName, "-", -1);
+
+    cdefnPtr = (ItclClass*)contextObj->classDefn;
+    entry = Tcl_FindHashEntry(&cdefnPtr->resolveVars, vdefn->member->fullname);
+    assert(entry != NULL);
+    vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+    Tcl_DStringAppend(&optName, vlookup->leastQualName, -1);
+
+    objPtr = Tcl_NewStringObj(Tcl_DStringValue(&optName), -1);
+    Tcl_ListObjAppendElement((Tcl_Interp*)NULL, listPtr, objPtr);
+    Tcl_DStringFree(&optName);
+
+
+    if (vdefn->init) {
+        objPtr = Tcl_NewStringObj(vdefn->init, -1);
+    } else {
+        objPtr = Tcl_NewStringObj("<undefined>", -1);
+    }
+    Tcl_ListObjAppendElement((Tcl_Interp*)NULL, listPtr, objPtr);
+
+    val = Itcl_GetInstanceVar(interp, vdefn->member->fullname, contextObj,
+        contextObj->classDefn);
+
+    if (val) {
+        objPtr = Tcl_NewStringObj((CONST84 char *)val, -1);
+    } else {
+        objPtr = Tcl_NewStringObj("<undefined>", -1);
+    }
+    Tcl_ListObjAppendElement((Tcl_Interp*)NULL, listPtr, objPtr);
+
+    return listPtr;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiChainCmd()
+ *
+ *  Invoked to handle the "chain" command, to access the version of
+ *  a method or proc that exists in a base class.  Handles the
+ *  following syntax:
+ *
+ *    chain ?<arg> <arg>...?
+ *
+ *  Looks up the inheritance hierarchy for another implementation
+ *  of the method/proc that is currently executing.  If another
+ *  implementation is found, it is invoked with the specified
+ *  <arg> arguments.  If it is not found, this command does nothing.
+ *  This allows a base class method to be called out in a generic way,
+ *  so the code will not have to change if the base class changes.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiChainCmd(dummy, interp, objc, objv)
+    ClientData dummy;        /* not used */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int result = TCL_OK;
+
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+
+    char *cmd, *head;
+    ItclClass *cdefn;
+    ItclHierIter hier;
+    Tcl_HashEntry *entry;
+    ItclMemberFunc *mfunc;
+    Tcl_DString buffer;
+    ItclCallFrame *framePtr;
+    Tcl_Obj *cmdlinePtr, **newobjv;
+
+    /*
+     *  If this command is not invoked within a class namespace,
+     *  signal an error.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        Tcl_ResetResult(interp);
+        Tcl_AppendResult(interp,
+            "cannot chain functions outside of a class context",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Try to get the command name from the current call frame.
+     *  If it cannot be determined, do nothing.  Otherwise, trim
+     *  off any leading path names.
+     */
+    framePtr = (ItclCallFrame*) _Tcl_GetCallFrame(interp, 0);
+    if (!framePtr || !framePtr->objv) {
+        return TCL_OK;
+    }
+    cmd = Tcl_GetStringFromObj(framePtr->objv[0], (int*)NULL);
+    Itcl_ParseNamespPath(cmd, &buffer, &head, &cmd);
+
+    /*
+     *  Look for the specified command in one of the base classes.
+     *  If we have an object context, then start from the most-specific
+     *  class and walk up the hierarchy to the current context.  If
+     *  there is multiple inheritance, having the entire inheritance
+     *  hierarchy will allow us to jump over to another branch of
+     *  the inheritance tree.
+     *
+     *  If there is no object context, just start with the current
+     *  class context.
+     */
+    if (contextObj) {
+        Itcl_InitHierIter(&hier, contextObj->classDefn);
+        while ((cdefn=Itcl_AdvanceHierIter(&hier)) != NULL) {
+            if (cdefn == contextClass) {
+                break;
+            }
+        }
+    }
+    else {
+        Itcl_InitHierIter(&hier, contextClass);
+        Itcl_AdvanceHierIter(&hier);    /* skip the current class */
+    }
+
+    /*
+     *  Now search up the class hierarchy for the next implementation.
+     *  If found, execute it.  Otherwise, do nothing.
+     */
+    while ((cdefn=Itcl_AdvanceHierIter(&hier)) != NULL) {
+        entry = Tcl_FindHashEntry(&cdefn->functions, cmd);
+        if (entry) {
+            mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+
+            /*
+             *  NOTE:  Avoid the usual "virtual" behavior of
+             *         methods by passing the full name as
+             *         the command argument.
+             */
+            cmdlinePtr = Itcl_CreateArgs(interp, mfunc->member->fullname,
+                objc-1, objv+1);
+
+            (void) Tcl_ListObjGetElements((Tcl_Interp*)NULL, cmdlinePtr,
+                &objc, &newobjv);
+
+            result = Itcl_EvalArgs(interp, objc, newobjv);
+
+            Tcl_DecrRefCount(cmdlinePtr);
+            break;
+        }
+    }
+
+    Tcl_DStringFree(&buffer);
+    Itcl_DeleteHierIter(&hier);
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiInfoClassCmd()
+ *
+ *  Returns information regarding the class for an object.  This command
+ *  can be invoked with or without an object context:
+ *
+ *    <objName> info class   <= returns most-specific class name
+ *    info class             <= returns active namespace name
+ *
+ *  Returns a status TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiInfoClassCmd(dummy, interp, objc, objv)
+    ClientData dummy;     /* not used */
+    Tcl_Interp *interp;   /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Tcl_Namespace *activeNs = Tcl_GetCurrentNamespace(interp);
+    Tcl_Namespace *contextNs = NULL;
+
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+
+    char *name;
+
+    if (objc != 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If this command is not invoked within a class namespace,
+     *  signal an error.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+       Tcl_Obj *msg = Tcl_NewStringObj("\nget info like this instead: " \
+               "\n  namespace eval className { info ", -1);
+       Tcl_AppendStringsToObj(msg, Tcl_GetString(objv[0]), "... }", NULL);
+        Tcl_SetObjResult(interp, msg);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If there is an object context, then return the most-specific
+     *  class for the object.  Otherwise, return the class namespace
+     *  name.  Use normal class names when possible.
+     */
+    if (contextObj) {
+        contextNs = contextObj->classDefn->namesp;
+    } else {
+      assert(contextClass != NULL);
+      assert(contextClass->namesp != NULL);
+      contextNs = contextClass->namesp;
+    }
+
+    if (!contextNs) {
+        name = activeNs->fullName;
+    } else if (contextNs->parentPtr == activeNs) {
+        name = contextNs->name;
+    } else {
+        name = contextNs->fullName;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiInfoInheritCmd()
+ *
+ *  Returns the list of base classes for the current class context.
+ *  Returns a status TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiInfoInheritCmd(dummy, interp, objc, objv)
+    ClientData dummy;     /* not used */
+    Tcl_Interp *interp;   /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Tcl_Namespace *activeNs = Tcl_GetCurrentNamespace(interp);
+
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+
+    ItclClass *cdefn;
+    Itcl_ListElem *elem;
+    Tcl_Obj *listPtr, *objPtr;
+
+    if (objc != 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If this command is not invoked within a class namespace,
+     *  signal an error.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        char *name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_ResetResult(interp);
+        Tcl_AppendResult(interp,
+            "\nget info like this instead: ",
+            "\n  namespace eval className { info ", name, "... }",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Return the list of base classes.
+     */
+    listPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+
+    elem = Itcl_FirstListElem(&contextClass->bases);
+    while (elem) {
+        cdefn = (ItclClass*)Itcl_GetListValue(elem);
+        if (cdefn->namesp->parentPtr == activeNs) {
+            objPtr = Tcl_NewStringObj(cdefn->namesp->name, -1);
+        } else {
+            objPtr = Tcl_NewStringObj(cdefn->namesp->fullName, -1);
+        }
+        Tcl_ListObjAppendElement((Tcl_Interp*)NULL, listPtr, objPtr);
+        elem = Itcl_NextListElem(elem);
+    }
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiInfoHeritageCmd()
+ *
+ *  Returns the entire derivation hierarchy for this class, presented
+ *  in the order that classes are traversed for finding data members
+ *  and member functions.
+ *
+ *  Returns a status TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiInfoHeritageCmd(dummy, interp, objc, objv)
+    ClientData dummy;     /* not used */
+    Tcl_Interp *interp;   /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Tcl_Namespace *activeNs = Tcl_GetCurrentNamespace(interp);
+
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+
+    char *name;
+    ItclHierIter hier;
+    Tcl_Obj *listPtr, *objPtr;
+    ItclClass *cdefn;
+
+    if (objc != 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If this command is not invoked within a class namespace,
+     *  signal an error.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_ResetResult(interp);
+        Tcl_AppendResult(interp,
+            "\nget info like this instead: ",
+            "\n  namespace eval className { info ", name, "... }",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Traverse through the derivation hierarchy and return
+     *  base class names.
+     */
+    listPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+
+    Itcl_InitHierIter(&hier, contextClass);
+    while ((cdefn=Itcl_AdvanceHierIter(&hier)) != NULL) {
+        if (cdefn->namesp->parentPtr == activeNs) {
+            objPtr = Tcl_NewStringObj(cdefn->namesp->name, -1);
+        } else {
+            objPtr = Tcl_NewStringObj(cdefn->namesp->fullName, -1);
+        }
+        Tcl_ListObjAppendElement((Tcl_Interp*)NULL, listPtr, objPtr);
+    }
+    Itcl_DeleteHierIter(&hier);
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiInfoFunctionCmd()
+ *
+ *  Returns information regarding class member functions (methods/procs).
+ *  Handles the following syntax:
+ *
+ *    info function ?cmdName? ?-protection? ?-type? ?-name? ?-args? ?-body?
+ *
+ *  If the ?cmdName? is not specified, then a list of all known
+ *  command members is returned.  Otherwise, the information for
+ *  a specific command is returned.  Returns a status TCL_OK/TCL_ERROR
+ *  to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiInfoFunctionCmd(dummy, interp, objc, objv)
+    ClientData dummy;     /* not used */
+    Tcl_Interp *interp;   /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    char *cmdName = NULL;
+    Tcl_Obj *resultPtr = NULL;
+    Tcl_Obj *objPtr = NULL;
+
+    static char *options[] = {
+        "-args", "-body", "-name", "-protection", "-type",
+        (char*)NULL
+    };
+    enum BIfIdx {
+        BIfArgsIdx, BIfBodyIdx, BIfNameIdx, BIfProtectIdx, BIfTypeIdx
+    } *iflist, iflistStorage[5];
+
+    static enum BIfIdx DefInfoFunction[5] = {
+        BIfProtectIdx,
+        BIfTypeIdx,
+        BIfNameIdx,
+        BIfArgsIdx,
+        BIfBodyIdx
+    };
+
+    ItclClass *contextClass, *cdefn;
+    ItclObject *contextObj;
+
+    int i, result;
+    char *name, *val;
+    Tcl_HashSearch place;
+    Tcl_HashEntry *entry;
+    ItclMemberFunc *mfunc;
+    ItclMemberCode *mcode;
+    ItclHierIter hier;
+
+    /*
+     *  If this command is not invoked within a class namespace,
+     *  signal an error.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_ResetResult(interp);
+        Tcl_AppendResult(interp,
+            "\nget info like this instead: ",
+            "\n  namespace eval className { info ", name, "... }",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Process args:
+     *  ?cmdName? ?-protection? ?-type? ?-name? ?-args? ?-body?
+     */
+    objv++;  /* skip over command name */
+    objc--;
+
+    if (objc > 0) {
+        cmdName = Tcl_GetStringFromObj(*objv, (int*)NULL);
+        objc--; objv++;
+    }
+
+    /*
+     *  Return info for a specific command.
+     */
+    if (cmdName) {
+        entry = Tcl_FindHashEntry(&contextClass->resolveCmds, cmdName);
+        if (entry == NULL) {
+            Tcl_AppendResult(interp,
+                "\"", cmdName, "\" isn't a member function in class \"",
+                contextClass->namesp->fullName, "\"",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+
+        mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+        mcode = mfunc->member->code;
+
+        /*
+         *  By default, return everything.
+         */
+        if (objc == 0) {
+            objc = 5;
+            iflist = DefInfoFunction;
+        }
+
+        /*
+         *  Otherwise, scan through all remaining flags and
+         *  figure out what to return.
+         */
+        else {
+            iflist = &iflistStorage[0];
+            for (i=0 ; i < objc; i++) {
+                result = Tcl_GetIndexFromObj(interp, objv[i],
+                    options, "option", 0, (int*)(&iflist[i]));
+                if (result != TCL_OK) {
+                    return TCL_ERROR;
+                }
+            }
+        }
+
+        if (objc > 1) {
+            resultPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+        }
+
+        for (i=0 ; i < objc; i++) {
+            switch (iflist[i]) {
+                case BIfArgsIdx:
+                    if (mcode && mcode->arglist) {
+                        objPtr = Itcl_ArgList(mcode->argcount, mcode->arglist);
+                    }
+                    else if ((mfunc->member->flags & ITCL_ARG_SPEC) != 0) {
+                        objPtr = Itcl_ArgList(mfunc->argcount, mfunc->arglist);
+                    }
+                    else {
+                        objPtr = Tcl_NewStringObj("<undefined>", -1);
+                    }
+                    break;
+
+                case BIfBodyIdx:
+                    if (mcode && Itcl_IsMemberCodeImplemented(mcode)) {
+                        objPtr = mcode->procPtr->bodyPtr;
+                    } else {
+                        objPtr = Tcl_NewStringObj("<undefined>", -1);
+                    }
+                    break;
+
+                case BIfNameIdx:
+                    objPtr = Tcl_NewStringObj(mfunc->member->fullname, -1);
+                    break;
+
+                case BIfProtectIdx:
+                    val = Itcl_ProtectionStr(mfunc->member->protection);
+                    objPtr = Tcl_NewStringObj(val, -1);
+                    break;
+
+                case BIfTypeIdx:
+                    val = ((mfunc->member->flags & ITCL_COMMON) != 0)
+                        ? "proc" : "method";
+                    objPtr = Tcl_NewStringObj(val, -1);
+                    break;
+            }
+
+            if (objc == 1) {
+                resultPtr = objPtr;
+            } else {
+                Tcl_ListObjAppendElement((Tcl_Interp*)NULL, resultPtr, objPtr);
+            }
+        }
+        Tcl_SetObjResult(interp, resultPtr);
+    }
+
+    /*
+     *  Return the list of available commands.
+     */
+    else {
+        resultPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+
+        Itcl_InitHierIter(&hier, contextClass);
+        while ((cdefn=Itcl_AdvanceHierIter(&hier)) != NULL) {
+            entry = Tcl_FirstHashEntry(&cdefn->functions, &place);
+            while (entry) {
+                mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+                objPtr = Tcl_NewStringObj(mfunc->member->fullname, -1);
+                Tcl_ListObjAppendElement((Tcl_Interp*)NULL, resultPtr, objPtr);
+
+                entry = Tcl_NextHashEntry(&place);
+            }
+        }
+        Itcl_DeleteHierIter(&hier);
+
+        Tcl_SetObjResult(interp, resultPtr);
+    }
+    return TCL_OK;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiInfoVariableCmd()
+ *
+ *  Returns information regarding class data members (variables and
+ *  commons).  Handles the following syntax:
+ *
+ *    info variable ?varName? ?-protection? ?-type? ?-name?
+ *        ?-init? ?-config? ?-value?
+ *
+ *  If the ?varName? is not specified, then a list of all known
+ *  data members is returned.  Otherwise, the information for a
+ *  specific member is returned.  Returns a status TCL_OK/TCL_ERROR
+ *  to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiInfoVariableCmd(dummy, interp, objc, objv)
+    ClientData dummy;        /* not used */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    char *varName = NULL;
+    Tcl_Obj *resultPtr = NULL;
+    Tcl_Obj *objPtr = NULL;
+
+    static char *options[] = {
+        "-config", "-init", "-name", "-protection", "-type",
+        "-value", (char*)NULL
+    };
+    enum BIvIdx {
+        BIvConfigIdx, BIvInitIdx, BIvNameIdx, BIvProtectIdx,
+        BIvTypeIdx, BIvValueIdx
+    } *ivlist, ivlistStorage[6];
+
+    static enum BIvIdx DefInfoVariable[5] = {
+        BIvProtectIdx,
+        BIvTypeIdx,
+        BIvNameIdx,
+        BIvInitIdx,
+        BIvValueIdx
+    };
+
+    static enum BIvIdx DefInfoPubVariable[6] = {
+        BIvProtectIdx,
+        BIvTypeIdx,
+        BIvNameIdx,
+        BIvInitIdx,
+        BIvConfigIdx,
+        BIvValueIdx
+    };
+
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+
+    int i, result;
+    CONST char *val, *name;
+    ItclClass *cdefn;
+    Tcl_HashSearch place;
+    Tcl_HashEntry *entry;
+    ItclVarDefn *vdefn;
+    ItclVarLookup *vlookup;
+    ItclMember *member;
+    ItclHierIter hier;
+
+    /*
+     *  If this command is not invoked within a class namespace,
+     *  signal an error.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_ResetResult(interp);
+        Tcl_AppendResult(interp,
+            "\nget info like this instead: ",
+            "\n  namespace eval className { info ", name, "... }",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Process args:
+     *  ?varName? ?-protection? ?-type? ?-name? ?-init? ?-config? ?-value?
+     */
+    objv++;  /* skip over command name */
+    objc--;
+
+    if (objc > 0) {
+        varName = Tcl_GetStringFromObj(*objv, (int*)NULL);
+        objc--; objv++;
+    }
+
+    /*
+     *  Return info for a specific variable.
+     */
+    if (varName) {
+        entry = Tcl_FindHashEntry(&contextClass->resolveVars, varName);
+        if (entry == NULL) {
+            Tcl_AppendResult(interp,
+                "\"", varName, "\" isn't a variable in class \"",
+                contextClass->namesp->fullName, "\"",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+
+        vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+        member = vlookup->vdefn->member;
+
+        /*
+         *  By default, return everything.
+         */
+        if (objc == 0) {
+            if (member->protection == ITCL_PUBLIC &&
+                ((member->flags & ITCL_COMMON) == 0)) {
+                ivlist = DefInfoPubVariable;
+                objc = 6;
+            } else {
+                ivlist = DefInfoVariable;
+                objc = 5;
+            }
+        }
+
+        /*
+         *  Otherwise, scan through all remaining flags and
+         *  figure out what to return.
+         */
+        else {
+            ivlist = &ivlistStorage[0];
+            for (i=0 ; i < objc; i++) {
+                result = Tcl_GetIndexFromObj(interp, objv[i],
+                    options, "option", 0, (int*)(&ivlist[i]));
+                if (result != TCL_OK) {
+                    return TCL_ERROR;
+                }
+            }
+        }
+
+        if (objc > 1) {
+            resultPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+        }
+
+        for (i=0 ; i < objc; i++) {
+            switch (ivlist[i]) {
+                case BIvConfigIdx:
+                    if (member->code && Itcl_IsMemberCodeImplemented(member->code)) {
+                        objPtr = member->code->procPtr->bodyPtr;
+                    } else {
+                        objPtr = Tcl_NewStringObj("", -1);
+                    }
+                    break;
+
+                case BIvInitIdx:
+                    /*
+                     *  If this is the built-in "this" variable, then
+                     *  report the object name as its initialization string.
+                     */
+                    if ((member->flags & ITCL_THIS_VAR) != 0) {
+                        if (contextObj && contextObj->accessCmd) {
+                            objPtr = Tcl_NewStringObj((char*)NULL, 0);
+                            Tcl_GetCommandFullName(
+                                contextObj->classDefn->interp,
+                                contextObj->accessCmd, objPtr);
+                        } else {
+                            objPtr = Tcl_NewStringObj("<objectName>", -1);
+                        }
+                    }
+                    else if (vlookup->vdefn->init) {
+                        objPtr = Tcl_NewStringObj(vlookup->vdefn->init, -1);
+                    }
+                    else {
+                        objPtr = Tcl_NewStringObj("<undefined>", -1);
+                    }
+                    break;
+
+                case BIvNameIdx:
+                    objPtr = Tcl_NewStringObj(member->fullname, -1);
+                    break;
+
+                case BIvProtectIdx:
+                    val = Itcl_ProtectionStr(member->protection);
+                    objPtr = Tcl_NewStringObj((CONST84 char *)val, -1);
+                    break;
+
+                case BIvTypeIdx:
+                    val = ((member->flags & ITCL_COMMON) != 0)
+                        ? "common" : "variable";
+                    objPtr = Tcl_NewStringObj((CONST84 char *)val, -1);
+                    break;
+
+                case BIvValueIdx:
+                    if ((member->flags & ITCL_COMMON) != 0) {
+                        val = Itcl_GetCommonVar(interp, member->fullname,
+                            member->classDefn);
+                    }
+                    else if (contextObj == NULL) {
+                        Tcl_ResetResult(interp);
+                        Tcl_AppendResult(interp,
+                            "cannot access object-specific info ",
+                            "without an object context",
+                            (char*)NULL);
+                        return TCL_ERROR;
+                    }
+                    else {
+                        val = Itcl_GetInstanceVar(interp, member->fullname,
+                            contextObj, member->classDefn);
+                    }
+
+                    if (val == NULL) {
+                        val = "<undefined>";
+                    }
+                    objPtr = Tcl_NewStringObj((CONST84 char *)val, -1);
+                    break;
+            }
+
+            if (objc == 1) {
+                resultPtr = objPtr;
+            } else {
+                Tcl_ListObjAppendElement((Tcl_Interp*)NULL, resultPtr,
+                    objPtr);
+            }
+        }
+        Tcl_SetObjResult(interp, resultPtr);
+    }
+
+    /*
+     *  Return the list of available variables.  Report the built-in
+     *  "this" variable only once, for the most-specific class.
+     */
+    else {
+        resultPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+
+        Itcl_InitHierIter(&hier, contextClass);
+        while ((cdefn=Itcl_AdvanceHierIter(&hier)) != NULL) {
+            entry = Tcl_FirstHashEntry(&cdefn->variables, &place);
+            while (entry) {
+                vdefn = (ItclVarDefn*)Tcl_GetHashValue(entry);
+                if ((vdefn->member->flags & ITCL_THIS_VAR) != 0) {
+                    if (cdefn == contextClass) {
+                        objPtr = Tcl_NewStringObj(vdefn->member->fullname, -1);
+                        Tcl_ListObjAppendElement((Tcl_Interp*)NULL,
+                            resultPtr, objPtr);
+                    }
+                }
+                else {
+                    objPtr = Tcl_NewStringObj(vdefn->member->fullname, -1);
+                    Tcl_ListObjAppendElement((Tcl_Interp*)NULL,
+                        resultPtr, objPtr);
+                }
+                entry = Tcl_NextHashEntry(&place);
+            }
+        }
+        Itcl_DeleteHierIter(&hier);
+
+        Tcl_SetObjResult(interp, resultPtr);
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiInfoBodyCmd()
+ *
+ *  Handles the usual "info body" request, returning the body for a
+ *  specific proc.  Included here for backward compatibility, since
+ *  otherwise Tcl would complain that class procs are not real "procs".
+ *  Returns a status TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiInfoBodyCmd(dummy, interp, objc, objv)
+    ClientData dummy;     /* not used */
+    Tcl_Interp *interp;   /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    char *name;
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+    ItclMemberFunc *mfunc;
+    ItclMemberCode *mcode;
+    Tcl_HashEntry *entry;
+    Tcl_Obj *objPtr;
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "function");
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If this command is not invoked within a class namespace,
+     *  then treat the procedure name as a normal Tcl procedure.
+     */
+    if (!Itcl_IsClassNamespace(Tcl_GetCurrentNamespace(interp))) {
+        Proc *procPtr;
+
+        name = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+        procPtr = TclFindProc((Interp*)interp, name);
+        if (procPtr == NULL) {
+            Tcl_AppendResult(interp,
+                "\"", name, "\" isn't a procedure",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+        Tcl_SetObjResult(interp, procPtr->bodyPtr);
+    }
+
+    /*
+     *  Otherwise, treat the name as a class method/proc.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_ResetResult(interp);
+        Tcl_AppendResult(interp,
+            "\nget info like this instead: ",
+            "\n  namespace eval className { info ", name, "... }",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    name = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    entry = Tcl_FindHashEntry(&contextClass->resolveCmds, name);
+    if (entry == NULL) {
+        Tcl_AppendResult(interp,
+            "\"", name, "\" isn't a procedure",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+    mcode = mfunc->member->code;
+
+    /*
+     *  Return a string describing the implementation.
+     */
+    if (mcode && Itcl_IsMemberCodeImplemented(mcode)) {
+        objPtr = mcode->procPtr->bodyPtr;
+    } else {
+        objPtr = Tcl_NewStringObj("<undefined>", -1);
+    }
+    Tcl_SetObjResult(interp, objPtr);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BiInfoArgsCmd()
+ *
+ *  Handles the usual "info args" request, returning the argument list
+ *  for a specific proc.  Included here for backward compatibility, since
+ *  otherwise Tcl would complain that class procs are not real "procs".
+ *  Returns a status TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BiInfoArgsCmd(dummy, interp, objc, objv)
+    ClientData dummy;     /* not used */
+    Tcl_Interp *interp;   /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    char *name;
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+    ItclMemberFunc *mfunc;
+    ItclMemberCode *mcode;
+    Tcl_HashEntry *entry;
+    Tcl_Obj *objPtr;
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "function");
+        return TCL_ERROR;
+    }
+
+    name = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+
+    /*
+     *  If this command is not invoked within a class namespace,
+     *  then treat the procedure name as a normal Tcl procedure.
+     */
+    if (!Itcl_IsClassNamespace(Tcl_GetCurrentNamespace(interp))) {
+        Proc *procPtr;
+        CompiledLocal *localPtr;
+
+        procPtr = TclFindProc((Interp*)interp, name);
+        if (procPtr == NULL) {
+            Tcl_AppendResult(interp,
+                "\"", name, "\" isn't a procedure",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+
+        objPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+        for (localPtr = procPtr->firstLocalPtr;
+             localPtr != NULL;
+             localPtr = localPtr->nextPtr) {
+            if (TclIsVarArgument(localPtr)) {
+                Tcl_ListObjAppendElement(interp, objPtr,
+                    Tcl_NewStringObj(localPtr->name, -1));
+            }
+        }
+
+        Tcl_SetObjResult(interp, objPtr);
+    }
+
+    /*
+     *  Otherwise, treat the name as a class method/proc.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_ResetResult(interp);
+        Tcl_AppendResult(interp,
+            "\nget info like this instead: ",
+            "\n  namespace eval className { info ", name, "... }",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    entry = Tcl_FindHashEntry(&contextClass->resolveCmds, name);
+    if (entry == NULL) {
+        Tcl_AppendResult(interp,
+            "\"", name, "\" isn't a procedure",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+    mcode = mfunc->member->code;
+
+    /*
+     *  Return a string describing the argument list.
+     */
+    if (mcode && mcode->arglist != NULL) {
+        objPtr = Itcl_ArgList(mcode->argcount, mcode->arglist);
+    }
+    else if ((mfunc->member->flags & ITCL_ARG_SPEC) != 0) {
+        objPtr = Itcl_ArgList(mfunc->argcount, mfunc->arglist);
+    }
+    else {
+        objPtr = Tcl_NewStringObj("<undefined>", -1);
+    }
+    Tcl_SetObjResult(interp, objPtr);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DefaultInfoCmd()
+ *
+ *  Handles any unknown options for the "itcl::builtin::info" command
+ *  by passing requests on to the usual "::info" command.  If the
+ *  option is recognized, then it is handled.  Otherwise, if it is
+ *  still unknown, then an error message is returned with the list
+ *  of possible options.
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_DefaultInfoCmd(dummy, interp, objc, objv)
+    ClientData dummy;     /* not used */
+    Tcl_Interp *interp;   /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int result;
+    char *name;
+    Tcl_Command cmd;
+    Command *cmdPtr;
+    Tcl_Obj *resultPtr;
+
+    /*
+     *  Look for the usual "::info" command, and use it to
+     *  evaluate the unknown option.
+     */
+    cmd = Tcl_FindCommand(interp, "::info", (Tcl_Namespace*)NULL, 0);
+    if (cmd == NULL) {
+        name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_ResetResult(interp);
+
+        resultPtr = Tcl_NewObj();
+        Tcl_AppendStringsToObj(resultPtr,
+            "bad option \"", name, "\" should be one of...\n",
+            (char*)NULL);
+        Itcl_GetEnsembleUsageForObj(interp, objv[0], resultPtr);
+       Tcl_SetObjResult(interp, resultPtr);
+
+        return TCL_ERROR;
+    }
+
+    cmdPtr = (Command*)cmd;
+    result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
+
+    /*
+     *  If the option was not recognized by the usual "info" command,
+     *  then we got a "bad option" error message.  Add the options
+     *  for the current ensemble to the error message.
+     */
+    if (result != TCL_OK &&
+           strncmp(Tcl_GetStringResult(interp),"bad option",10) == 0) {
+        resultPtr = Tcl_NewObj();
+        Tcl_AppendToObj(resultPtr, "\nor", -1);
+        Itcl_GetEnsembleUsageForObj(interp, objv[0], resultPtr);
+       Tcl_SetObjResult(interp, resultPtr);
+    }
+    return result;
+}
diff --git a/8.x/itcl/generic/itcl_class.c b/8.x/itcl/generic/itcl_class.c
new file mode 100644 (file)
index 0000000..42c27c3
--- /dev/null
@@ -0,0 +1,1826 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  These procedures handle class definitions.  Classes are composed of
+ *  data members (public/protected/common) and the member functions
+ *  (methods/procs) that operate on them.  Each class has its own
+ *  namespace which manages the class scope.
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_class.c,v 1.24 2007/08/07 20:05:29 msofer Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ * This structure is a subclass of Tcl_ResolvedVarInfo that contains the
+ * ItclVarLookup info needed at runtime.
+ */
+typedef struct ItclResolvedVarInfo {
+    Tcl_ResolvedVarInfo vinfo;        /* This must be the first element. */
+    ItclVarLookup *vlookup;           /* Pointer to lookup info. */
+} ItclResolvedVarInfo;
+
+/*
+ *  FORWARD DECLARATIONS
+ */
+static void ItclDestroyClass _ANSI_ARGS_((ClientData cdata));
+static void ItclDestroyClassNamesp _ANSI_ARGS_((ClientData cdata));
+static void ItclFreeClass _ANSI_ARGS_((char* cdata));
+
+static Tcl_Var ItclClassRuntimeVarResolver _ANSI_ARGS_((
+    Tcl_Interp *interp, Tcl_ResolvedVarInfo *vinfoPtr));
+
+extern int itclCompatFlags;
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateClass()
+ *
+ *  Creates a namespace and its associated class definition data.
+ *  If a namespace already exists with that name, then this routine
+ *  returns TCL_ERROR, along with an error message in the interp.
+ *  If successful, it returns TCL_OK and a pointer to the new class
+ *  definition.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CreateClass(interp, path, info, rPtr)
+    Tcl_Interp* interp;                /* interpreter that will contain new class */
+    CONST char* path;          /* name of new class */
+    ItclObjectInfo *info;      /* info for all known objects */
+    ItclClass **rPtr;          /* returns: pointer to class definition */
+{
+    char *head, *tail;
+    Tcl_DString buffer;
+    Tcl_Command cmd;
+    Tcl_Namespace *classNs;
+    ItclClass *cdPtr;
+    ItclVarDefn *vdefn;
+    Tcl_HashEntry *entry;
+    int newEntry;
+
+    /*
+     *  Make sure that a class with the given name does not
+     *  already exist in the current namespace context.  If a
+     *  namespace exists, that's okay.  It may have been created
+     *  to contain stubs during a "namespace import" operation.
+     *  We'll just replace the namespace data below with the
+     *  proper class data.
+     */
+    classNs = Tcl_FindNamespace(interp, (CONST84 char *)path,
+           (Tcl_Namespace*)NULL, /* flags */ 0);
+
+    if (classNs != NULL && Itcl_IsClassNamespace(classNs)) {
+        Tcl_AppendResult(interp,
+            "class \"", path, "\" already exists",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Make sure that a command with the given class name does not
+     *  already exist in the current namespace.  This prevents the
+     *  usual Tcl commands from being clobbered when a programmer
+     *  makes a bogus call like "class info".
+     */
+    cmd = Tcl_FindCommand(interp, (CONST84 char *)path,
+           (Tcl_Namespace*)NULL, /* flags */ TCL_NAMESPACE_ONLY);
+
+    if (cmd != NULL && !Itcl_IsStub(cmd)) {
+        Tcl_AppendResult(interp,
+            "command \"", path, "\" already exists",
+            (char*)NULL);
+
+        if (strstr(path,"::") == NULL) {
+            Tcl_AppendResult(interp,
+                " in namespace \"",
+                Tcl_GetCurrentNamespace(interp)->fullName, "\"",
+                (char*)NULL);
+        }
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Make sure that the class name does not have any goofy
+     *  characters:
+     *
+     *    .  =>  reserved for member access like:  class.publicVar
+     */
+    Itcl_ParseNamespPath(path, &buffer, &head, &tail);
+
+    if (strstr(tail,".")) {
+        Tcl_AppendResult(interp,
+            "bad class name \"", tail, "\"",
+            (char*)NULL);
+        Tcl_DStringFree(&buffer);
+        return TCL_ERROR;
+    }
+    Tcl_DStringFree(&buffer);
+
+    /*
+     *  Allocate class definition data.
+     */
+    cdPtr = (ItclClass*)ckalloc(sizeof(ItclClass));
+    cdPtr->name = NULL;
+    cdPtr->fullname = NULL;
+    cdPtr->interp = interp;
+    cdPtr->info = info;  Itcl_PreserveData((ClientData)info);
+    cdPtr->namesp = NULL;
+    cdPtr->accessCmd = NULL;
+
+    Tcl_InitHashTable(&cdPtr->variables, TCL_STRING_KEYS);
+    Tcl_InitHashTable(&cdPtr->functions, TCL_STRING_KEYS);
+
+    cdPtr->numInstanceVars = 0;
+    Tcl_InitHashTable(&cdPtr->resolveVars, TCL_STRING_KEYS);
+    Tcl_InitHashTable(&cdPtr->resolveCmds, TCL_STRING_KEYS);
+
+    Itcl_InitList(&cdPtr->bases);
+    Itcl_InitList(&cdPtr->derived);
+
+    cdPtr->initCode = NULL;
+    cdPtr->unique   = 0;
+    cdPtr->flags    = 0;
+
+    /*
+     *  Initialize the heritage info--each class starts with its
+     *  own class definition in the heritage.  Base classes are
+     *  added to the heritage from the "inherit" statement.
+     */
+    Tcl_InitHashTable(&cdPtr->heritage, TCL_ONE_WORD_KEYS);
+    (void) Tcl_CreateHashEntry(&cdPtr->heritage, (char*)cdPtr, &newEntry);
+
+    /*
+     *  Create a namespace to represent the class.  Add the class
+     *  definition info as client data for the namespace.  If the
+     *  namespace already exists, then replace any existing client
+     *  data with the class data.
+     */
+    Itcl_PreserveData((ClientData)cdPtr);
+
+    if (classNs == NULL) {
+        classNs = Tcl_CreateNamespace(interp, (CONST84 char *)path,
+            (ClientData)cdPtr, ItclDestroyClassNamesp);
+    }
+    else {
+        if (classNs->clientData && classNs->deleteProc) {
+            (*classNs->deleteProc)(classNs->clientData);
+        }
+        classNs->clientData = (ClientData)cdPtr;
+        classNs->deleteProc = ItclDestroyClassNamesp;
+    }
+
+    Itcl_EventuallyFree((ClientData)cdPtr, ItclFreeClass);
+
+    if (classNs == NULL) {
+        Itcl_ReleaseData((ClientData)cdPtr);
+        return TCL_ERROR;
+    }
+
+    cdPtr->namesp = classNs;
+
+    cdPtr->name = (char*)ckalloc((unsigned)(strlen(classNs->name)+1));
+    strcpy(cdPtr->name, classNs->name);
+
+    cdPtr->fullname = (char*)ckalloc((unsigned)(strlen(classNs->fullName)+1));
+    strcpy(cdPtr->fullname, classNs->fullName);
+
+    /*
+     *  Add special name resolution procedures to the class namespace
+     *  so that members are accessed according to the rules for
+     *  [incr Tcl].
+     */
+    Tcl_SetNamespaceResolvers(classNs,
+           (Tcl_ResolveCmdProc*)Itcl_ClassCmdResolver,
+           (Tcl_ResolveVarProc*)Itcl_ClassVarResolver,
+           (Tcl_ResolveCompiledVarProc*)Itcl_ClassCompiledVarResolver);
+
+    /*
+     *  Add the built-in "this" variable to the list of data members.
+     */
+    (void) Itcl_CreateVarDefn(interp, cdPtr, "this",
+        (char*)NULL, (char*)NULL, &vdefn);
+
+    vdefn->member->protection = ITCL_PROTECTED;  /* always "protected" */
+    vdefn->member->flags |= ITCL_THIS_VAR;       /* mark as "this" variable */
+
+    entry = Tcl_CreateHashEntry(&cdPtr->variables, "this", &newEntry);
+    Tcl_SetHashValue(entry, (ClientData)vdefn);
+
+    /*
+     *  Create a command in the current namespace to manage the class:
+     *    <className>
+     *    <className> <objName> ?<constructor-args>?
+     */
+    Itcl_PreserveData((ClientData)cdPtr);
+
+    cdPtr->accessCmd = Tcl_CreateObjCommand(interp,
+        cdPtr->fullname, Itcl_HandleClass,
+        (ClientData)cdPtr, ItclDestroyClass);
+
+    *rPtr = cdPtr;
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteClass()
+ *
+ *  Deletes a class by deleting all derived classes and all objects in
+ *  that class, and finally, by destroying the class namespace.  This
+ *  procedure provides a friendly way of doing this.  If any errors
+ *  are detected along the way, the process is aborted.
+ *
+ *  Returns TCL_OK if successful, or TCL_ERROR (along with an error
+ *  message in the interpreter) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_DeleteClass(interp, cdefnPtr)
+    Tcl_Interp *interp;     /* interpreter managing this class */
+    ItclClass *cdefnPtr;    /* class namespace */
+{
+    ItclClass *cdPtr = NULL;
+
+    Itcl_ListElem *elem;
+    ItclObject *contextObj;
+    Tcl_HashEntry *entry;
+    Tcl_HashSearch place;
+    Tcl_DString buffer;
+
+    /*
+     *  Destroy all derived classes, since these lose their meaning
+     *  when the base class goes away.  If anything goes wrong,
+     *  abort with an error.
+     *
+     *  TRICKY NOTE:  When a derived class is destroyed, it
+     *    automatically deletes itself from the "derived" list.
+     */
+    elem = Itcl_FirstListElem(&cdefnPtr->derived);
+    while (elem) {
+        cdPtr = (ItclClass*)Itcl_GetListValue(elem);
+        elem = Itcl_NextListElem(elem);  /* advance here--elem will go away */
+
+        if (Itcl_DeleteClass(interp, cdPtr) != TCL_OK) {
+            goto deleteClassFail;
+        }
+    }
+
+    /*
+     *  Scan through and find all objects that belong to this class.
+     *  Note that more specialized objects have already been
+     *  destroyed above, when derived classes were destroyed.
+     *  Destroy objects and report any errors.
+     */
+    entry = Tcl_FirstHashEntry(&cdefnPtr->info->objects, &place);
+    while (entry) {
+        contextObj = (ItclObject*)Tcl_GetHashValue(entry);
+
+        if (contextObj->classDefn == cdefnPtr) {
+            if (Itcl_DeleteObject(interp, contextObj) != TCL_OK) {
+                cdPtr = cdefnPtr;
+                goto deleteClassFail;
+            }
+
+           /*
+            * Fix 227804: Whenever an object to delete was found we
+            * have to reset the search to the beginning as the
+            * current entry in the search was deleted and accessing it
+            * is therefore not allowed anymore.
+            */
+
+           entry = Tcl_FirstHashEntry(&cdefnPtr->info->objects, &place);
+           continue;
+        }
+
+        entry = Tcl_NextHashEntry(&place);
+    }
+
+    /*
+     *  Destroy the namespace associated with this class.
+     *
+     *  TRICKY NOTE:
+     *    The cleanup procedure associated with the namespace is
+     *    invoked automatically.  It does all of the same things
+     *    above, but it also disconnects this class from its
+     *    base-class lists, and removes the class access command.
+     */
+    Tcl_DeleteNamespace(cdefnPtr->namesp);
+    return TCL_OK;
+
+deleteClassFail:
+    Tcl_DStringInit(&buffer);
+    Tcl_DStringAppend(&buffer, "\n    (while deleting class \"", -1);
+    Tcl_DStringAppend(&buffer, cdPtr->namesp->fullName, -1);
+    Tcl_DStringAppend(&buffer, "\")", -1);
+    Tcl_AddErrorInfo(interp, Tcl_DStringValue(&buffer));
+    Tcl_DStringFree(&buffer);
+    return TCL_ERROR;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclDestroyClass()
+ *
+ *  Invoked whenever the access command for a class is destroyed.
+ *  Destroys the namespace associated with the class, which also
+ *  destroys all objects in the class and all derived classes.
+ *  Disconnects this class from the "derived" class lists of its
+ *  base classes, and releases any claim to the class definition
+ *  data.  If this is the last use of that data, the class will
+ *  completely vanish at this point.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclDestroyClass(cdata)
+    ClientData cdata;  /* class definition to be destroyed */
+{
+    ItclClass *cdefnPtr = (ItclClass*)cdata;
+    cdefnPtr->accessCmd = NULL;
+
+    Tcl_DeleteNamespace(cdefnPtr->namesp);
+    Itcl_ReleaseData((ClientData)cdefnPtr);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclDestroyClassNamesp()
+ *
+ *  Invoked whenever the namespace associated with a class is destroyed.
+ *  Destroys all objects associated with this class and all derived
+ *  classes.  Disconnects this class from the "derived" class lists
+ *  of its base classes, and removes the class access command.  Releases
+ *  any claim to the class definition data.  If this is the last use
+ *  of that data, the class will completely vanish at this point.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclDestroyClassNamesp(cdata)
+    ClientData cdata;  /* class definition to be destroyed */
+{
+    ItclClass *cdefnPtr = (ItclClass*)cdata;
+    ItclObject *contextObj;
+    Itcl_ListElem *elem, *belem;
+    ItclClass *cdPtr, *basePtr, *derivedPtr;
+    Tcl_HashEntry *entry;
+    Tcl_HashSearch place;
+
+    /*
+     *  Destroy all derived classes, since these lose their meaning
+     *  when the base class goes away.
+     *
+     *  TRICKY NOTE:  When a derived class is destroyed, it
+     *    automatically deletes itself from the "derived" list.
+     */
+    elem = Itcl_FirstListElem(&cdefnPtr->derived);
+    while (elem) {
+        cdPtr = (ItclClass*)Itcl_GetListValue(elem);
+        Tcl_DeleteNamespace(cdPtr->namesp);
+
+       /* As the first namespace is now destroyed we have to get the
+         * new first element of the hash table. We cannot go to the
+         * next element from the current one, because the current one
+         * is deleted. itcl Patch #593112, for Bug #577719.
+        */
+
+        elem = Itcl_FirstListElem(&cdefnPtr->derived);
+    }
+
+    /*
+     *  Scan through and find all objects that belong to this class.
+     *  Destroy them quietly by deleting their access command.
+     */
+    entry = Tcl_FirstHashEntry(&cdefnPtr->info->objects, &place);
+    while (entry) {
+        contextObj = (ItclObject*)Tcl_GetHashValue(entry);
+        if (contextObj->classDefn == cdefnPtr) {
+            Tcl_DeleteCommandFromToken(cdefnPtr->interp, contextObj->accessCmd);
+           /*
+            * Fix 227804: Whenever an object to delete was found we
+            * have to reset the search to the beginning as the
+            * current entry in the search was deleted and accessing it
+            * is therefore not allowed anymore.
+            */
+
+           entry = Tcl_FirstHashEntry(&cdefnPtr->info->objects, &place);
+           continue;
+        }
+        entry = Tcl_NextHashEntry(&place);
+    }
+
+    /*
+     *  Next, remove this class from the "derived" list in
+     *  all base classes.
+     */
+    belem = Itcl_FirstListElem(&cdefnPtr->bases);
+    while (belem) {
+        basePtr = (ItclClass*)Itcl_GetListValue(belem);
+
+        elem = Itcl_FirstListElem(&basePtr->derived);
+        while (elem) {
+            derivedPtr = (ItclClass*)Itcl_GetListValue(elem);
+            if (derivedPtr == cdefnPtr) {
+                Itcl_ReleaseData( Itcl_GetListValue(elem) );
+                elem = Itcl_DeleteListElem(elem);
+            } else {
+                elem = Itcl_NextListElem(elem);
+            }
+        }
+        belem = Itcl_NextListElem(belem);
+    }
+
+    /*
+     *  Next, destroy the access command associated with the class.
+     */
+    if (cdefnPtr->accessCmd) {
+        Command *cmdPtr = (Command*)cdefnPtr->accessCmd;
+
+        cmdPtr->deleteProc = Itcl_ReleaseData;
+        Tcl_DeleteCommandFromToken(cdefnPtr->interp, cdefnPtr->accessCmd);
+    }
+
+    /*
+     *  Release the namespace's claim on the class definition.
+     */
+    Itcl_ReleaseData((ClientData)cdefnPtr);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclFreeClass()
+ *
+ *  Frees all memory associated with a class definition.  This is
+ *  usually invoked automatically by Itcl_ReleaseData(), when class
+ *  data is no longer being used.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclFreeClass(cdata)
+    char *cdata;  /* class definition to be destroyed */
+{
+    ItclClass *cdefnPtr = (ItclClass*)cdata;
+
+    Itcl_ListElem *elem;
+    Tcl_HashSearch place;
+    Tcl_HashEntry *entry;
+    ItclVarDefn *vdefn;
+    ItclVarLookup *vlookup;
+    VarInHash *varPtr;
+
+    /*
+     *  Tear down the list of derived classes.  This list should
+     *  really be empty if everything is working properly, but
+     *  release it here just in case.
+     */
+    elem = Itcl_FirstListElem(&cdefnPtr->derived);
+    while (elem) {
+        Itcl_ReleaseData( Itcl_GetListValue(elem) );
+        elem = Itcl_NextListElem(elem);
+    }
+    Itcl_DeleteList(&cdefnPtr->derived);
+
+    /*
+     *  Tear down the variable resolution table.  Some records
+     *  appear multiple times in the table (for x, foo::x, etc.)
+     *  so each one has a reference count.
+     */
+
+    entry = Tcl_FirstHashEntry(&cdefnPtr->resolveVars, &place);
+    while (entry) {
+        vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+        if (--vlookup->usage == 0) {
+            /*
+             *  If this is a common variable owned by this class,
+             *  then release the class's hold on it.  If it's no
+             *  longer being used, move it into a variable table
+             *  for destruction.
+             */
+            if ( (vlookup->vdefn->member->flags & ITCL_COMMON) != 0 &&
+                 vlookup->vdefn->member->classDefn == cdefnPtr ) {
+                varPtr = (VarInHash*)vlookup->var.common;
+                if (--ItclVarRefCount(varPtr) == 0) {
+                   /*
+                    * This is called after the namespace is already gone: the
+                    * variable is already unset and ready to be freed.
+                    */
+                   
+                   ckfree((char *)varPtr);
+                }
+            }
+            ckfree((char*)vlookup);
+        }
+        entry = Tcl_NextHashEntry(&place);
+    }
+    Tcl_DeleteHashTable(&cdefnPtr->resolveVars);
+
+    /*
+     *  Tear down the virtual method table...
+     */
+    Tcl_DeleteHashTable(&cdefnPtr->resolveCmds);
+
+    /*
+     *  Delete all variable definitions.
+     */
+    entry = Tcl_FirstHashEntry(&cdefnPtr->variables, &place);
+    while (entry) {
+        vdefn = (ItclVarDefn*)Tcl_GetHashValue(entry);
+        Itcl_DeleteVarDefn(vdefn);
+        entry = Tcl_NextHashEntry(&place);
+    }
+    Tcl_DeleteHashTable(&cdefnPtr->variables);
+
+    /*
+     *  Delete all function definitions.
+     */
+    entry = Tcl_FirstHashEntry(&cdefnPtr->functions, &place);
+    while (entry) {
+        Itcl_ReleaseData( Tcl_GetHashValue(entry) );
+        entry = Tcl_NextHashEntry(&place);
+    }
+    Tcl_DeleteHashTable(&cdefnPtr->functions);
+
+    /*
+     *  Release the claim on all base classes.
+     */
+    elem = Itcl_FirstListElem(&cdefnPtr->bases);
+    while (elem) {
+        Itcl_ReleaseData( Itcl_GetListValue(elem) );
+        elem = Itcl_NextListElem(elem);
+    }
+    Itcl_DeleteList(&cdefnPtr->bases);
+    Tcl_DeleteHashTable(&cdefnPtr->heritage);
+
+    /*
+     *  Free up the object initialization code.
+     */
+    if (cdefnPtr->initCode) {
+        Tcl_DecrRefCount(cdefnPtr->initCode);
+    }
+
+    Itcl_ReleaseData((ClientData)cdefnPtr->info);
+
+    ckfree(cdefnPtr->name);
+    ckfree(cdefnPtr->fullname);
+
+    ckfree((char*)cdefnPtr);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_IsClassNamespace()
+ *
+ *  Checks to see whether or not the given namespace represents an
+ *  [incr Tcl] class.  Returns non-zero if so, and zero otherwise.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_IsClassNamespace(namesp)
+    Tcl_Namespace *namesp;  /* namespace being tested */
+{
+    Namespace *nsPtr = (Namespace*)namesp;
+
+    if (nsPtr != NULL) {
+        return (nsPtr->deleteProc == ItclDestroyClassNamesp);
+    }
+    return 0;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_IsClass()
+ *
+ *  Checks the given Tcl command to see if it represents an itcl class.
+ *  Returns non-zero if the command is associated with a class.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_IsClass(cmd)
+    Tcl_Command cmd;         /* command being tested */
+{
+    Command *cmdPtr = (Command*)cmd;
+
+    if (cmdPtr->deleteProc == ItclDestroyClass) {
+        return 1;
+    }
+
+    /*
+     *  This may be an imported command.  Try to get the real
+     *  command and see if it represents a class.
+     */
+    cmdPtr = (Command*)TclGetOriginalCommand(cmd);
+    if (cmdPtr && cmdPtr->deleteProc == ItclDestroyClass) {
+        return 1;
+    }
+    return 0;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_FindClass()
+ *
+ *  Searches for the specified class in the active namespace.  If the
+ *  class is found, this procedure returns a pointer to the class
+ *  definition.  Otherwise, if the autoload flag is non-zero, an
+ *  attempt will be made to autoload the class definition.  If it
+ *  still can't be found, this procedure returns NULL, along with an
+ *  error message in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+ItclClass*
+Itcl_FindClass(interp, path, autoload)
+    Tcl_Interp* interp;                /* interpreter containing class */
+    CONST char* path;          /* path name for class */
+    int autoload;              /* should class be loaded */
+{
+    Tcl_Namespace* classNs;
+
+    /*
+     *  Search for a namespace with the specified name, and if
+     *  one is found, see if it is a class namespace.
+     */
+    classNs = Itcl_FindClassNamespace(interp, path);
+
+    if (classNs && Itcl_IsClassNamespace(classNs)) {
+        return (ItclClass*)classNs->clientData;
+    }
+
+    /*
+     *  If the autoload flag is set, try to autoload the class
+     *  definition.
+     */
+    if (autoload) {
+        if (Tcl_VarEval(interp, "::auto_load ", path, (char*)NULL) != TCL_OK) {
+            char msg[256];
+            sprintf(msg, "\n    (while attempting to autoload class \"%.200s\")", path);
+            Tcl_AddErrorInfo(interp, msg);
+            return NULL;
+        }
+        Tcl_ResetResult(interp);
+
+        classNs = Itcl_FindClassNamespace(interp, path);
+        if (classNs && Itcl_IsClassNamespace(classNs)) {
+            return (ItclClass*)classNs->clientData;
+        }
+    }
+
+    Tcl_AppendResult(interp, "class \"", path, "\" not found in context \"",
+        Tcl_GetCurrentNamespace(interp)->fullName, "\"",
+        (char*)NULL);
+
+    return NULL;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_FindClassNamespace()
+ *
+ *  Searches for the specified class namespace.  The normal Tcl procedure
+ *  Tcl_FindNamespace also searches for namespaces, but only in the
+ *  current namespace context.  This makes it hard to find one class
+ *  from within another.  For example, suppose. you have two namespaces
+ *  Foo and Bar.  If you're in the context of Foo and you look for
+ *  Bar, you won't find it with Tcl_FindNamespace.  This behavior is
+ *  okay for namespaces, but wrong for classes.
+ *
+ *  This procedure search for a class namespace.  If the name is
+ *  absolute (i.e., starts with "::"), then that one name is checked,
+ *  and the class is either found or not.  But if the name is relative,
+ *  it is sought in the current namespace context and in the global
+ *  context, just like the normal command lookup.
+ *
+ *  This procedure returns a pointer to the desired namespace, or
+ *  NULL if the namespace was not found.
+ * ------------------------------------------------------------------------
+ */
+Tcl_Namespace*
+Itcl_FindClassNamespace(interp, path)
+    Tcl_Interp* interp;        /* interpreter containing class */
+    CONST char* path;                /* path name for class */
+{
+    Tcl_Namespace* contextNs = Tcl_GetCurrentNamespace(interp);
+    Tcl_Namespace* classNs;
+    Tcl_DString buffer;
+
+    /*
+     *  Look up the namespace.  If the name is not absolute, then
+     *  see if it's the current namespace, and try the global
+     *  namespace as well.
+     */
+    classNs = Tcl_FindNamespace(interp, (CONST84 char *)path,
+           (Tcl_Namespace*)NULL, /* flags */ 0);
+
+    if ( !classNs && contextNs->parentPtr != NULL &&
+         !(*path == ':' && *(path+1) == ':') ) {
+
+        if (strcmp(contextNs->name, path) == 0) {
+            classNs = contextNs;
+        }
+        else {
+            Tcl_DStringInit(&buffer);
+            Tcl_DStringAppend(&buffer, "::", -1);
+            Tcl_DStringAppend(&buffer, path, -1);
+
+            classNs = Tcl_FindNamespace(interp, Tcl_DStringValue(&buffer),
+                (Tcl_Namespace*)NULL, /* flags */ 0);
+
+            Tcl_DStringFree(&buffer);
+        }
+    }
+    return classNs;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_HandleClass()
+ *
+ *  Invoked by Tcl whenever the user issues the command associated with
+ *  a class name.  Handles the following syntax:
+ *
+ *    <className>
+ *    <className> <objName> ?<args>...?
+ *
+ *  Without any arguments, the command does nothing.  In the olden days,
+ *  this allowed the class name to be invoked by itself to prompt the
+ *  autoloader to load the class definition.  Today, this behavior is
+ *  retained for backward compatibility with old releases.
+ *
+ *  If arguments are specified, then this procedure creates a new
+ *  object named <objName> in the appropriate class.  Note that if
+ *  <objName> contains "#auto", that part is automatically replaced
+ *  by a unique string built from the class name.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_HandleClass(clientData, interp, objc, objv)
+    ClientData clientData;   /* class definition */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclClass *cdefnPtr = (ItclClass*)clientData;
+    int result = TCL_OK;
+
+    Tcl_DString buffer;  /* buffer used to build object names */
+    char *token, *objName, *match;
+
+    ItclObject *newObj;
+    Itcl_CallFrame frame;
+
+    /*
+     *  If the command is invoked without an object name, then do nothing.
+     *  This used to support autoloading--that the class name could be
+     *  invoked as a command by itself, prompting the autoloader to
+     *  load the class definition.  We retain the behavior here for
+     *  backward-compatibility with earlier releases.
+     */
+    if (objc == 1) {
+        return TCL_OK;
+    }
+
+    /*
+     *  If the object name is "::", and if this is an old-style class
+     *  definition, then treat the remaining arguments as a command
+     *  in the class namespace.  This used to be the way of invoking
+     *  a class proc, but the new syntax is "class::proc" (without
+     *  spaces).
+     */
+    token = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    if ((*token == ':') && (strcmp(token,"::") == 0) && (objc > 2)) {
+        if ((cdefnPtr->flags & ITCL_OLD_STYLE) != 0) {
+
+            result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) &frame,
+                 cdefnPtr->namesp, /* isProcCallFrame */ 0);
+
+            if (result != TCL_OK) {
+                return result;
+            }
+            result = Itcl_EvalArgs(interp, objc-2, objv+2);
+
+            Tcl_PopCallFrame(interp);
+            return result;
+        }
+
+        /*
+         *  If this is not an old-style class, then return an error
+         *  describing the syntax change.
+         */
+        Tcl_AppendResult(interp,
+            "syntax \"class :: proc\" is an anachronism\n",
+            "[incr Tcl] no longer supports this syntax.\n",
+            "Instead, remove the spaces from your procedure invocations:\n",
+            "  ",
+            Tcl_GetStringFromObj(objv[0], (int*)NULL), "::",
+            Tcl_GetStringFromObj(objv[2], (int*)NULL), " ?args?",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Otherwise, we have a proper object name.  Create a new instance
+     *  with that name.  If the name contains "#auto", replace this with
+     *  a uniquely generated string based on the class name.
+     */
+    Tcl_DStringInit(&buffer);
+    objName = token;
+    match = strstr(token, "#auto");
+    if (match != NULL) {
+       int len;
+       char unique[TCL_INTEGER_SPACE]; /* for unique part of object names */
+       Tcl_CmdInfo dummy;
+       Tcl_UniChar ch;
+
+       Tcl_DStringAppend(&buffer, token, (match - token));
+
+       /*
+        * Only lowercase the first char of $class, per itcl #auto semantics
+        */
+       len = Tcl_UtfToUniChar(cdefnPtr->name, &ch);
+       ch = Tcl_UniCharToLower(ch);
+       Tcl_UniCharToUtfDString(&ch, 1, &buffer);
+       Tcl_DStringAppend(&buffer, cdefnPtr->name + len, -1);
+
+       /*
+        *  Substitute a unique part in for "#auto", and keep
+        *  incrementing a counter until a valid name is found.
+        */
+       len = Tcl_DStringLength(&buffer);
+       do {
+           sprintf(unique, "%d", cdefnPtr->unique++);
+
+           Tcl_DStringTrunc(&buffer, len);
+           Tcl_DStringAppend(&buffer, unique, -1);
+           Tcl_DStringAppend(&buffer, match+5, -1);
+
+           objName = Tcl_DStringValue(&buffer);
+
+           /*
+            * [Fix 227811] Check for any command with the given name, not
+            * only objects.
+            */
+
+           if (Tcl_GetCommandInfo (interp, objName, &dummy) == 0) {
+               break;  /* if an error is found, bail out! */
+           }
+       } while (1);
+    }
+
+    /*
+     *  Try to create a new object.  If successful, return the
+     *  object name as the result of this command.
+     */
+    result = Itcl_CreateObject(interp, objName, cdefnPtr,
+        objc-2, objv+2, &newObj);
+
+    if (result == TCL_OK) {
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(objName, -1));
+    }
+
+    Tcl_DStringFree(&buffer);
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassCmdResolver()
+ *
+ *  Used by the class namespaces to handle name resolution for all
+ *  commands.  This procedure looks for references to class methods
+ *  and procs, and returns TCL_OK along with the appropriate Tcl
+ *  command in the rPtr argument.  If a particular command is private,
+ *  this procedure returns TCL_ERROR and access to the command is
+ *  denied.  If a command is not recognized, this procedure returns
+ *  TCL_CONTINUE, and lookup continues via the normal Tcl name
+ *  resolution rules.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassCmdResolver(interp, name, context, flags, rPtr)
+    Tcl_Interp *interp;                /* current interpreter */
+    CONST char* name;          /* name of the command being accessed */
+    Tcl_Namespace *context;    /* namespace performing the resolution */
+    int flags;                 /* TCL_LEAVE_ERR_MSG => leave error messages
+                                *   in interp if anything goes wrong */
+    Tcl_Command *rPtr;         /* returns: resolved command */
+{
+    ItclClass *cdefn = (ItclClass*)context->clientData;
+
+    Tcl_HashEntry *entry;
+    ItclMemberFunc *mfunc;
+    Command *cmdPtr;
+    int isCmdDeleted;
+
+    /*
+     *  If the command is a member function, and if it is
+     *  accessible, return its Tcl command handle.
+     */
+    entry = Tcl_FindHashEntry(&cdefn->resolveCmds, name);
+    if (!entry) {
+        return TCL_CONTINUE;
+    }
+
+    mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+
+
+    /*
+     *  For protected/private functions, figure out whether or
+     *  not the function is accessible from the current context.
+     *
+     *  TRICKY NOTE:  Use Itcl_GetTrueNamespace to determine
+     *    the current context.  If the current call frame is
+     *    "transparent", this handles it properly.
+     */
+    if (mfunc->member->protection != ITCL_PUBLIC) {
+        context = Itcl_GetTrueNamespace(interp, cdefn->info);
+
+        if (!Itcl_CanAccessFunc(mfunc, context)) {
+
+            if ((flags & TCL_LEAVE_ERR_MSG) != 0) {
+                Tcl_AppendResult(interp,
+                    "can't access \"", name, "\": ",
+                    Itcl_ProtectionStr(mfunc->member->protection),
+                    " variable",
+                    (char*)NULL);
+            }
+            return TCL_ERROR;
+        }
+    }
+
+    /*
+     *  Looks like we found an accessible member function.
+     *
+     *  TRICKY NOTE:  Check to make sure that the command handle
+     *    is still valid.  If someone has deleted or renamed the
+     *    command, it may not be.  This is just the time to catch
+     *    it--as it is being resolved again by the compiler.
+     */
+    cmdPtr = (Command*)mfunc->accessCmd;
+    
+    /*
+     * The following #if is needed so itcl can be compiled with
+     * all versions of Tcl.  The integer "deleted" was renamed to
+     * "flags" in tcl8.4a2.  This #if is also found in itcl_ensemble.c .
+     * We're using a runtime check with itclCompatFlags to adjust for
+     * the behavior of this change, too.
+     *
+     */
+#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 4)
+#   define CMD_IS_DELETED 0x1  /* If someone ever changes this from tcl.h,
+                               * we must change our logic here, too */
+       isCmdDeleted = (!cmdPtr ||
+               (itclCompatFlags & ITCL_COMPAT_USECMDFLAGS ?
+               (cmdPtr->deleted & CMD_IS_DELETED) :
+               cmdPtr->deleted));
+#else
+       isCmdDeleted = (!cmdPtr ||
+               (itclCompatFlags & ITCL_COMPAT_USECMDFLAGS ?
+               (cmdPtr->flags & CMD_IS_DELETED) :
+               cmdPtr->flags));
+#endif
+
+    if (isCmdDeleted) {
+       mfunc->accessCmd = NULL;
+
+       if ((flags & TCL_LEAVE_ERR_MSG) != 0) {
+           Tcl_AppendResult(interp,
+               "can't access \"", name, "\": deleted or redefined\n",
+               "(use the \"body\" command to redefine methods/procs)",
+               (char*)NULL);
+       }
+       return TCL_ERROR;   /* disallow access! */
+    }
+
+    *rPtr = mfunc->accessCmd;
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassVarResolver()
+ *
+ *  Used by the class namespaces to handle name resolution for runtime
+ *  variable accesses.  This procedure looks for references to both
+ *  common variables and instance variables at runtime.  It is used as
+ *  a second line of defense, to handle references that could not be
+ *  resolved as compiled locals.
+ *
+ *  If a variable is found, this procedure returns TCL_OK along with
+ *  the appropriate Tcl variable in the rPtr argument.  If a particular
+ *  variable is private, this procedure returns TCL_ERROR and access
+ *  to the variable is denied.  If a variable is not recognized, this
+ *  procedure returns TCL_CONTINUE, and lookup continues via the normal
+ *  Tcl name resolution rules.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassVarResolver(interp, name, context, flags, rPtr)
+    Tcl_Interp *interp;       /* current interpreter */
+    CONST char* name;        /* name of the variable being accessed */
+    Tcl_Namespace *context;   /* namespace performing the resolution */
+    int flags;                /* TCL_LEAVE_ERR_MSG => leave error messages
+                               *   in interp if anything goes wrong */
+    Tcl_Var *rPtr;            /* returns: resolved variable */
+{
+    Interp *iPtr = (Interp *) interp;
+    ItclCallFrame *varFramePtr = (ItclCallFrame *) iPtr->varFramePtr;
+
+    ItclClass *cdefn = (ItclClass*)context->clientData;
+    ItclObject *contextObj;
+    Itcl_CallFrame *framePtr;
+    Tcl_HashEntry *entry;
+    ItclVarLookup *vlookup;
+
+    assert(Itcl_IsClassNamespace(context));
+
+    /*
+     *  If this is a global variable, handle it in the usual
+     *  Tcl manner.
+     */
+    if (flags & TCL_GLOBAL_ONLY) {
+        return TCL_CONTINUE;
+    }
+
+    /*
+     *  See if this is a formal parameter in the current proc scope.
+     *  If so, that variable has precedence.  Look it up and return
+     *  it here.  This duplicates some of the functionality of
+     *  TclLookupVar, but we return it here (instead of returning
+     *  TCL_CONTINUE) to avoid looking it up again later.
+     */
+    if (varFramePtr && varFramePtr->isProcCallFrame
+        && strstr(name,"::") == NULL) {
+
+        Proc *procPtr = varFramePtr->procPtr;
+
+        /*
+         *  Search through compiled locals first...
+         */
+        if (procPtr) {
+            int localCt = procPtr->numCompiledLocals;
+            CompiledLocal *localPtr = procPtr->firstLocalPtr;
+            Var *localVarPtr = varFramePtr->compiledLocals;
+            int nameLen = strlen(name);
+            int i;
+
+            for (i=0; i < localCt; i++) {
+                if (!TclIsVarTemporary(localPtr)) {
+                    register char *localName = localPtr->name;
+                    if ((name[0] == localName[0])
+                            && (nameLen == localPtr->nameLength)
+                            && (strcmp(name, localName) == 0)) {
+                        *rPtr = (Tcl_Var)localVarPtr;
+                        return TCL_OK;
+                    }
+                }
+                ItclNextLocal(localVarPtr);
+                localPtr = localPtr->nextPtr;
+            }
+        }
+
+        /*
+         *  If it's not a compiled local, then look in the frame's
+         *  var hash table next.  This variable may have been
+         *  created on the fly.
+         */
+        if (varFramePtr->varTablePtr != NULL) {
+           *rPtr = (Tcl_Var) ItclVarHashFindVar(varFramePtr->varTablePtr, name);
+           if (*rPtr) {
+                return TCL_OK;
+            }
+        }
+    }
+
+    /*
+     *  See if the variable is a known data member and accessible.
+     */
+    entry = Tcl_FindHashEntry(&cdefn->resolveVars, name);
+    if (entry == NULL) {
+        return TCL_CONTINUE;
+    }
+
+    vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+    if (!vlookup->accessible) {
+        return TCL_CONTINUE;
+    }
+
+    /*
+     * If this is a common data member, then its variable
+     * is easy to find.  Return it directly.
+     */
+    if ((vlookup->vdefn->member->flags & ITCL_COMMON) != 0) {
+        *rPtr = vlookup->var.common;
+        return TCL_OK;
+    }
+
+    /*
+     *  If this is an instance variable, then we have to
+     *  find the object context, then index into its data
+     *  array to get the actual variable.
+     */
+    framePtr = _Tcl_GetCallFrame(interp, 0);
+
+    entry = Tcl_FindHashEntry(&cdefn->info->contextFrames, (char*)framePtr);
+    if (entry == NULL) {
+        return TCL_CONTINUE;
+    }
+    contextObj = (ItclObject*)Tcl_GetHashValue(entry);
+
+    /*
+     *  TRICKY NOTE:  We've resolved the variable in the current
+     *    class context, but we must also be careful to get its
+     *    index from the most-specific class context.  Variables
+     *    are arranged differently depending on which class
+     *    constructed the object.
+     */
+    if (contextObj->classDefn != vlookup->vdefn->member->classDefn) {
+        entry = Tcl_FindHashEntry(&contextObj->classDefn->resolveVars,
+            vlookup->vdefn->member->fullname);
+
+        if (entry) {
+            vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+        }
+    }
+    *rPtr = (Tcl_Var)contextObj->data[vlookup->var.index];
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassCompiledVarResolver()
+ *
+ *  Used by the class namespaces to handle name resolution for compile
+ *  time variable accesses.  This procedure looks for references to
+ *  both common variables and instance variables at compile time.  If
+ *  the variables are found, they are characterized in a generic way
+ *  by their ItclVarLookup record.  At runtime, Tcl constructs the
+ *  compiled local variables by calling ItclClassRuntimeVarResolver.
+ *
+ *  If a variable is found, this procedure returns TCL_OK along with
+ *  information about the variable in the rPtr argument.  If a particular
+ *  variable is private, this procedure returns TCL_ERROR and access
+ *  to the variable is denied.  If a variable is not recognized, this
+ *  procedure returns TCL_CONTINUE, and lookup continues via the normal
+ *  Tcl name resolution rules.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassCompiledVarResolver(interp, name, length, context, rPtr)
+    Tcl_Interp *interp;         /* current interpreter */
+    CONST char* name;                 /* name of the variable being accessed */
+    int length;                 /* number of characters in name */
+    Tcl_Namespace *context;     /* namespace performing the resolution */
+    Tcl_ResolvedVarInfo **rPtr; /* returns: info that makes it possible to
+                                 *   resolve the variable at runtime */
+{
+    ItclClass *cdefn = (ItclClass*)context->clientData;
+    Tcl_HashEntry *entry;
+    ItclVarLookup *vlookup;
+    char *buffer, storage[64];
+
+    assert(Itcl_IsClassNamespace(context));
+
+    /*
+     *  Copy the name to local storage so we can NULL terminate it.
+     *  If the name is long, allocate extra space for it.
+     */
+    if (length < sizeof(storage)) {
+        buffer = storage;
+    } else {
+        buffer = (char*)ckalloc((unsigned)(length+1));
+    }
+    memcpy((void*)buffer, (void*)name, (size_t)length);
+    buffer[length] = '\0';
+
+    entry = Tcl_FindHashEntry(&cdefn->resolveVars, buffer);
+
+    if (buffer != storage) {
+        ckfree(buffer);
+    }
+
+    /*
+     *  If the name is not found, or if it is inaccessible,
+     *  continue on with the normal Tcl name resolution rules.
+     */
+    if (entry == NULL) {
+        return TCL_CONTINUE;
+    }
+
+    vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+    if (!vlookup->accessible) {
+        return TCL_CONTINUE;
+    }
+
+    /*
+     *  Return the ItclVarLookup record.  At runtime, Tcl will
+     *  call ItclClassRuntimeVarResolver with this record, to
+     *  plug in the appropriate variable for the current object
+     *  context.
+     */
+    (*rPtr) = (Tcl_ResolvedVarInfo *) ckalloc(sizeof(ItclResolvedVarInfo));
+    (*rPtr)->fetchProc = ItclClassRuntimeVarResolver;
+    (*rPtr)->deleteProc = NULL;
+    ((ItclResolvedVarInfo*)(*rPtr))->vlookup = vlookup;
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclClassRuntimeVarResolver()
+ *
+ *  Invoked when Tcl sets up the call frame for an [incr Tcl] method/proc
+ *  at runtime.  Resolves data members identified earlier by
+ *  Itcl_ClassCompiledVarResolver.  Returns the Tcl_Var representation
+ *  for the data member.
+ * ------------------------------------------------------------------------
+ */
+static Tcl_Var
+ItclClassRuntimeVarResolver(interp, resVarInfo)
+    Tcl_Interp *interp;               /* current interpreter */
+    Tcl_ResolvedVarInfo *resVarInfo;  /* contains ItclVarLookup rep
+                                       * for variable */
+{
+    ItclVarLookup *vlookup = ((ItclResolvedVarInfo*)resVarInfo)->vlookup;
+
+    Itcl_CallFrame *framePtr;
+    ItclClass *cdefn;
+    ItclObject *contextObj;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  If this is a common data member, then the associated
+     *  variable is known directly.
+     */
+    if ((vlookup->vdefn->member->flags & ITCL_COMMON) != 0) {
+        return vlookup->var.common;
+    }
+    cdefn = vlookup->vdefn->member->classDefn;
+
+    /*
+     *  Otherwise, get the current object context and find the
+     *  variable in its data table.
+     *
+     *  TRICKY NOTE:  Get the index for this variable using the
+     *    virtual table for the MOST-SPECIFIC class.
+     */
+    framePtr = _Tcl_GetCallFrame(interp, 0);
+
+    entry = Tcl_FindHashEntry(&cdefn->info->contextFrames, (char*)framePtr);
+    if (entry) {
+        contextObj = (ItclObject*)Tcl_GetHashValue(entry);
+
+        if (contextObj != NULL) {
+            if (contextObj->classDefn != vlookup->vdefn->member->classDefn) {
+                entry = Tcl_FindHashEntry(&contextObj->classDefn->resolveVars,
+                    vlookup->vdefn->member->fullname);
+
+                if (entry) {
+                    vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+                }
+            }
+            return (Tcl_Var)contextObj->data[vlookup->var.index];
+        }
+    }
+    return NULL;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BuildVirtualTables()
+ *
+ *  Invoked whenever the class heritage changes or members are added or
+ *  removed from a class definition to rebuild the member lookup
+ *  tables.  There are two tables:
+ *
+ *  METHODS:  resolveCmds
+ *    Used primarily in Itcl_ClassCmdResolver() to resolve all
+ *    command references in a namespace.
+ *
+ *  DATA MEMBERS:  resolveVars
+ *    Used primarily in Itcl_ClassVarResolver() to quickly resolve
+ *    variable references in each class scope.
+ *
+ *  These tables store every possible name for each command/variable
+ *  (member, class::member, namesp::class::member, etc.).  Members
+ *  in a derived class may shadow members with the same name in a
+ *  base class.  In that case, the simple name in the resolution
+ *  table will point to the most-specific member.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_BuildVirtualTables(cdefnPtr)
+    ItclClass* cdefnPtr;       /* class definition being updated */
+{
+    Tcl_HashEntry *entry;
+    Tcl_HashSearch place;
+    ItclVarLookup *vlookup;
+    ItclVarDefn *vdefn;
+    ItclMemberFunc *mfunc;
+    ItclHierIter hier;
+    ItclClass *cdPtr;
+    Namespace* nsPtr;
+    Tcl_DString buffer, buffer2;
+    int newEntry;
+
+    Tcl_DStringInit(&buffer);
+    Tcl_DStringInit(&buffer2);
+
+    /*
+     *  Clear the variable resolution table.
+     */
+    entry = Tcl_FirstHashEntry(&cdefnPtr->resolveVars, &place);
+    while (entry) {
+        vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+        if (--vlookup->usage == 0) {
+            ckfree((char*)vlookup);
+        }
+        entry = Tcl_NextHashEntry(&place);
+    }
+    Tcl_DeleteHashTable(&cdefnPtr->resolveVars);
+    Tcl_InitHashTable(&cdefnPtr->resolveVars, TCL_STRING_KEYS);
+    cdefnPtr->numInstanceVars = 0;
+
+    /*
+     *  Set aside the first object-specific slot for the built-in
+     *  "this" variable.  Only allocate one of these, even though
+     *  there is a definition for "this" in each class scope.
+     */
+    cdefnPtr->numInstanceVars++;
+
+    /*
+     *  Scan through all classes in the hierarchy, from most to
+     *  least specific.  Add a lookup entry for each variable
+     *  into the table.
+     */
+    Itcl_InitHierIter(&hier, cdefnPtr);
+    cdPtr = Itcl_AdvanceHierIter(&hier);
+    while (cdPtr != NULL) {
+        entry = Tcl_FirstHashEntry(&cdPtr->variables, &place);
+        while (entry) {
+            vdefn = (ItclVarDefn*)Tcl_GetHashValue(entry);
+
+            vlookup = (ItclVarLookup*)ckalloc(sizeof(ItclVarLookup));
+            vlookup->vdefn = vdefn;
+            vlookup->usage = 0;
+            vlookup->leastQualName = NULL;
+
+            /*
+             *  If this variable is PRIVATE to another class scope,
+             *  then mark it as "inaccessible".
+             */
+            vlookup->accessible =
+                ( vdefn->member->protection != ITCL_PRIVATE ||
+                  vdefn->member->classDefn == cdefnPtr );
+
+            /*
+             *  If this is a common variable, then keep a reference to
+             *  the variable directly.  Otherwise, keep an index into
+             *  the object's variable table.
+             */
+            if ((vdefn->member->flags & ITCL_COMMON) != 0) {
+                nsPtr = (Namespace*)cdPtr->namesp;
+                vlookup->var.common = (Tcl_Var) ItclVarHashFindVar(&nsPtr->varTable, vdefn->member->name);
+                assert(vlookup->var.common  != NULL);
+            }
+            else {
+                /*
+                 *  If this is a reference to the built-in "this"
+                 *  variable, then its index is "0".  Otherwise,
+                 *  add another slot to the end of the table.
+                 */
+                if ((vdefn->member->flags & ITCL_THIS_VAR) != 0) {
+                    vlookup->var.index = 0;
+                }
+                else {
+                    vlookup->var.index = cdefnPtr->numInstanceVars++;
+                }
+            }
+
+            /*
+             *  Create all possible names for this variable and enter
+             *  them into the variable resolution table:
+             *     var
+             *     class::var
+             *     namesp1::class::var
+             *     namesp2::namesp1::class::var
+             *     ...
+             */
+            Tcl_DStringSetLength(&buffer, 0);
+            Tcl_DStringAppend(&buffer, vdefn->member->name, -1);
+            nsPtr = (Namespace*)cdPtr->namesp;
+
+            while (1) {
+                entry = Tcl_CreateHashEntry(&cdefnPtr->resolveVars,
+                    Tcl_DStringValue(&buffer), &newEntry);
+
+                if (newEntry) {
+                    Tcl_SetHashValue(entry, (ClientData)vlookup);
+                    vlookup->usage++;
+
+                    if (!vlookup->leastQualName) {
+                        vlookup->leastQualName =
+                            Tcl_GetHashKey(&cdefnPtr->resolveVars, entry);
+                    }
+                }
+
+                if (nsPtr == NULL) {
+                    break;
+                }
+                Tcl_DStringSetLength(&buffer2, 0);
+                Tcl_DStringAppend(&buffer2, Tcl_DStringValue(&buffer), -1);
+                Tcl_DStringSetLength(&buffer, 0);
+                Tcl_DStringAppend(&buffer, nsPtr->name, -1);
+                Tcl_DStringAppend(&buffer, "::", -1);
+                Tcl_DStringAppend(&buffer, Tcl_DStringValue(&buffer2), -1);
+
+                nsPtr = nsPtr->parentPtr;
+            }
+
+            /*
+             *  If this record is not needed, free it now.
+             */
+            if (vlookup->usage == 0) {
+                ckfree((char*)vlookup);
+            }
+            entry = Tcl_NextHashEntry(&place);
+        }
+        cdPtr = Itcl_AdvanceHierIter(&hier);
+    }
+    Itcl_DeleteHierIter(&hier);
+
+    /*
+     *  Clear the command resolution table.
+     */
+    Tcl_DeleteHashTable(&cdefnPtr->resolveCmds);
+    Tcl_InitHashTable(&cdefnPtr->resolveCmds, TCL_STRING_KEYS);
+
+    /*
+     *  Scan through all classes in the hierarchy, from most to
+     *  least specific.  Look for the first (most-specific) definition
+     *  of each member function, and enter it into the table.
+     */
+    Itcl_InitHierIter(&hier, cdefnPtr);
+    cdPtr = Itcl_AdvanceHierIter(&hier);
+    while (cdPtr != NULL) {
+        entry = Tcl_FirstHashEntry(&cdPtr->functions, &place);
+        while (entry) {
+            mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+
+            /*
+             *  Create all possible names for this function and enter
+             *  them into the command resolution table:
+             *     func
+             *     class::func
+             *     namesp1::class::func
+             *     namesp2::namesp1::class::func
+             *     ...
+             */
+            Tcl_DStringSetLength(&buffer, 0);
+            Tcl_DStringAppend(&buffer, mfunc->member->name, -1);
+            nsPtr = (Namespace*)cdPtr->namesp;
+
+            while (1) {
+                entry = Tcl_CreateHashEntry(&cdefnPtr->resolveCmds,
+                    Tcl_DStringValue(&buffer), &newEntry);
+
+                if (newEntry) {
+                    Tcl_SetHashValue(entry, (ClientData)mfunc);
+                }
+
+                if (nsPtr == NULL) {
+                    break;
+                }
+                Tcl_DStringSetLength(&buffer2, 0);
+                Tcl_DStringAppend(&buffer2, Tcl_DStringValue(&buffer), -1);
+                Tcl_DStringSetLength(&buffer, 0);
+                Tcl_DStringAppend(&buffer, nsPtr->name, -1);
+                Tcl_DStringAppend(&buffer, "::", -1);
+                Tcl_DStringAppend(&buffer, Tcl_DStringValue(&buffer2), -1);
+
+                nsPtr = nsPtr->parentPtr;
+            }
+            entry = Tcl_NextHashEntry(&place);
+        }
+        cdPtr = Itcl_AdvanceHierIter(&hier);
+    }
+    Itcl_DeleteHierIter(&hier);
+
+    Tcl_DStringFree(&buffer);
+    Tcl_DStringFree(&buffer2);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateVarDefn()
+ *
+ *  Creates a new class variable definition.  If this is a public
+ *  variable, it may have a bit of "config" code that is used to
+ *  update the object whenever the variable is modified via the
+ *  built-in "configure" method.
+ *
+ *  Returns TCL_ERROR along with an error message in the specified
+ *  interpreter if anything goes wrong.  Otherwise, this returns
+ *  TCL_OK and a pointer to the new variable definition in "vdefnPtr".
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CreateVarDefn(interp, cdefn, name, init, config, vdefnPtr)
+    Tcl_Interp *interp;       /* interpreter managing this transaction */
+    ItclClass* cdefn;         /* class containing this variable */
+    char* name;               /* variable name */
+    char* init;               /* initial value */
+    char* config;             /* code invoked when variable is configured */
+    ItclVarDefn** vdefnPtr;   /* returns: new variable definition */
+{
+    int newEntry;
+    ItclVarDefn *vdefn;
+    ItclMemberCode *mcode;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  Add this variable to the variable table for the class.
+     *  Make sure that the variable name does not already exist.
+     */
+    entry = Tcl_CreateHashEntry(&cdefn->variables, name, &newEntry);
+    if (!newEntry) {
+        Tcl_AppendResult(interp,
+            "variable name \"", name, "\" already defined in class \"",
+            cdefn->fullname, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If this variable has some "config" code, try to capture
+     *  its implementation.
+     */
+    if (config) {
+        if (Itcl_CreateMemberCode(interp, cdefn, (char*)NULL, config,
+            &mcode) != TCL_OK) {
+
+            Tcl_DeleteHashEntry(entry);
+            return TCL_ERROR;
+        }
+        Itcl_PreserveData((ClientData)mcode);
+        Itcl_EventuallyFree((ClientData)mcode, (Tcl_FreeProc*) Itcl_DeleteMemberCode);
+    }
+    else {
+        mcode = NULL;
+    }
+
+    /*
+     *  If everything looks good, create the variable definition.
+     */
+    vdefn = (ItclVarDefn*)ckalloc(sizeof(ItclVarDefn));
+    vdefn->member = Itcl_CreateMember(interp, cdefn, name);
+    vdefn->member->code = mcode;
+
+    if (vdefn->member->protection == ITCL_DEFAULT_PROTECT) {
+        vdefn->member->protection = ITCL_PROTECTED;
+    }
+
+    if (init) {
+        vdefn->init = (char*)ckalloc((unsigned)(strlen(init)+1));
+        strcpy(vdefn->init, init);
+    }
+    else {
+        vdefn->init = NULL;
+    }
+
+    Tcl_SetHashValue(entry, (ClientData)vdefn);
+
+    *vdefnPtr = vdefn;
+    return TCL_OK;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteVarDefn()
+ *
+ *  Destroys a variable definition created by Itcl_CreateVarDefn(),
+ *  freeing all resources associated with it.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DeleteVarDefn(vdefn)
+    ItclVarDefn *vdefn;   /* variable definition to be destroyed */
+{
+    Itcl_DeleteMember(vdefn->member);
+
+    if (vdefn->init) {
+        ckfree(vdefn->init);
+    }
+    ckfree((char*)vdefn);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_GetCommonVar()
+ *
+ *  Returns the current value for a common class variable.  The member
+ *  name is interpreted with respect to the given class scope.  That
+ *  scope is installed as the current context before querying the
+ *  variable.  This by-passes the protection level in case the variable
+ *  is "private".
+ *
+ *  If successful, this procedure returns a pointer to a string value
+ *  which remains alive until the variable changes it value.  If
+ *  anything goes wrong, this returns NULL.
+ * ------------------------------------------------------------------------
+ */
+CONST char*
+Itcl_GetCommonVar(interp, name, contextClass)
+    Tcl_Interp *interp;        /* current interpreter */
+    CONST char *name;                /* name of desired instance variable */
+    ItclClass *contextClass;   /* name is interpreted in this scope */
+{
+    CONST char *val = NULL;
+    int result;
+    Itcl_CallFrame frame;
+
+    /*
+     *  Activate the namespace for the given class.  That installs
+     *  the appropriate name resolution rules and by-passes any
+     *  security restrictions.
+     */
+    result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) &frame,
+                 contextClass->namesp, /*isProcCallFrame*/ 0);
+
+    if (result == TCL_OK) {
+        val = Tcl_GetVar2(interp, (CONST84 char *)name, (char*)NULL, 0);
+        Tcl_PopCallFrame(interp);
+    }
+    return val;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateMember()
+ *
+ *  Creates the data record representing a class member.  This is the
+ *  generic representation for a data member or member function.
+ *  Returns a pointer to the new representation.
+ * ------------------------------------------------------------------------
+ */
+ItclMember*
+Itcl_CreateMember(interp, cdefn, name)
+    Tcl_Interp* interp;            /* interpreter managing this action */
+    ItclClass *cdefn;              /* class definition */
+    CONST char* name;              /* name of new member */
+{
+    ItclMember *memPtr;
+    int fullsize;
+
+    /*
+     *  Allocate the memory for a class member and fill in values.
+     */
+    memPtr = (ItclMember*)ckalloc(sizeof(ItclMember));
+    memPtr->interp       = interp;
+    memPtr->classDefn    = cdefn;
+    memPtr->flags        = 0;
+    memPtr->protection   = Itcl_Protection(interp, 0);
+    memPtr->code         = NULL;
+
+    fullsize = strlen(cdefn->fullname) + strlen(name) + 2;
+    memPtr->fullname = (char*)ckalloc((unsigned)(fullsize+1));
+    strcpy(memPtr->fullname, cdefn->fullname);
+    strcat(memPtr->fullname, "::");
+    strcat(memPtr->fullname, name);
+
+    memPtr->name = (char*)ckalloc((unsigned)(strlen(name)+1));
+    strcpy(memPtr->name, name);
+
+    return memPtr;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteMember()
+ *
+ *  Destroys all data associated with the given member function definition.
+ *  Usually invoked by the interpreter when a member function is deleted.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DeleteMember(memPtr)
+    ItclMember *memPtr;  /* pointer to member function definition */
+{
+    if (memPtr) {
+        ckfree(memPtr->name);
+        ckfree(memPtr->fullname);
+
+        if (memPtr->code) {
+            Itcl_ReleaseData((ClientData)memPtr->code);
+        }
+        memPtr->code = NULL;
+
+        ckfree((char*)memPtr);
+    }
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_InitHierIter()
+ *
+ *  Initializes an iterator for traversing the hierarchy of the given
+ *  class.  Subsequent calls to Itcl_AdvanceHierIter() will return
+ *  the base classes in order from most-to-least specific.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_InitHierIter(iter,cdefn)
+    ItclHierIter *iter;   /* iterator used for traversal */
+    ItclClass *cdefn;     /* class definition for start of traversal */
+{
+    Itcl_InitStack(&iter->stack);
+    Itcl_PushStack((ClientData)cdefn, &iter->stack);
+    iter->current = cdefn;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteHierIter()
+ *
+ *  Destroys an iterator for traversing class hierarchies, freeing
+ *  all memory associated with it.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DeleteHierIter(iter)
+    ItclHierIter *iter;  /* iterator used for traversal */
+{
+    Itcl_DeleteStack(&iter->stack);
+    iter->current = NULL;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_AdvanceHierIter()
+ *
+ *  Moves a class hierarchy iterator forward to the next base class.
+ *  Returns a pointer to the current class definition, or NULL when
+ *  the end of the hierarchy has been reached.
+ * ------------------------------------------------------------------------
+ */
+ItclClass*
+Itcl_AdvanceHierIter(iter)
+    ItclHierIter *iter;  /* iterator used for traversal */
+{
+    register Itcl_ListElem *elem;
+    ItclClass *cdPtr;
+
+    iter->current = (ItclClass*)Itcl_PopStack(&iter->stack);
+
+    /*
+     *  Push classes onto the stack in reverse order, so that
+     *  they will be popped off in the proper order.
+     */
+    if (iter->current) {
+        cdPtr = (ItclClass*)iter->current;
+        elem = Itcl_LastListElem(&cdPtr->bases);
+        while (elem) {
+            Itcl_PushStack(Itcl_GetListValue(elem), &iter->stack);
+            elem = Itcl_PrevListElem(elem);
+        }
+    }
+    return iter->current;
+}
diff --git a/8.x/itcl/generic/itcl_cmds.c b/8.x/itcl/generic/itcl_cmds.c
new file mode 100644 (file)
index 0000000..516c1e9
--- /dev/null
@@ -0,0 +1,1723 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  This file defines information that tracks classes and objects
+ *  at a global level for a given interpreter.
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_cmds.c,v 1.32 2008/12/15 20:02:58 andreas_kupries Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ *  FORWARD DECLARATIONS
+ */
+static void ItclDelObjectInfo _ANSI_ARGS_((char* cdata));
+static int Initialize _ANSI_ARGS_((Tcl_Interp *interp));
+static int ItclHandleStubCmd _ANSI_ARGS_((ClientData clientData,
+    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
+static void ItclDeleteStub _ANSI_ARGS_((ClientData cdata));
+
+/*
+ * The following string is the startup script executed in new
+ * interpreters.  It locates the Tcl code in the [incr Tcl] library
+ * directory and loads it in.
+ */
+
+static char initScript[] = "\n\
+namespace eval ::itcl {\n\
+    proc _find_init {} {\n\
+        global env tcl_library\n\
+        variable library\n\
+        variable version\n\
+        rename _find_init {}\n\
+        if {[info exists library]} {\n\
+            lappend dirs $library\n\
+        } else {\n\
+            if {[catch {uplevel #0 source -rsrc itcl}] == 0} {\n\
+                return\n\
+            }\n\
+            set dirs {}\n\
+            if {[info exists env(ITCL_LIBRARY)]} {\n\
+                lappend dirs $env(ITCL_LIBRARY)\n\
+            }\n\
+            lappend dirs [file join [file dirname $tcl_library] itcl$version]\n\
+            set bindir [file dirname [info nameofexecutable]]\n\
+            lappend dirs [file join $bindir .. lib itcl$version]\n\
+            lappend dirs [file join $bindir .. library]\n\
+            lappend dirs [file join $bindir .. .. library]\n\
+            lappend dirs [file join $bindir .. .. itcl library]\n\
+            lappend dirs [file join $bindir .. .. .. itcl library]\n\
+            # On MacOSX, check the directories in the tcl_pkgPath\n\
+            if {[string equal $::tcl_platform(platform) \"unix\"] && \
+                    [string equal $::tcl_platform(os) \"Darwin\"]} {\n\
+                foreach d $::tcl_pkgPath {\n\
+                    lappend dirs [file join $d itcl$version]\n\
+                }\n\
+            }\n\
+        }\n\
+        foreach i $dirs {\n\
+            set library $i\n\
+            set itclfile [file join $i itcl.tcl]\n\
+            if {![catch {uplevel #0 [list source $itclfile]} msg]} {\n\
+                return\n\
+            }\n\
+        }\n\
+        set msg \"Can't find a usable itcl.tcl in the following directories:\n\"\n\
+        append msg \"    $dirs\n\"\n\
+        append msg \"This probably means that Itcl/Tcl weren't installed properly.\n\"\n\
+        append msg \"If you know where the Itcl library directory was installed,\n\"\n\
+        append msg \"you can set the environment variable ITCL_LIBRARY to point\n\"\n\
+        append msg \"to the library directory.\n\"\n\
+        error $msg\n\
+    }\n\
+    _find_init\n\
+}";
+\f
+/*
+ * The following script is used to initialize Itcl in a safe interpreter.
+ */
+
+static char safeInitScript[] =
+"proc ::itcl::local {class name args} {\n\
+    set ptr [uplevel [list $class $name] $args]\n\
+    uplevel [list set itcl-local-$ptr $ptr]\n\
+    set cmd [uplevel namespace which -command $ptr]\n\
+    uplevel [list trace variable itcl-local-$ptr u \"::itcl::delete object $cmd; list\"]\n\
+    return $ptr\n\
+}";
+
+int itclCompatFlags = -1;
+
+#if ITCL_TCL_PRE_8_5
+int itclVarFlagOffset; 
+int itclVarRefCountOffset;
+int itclVarInHashSize;
+int itclVarLocalSize;
+int itclVarValueOffset;
+#endif
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Initialize()
+ *
+ *  Invoked whenever a new interpeter is created to install the
+ *  [incr Tcl] package.  Usually invoked within Tcl_AppInit() at
+ *  the start of execution.
+ *
+ *  Creates the "::itcl" namespace and installs access commands for
+ *  creating classes and querying info.
+ *
+ *  Returns TCL_OK on success, or TCL_ERROR (along with an error
+ *  message in the interpreter) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+static int
+Initialize(interp)
+    Tcl_Interp *interp;  /* interpreter to be updated */
+{
+    Tcl_CmdInfo cmdInfo;
+    Tcl_Namespace *itclNs;
+    ItclObjectInfo *info;
+
+#ifndef USE_TCL_STUBS
+    if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) {
+      return TCL_ERROR;
+    }
+#else
+    if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
+      return TCL_ERROR;
+    }
+#endif
+
+    /*
+     *  See if [incr Tcl] is already installed.
+     */
+    if (Tcl_GetCommandInfo(interp, "::itcl::class", &cmdInfo)) {
+        Tcl_SetResult(interp, "already installed: [incr Tcl]", TCL_STATIC);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Set the compatability options.  Stubs allows us to load into many
+     *  version of the Tcl core.  Some problems have crept-in, and we need
+     *  to adapt dynamically regarding use of some internal structures and
+     *  functions that have changed (or have been added) since 8.1.0
+     */
+#if TCL_DOES_STUBS
+    if (itclCompatFlags == -1) {
+       int maj, min, ptch, type;
+
+       itclCompatFlags = 0;
+       Tcl_GetVersion(&maj, &min, &ptch, &type);
+
+       /* ver >= 8.4a1 */
+       if ((maj == 8) && (min >= 4)) {
+           /* TODO: make a TIP for exporting a Tcl_CommandIsDeleted
+            * function in the core. */
+           itclCompatFlags |= ITCL_COMPAT_USECMDFLAGS;
+       }
+#if USE_TCL_STUBS
+       if ((maj == 8) && (min > 4) &&
+               ((type > TCL_ALPHA_RELEASE) || (ptch > 2))) {
+           itclCompatFlags |= ITCL_COMPAT_USE_ISTATE_API;
+       }
+#else
+    itclCompatFlags = 0;
+#endif
+
+#if ITCL_TCL_PRE_8_5
+#if USE_TCL_STUBS
+       if ((maj == 8) && (min < 5)) {
+#endif
+           itclVarFlagOffset     = ItclOffset(Var, flags);
+           itclVarRefCountOffset = ItclOffset(Var, refCount);
+           itclVarValueOffset    = ItclOffset(Var, value);
+           itclVarInHashSize     = sizeof(Var);
+           itclVarLocalSize      = sizeof(Var);
+#if USE_TCL_STUBS
+       } else {
+           itclVarFlagOffset     = ItclOffset(ItclShortVar, flags);
+           itclVarRefCountOffset = ItclOffset(ItclVarInHash, refCount);
+           itclVarValueOffset    = ItclOffset(ItclShortVar, value);
+           itclVarInHashSize     = sizeof(ItclVarInHash);
+           itclVarLocalSize      = sizeof(ItclShortVar);  
+       }
+#endif
+#endif
+    }
+
+    /*
+     *  Initialize the ensemble package first, since we need this
+     *  for other parts of [incr Tcl].
+     */
+    if (Itcl_EnsembleInit(interp) != TCL_OK) {
+        return TCL_ERROR;
+    }
+#endif
+    
+    /*
+     *  Create the top-level data structure for tracking objects.
+     *  Store this as "associated data" for easy access, but link
+     *  it to the itcl namespace for ownership.
+     */
+    info = (ItclObjectInfo*)ckalloc(sizeof(ItclObjectInfo));
+    info->interp = interp;
+    Tcl_InitHashTable(&info->objects, TCL_ONE_WORD_KEYS);
+    Itcl_InitStack(&info->transparentFrames);
+    Tcl_InitHashTable(&info->contextFrames, TCL_ONE_WORD_KEYS);
+    info->protection = ITCL_DEFAULT_PROTECT;
+    Itcl_InitStack(&info->cdefnStack);
+
+    Tcl_SetAssocData(interp, ITCL_INTERP_DATA,
+        (Tcl_InterpDeleteProc*)NULL, (ClientData)info);
+
+    /*
+     *  Install commands into the "::itcl" namespace.
+     */
+    Tcl_CreateObjCommand(interp, "::itcl::class", Itcl_ClassCmd,
+        (ClientData)info, Itcl_ReleaseData);
+    Itcl_PreserveData((ClientData)info);
+
+    Tcl_CreateObjCommand(interp, "::itcl::body", Itcl_BodyCmd,
+        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(interp, "::itcl::configbody", Itcl_ConfigBodyCmd,
+        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
+
+    Itcl_EventuallyFree((ClientData)info, ItclDelObjectInfo);
+
+    /*
+     *  Create the "itcl::find" command for high-level queries.
+     */
+    if (Itcl_CreateEnsemble(interp, "::itcl::find") != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (Itcl_AddEnsemblePart(interp, "::itcl::find",
+            "classes", "?pattern?",
+            Itcl_FindClassesCmd,
+            (ClientData)info, Itcl_ReleaseData) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    Itcl_PreserveData((ClientData)info);
+
+    if (Itcl_AddEnsemblePart(interp, "::itcl::find",
+            "objects", "?-class className? ?-isa className? ?pattern?",
+            Itcl_FindObjectsCmd,
+            (ClientData)info, Itcl_ReleaseData) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    Itcl_PreserveData((ClientData)info);
+
+
+    /*
+     *  Create the "itcl::delete" command to delete objects
+     *  and classes.
+     */
+    if (Itcl_CreateEnsemble(interp, "::itcl::delete") != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (Itcl_AddEnsemblePart(interp, "::itcl::delete",
+            "class", "name ?name...?",
+            Itcl_DelClassCmd,
+            (ClientData)info, Itcl_ReleaseData) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    Itcl_PreserveData((ClientData)info);
+
+    if (Itcl_AddEnsemblePart(interp, "::itcl::delete",
+            "object", "name ?name...?",
+            Itcl_DelObjectCmd,
+            (ClientData)info, Itcl_ReleaseData) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    Itcl_PreserveData((ClientData)info);
+
+    /*
+     *  Create the "itcl::is" command to test object
+     *  and classes existence.
+     */
+    if (Itcl_CreateEnsemble(interp, "::itcl::is") != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (Itcl_AddEnsemblePart(interp, "::itcl::is",
+            "class", "name", Itcl_IsClassCmd,
+            (ClientData)info, Itcl_ReleaseData) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    Itcl_PreserveData((ClientData)info);
+
+    if (Itcl_AddEnsemblePart(interp, "::itcl::is",
+            "object", "?-class classname? name", Itcl_IsObjectCmd,
+            (ClientData)info, Itcl_ReleaseData) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    Itcl_PreserveData((ClientData)info);
+
+
+    /*
+     *  Add "code" and "scope" commands for handling scoped values.
+     */
+    Tcl_CreateObjCommand(interp, "::itcl::code", Itcl_CodeCmd,
+        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(interp, "::itcl::scope", Itcl_ScopeCmd,
+        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
+
+    /*
+     *  Add commands for handling import stubs at the Tcl level.
+     */
+    if (Itcl_CreateEnsemble(interp, "::itcl::import::stub") != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (Itcl_AddEnsemblePart(interp, "::itcl::import::stub",
+            "create", "name", Itcl_StubCreateCmd,
+            (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (Itcl_AddEnsemblePart(interp, "::itcl::import::stub",
+            "exists", "name", Itcl_StubExistsCmd,
+            (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Install a variable resolution procedure to handle scoped
+     *  values everywhere within the interpreter.
+     */
+    Tcl_AddInterpResolvers(interp, "itcl", (Tcl_ResolveCmdProc*)NULL,
+           (Tcl_ResolveVarProc*)Itcl_ScopedVarResolver,
+           (Tcl_ResolveCompiledVarProc*)NULL);
+
+    /*
+     *  Install the "itcl::parser" namespace used to parse the
+     *  class definitions.
+     */
+    if (Itcl_ParseInit(interp, info) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Create "itcl::builtin" namespace for commands that
+     *  are automatically built into class definitions.
+     */
+    if (Itcl_BiInit(interp) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Export all commands in the "itcl" namespace so that they
+     *  can be imported with something like "namespace import itcl::*"
+     */
+    itclNs = Tcl_FindNamespace(interp, "::itcl", (Tcl_Namespace*)NULL,
+        TCL_LEAVE_ERR_MSG);
+
+    /*
+     *  This was changed from a glob export (itcl::*) to explicit
+     *  command exports, so that the itcl::is command can *not* be
+     *  exported. This is done for concern that the itcl::is command
+     *  imported might be confusing ("is").
+     */   
+    if (!itclNs ||
+           (Tcl_Export(interp, itclNs, "body", /* reset */ 1) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "class", 0) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "code", 0) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "configbody", 0) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "delete", 0) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "delete_helper", 0) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "ensemble", 0) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "find", 0) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "local", 0) != TCL_OK) ||
+           (Tcl_Export(interp, itclNs, "scope", 0) != TCL_OK)) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Set up the variables containing version info.
+     */
+
+    Tcl_SetVar(interp, "::itcl::patchLevel", ITCL_PATCH_LEVEL,
+        TCL_NAMESPACE_ONLY);
+
+    Tcl_SetVar(interp, "::itcl::version", ITCL_VERSION,
+        TCL_NAMESPACE_ONLY);
+
+    /*
+     *  Package is now loaded.
+     */
+#if TCL_DOES_STUBS
+    {
+       extern ItclStubs itclStubs;
+       if (Tcl_PkgProvideEx(interp, "Itcl", ITCL_VERSION,
+               (ClientData)&itclStubs) != TCL_OK) {
+           return TCL_ERROR;
+       }
+    }
+#else
+    if (Tcl_PkgProvide(interp, "Itcl", ITCL_VERSION) != TCL_OK) {
+       return TCL_ERROR;
+    }
+#endif
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_Init()
+ *
+ *  Invoked whenever a new INTERPRETER is created to install the
+ *  [incr Tcl] package.  Usually invoked within Tcl_AppInit() at
+ *  the start of execution.
+ *
+ *  Creates the "::itcl" namespace and installs access commands for
+ *  creating classes and querying info.
+ *
+ *  Returns TCL_OK on success, or TCL_ERROR (along with an error
+ *  message in the interpreter) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_Init(interp)
+    Tcl_Interp *interp;  /* interpreter to be updated */
+{
+    if (Initialize(interp) != TCL_OK) {
+       return TCL_ERROR;
+    }
+    return Tcl_Eval(interp, initScript);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_SafeInit()
+ *
+ *  Invoked whenever a new SAFE INTERPRETER is created to install
+ *  the [incr Tcl] package.
+ *
+ *  Creates the "::itcl" namespace and installs access commands for
+ *  creating classes and querying info.
+ *
+ *  Returns TCL_OK on success, or TCL_ERROR (along with an error
+ *  message in the interpreter) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_SafeInit(interp)
+    Tcl_Interp *interp;  /* interpreter to be updated */
+{
+    if (Initialize(interp) != TCL_OK) {
+       return TCL_ERROR;
+    }
+    return Tcl_Eval(interp, safeInitScript);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclDelObjectInfo()
+ *
+ *  Invoked when the management info for [incr Tcl] is no longer being
+ *  used in an interpreter.  This will only occur when all class
+ *  manipulation commands are removed from the interpreter.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclDelObjectInfo(cdata)
+    char* cdata;    /* client data for class command */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)cdata;
+
+    ItclObject *contextObj;
+    Tcl_HashSearch place;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  Destroy all known objects by deleting their access
+     *  commands.
+     */
+    entry = Tcl_FirstHashEntry(&info->objects, &place);
+    while (entry) {
+        contextObj = (ItclObject*)Tcl_GetHashValue(entry);
+        Tcl_DeleteCommandFromToken(info->interp, contextObj->accessCmd);
+           /*
+            * Fix 227804: Whenever an object to delete was found we
+            * have to reset the search to the beginning as the
+            * current entry in the search was deleted and accessing it
+            * is therefore not allowed anymore.
+            */
+
+           entry = Tcl_FirstHashEntry(&info->objects, &place);
+           /*entry = Tcl_NextHashEntry(&place);*/
+    }
+    Tcl_DeleteHashTable(&info->objects);
+
+    /*
+     *  Discard all known object contexts.
+     */
+    entry = Tcl_FirstHashEntry(&info->contextFrames, &place);
+    while (entry) {
+        Itcl_ReleaseData( Tcl_GetHashValue(entry) );
+        entry = Tcl_NextHashEntry(&place);
+    }
+    Tcl_DeleteHashTable(&info->contextFrames);
+
+    Itcl_DeleteStack(&info->transparentFrames);
+    Itcl_DeleteStack(&info->cdefnStack);
+    ckfree((char*)info);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_FindClassesCmd()
+ *
+ *  Invoked by Tcl whenever the user issues an "itcl::find classes"
+ *  command to query the list of known classes.  Handles the following
+ *  syntax:
+ *
+ *    find classes ?<pattern>?
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_FindClassesCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* class/object info */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Tcl_Namespace *activeNs = Tcl_GetCurrentNamespace(interp);
+    Tcl_Namespace *globalNs = Tcl_GetGlobalNamespace(interp);
+    int forceFullNames = 0;
+
+    char *pattern;
+    CONST char *cmdName;
+    int newEntry, handledActiveNs;
+    Tcl_HashTable unique;
+    Tcl_HashEntry *entry;
+    Tcl_HashSearch place;
+    Itcl_Stack search;
+    Tcl_Command cmd, originalCmd;
+    Namespace *nsPtr;
+    Tcl_Obj *objPtr;
+
+    if (objc > 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+        return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+        pattern = Tcl_GetString(objv[1]);
+        forceFullNames = (strstr(pattern, "::") != NULL);
+    } else {
+        pattern = NULL;
+    }
+
+    /*
+     *  Search through all commands in the current namespace first,
+     *  in the global namespace next, then in all child namespaces
+     *  in this interpreter.  If we find any commands that
+     *  represent classes, report them.
+     */
+
+    Itcl_InitStack(&search);
+    Itcl_PushStack((ClientData)globalNs, &search);
+    Itcl_PushStack((ClientData)activeNs, &search);  /* last in, first out! */
+
+    Tcl_InitHashTable(&unique, TCL_ONE_WORD_KEYS);
+
+    handledActiveNs = 0;
+    while (Itcl_GetStackSize(&search) > 0) {
+        nsPtr = (Namespace*)Itcl_PopStack(&search);
+        if (nsPtr == (Namespace*)activeNs && handledActiveNs) {
+            continue;
+        }
+
+        entry = Tcl_FirstHashEntry(&nsPtr->cmdTable, &place);
+        while (entry) {
+            cmd = (Tcl_Command)Tcl_GetHashValue(entry);
+            if (Itcl_IsClass(cmd)) {
+                originalCmd = TclGetOriginalCommand(cmd);
+
+                /*
+                 *  Report full names if:
+                 *  - the pattern has namespace qualifiers
+                 *  - the class namespace is not in the current namespace
+                 *  - the class's object creation command is imported from
+                 *      another namespace.
+                 *
+                 *  Otherwise, report short names.
+                 */
+                if (forceFullNames || nsPtr != (Namespace*)activeNs ||
+                    originalCmd != NULL) {
+
+                    objPtr = Tcl_NewStringObj((char*)NULL, 0);
+                    Tcl_GetCommandFullName(interp, cmd, objPtr);
+                    cmdName = Tcl_GetString(objPtr);
+                } else {
+                    cmdName = Tcl_GetCommandName(interp, cmd);
+                    objPtr = Tcl_NewStringObj((CONST84 char *)cmdName, -1);
+                }
+
+                if (originalCmd) {
+                    cmd = originalCmd;
+                }
+                Tcl_CreateHashEntry(&unique, (char*)cmd, &newEntry);
+
+                if (newEntry &&
+                       (!pattern || Tcl_StringMatch((CONST84 char *)cmdName,
+                       pattern))) {
+                    Tcl_ListObjAppendElement((Tcl_Interp*)NULL,
+                           Tcl_GetObjResult(interp), objPtr);
+                } else {
+                   /* if not appended to the result, free objPtr. */
+                   Tcl_DecrRefCount(objPtr);
+               }
+
+            }
+            entry = Tcl_NextHashEntry(&place);
+        }
+        handledActiveNs = 1;  /* don't process the active namespace twice */
+
+        /*
+         *  Push any child namespaces onto the stack and continue
+         *  the search in those namespaces.
+         */
+        entry = Tcl_FirstHashEntry(&nsPtr->childTable, &place);
+        while (entry != NULL) {
+            Itcl_PushStack(Tcl_GetHashValue(entry), &search);
+            entry = Tcl_NextHashEntry(&place);
+        }
+    }
+    Tcl_DeleteHashTable(&unique);
+    Itcl_DeleteStack(&search);
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_FindObjectsCmd()
+ *
+ *  Invoked by Tcl whenever the user issues an "itcl::find objects"
+ *  command to query the list of known objects.  Handles the following
+ *  syntax:
+ *
+ *    find objects ?-class <className>? ?-isa <className>? ?<pattern>?
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_FindObjectsCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* class/object info */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Tcl_Namespace *activeNs = Tcl_GetCurrentNamespace(interp);
+    Tcl_Namespace *globalNs = Tcl_GetGlobalNamespace(interp);
+    int forceFullNames = 0;
+
+    char *pattern = NULL;
+    ItclClass *classDefn = NULL;
+    ItclClass *isaDefn = NULL;
+
+    char *name = NULL, *token = NULL;
+    CONST char *cmdName = NULL;
+    int pos, newEntry, match, handledActiveNs;
+    ItclObject *contextObj;
+    Tcl_HashTable unique;
+    Tcl_HashEntry *entry;
+    Tcl_HashSearch place;
+    Itcl_Stack search;
+    Tcl_Command cmd, originalCmd;
+    Namespace *nsPtr;
+    Command *cmdPtr;
+    Tcl_Obj *objPtr;
+
+    /*
+     *  Parse arguments:
+     *  objects ?-class <className>? ?-isa <className>? ?<pattern>?
+     */
+    pos = 0;
+    while (++pos < objc) {
+        token = Tcl_GetString(objv[pos]);
+        if (*token != '-') {
+            if (!pattern) {
+                pattern = token;
+                forceFullNames = (strstr(pattern, "::") != NULL);
+            } else {
+                break;
+            }
+        }
+        else if ((pos+1 < objc) && (strcmp(token,"-class") == 0)) {
+            name = Tcl_GetString(objv[pos+1]);
+            classDefn = Itcl_FindClass(interp, name, /* autoload */ 1);
+            if (classDefn == NULL) {
+                return TCL_ERROR;
+            }
+            pos++;
+        }
+        else if ((pos+1 < objc) && (strcmp(token,"-isa") == 0)) {
+            name = Tcl_GetString(objv[pos+1]);
+            isaDefn = Itcl_FindClass(interp, name, /* autoload */ 1);
+            if (isaDefn == NULL) {
+                return TCL_ERROR;
+            }
+            pos++;
+        }
+
+        /*
+         * Last token? Take it as the pattern, even if it starts
+         * with a "-".  This allows us to match object names that
+         * start with "-".
+         */
+        else if (pos == objc-1 && !pattern) {
+            pattern = token;
+            forceFullNames = (strstr(pattern, "::") != NULL);
+        }
+        else {
+            break;
+        }
+    }
+
+    if (pos < objc) {
+        Tcl_WrongNumArgs(interp, 1, objv,
+            "?-class className? ?-isa className? ?pattern?");
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Search through all commands in the current namespace first,
+     *  in the global namespace next, then in all child namespaces
+     *  in this interpreter.  If we find any commands that
+     *  represent objects, report them.
+     */
+
+    Itcl_InitStack(&search);
+    Itcl_PushStack((ClientData)globalNs, &search);
+    Itcl_PushStack((ClientData)activeNs, &search);  /* last in, first out! */
+
+    Tcl_InitHashTable(&unique, TCL_ONE_WORD_KEYS);
+
+    handledActiveNs = 0;
+    while (Itcl_GetStackSize(&search) > 0) {
+        nsPtr = (Namespace*)Itcl_PopStack(&search);
+        if (nsPtr == (Namespace*)activeNs && handledActiveNs) {
+            continue;
+        }
+
+        entry = Tcl_FirstHashEntry(&nsPtr->cmdTable, &place);
+        while (entry) {
+            cmd = (Tcl_Command)Tcl_GetHashValue(entry);
+            if (Itcl_IsObject(cmd)) {
+                originalCmd = TclGetOriginalCommand(cmd);
+                if (originalCmd) {
+                    cmd = originalCmd;
+                }
+                cmdPtr = (Command*)cmd;
+                contextObj = (ItclObject*)cmdPtr->objClientData;
+
+                /*
+                 *  Report full names if:
+                 *  - the pattern has namespace qualifiers
+                 *  - the class namespace is not in the current namespace
+                 *  - the class's object creation command is imported from
+                 *      another namespace.
+                 *
+                 *  Otherwise, report short names.
+                 */
+                if (forceFullNames || nsPtr != (Namespace*)activeNs ||
+                    originalCmd != NULL) {
+
+                    objPtr = Tcl_NewStringObj((char*)NULL, 0);
+                    Tcl_GetCommandFullName(interp, cmd, objPtr);
+                   cmdName = Tcl_GetString(objPtr);
+                } else {
+                    cmdName = Tcl_GetCommandName(interp, cmd);
+                    objPtr = Tcl_NewStringObj((CONST84 char *)cmdName, -1);
+                }
+
+                Tcl_CreateHashEntry(&unique, (char*)cmd, &newEntry);
+
+                match = 0;
+               if (newEntry &&
+                       (!pattern || Tcl_StringMatch((CONST84 char *)cmdName,
+                       pattern))) {
+                    if (!classDefn || (contextObj->classDefn == classDefn)) {
+                        if (!isaDefn) {
+                            match = 1;
+                        } else {
+                            entry = Tcl_FindHashEntry(
+                                &contextObj->classDefn->heritage,
+                                (char*)isaDefn);
+
+                            if (entry) {
+                                match = 1;
+                            }
+                        }
+                    }
+                }
+
+                if (match) {
+                    Tcl_ListObjAppendElement((Tcl_Interp*)NULL,
+                        Tcl_GetObjResult(interp), objPtr);
+                } else {
+                    Tcl_DecrRefCount(objPtr);  /* throw away the name */
+                }
+            }
+            entry = Tcl_NextHashEntry(&place);
+        }
+        handledActiveNs = 1;  /* don't process the active namespace twice */
+
+        /*
+         *  Push any child namespaces onto the stack and continue
+         *  the search in those namespaces.
+         */
+        entry = Tcl_FirstHashEntry(&nsPtr->childTable, &place);
+        while (entry != NULL) {
+            Itcl_PushStack(Tcl_GetHashValue(entry), &search);
+            entry = Tcl_NextHashEntry(&place);
+        }
+    }
+    Tcl_DeleteHashTable(&unique);
+    Itcl_DeleteStack(&search);
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ProtectionCmd()
+ *
+ *  Invoked by Tcl whenever the user issues a protection setting
+ *  command like "public" or "private".  Creates commands and
+ *  variables, and assigns a protection level to them.  Protection
+ *  levels are defined as follows:
+ *
+ *    public    => accessible from any namespace
+ *    protected => accessible from selected namespaces
+ *    private   => accessible only in the namespace where it was defined
+ *
+ *  Handles the following syntax:
+ *
+ *    public <command> ?<arg> <arg>...?
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ProtectionCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* protection level (public/protected/private) */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int pLevel = (int)clientData;
+
+    int result;
+    int oldLevel;
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "command ?arg arg...?");
+        return TCL_ERROR;
+    }
+
+    oldLevel = Itcl_Protection(interp, pLevel);
+
+    if (objc == 2) {
+        result = Tcl_EvalObj(interp, objv[1]);
+    } else {
+        result = Itcl_EvalArgs(interp, objc-1, objv+1);
+    }
+
+    if (result == TCL_BREAK) {
+        Tcl_SetResult(interp, "invoked \"break\" outside of a loop",
+            TCL_STATIC);
+        result = TCL_ERROR;
+    }
+    else if (result == TCL_CONTINUE) {
+        Tcl_SetResult(interp, "invoked \"continue\" outside of a loop",
+            TCL_STATIC);
+        result = TCL_ERROR;
+    }
+    else if (result != TCL_OK) {
+        char mesg[256], *name;
+        name = Tcl_GetString(objv[0]);
+        sprintf(mesg, "\n    (%.100s body line %d)", name, ERRORLINE(interp));
+        Tcl_AddErrorInfo(interp, mesg);
+    }
+
+    Itcl_Protection(interp, oldLevel);
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DelClassCmd()
+ *
+ *  Part of the "delete" ensemble.  Invoked by Tcl whenever the
+ *  user issues a "delete class" command to delete classes.
+ *  Handles the following syntax:
+ *
+ *    delete class <name> ?<name>...?
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_DelClassCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* unused */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int i;
+    char *name;
+    ItclClass *cdefn;
+
+    /*
+     *  Since destroying a base class will destroy all derived
+     *  classes, calls like "destroy class Base Derived" could
+     *  fail.  Break this into two passes:  first check to make
+     *  sure that all classes on the command line are valid,
+     *  then delete them.
+     */
+    for (i=1; i < objc; i++) {
+        name = Tcl_GetString(objv[i]);
+        cdefn = Itcl_FindClass(interp, name, /* autoload */ 1);
+        if (cdefn == NULL) {
+            return TCL_ERROR;
+        }
+    }
+
+    for (i=1; i < objc; i++) {
+        name = Tcl_GetString(objv[i]);
+        cdefn = Itcl_FindClass(interp, name, /* autoload */ 0);
+
+        if (cdefn) {
+            Tcl_ResetResult(interp);
+            if (Itcl_DeleteClass(interp, cdefn) != TCL_OK) {
+                return TCL_ERROR;
+            }
+        }
+    }
+    Tcl_ResetResult(interp);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DelObjectCmd()
+ *
+ *  Part of the "delete" ensemble.  Invoked by Tcl whenever the user
+ *  issues a "delete object" command to delete [incr Tcl] objects.
+ *  Handles the following syntax:
+ *
+ *    delete object <name> ?<name>...?
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_DelObjectCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* object management info */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int i;
+    char *name;
+    ItclObject *contextObj;
+
+    /*
+     *  Scan through the list of objects and attempt to delete them.
+     *  If anything goes wrong (i.e., destructors fail), then
+     *  abort with an error.
+     */
+    for (i=1; i < objc; i++) {
+        name = Tcl_GetStringFromObj(objv[i], (int*)NULL);
+        if (Itcl_FindObject(interp, name, &contextObj) != TCL_OK) {
+            return TCL_ERROR;
+        }
+
+        if (contextObj == NULL) {
+            Tcl_AppendResult(interp,
+                "object \"", name, "\" not found",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+
+        if (Itcl_DeleteObject(interp, contextObj) != TCL_OK) {
+            return TCL_ERROR;
+        }
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ScopeCmd()
+ *
+ *  Invoked by Tcl whenever the user issues a "scope" command to
+ *  create a fully qualified variable name.  Handles the following
+ *  syntax:
+ *
+ *    scope <variable>
+ *
+ *  If the input string is already fully qualified (starts with "::"),
+ *  then this procedure does nothing.  Otherwise, it looks for a
+ *  data member called <variable> and returns its fully qualified
+ *  name.  If the <variable> is a common data member, this procedure
+ *  returns a name of the form:
+ *
+ *    ::namesp::namesp::class::variable
+ *
+ *  If the <variable> is an instance variable, this procedure returns
+ *  a name of the form:
+ *
+ *    @itcl ::namesp::namesp::object variable
+ *
+ *  This kind of scoped value is recognized by the Itcl_ScopedVarResolver
+ *  proc, which handles variable resolution for the entire interpreter.
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_ScopeCmd(dummy, interp, objc, objv)
+    ClientData dummy;        /* unused */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int result = TCL_OK;
+    Tcl_Namespace *contextNs = Tcl_GetCurrentNamespace(interp);
+    char *openParen = NULL;
+
+    register char *p;
+    char *token;
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+    ItclObjectInfo *info;
+    Itcl_CallFrame *framePtr;
+    Tcl_HashEntry *entry;
+    ItclVarLookup *vlookup;
+    Tcl_Obj *objPtr;
+    Tcl_Var var;
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "varname");
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If this looks like a fully qualified name already,
+     *  then return it as is.
+     */
+    token = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    if (*token == ':' && *(token+1) == ':') {
+        Tcl_SetObjResult(interp, objv[1]);
+        return TCL_OK;
+    }
+
+    /*
+     *  If the variable name is an array reference, pick out
+     *  the array name and use that for the lookup operations
+     *  below.
+     */
+    for (p=token; *p != '\0'; p++) {
+        if (*p == '(') {
+            openParen = p;
+        }
+        else if (*p == ')' && openParen) {
+            *openParen = '\0';
+            break;
+        }
+    }
+
+    /*
+     *  Figure out what context we're in.  If this is a class,
+     *  then look up the variable in the class definition.
+     *  If this is a namespace, then look up the variable in its
+     *  varTable.  Note that the normal Itcl_GetContext function
+     *  returns an error if we're not in a class context, so we
+     *  perform a similar function here, the hard way.
+     *
+     *  TRICKY NOTE:  If this is an array reference, we'll get
+     *    the array variable as the variable name.  We must be
+     *    careful to add the index (everything from openParen
+     *    onward) as well.
+     */
+    if (Itcl_IsClassNamespace(contextNs)) {
+        contextClass = (ItclClass*)contextNs->clientData;
+
+        entry = Tcl_FindHashEntry(&contextClass->resolveVars, token);
+        if (!entry) {
+            Tcl_AppendResult(interp,
+                "variable \"", token, "\" not found in class \"",
+                contextClass->fullname, "\"",
+                (char*)NULL);
+            result = TCL_ERROR;
+            goto scopeCmdDone;
+        }
+        vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+
+        if (vlookup->vdefn->member->flags & ITCL_COMMON) {
+            Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
+            Tcl_AppendToObj(resultPtr, vlookup->vdefn->member->fullname, -1);
+            if (openParen) {
+                *openParen = '(';
+                Tcl_AppendToObj(resultPtr, openParen, -1);
+                openParen = NULL;
+            }
+            result = TCL_OK;
+            goto scopeCmdDone;
+        }
+
+        /*
+         *  If this is not a common variable, then we better have
+         *  an object context.  Return the name "@itcl object variable".
+         */
+        framePtr = _Tcl_GetCallFrame(interp, 0);
+        info = contextClass->info;
+
+        entry = Tcl_FindHashEntry(&info->contextFrames, (char*)framePtr);
+        if (!entry) {
+            Tcl_AppendResult(interp,
+                "can't scope variable \"", token,
+                "\": missing object context\"",
+                (char*)NULL);
+            result = TCL_ERROR;
+            goto scopeCmdDone;
+        }
+        contextObj = (ItclObject*)Tcl_GetHashValue(entry);
+
+        Tcl_AppendElement(interp, "@itcl");
+
+        objPtr = Tcl_NewStringObj((char*)NULL, 0);
+        Tcl_IncrRefCount(objPtr);
+        Tcl_GetCommandFullName(interp, contextObj->accessCmd, objPtr);
+        Tcl_AppendElement(interp, Tcl_GetStringFromObj(objPtr, (int*)NULL));
+        Tcl_DecrRefCount(objPtr);
+
+        objPtr = Tcl_NewStringObj((char*)NULL, 0);
+        Tcl_IncrRefCount(objPtr);
+        Tcl_AppendToObj(objPtr, vlookup->vdefn->member->fullname, -1);
+
+        if (openParen) {
+            *openParen = '(';
+            Tcl_AppendToObj(objPtr, openParen, -1);
+            openParen = NULL;
+        }
+        Tcl_AppendElement(interp, Tcl_GetStringFromObj(objPtr, (int*)NULL));
+        Tcl_DecrRefCount(objPtr);
+    }
+
+    /*
+     *  We must be in an ordinary namespace context.  Resolve
+     *  the variable using Tcl_FindNamespaceVar.
+     *
+     *  TRICKY NOTE:  If this is an array reference, we'll get
+     *    the array variable as the variable name.  We must be
+     *    careful to add the index (everything from openParen
+     *    onward) as well.
+     */
+    else {
+        Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
+
+        var = Tcl_FindNamespaceVar(interp, token, contextNs,
+            TCL_NAMESPACE_ONLY);
+
+        if (!var) {
+            Tcl_AppendResult(interp,
+                "variable \"", token, "\" not found in namespace \"",
+                contextNs->fullName, "\"",
+                (char*)NULL);
+            result = TCL_ERROR;
+            goto scopeCmdDone;
+        }
+
+        Tcl_GetVariableFullName(interp, var, resultPtr);
+        if (openParen) {
+            *openParen = '(';
+            Tcl_AppendToObj(resultPtr, openParen, -1);
+            openParen = NULL;
+        }
+    }
+
+scopeCmdDone:
+    if (openParen) {
+        *openParen = '(';
+    }
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CodeCmd()
+ *
+ *  Invoked by Tcl whenever the user issues a "code" command to
+ *  create a scoped command string.  Handles the following syntax:
+ *
+ *    code ?-namespace foo? arg ?arg arg ...?
+ *
+ *  Unlike the scope command, the code command DOES NOT look for
+ *  scoping information at the beginning of the command.  So scopes
+ *  will nest in the code command.
+ *
+ *  The code command is similar to the "namespace code" command in
+ *  Tcl, but it preserves the list structure of the input arguments,
+ *  so it is a lot more useful.
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_CodeCmd(dummy, interp, objc, objv)
+    ClientData dummy;        /* unused */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Tcl_Namespace *contextNs = Tcl_GetCurrentNamespace(interp);
+
+    int pos;
+    char *token;
+    Tcl_Obj *listPtr, *objPtr;
+
+    /*
+     *  Handle flags like "-namespace"...
+     */
+    for (pos=1; pos < objc; pos++) {
+        token = Tcl_GetStringFromObj(objv[pos], (int*)NULL);
+        if (*token != '-') {
+            break;
+        }
+
+        if (strcmp(token, "-namespace") == 0) {
+            if (objc == 2) {
+                Tcl_WrongNumArgs(interp, 1, objv,
+                    "?-namespace name? command ?arg arg...?");
+                return TCL_ERROR;
+            } else {
+                token = Tcl_GetStringFromObj(objv[pos+1], (int*)NULL);
+                contextNs = Tcl_FindNamespace(interp, token,
+                    (Tcl_Namespace*)NULL, TCL_LEAVE_ERR_MSG);
+
+                if (!contextNs) {
+                    return TCL_ERROR;
+                }
+                pos++;
+            }
+        }
+        else if (strcmp(token, "--") == 0) {
+            pos++;
+            break;
+        }
+        else {
+            Tcl_AppendResult(interp,
+                "bad option \"", token, "\": should be -namespace or --",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+    }
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv,
+            "?-namespace name? command ?arg arg...?");
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Now construct a scoped command by integrating the
+     *  current namespace context, and appending the remaining
+     *  arguments AS A LIST...
+     */
+    listPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+
+    Tcl_ListObjAppendElement(interp, listPtr,
+        Tcl_NewStringObj("namespace", -1));
+    Tcl_ListObjAppendElement(interp, listPtr,
+        Tcl_NewStringObj("inscope", -1));
+
+    if (contextNs == Tcl_GetGlobalNamespace(interp)) {
+        objPtr = Tcl_NewStringObj("::", -1);
+    } else {
+        objPtr = Tcl_NewStringObj(contextNs->fullName, -1);
+    }
+    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
+
+    if (objc-pos == 1) {
+        objPtr = objv[pos];
+    } else {
+        objPtr = Tcl_NewListObj(objc-pos, &objv[pos]);
+    }
+    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_StubCreateCmd()
+ *
+ *  Invoked by Tcl whenever the user issues a "stub create" command to
+ *  create an autoloading stub for imported commands.  Handles the
+ *  following syntax:
+ *
+ *    stub create <name>
+ *
+ *  Creates a command called <name>.  Executing this command will cause
+ *  the real command <name> to be autoloaded.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_StubCreateCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* not used */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    char *cmdName;
+    Command *cmdPtr;
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name");
+        return TCL_ERROR;
+    }
+    cmdName = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+
+    /*
+     *  Create a stub command with the characteristic ItclDeleteStub
+     *  procedure.  That way, we can recognize this command later
+     *  on as a stub.  Save the cmd token as client data, so we can
+     *  get the full name of this command later on.
+     */
+    cmdPtr = (Command *) Tcl_CreateObjCommand(interp, cmdName,
+        ItclHandleStubCmd, (ClientData)NULL,
+        (Tcl_CmdDeleteProc*)ItclDeleteStub);
+
+    cmdPtr->objClientData = (ClientData) cmdPtr;
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_StubExistsCmd()
+ *
+ *  Invoked by Tcl whenever the user issues a "stub exists" command to
+ *  see if an existing command is an autoloading stub.  Handles the
+ *  following syntax:
+ *
+ *    stub exists <name>
+ *
+ *  Looks for a command called <name> and checks to see if it is an
+ *  autoloading stub.  Returns a boolean result.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_StubExistsCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* not used */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    char *cmdName;
+    Tcl_Command cmd;
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name");
+        return TCL_ERROR;
+    }
+    cmdName = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+
+    cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace*)NULL, 0);
+
+    if (cmd != NULL && Itcl_IsStub(cmd)) {
+        Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
+    } else {
+        Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_IsStub()
+ *
+ *  Checks the given Tcl command to see if it represents an autoloading
+ *  stub created by the "stub create" command.  Returns non-zero if
+ *  the command is indeed a stub.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_IsStub(cmd)
+    Tcl_Command cmd;         /* command being tested */
+{
+    Command *cmdPtr = (Command*)cmd;
+
+    /*
+     *  This may be an imported command, but don't try to get the
+     *  original.  Just check to see if this particular command
+     *  is a stub.  If we really want the original command, we'll
+     *  find it at a higher level.
+     */
+    if (cmdPtr->deleteProc == ItclDeleteStub) {
+        return 1;
+    }
+    return 0;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclHandleStubCmd()
+ *
+ *  Invoked by Tcl to handle commands created by "stub create".
+ *  Calls "auto_load" with the full name of the current command to
+ *  trigger autoloading of the real implementation.  Then, calls the
+ *  command to handle its function.  If successful, this command
+ *  returns TCL_OK along with the result from the real implementation
+ *  of this command.  Otherwise, it returns TCL_ERROR, along with an
+ *  error message in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+static int
+ItclHandleStubCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* command token for this stub */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Tcl_Command cmd = (Tcl_Command) clientData;
+
+    int result, loaded;
+    char *cmdName;
+    int cmdlinec;
+    Tcl_Obj **cmdlinev;
+    Tcl_Obj *objAutoLoad[2], *objPtr, *cmdNamePtr, *cmdlinePtr;
+
+    cmdNamePtr = Tcl_NewStringObj((char*)NULL, 0);
+    Tcl_GetCommandFullName(interp, cmd, cmdNamePtr);
+    Tcl_IncrRefCount(cmdNamePtr);
+    cmdName = Tcl_GetStringFromObj(cmdNamePtr, (int*)NULL);
+
+    /*
+     *  Try to autoload the real command for this stub.
+     */
+    objAutoLoad[0] = Tcl_NewStringObj("::auto_load", -1);
+    Tcl_IncrRefCount(objAutoLoad[0]);
+    objAutoLoad[1] = cmdNamePtr;
+    Tcl_IncrRefCount(objAutoLoad[1]);
+
+    result = Itcl_EvalArgs(interp, 2, objAutoLoad);
+
+    Tcl_DecrRefCount(objAutoLoad[0]);
+    Tcl_DecrRefCount(objAutoLoad[1]);
+
+    if (result != TCL_OK) {
+        Tcl_DecrRefCount(cmdNamePtr);
+        return TCL_ERROR;
+    }
+
+    objPtr = Tcl_GetObjResult(interp);
+    result = Tcl_GetIntFromObj(interp, objPtr, &loaded);
+    if (result != TCL_OK || !loaded) {
+        Tcl_ResetResult(interp);
+        Tcl_AppendResult(interp,
+            "can't autoload \"", cmdName, "\"", (char*)NULL);
+        Tcl_DecrRefCount(cmdNamePtr);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  At this point, the real implementation has been loaded.
+     *  Invoke the command again with the arguments passed in.
+     */
+    cmdlinePtr = Itcl_CreateArgs(interp, cmdName, objc-1, objv+1);
+
+    (void) Tcl_ListObjGetElements((Tcl_Interp*)NULL, cmdlinePtr,
+        &cmdlinec, &cmdlinev);
+
+    Tcl_ResetResult(interp);
+    result = Itcl_EvalArgs(interp, cmdlinec, cmdlinev);
+    Tcl_DecrRefCount(cmdlinePtr);
+
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclDeleteStub()
+ *
+ *  Invoked by Tcl whenever a stub command is deleted.  This procedure
+ *  does nothing, but its presence identifies a command as a stub.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static void
+ItclDeleteStub(cdata)
+    ClientData cdata;      /* not used */
+{
+    /* do nothing */
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_IsObjectCmd()
+ *
+ *  Invoked by Tcl whenever the user issues an "itcl::is object"
+ *  command to test whether the argument is an object or not.
+ *  syntax:
+ *
+ *    itcl::is object ?-class classname? commandname
+ *
+ *  Sets interp result to 1 if it is an object, 0 otherwise
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_IsObjectCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* class/object info */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+
+    int             classFlag = 0;
+    int             idx = 0;
+    char            *name = "";
+    char            *cname;
+    char            *cmdName;
+    char            *token;
+    Tcl_Command     cmd;
+    Command         *cmdPtr;
+    Tcl_Namespace   *contextNs = NULL;
+    ItclClass       *classDefn = NULL;
+    ItclObject      *contextObj;
+
+    /*
+     *    Handle the arguments.
+     *    objc needs to be either:
+     *        2    itcl::is object commandname
+     *        4    itcl::is object -class classname commandname
+     */
+    if (objc != 2 && objc != 4) {
+        Tcl_WrongNumArgs(interp, 1, objv, "?-class classname? commandname");
+        return TCL_ERROR;
+    }
+
+    /*
+     *    Parse the command args. Look for the -class
+     *    keyword.
+     */
+    for (idx=1; idx < objc; idx++) {
+        token = Tcl_GetString(objv[idx]);
+
+        if (strcmp(token,"-class") == 0) {
+            cname = Tcl_GetString(objv[idx+1]);
+            classDefn = Itcl_FindClass(interp, cname, /* no autoload */ 0);
+
+            if (classDefn == NULL) {
+                    return TCL_ERROR;
+            }
+
+            idx++;
+            classFlag = 1;
+        } else {
+            name = Tcl_GetString(objv[idx]);
+        }
+
+    } /* end for objc loop */
+
+    /*
+     *  The object name may be a scoped value of the form
+     *  "namespace inscope <namesp> <command>".  If it is,
+     *  decode it.
+     */
+    if (Itcl_DecodeScopedCommand(interp, name, &contextNs, &cmdName)
+        != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    cmd = Tcl_FindCommand(interp, cmdName, contextNs, /* flags */ 0);
+
+    /*
+     *    Need the NULL test, or the test will fail if cmd is NULL
+     */
+    if (cmd == NULL || ! Itcl_IsObject(cmd)) {
+        Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
+        return TCL_OK;
+    }
+
+    /*
+     *    Handle the case when the -class flag is given
+     */
+    if (classFlag) {
+        cmdPtr = (Command*)cmd;
+        contextObj = (ItclObject*)cmdPtr->objClientData;
+
+        if (! Itcl_ObjectIsa(contextObj, classDefn)) {
+
+            Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
+            return TCL_OK;
+        }
+
+    }
+
+    /*
+     *    Got this far, so assume that it is a valid object
+     */
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
+    ckfree(cmdName);
+
+    return TCL_OK;
+}
+
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_IsClassCmd()
+ *
+ *  Invoked by Tcl whenever the user issues an "itcl::is class"
+ *  command to test whether the argument is an itcl class or not
+ *  syntax:
+ *
+ *    itcl::is class commandname
+ *
+ *  Sets interp result to 1 if it is a class, 0 otherwise
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_IsClassCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* class/object info */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+
+    char           *cname;
+    char           *name;
+    ItclClass      *classDefn = NULL;
+    Tcl_Namespace  *contextNs = NULL;
+
+    /*
+     *    Need itcl::is class classname
+     */
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "commandname");
+        return TCL_ERROR;
+    }
+
+    name = Tcl_GetString(objv[1]);
+
+    /*
+     *    The object name may be a scoped value of the form
+     *    "namespace inscope <namesp> <command>".  If it is,
+     *    decode it.
+     */
+    if (Itcl_DecodeScopedCommand(interp, name, &contextNs, &cname) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    classDefn = Itcl_FindClass(interp, cname, /* no autoload */ 0);
+
+    /*
+     *    If classDefn is NULL, then it wasn't found, hence it
+     *    isn't a class
+     */
+    if (classDefn != NULL) {
+        Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
+    } else {
+        Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
+    }
+
+    ckfree(cname);
+
+    return TCL_OK;
+
+} /* end Itcl_IsClassCmd function */
diff --git a/8.x/itcl/generic/itcl_ensemble.c b/8.x/itcl/generic/itcl_ensemble.c
new file mode 100644 (file)
index 0000000..5109eca
--- /dev/null
@@ -0,0 +1,2231 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  This part handles ensembles, which support compound commands in Tcl.
+ *  The usual "info" command is an ensemble with parts like "info body"
+ *  and "info globals".  Extension developers can extend commands like
+ *  "info" by adding their own parts to the ensemble.
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_ensemble.c,v 1.13 2008/12/15 20:02:58 andreas_kupries Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ *  Data used to represent an ensemble:
+ */
+struct Ensemble;
+typedef struct EnsemblePart {
+    char *name;                 /* name of this part */
+    int minChars;               /* chars needed to uniquely identify part */
+    Command *cmdPtr;            /* command handling this part */
+    char *usage;                /* usage string describing syntax */
+    struct Ensemble* ensemble;  /* ensemble containing this part */
+} EnsemblePart;
+
+/*
+ *  Data used to represent an ensemble:
+ */
+typedef struct Ensemble {
+    Tcl_Interp *interp;         /* interpreter containing this ensemble */
+    EnsemblePart **parts;       /* list of parts in this ensemble */
+    int numParts;               /* number of parts in part list */
+    int maxParts;               /* current size of parts list */
+    Tcl_Command cmd;            /* command representing this ensemble */
+    EnsemblePart* parent;       /* parent part for sub-ensembles
+                                 * NULL => toplevel ensemble */
+} Ensemble;
+
+/*
+ *  Data shared by ensemble access commands and ensemble parser:
+ */
+typedef struct EnsembleParser {
+    Tcl_Interp* master;           /* master interp containing ensembles */
+    Tcl_Interp* parser;           /* slave interp for parsing */
+    Ensemble* ensData;            /* add parts to this ensemble */
+} EnsembleParser;
+
+/*
+ *  Declarations for local procedures to this file:
+ */
+static void FreeEnsInvocInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr));
+static void DupEnsInvocInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr,
+    Tcl_Obj *copyPtr));
+static void UpdateStringOfEnsInvoc _ANSI_ARGS_((Tcl_Obj *objPtr));
+static int SetEnsInvocFromAny _ANSI_ARGS_((Tcl_Interp *interp,
+    Tcl_Obj *objPtr));
+
+/*
+ *  This structure defines a Tcl object type that takes the
+ *  place of a part name during ensemble invocations.  When an
+ *  error occurs and the caller tries to print objv[0], it will
+ *  get a string that contains a complete path to the ensemble
+ *  part.
+ */
+Tcl_ObjType itclEnsInvocType = {
+    "ensembleInvoc",                    /* name */
+    FreeEnsInvocInternalRep,            /* freeIntRepProc */
+    DupEnsInvocInternalRep,             /* dupIntRepProc */
+    UpdateStringOfEnsInvoc,             /* updateStringProc */
+    SetEnsInvocFromAny                  /* setFromAnyProc */
+};
+
+
+/*
+ *  Forward declarations for the procedures used in this file.
+ */
+static void GetEnsembleUsage _ANSI_ARGS_((Ensemble *ensData,
+    Tcl_Obj *objPtr));
+
+static void GetEnsemblePartUsage _ANSI_ARGS_((EnsemblePart *ensPart,
+    Tcl_Obj *objPtr));
+
+static int CreateEnsemble _ANSI_ARGS_((Tcl_Interp *interp,
+    Ensemble *parentEnsData, char *ensName));
+
+static int AddEnsemblePart _ANSI_ARGS_((Tcl_Interp *interp,
+    Ensemble* ensData, CONST char* partName, CONST char* usageInfo,
+    Tcl_ObjCmdProc *objProc, ClientData clientData,
+    Tcl_CmdDeleteProc *deleteProc, EnsemblePart **rVal));
+
+static void DeleteEnsemble _ANSI_ARGS_((ClientData clientData));
+
+static int FindEnsemble _ANSI_ARGS_((Tcl_Interp *interp, char **nameArgv,
+    int nameArgc, Ensemble** ensDataPtr));
+
+static int CreateEnsemblePart _ANSI_ARGS_((Tcl_Interp *interp,
+    Ensemble *ensData, CONST char* partName, EnsemblePart **ensPartPtr));
+
+static void DeleteEnsemblePart _ANSI_ARGS_((EnsemblePart *ensPart));
+
+static int FindEnsemblePart _ANSI_ARGS_((Tcl_Interp *interp,
+    Ensemble *ensData, CONST char* partName, EnsemblePart **rensPart));
+
+static int FindEnsemblePartIndex _ANSI_ARGS_((Ensemble *ensData,
+    CONST char *partName, int *posPtr));
+
+static void ComputeMinChars _ANSI_ARGS_((Ensemble *ensData, int pos));
+
+static int HandleEnsemble _ANSI_ARGS_((ClientData clientData,
+    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
+
+static EnsembleParser* GetEnsembleParser _ANSI_ARGS_((Tcl_Interp *interp));
+
+static void DeleteEnsParser _ANSI_ARGS_((ClientData clientData,
+    Tcl_Interp* interp));
+
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_EnsembleInit --
+ *
+ *      Called when any interpreter is created to make sure that
+ *      things are properly set up for ensembles.
+ *
+ * Results:
+ *      Returns TCL_OK if successful, and TCL_ERROR if anything goes
+ *      wrong.
+ *
+ * Side effects:
+ *      On the first call, the "ensemble" object type is registered
+ *      with the Tcl compiler.  If an error is encountered, an error
+ *      is left as the result in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+       /* ARGSUSED */
+int
+Itcl_EnsembleInit(interp)
+    Tcl_Interp *interp;         /* interpreter being initialized */
+{
+    if (Tcl_GetObjType(itclEnsInvocType.name) == NULL) {
+        Tcl_RegisterObjType(&itclEnsInvocType);
+    }
+
+    Tcl_CreateObjCommand(interp, "::itcl::ensemble",
+        Itcl_EnsembleCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
+
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_CreateEnsemble --
+ *
+ *      Creates an ensemble command, or adds a sub-ensemble to an
+ *      existing ensemble command.  The ensemble name is a space-
+ *      separated list.  The first word in the list is the command
+ *      name for the top-level ensemble.  Other names do not have
+ *      commands associated with them; they are merely sub-ensembles
+ *      within the ensemble.  So a name like "a::b::foo bar baz"
+ *      represents an ensemble command called "foo" in the namespace
+ *      "a::b" that has a sub-ensemble "bar", that has a sub-ensemble
+ *      "baz".
+ *
+ *      If the name is a single word, then this procedure creates
+ *      a top-level ensemble and installs an access command for it.
+ *      If a command already exists with that name, it is deleted.
+ *
+ *      If the name has more than one word, then the leading words
+ *      are treated as a path name for an existing ensemble.  The
+ *      last word is treated as the name for a new sub-ensemble.
+ *      If an part already exists with that name, it is an error.
+ *
+ * Results:
+ *      Returns TCL_OK if successful, and TCL_ERROR if anything goes
+ *      wrong.
+ *
+ * Side effects:
+ *      If an error is encountered, an error is left as the result
+ *      in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+Itcl_CreateEnsemble(interp, ensName)
+    Tcl_Interp *interp;            /* interpreter to be updated */
+    CONST char* ensName;           /* name of the new ensemble */
+{
+    char **nameArgv = NULL;
+    int nameArgc;
+    Ensemble *parentEnsData;
+    Tcl_DString buffer;
+
+    /*
+     *  Split the ensemble name into its path components.
+     */
+    if (Tcl_SplitList(interp, (CONST84 char *)ensName, &nameArgc,
+           &nameArgv) != TCL_OK) {
+        goto ensCreateFail;
+    }
+    if (nameArgc < 1) {
+        Tcl_AppendResult(interp,
+            "invalid ensemble name \"", ensName, "\"",
+            (char*)NULL);
+        goto ensCreateFail;
+    }
+
+    /*
+     *  If there is more than one path component, then follow
+     *  the path down to the last component, to find the containing
+     *  ensemble.
+     */
+    parentEnsData = NULL;
+    if (nameArgc > 1) {
+        if (FindEnsemble(interp, nameArgv, nameArgc-1, &parentEnsData)
+            != TCL_OK) {
+            goto ensCreateFail;
+        }
+
+        if (parentEnsData == NULL) {
+            char *pname = Tcl_Merge(nameArgc-1, nameArgv);
+            Tcl_AppendResult(interp,
+                "invalid ensemble name \"", pname, "\"",
+                (char*)NULL);
+            ckfree(pname);
+            goto ensCreateFail;
+        }
+    }
+
+    /*
+     *  Create the ensemble.
+     */
+    if (CreateEnsemble(interp, parentEnsData, nameArgv[nameArgc-1])
+        != TCL_OK) {
+        goto ensCreateFail;
+    }
+
+    ckfree((char*)nameArgv);
+    return TCL_OK;
+
+ensCreateFail:
+    if (nameArgv) {
+        ckfree((char*)nameArgv);
+    }
+    Tcl_DStringInit(&buffer);
+    Tcl_DStringAppend(&buffer, "\n    (while creating ensemble \"", -1);
+    Tcl_DStringAppend(&buffer, ensName, -1);
+    Tcl_DStringAppend(&buffer, "\")", -1);
+    Tcl_AddObjErrorInfo(interp, Tcl_DStringValue(&buffer), -1);
+    Tcl_DStringFree(&buffer);
+
+    return TCL_ERROR;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_AddEnsemblePart --
+ *
+ *      Adds a part to an ensemble which has been created by
+ *      Itcl_CreateEnsemble.  Ensembles are addressed by name, as
+ *      described in Itcl_CreateEnsemble.
+ *
+ *      If the ensemble already has a part with the specified name,
+ *      this procedure returns an error.  Otherwise, it adds a new
+ *      part to the ensemble.
+ *
+ *      Any client data specified is automatically passed to the
+ *      handling procedure whenever the part is invoked.  It is
+ *      automatically destroyed by the deleteProc when the part is
+ *      deleted.
+ *
+ * Results:
+ *      Returns TCL_OK if successful, and TCL_ERROR if anything goes
+ *      wrong.
+ *
+ * Side effects:
+ *      If an error is encountered, an error is left as the result
+ *      in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+Itcl_AddEnsemblePart(interp, ensName, partName, usageInfo,
+    objProc, clientData, deleteProc)
+
+    Tcl_Interp *interp;            /* interpreter to be updated */
+    CONST char* ensName;           /* ensemble containing this part */
+    CONST char* partName;          /* name of the new part */
+    CONST char* usageInfo;         /* usage info for argument list */
+    Tcl_ObjCmdProc *objProc;       /* handling procedure for part */
+    ClientData clientData;         /* client data associated with part */
+    Tcl_CmdDeleteProc *deleteProc; /* procedure used to destroy client data */
+{
+    char **nameArgv = NULL;
+    int nameArgc;
+    Ensemble *ensData;
+    EnsemblePart *ensPart;
+    Tcl_DString buffer;
+
+    /*
+     *  Parse the ensemble name and look for a containing ensemble.
+     */
+    if (Tcl_SplitList(interp, (CONST84 char *)ensName, &nameArgc,
+           &nameArgv) != TCL_OK) {
+        goto ensPartFail;
+    }
+    if (FindEnsemble(interp, nameArgv, nameArgc, &ensData) != TCL_OK) {
+        goto ensPartFail;
+    }
+
+    if (ensData == NULL) {
+        char *pname = Tcl_Merge(nameArgc, nameArgv);
+        Tcl_AppendResult(interp,
+            "invalid ensemble name \"", pname, "\"",
+            (char*)NULL);
+        ckfree(pname);
+        goto ensPartFail;
+    }
+
+    /*
+     *  Install the new part into the part list.
+     */
+    if (AddEnsemblePart(interp, ensData, partName, usageInfo,
+        objProc, clientData, deleteProc, &ensPart) != TCL_OK) {
+        goto ensPartFail;
+    }
+
+    ckfree((char*)nameArgv);
+    return TCL_OK;
+
+ensPartFail:
+    if (nameArgv) {
+        ckfree((char*)nameArgv);
+    }
+    Tcl_DStringInit(&buffer);
+    Tcl_DStringAppend(&buffer, "\n    (while adding to ensemble \"", -1);
+    Tcl_DStringAppend(&buffer, ensName, -1);
+    Tcl_DStringAppend(&buffer, "\")", -1);
+    Tcl_AddObjErrorInfo(interp, Tcl_DStringValue(&buffer), -1);
+    Tcl_DStringFree(&buffer);
+
+    return TCL_ERROR;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_GetEnsemblePart --
+ *
+ *      Looks for a part within an ensemble, and returns information
+ *      about it.
+ *
+ * Results:
+ *      If the ensemble and its part are found, this procedure
+ *      loads information about the part into the "infoPtr" structure
+ *      and returns 1.  Otherwise, it returns 0.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+Itcl_GetEnsemblePart(interp, ensName, partName, infoPtr)
+    Tcl_Interp *interp;            /* interpreter to be updated */
+    CONST char *ensName;           /* ensemble containing the part */
+    CONST char *partName;          /* name of the desired part */
+    Tcl_CmdInfo *infoPtr;          /* returns: info associated with part */
+{
+    char **nameArgv = NULL;
+    int nameArgc;
+    Ensemble *ensData;
+    EnsemblePart *ensPart;
+    Command *cmdPtr;
+    Itcl_InterpState state;
+
+    /*
+     *  Parse the ensemble name and look for a containing ensemble.
+     *  Save the interpreter state before we do this.  If we get any
+     *  errors, we don't want them to affect the interpreter.
+     */
+    state = Itcl_SaveInterpState(interp, TCL_OK);
+
+    if (Tcl_SplitList(interp, (CONST84 char *)ensName, &nameArgc,
+           &nameArgv) != TCL_OK) {
+        goto ensGetFail;
+    }
+    if (FindEnsemble(interp, nameArgv, nameArgc, &ensData) != TCL_OK) {
+        goto ensGetFail;
+    }
+    if (ensData == NULL) {
+        goto ensGetFail;
+    }
+
+    /*
+     *  Look for a part with the desired name.  If found, load
+     *  its data into the "infoPtr" structure.
+     */
+    if (FindEnsemblePart(interp, ensData, partName, &ensPart)
+        != TCL_OK || ensPart == NULL) {
+        goto ensGetFail;
+    }
+
+    cmdPtr = ensPart->cmdPtr;
+    infoPtr->isNativeObjectProc = (cmdPtr->objProc != TclInvokeStringCommand);
+    infoPtr->objProc = cmdPtr->objProc;
+    infoPtr->objClientData = cmdPtr->objClientData;
+    infoPtr->proc = cmdPtr->proc;
+    infoPtr->clientData = cmdPtr->clientData;
+    infoPtr->deleteProc = cmdPtr->deleteProc;
+    infoPtr->deleteData = cmdPtr->deleteData;
+    infoPtr->namespacePtr = (Tcl_Namespace*)cmdPtr->nsPtr;
+
+    Itcl_DiscardInterpState(state);
+    return 1;
+
+ensGetFail:
+    Itcl_RestoreInterpState(interp, state);
+    return 0;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_IsEnsemble --
+ *
+ *      Determines whether or not an existing command is an ensemble.
+ *
+ * Results:
+ *      Returns non-zero if the command is an ensemble, and zero
+ *      otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+Itcl_IsEnsemble(infoPtr)
+    Tcl_CmdInfo* infoPtr;  /* command info from Tcl_GetCommandInfo() */
+{
+    if (infoPtr) {
+        return (infoPtr->deleteProc == DeleteEnsemble);
+    }
+    return 0;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_GetEnsembleUsage --
+ *
+ *      Returns a summary of all of the parts of an ensemble and
+ *      the meaning of their arguments.  Each part is listed on
+ *      a separate line.  Having this summary is sometimes useful
+ *      when building error messages for the "@error" handler in
+ *      an ensemble.
+ *
+ *      Ensembles are accessed by name, as described in
+ *      Itcl_CreateEnsemble.
+ *
+ * Results:
+ *      If the ensemble is found, its usage information is appended
+ *      onto the object "objPtr", and this procedure returns
+ *      non-zero.  It is the responsibility of the caller to
+ *      initialize and free the object.  If anything goes wrong,
+ *      this procedure returns 0.
+ *
+ * Side effects:
+ *      Object passed in is modified.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+Itcl_GetEnsembleUsage(interp, ensName, objPtr)
+    Tcl_Interp *interp;    /* interpreter containing the ensemble */
+    CONST char *ensName;         /* name of the ensemble */
+    Tcl_Obj *objPtr;       /* returns: summary of usage info */
+{
+    char **nameArgv = NULL;
+    int nameArgc;
+    Ensemble *ensData;
+    Itcl_InterpState state;
+
+    /*
+     *  Parse the ensemble name and look for the ensemble.
+     *  Save the interpreter state before we do this.  If we get
+     *  any errors, we don't want them to affect the interpreter.
+     */
+    state = Itcl_SaveInterpState(interp, TCL_OK);
+
+    if (Tcl_SplitList(interp, (CONST84 char *)ensName, &nameArgc,
+           &nameArgv) != TCL_OK) {
+        goto ensUsageFail;
+    }
+    if (FindEnsemble(interp, nameArgv, nameArgc, &ensData) != TCL_OK) {
+        goto ensUsageFail;
+    }
+    if (ensData == NULL) {
+        goto ensUsageFail;
+    }
+
+    /*
+     *  Add a summary of usage information to the return buffer.
+     */
+    GetEnsembleUsage(ensData, objPtr);
+
+    Itcl_DiscardInterpState(state);
+    return 1;
+
+ensUsageFail:
+    Itcl_RestoreInterpState(interp, state);
+    return 0;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_GetEnsembleUsageForObj --
+ *
+ *      Returns a summary of all of the parts of an ensemble and
+ *      the meaning of their arguments.  This procedure is just
+ *      like Itcl_GetEnsembleUsage, but it determines the desired
+ *      ensemble from a command line argument.  The argument should
+ *      be the first argument on the command line--the ensemble
+ *      command or one of its parts.
+ *
+ * Results:
+ *      If the ensemble is found, its usage information is appended
+ *      onto the object "objPtr", and this procedure returns
+ *      non-zero.  It is the responsibility of the caller to
+ *      initialize and free the object.  If anything goes wrong,
+ *      this procedure returns 0.
+ *
+ * Side effects:
+ *      Object passed in is modified.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+Itcl_GetEnsembleUsageForObj(interp, ensObjPtr, objPtr)
+    Tcl_Interp *interp;    /* interpreter containing the ensemble */
+    Tcl_Obj *ensObjPtr;    /* argument representing ensemble */
+    Tcl_Obj *objPtr;       /* returns: summary of usage info */
+{
+    Ensemble *ensData;
+    Tcl_Obj *chainObj;
+    Tcl_Command cmd;
+    Command *cmdPtr;
+
+    /*
+     *  If the argument is an ensemble part, then follow the chain
+     *  back to the command word for the entire ensemble.
+     */
+    chainObj = ensObjPtr;
+    while (chainObj && chainObj->typePtr == &itclEnsInvocType) {
+         chainObj = (Tcl_Obj*)chainObj->internalRep.twoPtrValue.ptr2;
+    }
+
+    if (chainObj) {
+        cmd = Tcl_GetCommandFromObj(interp, chainObj);
+        cmdPtr = (Command*)cmd;
+        if (cmdPtr->deleteProc == DeleteEnsemble) {
+            ensData = (Ensemble*)cmdPtr->objClientData;
+            GetEnsembleUsage(ensData, objPtr);
+            return 1;
+        }
+    }
+    return 0;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetEnsembleUsage --
+ *
+ *      
+ *      Returns a summary of all of the parts of an ensemble and
+ *      the meaning of their arguments.  Each part is listed on
+ *      a separate line.  This procedure is used internally to
+ *      generate usage information for error messages.
+ *
+ * Results:
+ *      Appends usage information onto the object in "objPtr".
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+GetEnsembleUsage(ensData, objPtr)
+    Ensemble *ensData;     /* ensemble data */
+    Tcl_Obj *objPtr;       /* returns: summary of usage info */
+{
+    char *spaces = "  ";
+    int isOpenEnded = 0;
+
+    int i;
+    EnsemblePart *ensPart;
+
+    for (i=0; i < ensData->numParts; i++) {
+        ensPart = ensData->parts[i];
+
+        if (*ensPart->name == '@' && strcmp(ensPart->name,"@error") == 0) {
+            isOpenEnded = 1;
+        }
+        else {
+            Tcl_AppendToObj(objPtr, spaces, -1);
+            GetEnsemblePartUsage(ensPart, objPtr);
+            spaces = "\n  ";
+        }
+    }
+    if (isOpenEnded) {
+        Tcl_AppendToObj(objPtr,
+            "\n...and others described on the man page", -1);
+    }
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetEnsemblePartUsage --
+ *
+ *      Determines the usage for a single part within an ensemble,
+ *      and appends a summary onto a dynamic string.  The usage
+ *      is a combination of the part name and the argument summary.
+ *      It is the caller's responsibility to initialize and free
+ *      the dynamic string.
+ *
+ * Results:
+ *      Returns usage information in the object "objPtr".
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+GetEnsemblePartUsage(ensPart, objPtr)
+    EnsemblePart *ensPart;   /* ensemble part for usage info */
+    Tcl_Obj *objPtr;         /* returns: usage information */
+{
+    EnsemblePart *part;
+    Command *cmdPtr;
+    char *name;
+    Itcl_List trail;
+    Itcl_ListElem *elem;
+    Tcl_DString buffer;
+
+    /*
+     *  Build the trail of ensemble names leading to this part.
+     */
+    Tcl_DStringInit(&buffer);
+    Itcl_InitList(&trail);
+    for (part=ensPart; part; part=part->ensemble->parent) {
+        Itcl_InsertList(&trail, (ClientData)part);
+    }
+
+    cmdPtr = (Command*)ensPart->ensemble->cmd;
+    name = Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
+    Tcl_DStringAppendElement(&buffer, name);
+
+    for (elem=Itcl_FirstListElem(&trail); elem; elem=Itcl_NextListElem(elem)) {
+        part = (EnsemblePart*)Itcl_GetListValue(elem);
+        Tcl_DStringAppendElement(&buffer, part->name);
+    }
+    Itcl_DeleteList(&trail);
+
+    /*
+     *  If the part has usage info, use it directly.
+     */
+    if (ensPart->usage && *ensPart->usage != '\0') {
+        Tcl_DStringAppend(&buffer, " ", 1);
+        Tcl_DStringAppend(&buffer, ensPart->usage, -1);
+    }
+
+    /*
+     *  If the part is itself an ensemble, summarize its usage.
+     */
+    else if (ensPart->cmdPtr &&
+             ensPart->cmdPtr->deleteProc == DeleteEnsemble) {
+        Tcl_DStringAppend(&buffer, " option ?arg arg ...?", 21);
+    }
+
+    Tcl_AppendToObj(objPtr, Tcl_DStringValue(&buffer),
+        Tcl_DStringLength(&buffer));
+
+    Tcl_DStringFree(&buffer);
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * CreateEnsemble --
+ *
+ *      Creates an ensemble command, or adds a sub-ensemble to an
+ *      existing ensemble command.  Works like Itcl_CreateEnsemble,
+ *      except that the ensemble name is a single name, not a path.
+ *      If a parent ensemble is specified, then a new ensemble is
+ *      added to that parent.  If a part already exists with the
+ *      same name, it is an error.  If a parent ensemble is not
+ *      specified, then a top-level ensemble is created.  If a
+ *      command already exists with the same name, it is deleted.
+ *
+ * Results:
+ *      Returns TCL_OK if successful, and TCL_ERROR if anything goes
+ *      wrong.
+ *
+ * Side effects:
+ *      If an error is encountered, an error is left as the result
+ *      in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+CreateEnsemble(interp, parentEnsData, ensName)
+    Tcl_Interp *interp;            /* interpreter to be updated */
+    Ensemble *parentEnsData;       /* parent ensemble or NULL */
+    char *ensName;                 /* name of the new ensemble */
+{
+    Ensemble *ensData;
+    EnsemblePart *ensPart;
+    Command *cmdPtr;
+    Tcl_CmdInfo cmdInfo;
+
+    /*
+     *  Create the data associated with the ensemble.
+     */
+    ensData = (Ensemble*)ckalloc(sizeof(Ensemble));
+    ensData->interp = interp;
+    ensData->numParts = 0;
+    ensData->maxParts = 10;
+    ensData->parts = (EnsemblePart**)ckalloc(
+        (unsigned)(ensData->maxParts*sizeof(EnsemblePart*))
+    );
+    ensData->cmd = NULL;
+    ensData->parent = NULL;
+
+    /*
+     *  If there is no parent data, then this is a top-level
+     *  ensemble.  Create the ensemble by installing its access
+     *  command.
+     *
+     *  BE CAREFUL:  Set the string-based proc to the wrapper
+     *    procedure TclInvokeObjectCommand.  Otherwise, the
+     *    ensemble command may fail.  For example, it will fail
+     *    when invoked as a hidden command.
+     */
+    if (parentEnsData == NULL) {
+        ensData->cmd = Tcl_CreateObjCommand(interp, ensName,
+            HandleEnsemble, (ClientData)ensData, DeleteEnsemble);
+
+        if (Tcl_GetCommandInfo(interp, ensName, &cmdInfo)) {
+            cmdInfo.proc = TclInvokeObjectCommand;
+            Tcl_SetCommandInfo(interp, ensName, &cmdInfo);
+        }
+        return TCL_OK;
+    }
+
+    /*
+     *  Otherwise, this ensemble is contained within another parent.
+     *  Install the new ensemble as a part within its parent.
+     */
+    if (CreateEnsemblePart(interp, parentEnsData, ensName, &ensPart)
+        != TCL_OK) {
+        DeleteEnsemble((ClientData)ensData);
+        return TCL_ERROR;
+    }
+
+    ensData->cmd               = parentEnsData->cmd;
+    ensData->parent            = ensPart;
+
+    /*
+     * Initialize non-NULL data only.  This allows us to handle the
+     * structure differences between versions better.
+     */
+    cmdPtr                     = (Command *) ckalloc(sizeof(Command));
+    memset((VOID *) cmdPtr, 0, sizeof(Command));
+    cmdPtr->nsPtr              = ((Command *) ensData->cmd)->nsPtr;
+    cmdPtr->objProc            = HandleEnsemble;
+    cmdPtr->objClientData      = (ClientData)ensData;
+    cmdPtr->deleteProc         = DeleteEnsemble;
+    cmdPtr->deleteData         = cmdPtr->objClientData;
+
+    ensPart->cmdPtr            = cmdPtr;
+
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * AddEnsemblePart --
+ *
+ *      Adds a part to an existing ensemble.  Works like
+ *      Itcl_AddEnsemblePart, but the part name is a single word,
+ *      not a path.
+ *
+ *      If the ensemble already has a part with the specified name,
+ *      this procedure returns an error.  Otherwise, it adds a new
+ *      part to the ensemble.
+ *
+ *      Any client data specified is automatically passed to the
+ *      handling procedure whenever the part is invoked.  It is
+ *      automatically destroyed by the deleteProc when the part is
+ *      deleted.
+ *
+ * Results:
+ *      Returns TCL_OK if successful, along with a pointer to the
+ *      new part.  Returns TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *      If an error is encountered, an error is left as the result
+ *      in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+AddEnsemblePart(interp, ensData, partName, usageInfo,
+    objProc, clientData, deleteProc, rVal)
+
+    Tcl_Interp *interp;            /* interpreter to be updated */
+    Ensemble* ensData;             /* ensemble that will contain this part */
+    CONST char* partName;          /* name of the new part */
+    CONST char* usageInfo;         /* usage info for argument list */
+    Tcl_ObjCmdProc *objProc;       /* handling procedure for part */
+    ClientData clientData;         /* client data associated with part */
+    Tcl_CmdDeleteProc *deleteProc; /* procedure used to destroy client data */
+    EnsemblePart **rVal;           /* returns: new ensemble part */
+{
+    EnsemblePart *ensPart;
+    Command *cmdPtr;
+
+    /*
+     *  Install the new part into the part list.
+     */
+    if (CreateEnsemblePart(interp, ensData, partName, &ensPart) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    if (usageInfo) {
+        ensPart->usage = ckalloc((unsigned)(strlen(usageInfo)+1));
+        strcpy(ensPart->usage, usageInfo);
+    }
+
+    /*
+     * Initialize non-NULL data only.  This allows us to handle the
+     * structure differences between versions better.
+     */
+    cmdPtr                     = (Command *) ckalloc(sizeof(Command));
+    memset((VOID *) cmdPtr, 0, sizeof(Command));
+    cmdPtr->nsPtr              = ((Command *) ensData->cmd)->nsPtr;
+    cmdPtr->objProc            = objProc;
+    cmdPtr->objClientData      = (ClientData)clientData;
+    cmdPtr->deleteProc         = deleteProc;
+    cmdPtr->deleteData         = (ClientData)clientData;
+
+    ensPart->cmdPtr            = cmdPtr;
+    *rVal                      = ensPart;
+
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteEnsemble --
+ *
+ *      Invoked when the command associated with an ensemble is
+ *      destroyed, to delete the ensemble.  Destroys all parts
+ *      included in the ensemble, and frees all memory associated
+ *      with it.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+DeleteEnsemble(clientData)
+    ClientData clientData;    /* ensemble data */
+{
+    Ensemble* ensData = (Ensemble*)clientData;
+
+    /*
+     *  BE CAREFUL:  Each ensemble part removes itself from the list.
+     *    So keep deleting the first part until all parts are gone.
+     */
+    while (ensData->numParts > 0) {
+        DeleteEnsemblePart(ensData->parts[0]);
+    }
+    ckfree((char*)ensData->parts);
+    ckfree((char*)ensData);
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * FindEnsemble --
+ *
+ *      Searches for an ensemble command and follows a path to
+ *      sub-ensembles.
+ *
+ * Results:
+ *      Returns TCL_OK if the ensemble was found, along with a
+ *      pointer to the ensemble data in "ensDataPtr".  Returns
+ *      TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *      If anything goes wrong, this procedure returns an error
+ *      message as the result in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+FindEnsemble(interp, nameArgv, nameArgc, ensDataPtr)
+    Tcl_Interp *interp;            /* interpreter containing the ensemble */
+    char **nameArgv;               /* path of names leading to ensemble */
+    int nameArgc;                  /* number of strings in nameArgv */
+    Ensemble** ensDataPtr;         /* returns: ensemble data */
+{
+    int i;
+    Command* cmdPtr;
+    Ensemble *ensData;
+    EnsemblePart *ensPart;
+
+    *ensDataPtr = NULL;  /* assume that no data will be found */
+
+    /*
+     *  If there are no names in the path, then return an error.
+     */
+    if (nameArgc < 1) {
+        Tcl_AppendToObj(Tcl_GetObjResult(interp),
+            "invalid ensemble name \"\"", -1);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Use the first name to find the command for the top-level
+     *  ensemble.
+     */
+    cmdPtr = (Command*) Tcl_FindCommand(interp, nameArgv[0],
+        (Tcl_Namespace*)NULL, TCL_LEAVE_ERR_MSG);
+
+    if (cmdPtr == NULL || cmdPtr->deleteProc != DeleteEnsemble) {
+        Tcl_AppendResult(interp,
+            "command \"", nameArgv[0], "\" is not an ensemble",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+    ensData = (Ensemble*)cmdPtr->objClientData;
+
+    /*
+     *  Follow the trail of sub-ensemble names.
+     */
+    for (i=1; i < nameArgc; i++) {
+        if (FindEnsemblePart(interp, ensData, nameArgv[i], &ensPart)
+            != TCL_OK) {
+            return TCL_ERROR;
+        }
+        if (ensPart == NULL) {
+            char *pname = Tcl_Merge(i, nameArgv);
+            Tcl_AppendResult(interp,
+                "invalid ensemble name \"", pname, "\"",
+                (char*)NULL);
+            ckfree(pname);
+            return TCL_ERROR;
+        }
+
+        cmdPtr = ensPart->cmdPtr;
+        if (cmdPtr == NULL || cmdPtr->deleteProc != DeleteEnsemble) {
+            Tcl_AppendResult(interp,
+                "part \"", nameArgv[i], "\" is not an ensemble",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+        ensData = (Ensemble*)cmdPtr->objClientData;
+    }
+    *ensDataPtr = ensData;
+
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * CreateEnsemblePart --
+ *
+ *      Creates a new part within an ensemble.
+ *
+ * Results:
+ *      If successful, this procedure returns TCL_OK, along with a
+ *      pointer to the new part in "ensPartPtr".  If a part with the
+ *      same name already exists, this procedure returns TCL_ERROR.
+ *
+ * Side effects:
+ *      If anything goes wrong, this procedure returns an error
+ *      message as the result in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+CreateEnsemblePart(interp, ensData, partName, ensPartPtr)
+    Tcl_Interp *interp;          /* interpreter containing the ensemble */
+    Ensemble *ensData;           /* ensemble being modified */
+    CONST char* partName;        /* name of the new part */
+    EnsemblePart **ensPartPtr;   /* returns: new ensemble part */
+{
+    int i, pos, size;
+    EnsemblePart** partList;
+    EnsemblePart* part;
+
+    /*
+     *  If a matching entry was found, then return an error.
+     */
+    if (FindEnsemblePartIndex(ensData, partName, &pos)) {
+        Tcl_AppendResult(interp,
+            "part \"", partName, "\" already exists in ensemble",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Otherwise, make room for a new entry.  Keep the parts in
+     *  lexicographical order, so we can search them quickly
+     *  later.
+     */
+    if (ensData->numParts >= ensData->maxParts) {
+        size = ensData->maxParts*sizeof(EnsemblePart*);
+        partList = (EnsemblePart**)ckalloc((unsigned)2*size);
+        memcpy((VOID*)partList, (VOID*)ensData->parts, (size_t)size);
+        ckfree((char*)ensData->parts);
+
+        ensData->parts = partList;
+        ensData->maxParts *= 2;
+    }
+
+    for (i=ensData->numParts; i > pos; i--) {
+        ensData->parts[i] = ensData->parts[i-1];
+    }
+    ensData->numParts++;
+
+    part = (EnsemblePart*)ckalloc(sizeof(EnsemblePart));
+    part->name = (char*)ckalloc((unsigned)(strlen(partName)+1));
+    strcpy(part->name, partName);
+    part->cmdPtr   = NULL;
+    part->usage    = NULL;
+    part->ensemble = ensData;
+
+    ensData->parts[pos] = part;
+
+    /*
+     *  Compare the new part against the one on either side of
+     *  it.  Determine how many letters are needed in each part
+     *  to guarantee that an abbreviated form is unique.  Update
+     *  the parts on either side as well, since they are influenced
+     *  by the new part.
+     */
+    ComputeMinChars(ensData, pos);
+    ComputeMinChars(ensData, pos-1);
+    ComputeMinChars(ensData, pos+1);
+
+    *ensPartPtr = part;
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteEnsemblePart --
+ *
+ *      Deletes a single part from an ensemble.  The part must have 
+ *      been created previously by CreateEnsemblePart.
+ *
+ *      If the part has a delete proc, then it is called to free the
+ *      associated client data.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Delete proc is called.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+DeleteEnsemblePart(ensPart)
+    EnsemblePart *ensPart;     /* part being destroyed */
+{
+    int i, pos;
+    Command *cmdPtr;
+    Ensemble *ensData;
+    cmdPtr = ensPart->cmdPtr;
+
+    /*
+     *  If this part has a delete proc, then call it to free
+     *  up the client data.
+     */
+    if (cmdPtr->deleteData && cmdPtr->deleteProc) {
+        (*cmdPtr->deleteProc)(cmdPtr->deleteData);
+    }
+    ckfree((char*)cmdPtr);
+
+    /*
+     *  Find this part within its ensemble, and remove it from
+     *  the list of parts.
+     */
+    if (FindEnsemblePartIndex(ensPart->ensemble, ensPart->name, &pos)) {
+        ensData = ensPart->ensemble;
+        for (i=pos; i < ensData->numParts-1; i++) {
+            ensData->parts[i] = ensData->parts[i+1];
+        }
+        ensData->numParts--;
+    }
+
+    /*
+     *  Free the memory associated with the part.
+     */
+    if (ensPart->usage) {
+        ckfree(ensPart->usage);
+    }
+    ckfree(ensPart->name);
+    ckfree((char*)ensPart);
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * FindEnsemblePart --
+ *
+ *      Searches for a part name within an ensemble.  Recognizes
+ *      unique abbreviations for part names.
+ *
+ * Results:
+ *      If the part name is not a unique abbreviation, this procedure
+ *      returns TCL_ERROR.  Otherwise, it returns TCL_OK.  If the
+ *      part can be found, "rensPart" returns a pointer to the part.
+ *      Otherwise, it returns NULL.
+ *
+ * Side effects:
+ *      If anything goes wrong, this procedure returns an error
+ *      message as the result in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+FindEnsemblePart(interp, ensData, partName, rensPart)
+    Tcl_Interp *interp;       /* interpreter containing the ensemble */
+    Ensemble *ensData;        /* ensemble being searched */
+    CONST char* partName;     /* name of the desired part */
+    EnsemblePart **rensPart;  /* returns:  pointer to the desired part */
+{
+    int pos = 0;
+    int first, last, nlen;
+    int i, cmp;
+
+    *rensPart = NULL;
+
+    /*
+     *  Search for the desired part name.
+     *  All parts are in lexicographical order, so use a
+     *  binary search to find the part quickly.  Match only
+     *  as many characters as are included in the specified
+     *  part name.
+     */
+    first = 0;
+    last  = ensData->numParts-1;
+    nlen  = strlen(partName);
+
+    while (last >= first) {
+        pos = (first+last)/2;
+        if (*partName == *ensData->parts[pos]->name) {
+            cmp = strncmp(partName, ensData->parts[pos]->name, nlen);
+            if (cmp == 0) {
+                break;    /* found it! */
+            }
+        }
+        else if (*partName < *ensData->parts[pos]->name) {
+            cmp = -1;
+        }
+        else {
+            cmp = 1;
+        }
+
+        if (cmp > 0) {
+            first = pos+1;
+        } else {
+            last = pos-1;
+        }
+    }
+
+    /*
+     *  If a matching entry could not be found, then quit.
+     */
+    if (last < first) {
+        return TCL_OK;
+    }
+
+    /*
+     *  If a matching entry was found, there may be some ambiguity
+     *  if the user did not specify enough characters.  Find the
+     *  top-most match in the list, and see if the part name has
+     *  enough characters.  If there are two parts like "foo"
+     *  and "food", this allows us to match "foo" exactly.
+     */
+    if (nlen < ensData->parts[pos]->minChars) {
+        while (pos > 0) {
+            pos--;
+            if (strncmp(partName, ensData->parts[pos]->name, nlen) != 0) {
+                pos++;
+                break;
+            }
+        }
+    }
+    if (nlen < ensData->parts[pos]->minChars) {
+        Tcl_Obj *resultPtr = Tcl_NewStringObj((char*)NULL, 0);
+
+        Tcl_AppendStringsToObj(resultPtr,
+            "ambiguous option \"", partName, "\": should be one of...",
+            (char*)NULL);
+
+        for (i=pos; i < ensData->numParts; i++) {
+            if (strncmp(partName, ensData->parts[i]->name, nlen) != 0) {
+                break;
+            }
+            Tcl_AppendToObj(resultPtr, "\n  ", 3); 
+            GetEnsemblePartUsage(ensData->parts[i], resultPtr);
+        }
+        Tcl_SetObjResult(interp, resultPtr);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Found a match.  Return the desired part.
+     */
+    *rensPart = ensData->parts[pos];
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * FindEnsemblePartIndex --
+ *
+ *      Searches for a part name within an ensemble.  The part name
+ *      must be an exact match for an existing part name in the
+ *      ensemble.  This procedure is useful for managing (i.e.,
+ *      creating and deleting) parts in an ensemble.
+ *
+ * Results:
+ *      If an exact match is found, this procedure returns
+ *      non-zero, along with the index of the part in posPtr.
+ *      Otherwise, it returns zero, along with an index in posPtr
+ *      indicating where the part should be.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+FindEnsemblePartIndex(ensData, partName, posPtr)
+    Ensemble *ensData;        /* ensemble being searched */
+    CONST char *partName;     /* name of desired part */
+    int *posPtr;              /* returns: index for part */
+{
+    int pos = 0;
+    int first, last;
+    int cmp;
+
+    /*
+     *  Search for the desired part name.
+     *  All parts are in lexicographical order, so use a
+     *  binary search to find the part quickly.
+     */
+    first = 0;
+    last  = ensData->numParts-1;
+
+    while (last >= first) {
+        pos = (first+last)/2;
+        if (*partName == *ensData->parts[pos]->name) {
+            cmp = strcmp(partName, ensData->parts[pos]->name);
+            if (cmp == 0) {
+                break;    /* found it! */
+            }
+        }
+        else if (*partName < *ensData->parts[pos]->name) {
+            cmp = -1;
+        }
+        else {
+            cmp = 1;
+        }
+
+        if (cmp > 0) {
+            first = pos+1;
+        } else {
+            last = pos-1;
+        }
+    }
+
+    if (last >= first) {
+        *posPtr = pos;
+        return 1;
+    }
+    *posPtr = first;
+    return 0;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ComputeMinChars --
+ *
+ *      Compares part names on an ensemble's part list and
+ *      determines the minimum number of characters needed for a
+ *      unique abbreviation.  The parts on either side of a
+ *      particular part index are compared.  As long as there is
+ *      a part on one side or the other, this procedure updates
+ *      the parts to have the proper minimum abbreviations.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Updates three parts within the ensemble to remember
+ *      the minimum abbreviations.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+ComputeMinChars(ensData, pos)
+    Ensemble *ensData;        /* ensemble being modified */
+    int pos;                  /* index of part being updated */
+{
+    int min, max;
+    char *p, *q;
+
+    /*
+     *  If the position is invalid, do nothing.
+     */
+    if (pos < 0 || pos >= ensData->numParts) {
+        return;
+    }
+
+    /*
+     *  Start by assuming that only the first letter is required
+     *  to uniquely identify this part.  Then compare the name
+     *  against each neighboring part to determine the real minimum.
+     */
+    ensData->parts[pos]->minChars = 1;
+
+    if (pos-1 >= 0) {
+        p = ensData->parts[pos]->name;
+        q = ensData->parts[pos-1]->name;
+        for (min=1; *p == *q && *p != '\0' && *q != '\0'; min++) {
+            p++;
+            q++;
+        }
+        if (min > ensData->parts[pos]->minChars) {
+            ensData->parts[pos]->minChars = min;
+        }
+    }
+
+    if (pos+1 < ensData->numParts) {
+        p = ensData->parts[pos]->name;
+        q = ensData->parts[pos+1]->name;
+        for (min=1; *p == *q && *p != '\0' && *q != '\0'; min++) {
+            p++;
+            q++;
+        }
+        if (min > ensData->parts[pos]->minChars) {
+            ensData->parts[pos]->minChars = min;
+        }
+    }
+
+    max = strlen(ensData->parts[pos]->name);
+    if (ensData->parts[pos]->minChars > max) {
+        ensData->parts[pos]->minChars = max;
+    }
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * HandleEnsemble --
+ *
+ *      Invoked by Tcl whenever the user issues an ensemble-style
+ *      command.  Handles commands of the form:
+ *
+ *        <ensembleName> <partName> ?<arg> <arg>...?
+ *
+ *      Looks for the <partName> within the ensemble, and if it
+ *      exists, the procedure transfers control to it.
+ *
+ * Results:
+ *      Returns TCL_OK if successful, and TCL_ERROR if anything
+ *      goes wrong.
+ *
+ * Side effects:
+ *      If anything goes wrong, this procedure returns an error
+ *      message as the result in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+HandleEnsemble(clientData, interp, objc, objv)
+    ClientData clientData;   /* ensemble data */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Ensemble *ensData = (Ensemble*)clientData;
+
+    int i, result;
+    Command *cmdPtr;
+    EnsemblePart *ensPart;
+    char *partName;
+    int partNameLen;
+    Tcl_Obj *cmdlinePtr, *chainObj;
+    int cmdlinec;
+    Tcl_Obj **cmdlinev;
+
+    /*
+     *  If a part name is not specified, return an error that
+     *  summarizes the usage for this ensemble.
+     */
+    if (objc < 2) {
+        Tcl_Obj *resultPtr = Tcl_NewStringObj(
+            "wrong # args: should be one of...\n", -1);
+
+        GetEnsembleUsage(ensData, resultPtr);
+        Tcl_SetObjResult(interp, resultPtr);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Lookup the desired part.  If an ambiguous abbrevition is
+     *  found, return an error immediately.
+     */
+    partName = Tcl_GetStringFromObj(objv[1], &partNameLen);
+    if (FindEnsemblePart(interp, ensData, partName, &ensPart) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If the part was not found, then look for an "@error" part
+     *  to handle the error.
+     */
+    if (ensPart == NULL) {
+        if (FindEnsemblePart(interp, ensData, "@error", &ensPart) != TCL_OK) {
+            return TCL_ERROR;
+        }
+        if (ensPart != NULL) {
+            cmdPtr = (Command*)ensPart->cmdPtr;
+            result = (*cmdPtr->objProc)(cmdPtr->objClientData,
+                interp, objc, objv);
+            return result;
+        }
+    }
+    if (ensPart == NULL) {
+        return Itcl_EnsembleErrorCmd((ClientData)ensData,
+            interp, objc-1, objv+1);
+    }
+
+    /*
+     *  Pass control to the part, and return the result.
+     */
+    chainObj = Tcl_NewObj();
+    chainObj->bytes = NULL;
+    chainObj->typePtr = &itclEnsInvocType;
+    chainObj->internalRep.twoPtrValue.ptr1 = (VOID *) ensPart;
+    Tcl_IncrRefCount(objv[1]);
+    chainObj->internalRep.twoPtrValue.ptr2 = (VOID *) objv[0];
+    Tcl_IncrRefCount(objv[0]);
+
+    cmdlinePtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+    Tcl_ListObjAppendElement((Tcl_Interp*)NULL, cmdlinePtr, chainObj);
+    for (i=2; i < objc; i++) {
+        Tcl_ListObjAppendElement((Tcl_Interp*)NULL, cmdlinePtr, objv[i]);
+    }
+    Tcl_IncrRefCount(cmdlinePtr);
+
+    result = Tcl_ListObjGetElements((Tcl_Interp*)NULL, cmdlinePtr,
+        &cmdlinec, &cmdlinev);
+
+    if (result == TCL_OK) {
+        cmdPtr = (Command*)ensPart->cmdPtr;
+        result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp,
+            cmdlinec, cmdlinev);
+    }
+    Tcl_DecrRefCount(cmdlinePtr);
+
+    return result;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_EnsembleCmd --
+ *
+ *      Invoked by Tcl whenever the user issues the "ensemble"
+ *      command to manipulate an ensemble.  Handles the following
+ *      syntax:
+ *
+ *        ensemble <ensName> ?<command> <arg> <arg>...?
+ *        ensemble <ensName> {
+ *            part <partName> <args> <body>
+ *            ensemble <ensName> {
+ *                ...
+ *            }
+ *        }
+ *
+ *      Finds or creates the ensemble <ensName>, and then executes
+ *      the commands to add parts.
+ *
+ * Results:
+ *      Returns TCL_OK if successful, and TCL_ERROR if anything
+ *      goes wrong.
+ *
+ * Side effects:
+ *      If anything goes wrong, this procedure returns an error
+ *      message as the result in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+Itcl_EnsembleCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* ensemble data */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int status;
+    char *ensName;
+    EnsembleParser *ensInfo;
+    Ensemble *ensData, *savedEnsData;
+    EnsemblePart *ensPart;
+    Tcl_Command cmd;
+    Command *cmdPtr;
+    Tcl_Obj *objPtr;
+
+    /*
+     *  Make sure that an ensemble name was specified.
+     */
+    if (objc < 2) {
+        Tcl_AppendResult(interp,
+            "wrong # args: should be \"",
+            Tcl_GetStringFromObj(objv[0], (int*)NULL),
+            " name ?command arg arg...?\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If this is the "ensemble" command in the main interpreter,
+     *  then the client data will be null.  Otherwise, it is
+     *  the "ensemble" command in the ensemble body parser, and
+     *  the client data indicates which ensemble we are modifying.
+     */
+    if (clientData) {
+        ensInfo = (EnsembleParser*)clientData;
+    } else {
+        ensInfo = GetEnsembleParser(interp);
+    }
+    ensData = ensInfo->ensData;
+
+    /*
+     *  Find or create the desired ensemble.  If an ensemble is
+     *  being built, then this "ensemble" command is enclosed in
+     *  another "ensemble" command.  Use the current ensemble as
+     *  the parent, and find or create an ensemble part within it.
+     */
+    ensName = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+
+    if (ensData) {
+        if (FindEnsemblePart(interp, ensData, ensName, &ensPart) != TCL_OK) {
+            ensPart = NULL;
+        }
+        if (ensPart == NULL) {
+            if (CreateEnsemble(interp, ensData, ensName) != TCL_OK) {
+                return TCL_ERROR;
+            }
+            if (FindEnsemblePart(interp, ensData, ensName, &ensPart)
+                != TCL_OK) {
+                Tcl_Panic("Itcl_EnsembleCmd: can't create ensemble");
+            }
+        }
+
+        cmdPtr = (Command*)ensPart->cmdPtr;
+        if (cmdPtr->deleteProc != DeleteEnsemble) {
+            Tcl_AppendResult(interp,
+                "part \"", Tcl_GetStringFromObj(objv[1], (int*)NULL),
+                "\" is not an ensemble",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+        ensData = (Ensemble*)cmdPtr->objClientData;
+    }
+
+    /*
+     *  Otherwise, the desired ensemble is a top-level ensemble.
+     *  Find or create the access command for the ensemble, and
+     *  then get its data.
+     */
+    else {
+        cmd = Tcl_FindCommand(interp, ensName, (Tcl_Namespace*)NULL, 0);
+        if (cmd == NULL) {
+            if (CreateEnsemble(interp, (Ensemble*)NULL, ensName)
+                != TCL_OK) {
+                return TCL_ERROR;
+            }
+            cmd = Tcl_FindCommand(interp, ensName, (Tcl_Namespace*)NULL, 0);
+        }
+        cmdPtr = (Command*)cmd;
+
+        if (cmdPtr == NULL || cmdPtr->deleteProc != DeleteEnsemble) {
+            Tcl_AppendResult(interp,
+                "command \"", Tcl_GetStringFromObj(objv[1], (int*)NULL),
+                "\" is not an ensemble",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+        ensData = (Ensemble*)cmdPtr->objClientData;
+    }
+
+    /*
+     *  At this point, we have the data for the ensemble that is
+     *  being manipulated.  Plug this into the parser, and then
+     *  interpret the rest of the arguments in the ensemble parser. 
+     */
+    status = TCL_OK;
+    savedEnsData = ensInfo->ensData;
+    ensInfo->ensData = ensData;
+
+    if (objc == 3) {
+        status = Tcl_EvalObj(ensInfo->parser, objv[2]);
+    }
+    else if (objc > 3) {
+        objPtr = Tcl_NewListObj(objc-2, objv+2);
+        Tcl_IncrRefCount(objPtr);  /* stop Eval trashing it */
+        status = Tcl_EvalObj(ensInfo->parser, objPtr);
+        Tcl_DecrRefCount(objPtr);  /* we're done with the object */
+    }
+
+    /*
+     *  Copy the result from the parser interpreter to the
+     *  master interpreter.  If an error was encountered,
+     *  copy the error info first, and then set the result.
+     *  Otherwise, the offending command is reported twice.
+     */
+    if (status == TCL_ERROR) {
+        CONST char *errInfo = Tcl_GetVar2(ensInfo->parser, "::errorInfo",
+            (char*)NULL, TCL_GLOBAL_ONLY);
+
+        if (errInfo) {
+            Tcl_AddObjErrorInfo(interp, (CONST84 char *)errInfo, -1);
+        }
+
+        if (objc == 3) {
+            char msg[128];
+            sprintf(msg, "\n    (\"ensemble\" body line %d)",
+                   ERRORLINE(ensInfo->parser));
+            Tcl_AddObjErrorInfo(interp, msg, -1);
+        }
+    }
+    Tcl_SetObjResult(interp, Tcl_GetObjResult(ensInfo->parser));
+
+    ensInfo->ensData = savedEnsData;
+    return status;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetEnsembleParser --
+ *
+ *      Returns the slave interpreter that acts as a parser for
+ *      the body of an "ensemble" definition.  The first time that
+ *      this is called for an interpreter, the parser is created
+ *      and registered as associated data.  After that, it is
+ *      simply returned.
+ *
+ * Results:
+ *      Returns a pointer to the ensemble parser data structure.
+ *
+ * Side effects:
+ *      On the first call, the ensemble parser is created and
+ *      registered as "itcl_ensembleParser" with the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+static EnsembleParser*
+GetEnsembleParser(interp)
+    Tcl_Interp *interp;     /* interpreter handling the ensemble */
+{
+    Namespace *nsPtr;
+    Tcl_Namespace *childNs;
+    EnsembleParser *ensInfo;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+    Tcl_Command cmd;
+
+    /*
+     *  Look for an existing ensemble parser.  If it is found,
+     *  return it immediately.
+     */
+    ensInfo = (EnsembleParser*) Tcl_GetAssocData(interp,
+        "itcl_ensembleParser", NULL);
+
+    if (ensInfo) {
+        return ensInfo;
+    }
+
+    /*
+     *  Create a slave interpreter that can be used to parse
+     *  the body of an ensemble definition.
+     */
+    ensInfo = (EnsembleParser*)ckalloc(sizeof(EnsembleParser));
+    ensInfo->master = interp;
+    ensInfo->parser = Tcl_CreateInterp();
+    ensInfo->ensData = NULL;
+
+    /*
+     *  Remove all namespaces and all normal commands from the
+     *  parser interpreter.
+     */
+    nsPtr = (Namespace*)Tcl_GetGlobalNamespace(ensInfo->parser);
+
+    for (hPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
+         hPtr != NULL;
+         hPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search)) {
+
+        childNs = (Tcl_Namespace*)Tcl_GetHashValue(hPtr);
+        Tcl_DeleteNamespace(childNs);
+    }
+
+    for (hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+         hPtr != NULL;
+         hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search)) {
+
+        cmd = (Tcl_Command)Tcl_GetHashValue(hPtr);
+        Tcl_DeleteCommandFromToken(ensInfo->parser, cmd);
+    }
+
+    /*
+     *  Add the allowed commands to the parser interpreter:
+     *  part, delete, ensemble
+     */
+    Tcl_CreateObjCommand(ensInfo->parser, "part", Itcl_EnsPartCmd,
+        (ClientData)ensInfo, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(ensInfo->parser, "option", Itcl_EnsPartCmd,
+        (ClientData)ensInfo, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(ensInfo->parser, "ensemble", Itcl_EnsembleCmd,
+        (ClientData)ensInfo, (Tcl_CmdDeleteProc*)NULL);
+
+    /*
+     *  Install the parser data, so we'll have it the next time
+     *  we call this procedure.
+     */
+    (void) Tcl_SetAssocData(interp, "itcl_ensembleParser",
+            DeleteEnsParser, (ClientData)ensInfo);
+
+    return ensInfo;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteEnsParser --
+ *
+ *      Called when an interpreter is destroyed to clean up the
+ *      ensemble parser within it.  Destroys the slave interpreter
+ *      and frees up the data associated with it.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+       /* ARGSUSED */
+static void
+DeleteEnsParser(clientData, interp)
+    ClientData clientData;    /* client data for ensemble-related commands */
+    Tcl_Interp *interp;       /* interpreter containing the data */
+{
+    EnsembleParser* ensInfo = (EnsembleParser*)clientData;
+    Tcl_DeleteInterp(ensInfo->parser);
+    ckfree((char*)ensInfo);
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_EnsPartCmd --
+ *
+ *      Invoked by Tcl whenever the user issues the "part" command
+ *      to manipulate an ensemble.  This command can only be used
+ *      inside the "ensemble" command, which handles ensembles.
+ *      Handles the following syntax:
+ *
+ *        ensemble <ensName> {
+ *            part <partName> <args> <body>
+ *        }
+ *
+ *      Adds a new part called <partName> to the ensemble.  If a
+ *      part already exists with that name, it is an error.  The
+ *      new part is handled just like an ordinary Tcl proc, with
+ *      a list of <args> and a <body> of code to execute.
+ *
+ * Results:
+ *      Returns TCL_OK if successful, and TCL_ERROR if anything
+ *      goes wrong.
+ *
+ * Side effects:
+ *      If anything goes wrong, this procedure returns an error
+ *      message as the result in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+Itcl_EnsPartCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* ensemble data */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    EnsembleParser *ensInfo = (EnsembleParser*)clientData;
+    Ensemble *ensData = (Ensemble*)ensInfo->ensData;
+
+    int status, varArgs, space;
+    char *partName, *usage;
+    Proc *procPtr;
+    Command *cmdPtr;
+    CompiledLocal *localPtr;
+    EnsemblePart *ensPart;
+    Tcl_DString buffer;
+
+    if (objc != 4) {
+        Tcl_AppendResult(interp,
+            "wrong # args: should be \"",
+            Tcl_GetStringFromObj(objv[0], (int*)NULL),
+            " name args body\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Create a Tcl-style proc definition using the specified args
+     *  and body.  This is not a proc in the usual sense.  It belongs
+     *  to the namespace that contains the ensemble, but it is
+     *  accessed through the ensemble, not through a Tcl command.
+     */
+    partName = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    cmdPtr = (Command*)ensData->cmd;
+
+    if (TclCreateProc(interp, cmdPtr->nsPtr, partName, objv[2], objv[3],
+        &procPtr) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Deduce the usage information from the argument list.
+     *  We'll register this when we create the part, in a moment.
+     */
+    Tcl_DStringInit(&buffer);
+    varArgs = 0;
+    space = 0;
+
+    for (localPtr=procPtr->firstLocalPtr;
+         localPtr != NULL;
+         localPtr=localPtr->nextPtr) {
+
+        if (TclIsVarArgument(localPtr)) {
+            varArgs = 0;
+            if (strcmp(localPtr->name, "args") == 0) {
+                varArgs = 1;
+            }
+            else if (localPtr->defValuePtr) {
+                if (space) {
+                    Tcl_DStringAppend(&buffer, " ", 1);
+                }
+                Tcl_DStringAppend(&buffer, "?", 1);
+                Tcl_DStringAppend(&buffer, localPtr->name, -1);
+                Tcl_DStringAppend(&buffer, "?", 1);
+                space = 1;
+            }
+            else {
+                if (space) {
+                    Tcl_DStringAppend(&buffer, " ", 1);
+                }
+                Tcl_DStringAppend(&buffer, localPtr->name, -1);
+                space = 1;
+            }
+        }
+    }
+    if (varArgs) {
+        if (space) {
+            Tcl_DStringAppend(&buffer, " ", 1);
+        }
+        Tcl_DStringAppend(&buffer, "?arg arg ...?", 13);
+    }
+
+    usage = Tcl_DStringValue(&buffer);
+
+    /*
+     *  Create a new part within the ensemble.  If successful,
+     *  plug the command token into the proc; we'll need it later
+     *  if we try to compile the Tcl code for the part.  If
+     *  anything goes wrong, clean up before bailing out.
+     */
+    status = AddEnsemblePart(interp, ensData, partName, usage,
+        TclObjInterpProc, (ClientData)procPtr, TclProcDeleteProc,
+        &ensPart);
+
+    if (status == TCL_OK) {
+        procPtr->cmdPtr = ensPart->cmdPtr;
+    } else {
+        TclProcDeleteProc((ClientData)procPtr);
+    }
+    Tcl_DStringFree(&buffer);
+
+    return status;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Itcl_EnsembleErrorCmd --
+ *
+ *      Invoked when the user tries to access an unknown part for
+ *      an ensemble.  Acts as the default handler for the "@error"
+ *      part.  Generates an error message like:
+ *
+ *          bad option "foo": should be one of...
+ *            info args procname
+ *            info body procname
+ *            info cmdcount
+ *            ...
+ *
+ * Results:
+ *      Always returns TCL_OK.
+ *
+ * Side effects:
+ *      Returns the error message as the result in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+       /* ARGSUSED */
+int
+Itcl_EnsembleErrorCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* ensemble info */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    Ensemble *ensData = (Ensemble*)clientData;
+
+    char *cmdName;
+    Tcl_Obj *objPtr;
+
+    cmdName = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+
+    objPtr = Tcl_NewStringObj((char*)NULL, 0);
+    Tcl_AppendStringsToObj(objPtr,
+        "bad option \"", cmdName, "\": should be one of...\n",
+        (char*)NULL);
+    GetEnsembleUsage(ensData, objPtr);
+
+    Tcl_SetObjResult(interp, objPtr);
+    return TCL_ERROR;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeEnsInvocInternalRep --
+ *
+ *      Frees the resources associated with an ensembleInvoc object's
+ *      internal representation.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Decrements the ref count of the two objects referenced by
+ *      this object.  If there are no more uses, this will free
+ *      the other objects.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+FreeEnsInvocInternalRep(objPtr)
+    register Tcl_Obj *objPtr;   /* namespName object with internal
+                                 * representation to free */
+{
+    Tcl_Obj *prevArgObj = (Tcl_Obj*)objPtr->internalRep.twoPtrValue.ptr2;
+
+    if (prevArgObj) {
+        Tcl_DecrRefCount(prevArgObj);
+    }
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupEnsInvocInternalRep --
+ *
+ *      Initializes the internal representation of an ensembleInvoc
+ *      object to a copy of the internal representation of
+ *      another ensembleInvoc object.
+ *
+ *      This shouldn't be called.  Normally, a temporary ensembleInvoc
+ *      object is created while an ensemble call is in progress.
+ *      This object may be converted to string form if an error occurs.
+ *      It does not stay around long, and there is no reason for it
+ *      to be duplicated.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      copyPtr's internal rep is set to duplicates of the objects
+ *      pointed to by srcPtr's internal rep.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+DupEnsInvocInternalRep(srcPtr, copyPtr)
+    Tcl_Obj *srcPtr;                /* Object with internal rep to copy. */
+    register Tcl_Obj *copyPtr;      /* Object with internal rep to set. */
+{
+    EnsemblePart *ensPart = (EnsemblePart*)srcPtr->internalRep.twoPtrValue.ptr1;
+    Tcl_Obj *prevArgObj = (Tcl_Obj*)srcPtr->internalRep.twoPtrValue.ptr2;
+    Tcl_Obj *objPtr;
+
+    copyPtr->internalRep.twoPtrValue.ptr1 = (VOID *) ensPart;
+
+    if (prevArgObj) {
+        objPtr = Tcl_DuplicateObj(prevArgObj);
+        Tcl_IncrRefCount(objPtr);
+        copyPtr->internalRep.twoPtrValue.ptr2 = (VOID *) objPtr;
+    }
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetEnsInvocFromAny --
+ *
+ *      Generates the internal representation for an ensembleInvoc
+ *      object.  This conversion really shouldn't take place.
+ *      Normally, a temporary ensembleInvoc object is created while
+ *      an ensemble call is in progress.  This object may be converted
+ *      to string form if an error occurs.  But there is no reason
+ *      for any other object to be converted to ensembleInvoc form.
+ *
+ * Results:
+ *      Always returns TCL_OK.
+ *
+ * Side effects:
+ *      The string representation is saved as if it were the
+ *      command line argument for the ensemble invocation.  The
+ *      reference to the ensemble part is set to NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+SetEnsInvocFromAny(interp, objPtr)
+    Tcl_Interp *interp;              /* Determines the context for
+                                        name resolution */
+    register Tcl_Obj *objPtr;        /* The object to convert */
+{
+    int length;
+    char *name;
+    Tcl_Obj *argObj;
+
+    /*
+     *  Get objPtr's string representation.
+     *  Make it up-to-date if necessary.
+     *  THIS FAILS IF THE OBJECT'S STRING REP CONTAINS NULLS.
+     */
+    name = Tcl_GetStringFromObj(objPtr, &length);
+
+    /*
+     *  Make an argument object to contain the string, and
+     *  set the ensemble part definition to NULL.  At this point,
+     *  we don't know anything about an ensemble, so we'll just
+     *  keep the string around as if it were the command line
+     *  invocation.
+     */
+    argObj = Tcl_NewStringObj(name, length);
+
+    /*
+     *  Free the old representation and install a new one.
+     */
+    if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc != NULL) {
+        (*objPtr->typePtr->freeIntRepProc)(objPtr);
+    }
+    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+    objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) argObj;
+    objPtr->typePtr = &itclEnsInvocType;
+
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfEnsInvoc --
+ *
+ *      Updates the string representation for an ensembleInvoc object.
+ *      This is called when an error occurs in an ensemble part, when
+ *      the code tries to print objv[0] as the command name.  This
+ *      code automatically chains together all of the names leading
+ *      to the ensemble part, so the error message references the
+ *      entire command, not just the part name.
+ *
+ *      Note: This procedure does not free an existing old string rep
+ *      so storage will be lost if this has not already been done.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      The object's string is set to the full command name for
+ *      the ensemble part.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+UpdateStringOfEnsInvoc(objPtr)
+    register Tcl_Obj *objPtr;      /* NamespName obj to update string rep. */
+{
+    EnsemblePart *ensPart = (EnsemblePart*)objPtr->internalRep.twoPtrValue.ptr1;
+    Tcl_Obj *prevArgObj = (Tcl_Obj*)objPtr->internalRep.twoPtrValue.ptr2;
+
+    Tcl_DString buffer;
+    int length;
+    char *name;
+
+    Tcl_DStringInit(&buffer);
+
+    /*
+     *  Get the string representation for the previous argument.
+     *  This will force each ensembleInvoc argument up the line
+     *  to get its string representation.  So we will get the
+     *  original command name, followed by the sub-ensemble, and
+     *  the next sub-ensemble, and so on.  Then add the part
+     *  name from the ensPart argument.
+     */
+    if (prevArgObj) {
+        name = Tcl_GetStringFromObj(prevArgObj, &length);
+        Tcl_DStringAppend(&buffer, name, length);
+    }
+
+    if (ensPart) {
+        Tcl_DStringAppendElement(&buffer, ensPart->name);
+    }
+
+    /*
+     *  The following allocates an empty string on the heap if name is ""
+     *  (e.g., if the internal rep is NULL).
+     */
+    name = Tcl_DStringValue(&buffer);
+    length = strlen(name);
+    objPtr->bytes = (char *) ckalloc((unsigned) (length + 1));
+    memcpy((VOID *) objPtr->bytes, (VOID *) name, (unsigned) length);
+    objPtr->bytes[length] = '\0';
+    objPtr->length = length;
+}
diff --git a/8.x/itcl/generic/itcl_linkage.c b/8.x/itcl/generic/itcl_linkage.c
new file mode 100644 (file)
index 0000000..83c6114
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  This part adds a mechanism for integrating C procedures into
+ *  [incr Tcl] classes as methods and procs.  Each C procedure must
+ *  either be declared via Itcl_RegisterC() or dynamically loaded.
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_linkage.c,v 1.2 2003/12/17 02:25:37 davygrvy Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ *  These records store the pointers for all "RegisterC" functions.
+ */
+typedef struct ItclCfunc {
+    Tcl_CmdProc *argCmdProc;        /* old-style (argc,argv) command handler */
+    Tcl_ObjCmdProc *objCmdProc;     /* new (objc,objv) command handler */
+    ClientData clientData;          /* client data passed into this function */
+    Tcl_CmdDeleteProc *deleteProc;  /* proc called to free clientData */
+} ItclCfunc;
+
+static Tcl_HashTable* ItclGetRegisteredProcs _ANSI_ARGS_((Tcl_Interp *interp));
+static void ItclFreeC _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp));
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_RegisterC()
+ *
+ *  Used to associate a symbolic name with an (argc,argv) C procedure
+ *  that handles a Tcl command.  Procedures that are registered in this
+ *  manner can be referenced in the body of an [incr Tcl] class
+ *  definition to specify C procedures to acting as methods/procs.
+ *  Usually invoked in an initialization routine for an extension,
+ *  called out in Tcl_AppInit() at the start of an application.
+ *
+ *  Each symbolic procedure can have an arbitrary client data value
+ *  associated with it.  This value is passed into the command
+ *  handler whenever it is invoked.
+ *
+ *  A symbolic procedure name can be used only once for a given style
+ *  (arg/obj) handler.  If the name is defined with an arg-style
+ *  handler, it can be redefined with an obj-style handler; or if
+ *  the name is defined with an obj-style handler, it can be redefined
+ *  with an arg-style handler.  In either case, any previous client
+ *  data is discarded and the new client data is remembered.  However,
+ *  if a name is redefined to a different handler of the same style,
+ *  this procedure returns an error.
+ *
+ *  Returns TCL_OK on success, or TCL_ERROR (along with an error message
+ *  in interp->result) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_RegisterC(interp, name, proc, clientData, deleteProc)
+    Tcl_Interp *interp;             /* interpreter handling this registration */
+    CONST char *name;               /* symbolic name for procedure */
+    Tcl_CmdProc *proc;              /* procedure handling Tcl command */
+    ClientData clientData;          /* client data associated with proc */
+    Tcl_CmdDeleteProc *deleteProc;  /* proc called to free up client data */
+{
+    int newEntry;
+    Tcl_HashEntry *entry;
+    Tcl_HashTable *procTable;
+    ItclCfunc *cfunc;
+
+    /*
+     *  Make sure that a proc was specified.
+     */
+    if (!proc) {
+        Tcl_AppendResult(interp, "initialization error: null pointer for ",
+            "C procedure \"", name, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Add a new entry for the given procedure.  If an entry with
+     *  this name already exists, then make sure that it was defined
+     *  with the same proc.
+     */
+    procTable = ItclGetRegisteredProcs(interp);
+    entry = Tcl_CreateHashEntry(procTable, name, &newEntry);
+    if (!newEntry) {
+        cfunc = (ItclCfunc*)Tcl_GetHashValue(entry);
+        if (cfunc->argCmdProc != NULL && cfunc->argCmdProc != proc) {
+            Tcl_AppendResult(interp, "initialization error: C procedure ",
+                "with name \"", name, "\" already defined",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+
+        if (cfunc->deleteProc != NULL) {
+            (*cfunc->deleteProc)(cfunc->clientData);
+        }
+    }
+    else {
+        cfunc = (ItclCfunc*)ckalloc(sizeof(ItclCfunc));
+        cfunc->objCmdProc = NULL;
+    }
+
+    cfunc->argCmdProc = proc;
+    cfunc->clientData = clientData;
+    cfunc->deleteProc = deleteProc;
+
+    Tcl_SetHashValue(entry, (ClientData)cfunc);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_RegisterObjC()
+ *
+ *  Used to associate a symbolic name with an (objc,objv) C procedure
+ *  that handles a Tcl command.  Procedures that are registered in this
+ *  manner can be referenced in the body of an [incr Tcl] class
+ *  definition to specify C procedures to acting as methods/procs.
+ *  Usually invoked in an initialization routine for an extension,
+ *  called out in Tcl_AppInit() at the start of an application.
+ *
+ *  Each symbolic procedure can have an arbitrary client data value
+ *  associated with it.  This value is passed into the command
+ *  handler whenever it is invoked.
+ *
+ *  A symbolic procedure name can be used only once for a given style
+ *  (arg/obj) handler.  If the name is defined with an arg-style
+ *  handler, it can be redefined with an obj-style handler; or if
+ *  the name is defined with an obj-style handler, it can be redefined
+ *  with an arg-style handler.  In either case, any previous client
+ *  data is discarded and the new client data is remembered.  However,
+ *  if a name is redefined to a different handler of the same style,
+ *  this procedure returns an error.
+ *
+ *  Returns TCL_OK on success, or TCL_ERROR (along with an error message
+ *  in interp->result) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_RegisterObjC(interp, name, proc, clientData, deleteProc)
+    Tcl_Interp *interp;     /* interpreter handling this registration */
+    CONST char *name;       /* symbolic name for procedure */
+    Tcl_ObjCmdProc *proc;   /* procedure handling Tcl command */
+    ClientData clientData;          /* client data associated with proc */
+    Tcl_CmdDeleteProc *deleteProc;  /* proc called to free up client data */
+{
+    int newEntry;
+    Tcl_HashEntry *entry;
+    Tcl_HashTable *procTable;
+    ItclCfunc *cfunc;
+
+    /*
+     *  Make sure that a proc was specified.
+     */
+    if (!proc) {
+        Tcl_AppendResult(interp, "initialization error: null pointer for ",
+            "C procedure \"", name, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Add a new entry for the given procedure.  If an entry with
+     *  this name already exists, then make sure that it was defined
+     *  with the same proc.
+     */
+    procTable = ItclGetRegisteredProcs(interp);
+    entry = Tcl_CreateHashEntry(procTable, name, &newEntry);
+    if (!newEntry) {
+        cfunc = (ItclCfunc*)Tcl_GetHashValue(entry);
+        if (cfunc->objCmdProc != NULL && cfunc->objCmdProc != proc) {
+            Tcl_AppendResult(interp, "initialization error: C procedure ",
+                "with name \"", name, "\" already defined",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+
+        if (cfunc->deleteProc != NULL) {
+            (*cfunc->deleteProc)(cfunc->clientData);
+        }
+    }
+    else {
+        cfunc = (ItclCfunc*)ckalloc(sizeof(ItclCfunc));
+        cfunc->argCmdProc = NULL;
+    }
+
+    cfunc->objCmdProc = proc;
+    cfunc->clientData = clientData;
+    cfunc->deleteProc = deleteProc;
+
+    Tcl_SetHashValue(entry, (ClientData)cfunc);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_FindC()
+ *
+ *  Used to query a C procedure via its symbolic name.  Looks at the
+ *  list of procedures registered previously by either Itcl_RegisterC
+ *  or Itcl_RegisterObjC and returns pointers to the appropriate
+ *  (argc,argv) or (objc,objv) handlers.  Returns non-zero if the
+ *  name is recognized and pointers are returned; returns zero
+ *  otherwise.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_FindC(interp, name, argProcPtr, objProcPtr, cDataPtr)
+    Tcl_Interp *interp;           /* interpreter handling this registration */
+    CONST char *name;             /* symbolic name for procedure */
+    Tcl_CmdProc **argProcPtr;     /* returns (argc,argv) command handler */
+    Tcl_ObjCmdProc **objProcPtr;  /* returns (objc,objv) command handler */
+    ClientData *cDataPtr;         /* returns client data */
+{
+    Tcl_HashEntry *entry;
+    Tcl_HashTable *procTable;
+    ItclCfunc *cfunc;
+
+    *argProcPtr = NULL;  /* assume info won't be found */
+    *objProcPtr = NULL;
+    *cDataPtr   = NULL;
+
+    if (interp) {
+        procTable = (Tcl_HashTable*)Tcl_GetAssocData(interp,
+            "itcl_RegC", (Tcl_InterpDeleteProc**)NULL);
+
+        if (procTable) {
+            entry = Tcl_FindHashEntry(procTable, name);
+            if (entry) {
+                cfunc = (ItclCfunc*)Tcl_GetHashValue(entry);
+                *argProcPtr = cfunc->argCmdProc;
+                *objProcPtr = cfunc->objCmdProc;
+                *cDataPtr   = cfunc->clientData;
+            }
+        }
+    }
+    return (*argProcPtr != NULL || *objProcPtr != NULL);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclGetRegisteredProcs()
+ *
+ *  Returns a pointer to a hash table containing the list of registered
+ *  procs in the specified interpreter.  If the hash table does not
+ *  already exist, it is created.
+ * ------------------------------------------------------------------------
+ */
+static Tcl_HashTable*
+ItclGetRegisteredProcs(interp)
+    Tcl_Interp *interp;  /* interpreter handling this registration */
+{
+    Tcl_HashTable* procTable;
+
+    /*
+     *  If the registration table does not yet exist, then create it.
+     */
+    procTable = (Tcl_HashTable*)Tcl_GetAssocData(interp, "itcl_RegC",
+        (Tcl_InterpDeleteProc**)NULL);
+
+    if (!procTable) {
+        procTable = (Tcl_HashTable*)ckalloc(sizeof(Tcl_HashTable));
+        Tcl_InitHashTable(procTable, TCL_STRING_KEYS);
+        Tcl_SetAssocData(interp, "itcl_RegC", ItclFreeC,
+            (ClientData)procTable);
+    }
+    return procTable;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclFreeC()
+ *
+ *  When an interpreter is deleted, this procedure is called to
+ *  free up the associated data created by Itcl_RegisterC and
+ *  Itcl_RegisterObjC.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclFreeC(clientData, interp)
+    ClientData clientData;       /* associated data */
+    Tcl_Interp *interp;          /* intepreter being deleted */
+{
+    Tcl_HashTable *tablePtr = (Tcl_HashTable*)clientData;
+    Tcl_HashSearch place;
+    Tcl_HashEntry *entry;
+    ItclCfunc *cfunc;
+
+    entry = Tcl_FirstHashEntry(tablePtr, &place);
+    while (entry) {
+        cfunc = (ItclCfunc*)Tcl_GetHashValue(entry);
+
+        if (cfunc->deleteProc != NULL) {
+            (*cfunc->deleteProc)(cfunc->clientData);
+        }
+        ckfree ( (char*)cfunc );
+        entry = Tcl_NextHashEntry(&place);
+    }
+
+    Tcl_DeleteHashTable(tablePtr);
+    ckfree((char*)tablePtr);
+}
diff --git a/8.x/itcl/generic/itcl_methods.c b/8.x/itcl/generic/itcl_methods.c
new file mode 100644 (file)
index 0000000..7e15b3d
--- /dev/null
@@ -0,0 +1,2530 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  These procedures handle commands available within a class scope.
+ *  In [incr Tcl], the term "method" is used for a procedure that has
+ *  access to object-specific data, while the term "proc" is used for
+ *  a procedure that has access only to common class data.
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_methods.c,v 1.24 2008/12/15 20:02:58 andreas_kupries Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ *  FORWARD DECLARATIONS
+ */
+static int ItclParseConfig _ANSI_ARGS_((Tcl_Interp *interp,
+    int objc, Tcl_Obj *CONST objv[], ItclObject *contextObj,
+    int *rargc, ItclVarDefn ***rvars, char ***rvals));
+
+static int ItclHandleConfig _ANSI_ARGS_((Tcl_Interp *interp,
+    int argc, ItclVarDefn **vars, char **vals, ItclObject *contextObj));
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_BodyCmd()
+ *
+ *  Invoked by Tcl whenever the user issues an "itcl::body" command to
+ *  define or redefine the implementation for a class method/proc.
+ *  Handles the following syntax:
+ *
+ *    itcl::body <class>::<func> <arglist> <body>
+ *
+ *  Looks for an existing class member function with the name <func>,
+ *  and if found, tries to assign the implementation.  If an argument
+ *  list was specified in the original declaration, it must match
+ *  <arglist> or an error is flagged.  If <body> has the form "@name"
+ *  then it is treated as a reference to a C handling procedure;
+ *  otherwise, it is taken as a body of Tcl statements.
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_BodyCmd(dummy, interp, objc, objv)
+    ClientData dummy;        /* unused */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int status = TCL_OK;
+
+    char *head, *tail, *token, *arglist, *body;
+    ItclClass *cdefn;
+    ItclMemberFunc *mfunc;
+    Tcl_HashEntry *entry;
+    Tcl_DString buffer;
+
+    if (objc != 4) {
+        token = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        Tcl_AppendResult(interp,
+            "wrong # args: should be \"",
+            token, " class::func arglist body\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Parse the member name "namesp::namesp::class::func".
+     *  Make sure that a class name was specified, and that the
+     *  class exists.
+     */
+    token = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    Itcl_ParseNamespPath(token, &buffer, &head, &tail);
+
+    if (!head || *head == '\0') {
+        Tcl_AppendResult(interp,
+            "missing class specifier for body declaration \"", token, "\"",
+            (char*)NULL);
+        status = TCL_ERROR;
+        goto bodyCmdDone;
+    }
+
+    cdefn = Itcl_FindClass(interp, head, /* autoload */ 1);
+    if (cdefn == NULL) {
+        status = TCL_ERROR;
+        goto bodyCmdDone;
+    }
+
+    /*
+     *  Find the function and try to change its implementation.
+     *  Note that command resolution table contains *all* functions,
+     *  even those in a base class.  Make sure that the class
+     *  containing the method definition is the requested class.
+     */
+
+    mfunc = NULL;
+    entry = Tcl_FindHashEntry(&cdefn->resolveCmds, tail);
+    if (entry) {
+        mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+        if (mfunc->member->classDefn != cdefn) {
+            mfunc = NULL;
+        }
+    }
+
+    if (mfunc == NULL) {
+        Tcl_AppendResult(interp,
+            "function \"", tail, "\" is not defined in class \"",
+            cdefn->fullname, "\"",
+            (char*)NULL);
+        status = TCL_ERROR;
+        goto bodyCmdDone;
+    }
+
+    arglist = Tcl_GetStringFromObj(objv[2], (int*)NULL);
+    body    = Tcl_GetStringFromObj(objv[3], (int*)NULL);
+
+    if (Itcl_ChangeMemberFunc(interp, mfunc, arglist, body) != TCL_OK) {
+        status = TCL_ERROR;
+        goto bodyCmdDone;
+    }
+
+bodyCmdDone:
+    Tcl_DStringFree(&buffer);
+    return status;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ConfigBodyCmd()
+ *
+ *  Invoked by Tcl whenever the user issues an "itcl::configbody" command
+ *  to define or redefine the configuration code associated with a
+ *  public variable.  Handles the following syntax:
+ *
+ *    itcl::configbody <class>::<publicVar> <body>
+ *
+ *  Looks for an existing public variable with the name <publicVar>,
+ *  and if found, tries to assign the implementation.  If <body> has
+ *  the form "@name" then it is treated as a reference to a C handling
+ *  procedure; otherwise, it is taken as a body of Tcl statements.
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_ConfigBodyCmd(dummy, interp, objc, objv)
+    ClientData dummy;        /* unused */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int status = TCL_OK;
+
+    char *head, *tail, *token;
+    Tcl_DString buffer;
+    ItclClass *cdefn;
+    ItclVarLookup *vlookup;
+    ItclMember *member;
+    ItclMemberCode *mcode;
+    Tcl_HashEntry *entry;
+
+    if (objc != 3) {
+        Tcl_WrongNumArgs(interp, 1, objv, "class::option body");
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Parse the member name "namesp::namesp::class::option".
+     *  Make sure that a class name was specified, and that the
+     *  class exists.
+     */
+    token = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    Itcl_ParseNamespPath(token, &buffer, &head, &tail);
+
+    if (!head || *head == '\0') {
+        Tcl_AppendResult(interp,
+            "missing class specifier for body declaration \"", token, "\"",
+            (char*)NULL);
+        status = TCL_ERROR;
+        goto configBodyCmdDone;
+    }
+
+    cdefn = Itcl_FindClass(interp, head, /* autoload */ 1);
+    if (cdefn == NULL) {
+        status = TCL_ERROR;
+        goto configBodyCmdDone;
+    }
+
+    /*
+     *  Find the variable and change its implementation.
+     *  Note that variable resolution table has *all* variables,
+     *  even those in a base class.  Make sure that the class
+     *  containing the variable definition is the requested class.
+     */
+    vlookup = NULL;
+    entry = Tcl_FindHashEntry(&cdefn->resolveVars, tail);
+    if (entry) {
+        vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+        if (vlookup->vdefn->member->classDefn != cdefn) {
+            vlookup = NULL;
+        }
+    }
+
+    if (vlookup == NULL) {
+        Tcl_AppendResult(interp,
+            "option \"", tail, "\" is not defined in class \"",
+            cdefn->fullname, "\"",
+            (char*)NULL);
+        status = TCL_ERROR;
+        goto configBodyCmdDone;
+    }
+    member = vlookup->vdefn->member;
+
+    if (member->protection != ITCL_PUBLIC) {
+        Tcl_AppendResult(interp,
+            "option \"", member->fullname,
+            "\" is not a public configuration option",
+            (char*)NULL);
+        status = TCL_ERROR;
+        goto configBodyCmdDone;
+    }
+
+    token = Tcl_GetStringFromObj(objv[2], (int*)NULL);
+
+    if (Itcl_CreateMemberCode(interp, cdefn, (char*)NULL, token,
+        &mcode) != TCL_OK) {
+
+        status = TCL_ERROR;
+        goto configBodyCmdDone;
+    }
+
+    Itcl_PreserveData((ClientData)mcode);
+    Itcl_EventuallyFree((ClientData)mcode, (Tcl_FreeProc*) Itcl_DeleteMemberCode);
+
+    if (member->code) {
+        Itcl_ReleaseData((ClientData)member->code);
+    }
+    member->code = mcode;
+
+configBodyCmdDone:
+    Tcl_DStringFree(&buffer);
+    return status;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateMethod()
+ *
+ *  Installs a method into the namespace associated with a class.
+ *  If another command with the same name is already installed, then
+ *  it is overwritten.
+ *
+ *  Returns TCL_OK on success, or TCL_ERROR (along with an error message
+ *  in the specified interp) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CreateMethod(interp, cdefn, name, arglist, body)
+    Tcl_Interp* interp;  /* interpreter managing this action */
+    ItclClass *cdefn;    /* class definition */
+    CONST char* name;    /* name of new method */
+    CONST char* arglist; /* space-separated list of arg names */
+    CONST char* body;    /* body of commands for the method */
+{
+    ItclMemberFunc *mfunc;
+    Tcl_DString buffer;
+
+    /*
+     *  Make sure that the method name does not contain anything
+     *  goofy like a "::" scope qualifier.
+     */
+    if (strstr(name,"::")) {
+        Tcl_AppendResult(interp,
+            "bad method name \"", name, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Create the method definition.
+     */
+    if (Itcl_CreateMemberFunc(interp, cdefn, name, arglist, body, &mfunc)
+        != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Build a fully-qualified name for the method, and install
+     *  the command handler.
+     */
+    Tcl_DStringInit(&buffer);
+    Tcl_DStringAppend(&buffer, cdefn->namesp->fullName, -1);
+    Tcl_DStringAppend(&buffer, "::", 2);
+    Tcl_DStringAppend(&buffer, name, -1);
+    name = Tcl_DStringValue(&buffer);
+
+    Itcl_PreserveData((ClientData)mfunc);
+    mfunc->accessCmd = Tcl_CreateObjCommand(interp, (CONST84 char *)name,
+       Itcl_ExecMethod, (ClientData)mfunc, Itcl_ReleaseData);
+
+    Tcl_DStringFree(&buffer);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateProc()
+ *
+ *  Installs a class proc into the namespace associated with a class.
+ *  If another command with the same name is already installed, then
+ *  it is overwritten.  Returns TCL_OK on success, or TCL_ERROR  (along
+ *  with an error message in the specified interp) if anything goes
+ *  wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CreateProc(interp, cdefn, name, arglist, body)
+    Tcl_Interp* interp;  /* interpreter managing this action */
+    ItclClass *cdefn;    /* class definition */
+    CONST char* name;    /* name of new proc */
+    CONST char* arglist; /* space-separated list of arg names */
+    CONST char* body;    /* body of commands for the proc */
+{
+    ItclMemberFunc *mfunc;
+    Tcl_DString buffer;
+
+    /*
+     *  Make sure that the proc name does not contain anything
+     *  goofy like a "::" scope qualifier.
+     */
+    if (strstr(name,"::")) {
+        Tcl_AppendResult(interp,
+            "bad proc name \"", name, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Create the proc definition.
+     */
+    if (Itcl_CreateMemberFunc(interp, cdefn, name, arglist, body, &mfunc)
+        != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Mark procs as "common".  This distinguishes them from methods.
+     */
+    mfunc->member->flags |= ITCL_COMMON;
+
+    /*
+     *  Build a fully-qualified name for the proc, and install
+     *  the command handler.
+     */
+    Tcl_DStringInit(&buffer);
+    Tcl_DStringAppend(&buffer, cdefn->namesp->fullName, -1);
+    Tcl_DStringAppend(&buffer, "::", 2);
+    Tcl_DStringAppend(&buffer, name, -1);
+    name = Tcl_DStringValue(&buffer);
+
+    Itcl_PreserveData((ClientData)mfunc);
+    mfunc->accessCmd = Tcl_CreateObjCommand(interp, (CONST84 char *)name,
+       Itcl_ExecProc, (ClientData)mfunc, Itcl_ReleaseData);
+
+    Tcl_DStringFree(&buffer);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateMemberFunc()
+ *
+ *  Creates the data record representing a member function.  This
+ *  includes the argument list and the body of the function.  If the
+ *  body is of the form "@name", then it is treated as a label for
+ *  a C procedure registered by Itcl_RegisterC().
+ *
+ *  If any errors are encountered, this procedure returns TCL_ERROR
+ *  along with an error message in the interpreter.  Otherwise, it
+ *  returns TCL_OK, and "mfuncPtr" returns a pointer to the new
+ *  member function.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CreateMemberFunc(interp, cdefn, name, arglist, body, mfuncPtr)
+    Tcl_Interp* interp;            /* interpreter managing this action */
+    ItclClass *cdefn;              /* class definition */
+    CONST char* name;              /* name of new member */
+    CONST char* arglist;           /* space-separated list of arg names */
+    CONST char* body;              /* body of commands for the method */
+    ItclMemberFunc** mfuncPtr;     /* returns: pointer to new method defn */
+{
+    int newEntry;
+    ItclMemberFunc *mfunc;
+    ItclMemberCode *mcode;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  Add the member function to the list of functions for
+     *  the class.  Make sure that a member function with the
+     *  same name doesn't already exist.
+     */
+    entry = Tcl_CreateHashEntry(&cdefn->functions, name, &newEntry);
+
+    if (!newEntry) {
+        Tcl_AppendResult(interp,
+            "\"", name, "\" already defined in class \"",
+            cdefn->fullname, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Try to create the implementation for this command member.
+     */
+    if (Itcl_CreateMemberCode(interp, cdefn, arglist, body,
+        &mcode) != TCL_OK) {
+
+        Tcl_DeleteHashEntry(entry);
+        return TCL_ERROR;
+    }
+    Itcl_PreserveData((ClientData)mcode);
+    Itcl_EventuallyFree((ClientData)mcode, (Tcl_FreeProc*) Itcl_DeleteMemberCode);
+
+    /*
+     *  Allocate a member function definition and return.
+     */
+    mfunc = (ItclMemberFunc*)ckalloc(sizeof(ItclMemberFunc));
+    mfunc->member = Itcl_CreateMember(interp, cdefn, name);
+    mfunc->member->code = mcode;
+
+    if (mfunc->member->protection == ITCL_DEFAULT_PROTECT) {
+        mfunc->member->protection = ITCL_PUBLIC;
+    }
+
+    mfunc->arglist   = NULL;
+    mfunc->argcount  = 0;
+    mfunc->accessCmd = NULL;
+
+    if (arglist) {
+        mfunc->member->flags |= ITCL_ARG_SPEC;
+    }
+    if (mcode->arglist) {
+        Itcl_CreateArgList(interp, arglist, &mfunc->argcount, &mfunc->arglist);
+    }
+
+    if (strcmp(name,"constructor") == 0) {
+        mfunc->member->flags |= ITCL_CONSTRUCTOR;
+    }
+    if (strcmp(name,"destructor") == 0) {
+        mfunc->member->flags |= ITCL_DESTRUCTOR;
+    }
+
+    Tcl_SetHashValue(entry, (ClientData)mfunc);
+    Itcl_PreserveData((ClientData)mfunc);
+    Itcl_EventuallyFree((ClientData)mfunc, (Tcl_FreeProc*) Itcl_DeleteMemberFunc);
+
+    *mfuncPtr = mfunc;
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ChangeMemberFunc()
+ *
+ *  Modifies the data record representing a member function.  This
+ *  is usually the body of the function, but can include the argument
+ *  list if it was not defined when the member was first created.
+ *  If the body is of the form "@name", then it is treated as a label
+ *  for a C procedure registered by Itcl_RegisterC().
+ *
+ *  If any errors are encountered, this procedure returns TCL_ERROR
+ *  along with an error message in the interpreter.  Otherwise, it
+ *  returns TCL_OK, and "mfuncPtr" returns a pointer to the new
+ *  member function.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ChangeMemberFunc(interp, mfunc, arglist, body)
+    Tcl_Interp* interp;            /* interpreter managing this action */
+    ItclMemberFunc* mfunc;         /* command member being changed */
+    CONST char* arglist;           /* space-separated list of arg names */
+    CONST char* body;              /* body of commands for the method */
+{
+    ItclMemberCode *mcode = NULL;
+    Tcl_Obj *objPtr;
+
+    /*
+     *  Try to create the implementation for this command member.
+     */
+    if (Itcl_CreateMemberCode(interp, mfunc->member->classDefn,
+        arglist, body, &mcode) != TCL_OK) {
+
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If the argument list was defined when the function was
+     *  created, compare the arg lists or usage strings to make sure
+     *  that the interface is not being redefined.
+     */
+    if ((mfunc->member->flags & ITCL_ARG_SPEC) != 0 &&
+        !Itcl_EquivArgLists(mfunc->arglist, mfunc->argcount,
+            mcode->arglist, mcode->argcount)) {
+
+        objPtr = Itcl_ArgList(mfunc->argcount, mfunc->arglist);
+        Tcl_IncrRefCount(objPtr);
+
+        Tcl_AppendResult(interp,
+            "argument list changed for function \"",
+            mfunc->member->fullname, "\": should be \"",
+            Tcl_GetStringFromObj(objPtr, (int*)NULL), "\"",
+            (char*)NULL);
+        Tcl_DecrRefCount(objPtr);
+
+        Itcl_DeleteMemberCode((char*)mcode);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Free up the old implementation and install the new one.
+     */
+    Itcl_PreserveData((ClientData)mcode);
+    Itcl_EventuallyFree((ClientData)mcode, (Tcl_FreeProc*) Itcl_DeleteMemberCode);
+
+    Itcl_ReleaseData((ClientData)mfunc->member->code);
+    mfunc->member->code = mcode;
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteMemberFunc()
+ *
+ *  Destroys all data associated with the given member function definition.
+ *  Usually invoked by the interpreter when a member function is deleted.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DeleteMemberFunc(cdata)
+    CONST char* cdata;  /* pointer to member function definition */
+{
+    ItclMemberFunc* mfunc = (ItclMemberFunc*)cdata;
+
+    if (mfunc) {
+        Itcl_DeleteMember(mfunc->member);
+
+        if (mfunc->arglist) {
+            Itcl_DeleteArgList(mfunc->arglist);
+        }
+        ckfree((char*)mfunc);
+    }
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateMemberCode()
+ *
+ *  Creates the data record representing the implementation behind a
+ *  class member function.  This includes the argument list and the body
+ *  of the function.  If the body is of the form "@name", then it is
+ *  treated as a label for a C procedure registered by Itcl_RegisterC().
+ *
+ *  The implementation is kept by the member function definition, and
+ *  controlled by a preserve/release paradigm.  That way, if it is in
+ *  use while it is being redefined, it will stay around long enough
+ *  to avoid a core dump.
+ *
+ *  If any errors are encountered, this procedure returns TCL_ERROR
+ *  along with an error message in the interpreter.  Otherwise, it
+ *  returns TCL_OK, and "mcodePtr" returns a pointer to the new
+ *  implementation.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CreateMemberCode(interp, cdefn, arglist, body, mcodePtr)
+    Tcl_Interp* interp;            /* interpreter managing this action */
+    ItclClass *cdefn;              /* class containing this member */
+    CONST char* arglist;           /* space-separated list of arg names */
+    CONST char* body;              /* body of commands for the method */
+    ItclMemberCode** mcodePtr;     /* returns: pointer to new implementation */
+{
+    int argc;
+    CompiledLocal *args, *localPtr;
+    ItclMemberCode *mcode;
+    Proc *procPtr;
+
+    /*
+     *  Allocate some space to hold the implementation.
+     */
+    mcode = (ItclMemberCode*)ckalloc(sizeof(ItclMemberCode));
+    memset(mcode, 0, sizeof(ItclMemberCode));
+
+    if (arglist) {
+        if (Itcl_CreateArgList(interp, arglist, &argc, &args)
+            != TCL_OK) {
+
+            Itcl_DeleteMemberCode((char*)mcode);
+            return TCL_ERROR;
+        }
+        mcode->argcount = argc;
+        mcode->arglist  = args;
+        mcode->flags   |= ITCL_ARG_SPEC;
+    } else {
+        argc = 0;
+        args = NULL;
+    }
+
+    /*
+     *  Create a standard Tcl Proc representation for this code body.
+     *  This is required, since the Tcl compiler looks for a proc
+     *  when handling things such as the call frame context and
+     *  compiled locals.
+     */
+    procPtr = (Proc*)ckalloc(sizeof(Proc));
+    mcode->procPtr = procPtr;
+
+    procPtr->iPtr = (Interp*)interp;
+    procPtr->refCount = 1;
+    procPtr->cmdPtr = (Command*)ckalloc(sizeof(Command));
+    memset(procPtr->cmdPtr, 0, sizeof(Command));
+    procPtr->cmdPtr->nsPtr = (Namespace*)cdefn->namesp;
+
+    if (body) {
+        procPtr->bodyPtr = Tcl_NewStringObj((CONST84 char *)body, -1);
+    } else {
+        procPtr->bodyPtr = Tcl_NewStringObj((CONST84 char *)"", -1);
+        mcode->flags |= ITCL_IMPLEMENT_NONE;
+    }
+    Tcl_IncrRefCount(procPtr->bodyPtr);
+
+    /*
+     *  Plug the argument list into the "compiled locals" list.
+     *
+     *  NOTE:  The storage for this argument list is owned by
+     *    the caller, so although we plug it in here, it is not
+     *    our responsibility to free it.
+     */
+    procPtr->firstLocalPtr = args;
+    procPtr->lastLocalPtr = NULL;
+
+    for (localPtr=mcode->arglist; localPtr; localPtr=localPtr->nextPtr) {
+        procPtr->lastLocalPtr = localPtr;
+    }
+    procPtr->numArgs = argc;
+    procPtr->numCompiledLocals = argc;
+
+    /*
+     *  If the body definition starts with '@', then treat the value
+     *  as a symbolic name for a C procedure.
+     */
+    if (body == NULL) {
+        /* No-op */
+    }
+    else if (*body == '@') {
+        Tcl_CmdProc *argCmdProc;
+        Tcl_ObjCmdProc *objCmdProc;
+        ClientData cdata;
+
+        if (!Itcl_FindC(interp, body+1, &argCmdProc, &objCmdProc, &cdata)) {
+            Tcl_AppendResult(interp,
+                "no registered C procedure with name \"", body+1, "\"",
+                (char*)NULL);
+            Itcl_DeleteMemberCode((char*)mcode);
+            return TCL_ERROR;
+        }
+
+        if (objCmdProc != NULL) {
+            mcode->flags |= ITCL_IMPLEMENT_OBJCMD;
+            mcode->cfunc.objCmd = objCmdProc;
+            mcode->clientData = cdata;
+        }
+        else if (argCmdProc != NULL) {
+            mcode->flags |= ITCL_IMPLEMENT_ARGCMD;
+            mcode->cfunc.argCmd = argCmdProc;
+            mcode->clientData = cdata;
+        }
+    }
+
+    /*
+     *  Otherwise, treat the body as a chunk of Tcl code.
+     */
+    else {
+        mcode->flags |= ITCL_IMPLEMENT_TCL;
+    }
+
+    *mcodePtr = mcode;
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteMemberCode()
+ *
+ *  Destroys all data associated with the given command implementation.
+ *  Invoked automatically by Itcl_ReleaseData() when the implementation
+ *  is no longer being used.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DeleteMemberCode(cdata)
+    CONST char* cdata;  /* pointer to member function definition */
+{
+    ItclMemberCode* mcode = (ItclMemberCode*)cdata;
+
+    /*
+     * Free the argument list.  If empty, free the compiled locals, if any.
+     */
+    if (mcode->arglist) {
+        Itcl_DeleteArgList(mcode->arglist);
+    } else if (mcode->procPtr && mcode->procPtr->firstLocalPtr) {
+       Itcl_DeleteArgList(mcode->procPtr->firstLocalPtr);
+    }
+
+    if (mcode->procPtr) {
+        ckfree((char*) mcode->procPtr->cmdPtr);
+
+        if (mcode->procPtr->bodyPtr) {
+            Tcl_DecrRefCount(mcode->procPtr->bodyPtr);
+        }
+        ckfree((char*)mcode->procPtr);
+    }
+    ckfree((char*)mcode);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_GetMemberCode()
+ *
+ *  Makes sure that the implementation for an [incr Tcl] code body is
+ *  ready to run.  Note that a member function can be declared without
+ *  being defined.  The class definition may contain a declaration of
+ *  the member function, but its body may be defined in a separate file.
+ *  If an undefined function is encountered, this routine automatically
+ *  attempts to autoload it.  If the body is implemented via Tcl code,
+ *  then it is compiled here as well.
+ *
+ *  Returns TCL_ERROR (along with an error message in the interpreter)
+ *  if an error is encountered, or if the implementation is not defined
+ *  and cannot be autoloaded.  Returns TCL_OK if implementation is
+ *  ready to use.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_GetMemberCode(interp, member)
+    Tcl_Interp* interp;        /* interpreter managing this action */
+    ItclMember* member;        /* member containing code body */
+{
+    int result;
+    ItclMemberCode *mcode = member->code;
+    assert(mcode != NULL);
+
+    /*
+     *  If the implementation has not yet been defined, try to
+     *  autoload it now.
+     */
+
+    if (!Itcl_IsMemberCodeImplemented(mcode)) {
+        result = Tcl_VarEval(interp, "::auto_load ", member->fullname,
+            (char*)NULL);
+        if (result != TCL_OK) {
+            char msg[256];
+            sprintf(msg, "\n    (while autoloading code for \"%.100s\")",
+                member->fullname);
+            Tcl_AddErrorInfo(interp, msg);
+            return result;
+        }
+        Tcl_ResetResult(interp);  /* get rid of 1/0 status */
+    }
+
+    /*
+     *  If the implementation is still not available, then
+     *  autoloading must have failed.
+     *
+     *  TRICKY NOTE:  If code has been autoloaded, then the
+     *    old mcode pointer is probably invalid.  Go back to
+     *    the member and look at the current code pointer again.
+     */
+    mcode = member->code;
+    assert(mcode != NULL);
+
+    if (!Itcl_IsMemberCodeImplemented(mcode)) {
+        Tcl_AppendResult(interp,
+            "member function \"", member->fullname,
+            "\" is not defined and cannot be autoloaded",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If the member is a constructor and the class has an
+     *  initialization command, compile it here.
+     */
+    if ((member->flags & ITCL_CONSTRUCTOR) != 0 &&
+        (member->classDefn->initCode != NULL)) {
+        result = TclProcCompileProc(interp, mcode->procPtr,
+            member->classDefn->initCode, (Namespace*)member->classDefn->namesp,
+            "initialization code for", member->fullname);
+
+        if (result != TCL_OK) {
+            return result;
+        }
+    }
+
+    /*
+     *  If the code body has a Tcl implementation, then compile it here.
+     */
+    if ((mcode->flags & ITCL_IMPLEMENT_TCL) != 0) {
+
+        result = TclProcCompileProc(interp, mcode->procPtr,
+            mcode->procPtr->bodyPtr, (Namespace*)member->classDefn->namesp,
+            "body for", member->fullname);
+
+        if (result != TCL_OK) {
+            return result;
+        }
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_EvalMemberCode()
+ *
+ *  Used to execute an ItclMemberCode representation of a code
+ *  fragment.  This code may be a body of Tcl commands, or a C handler
+ *  procedure.
+ *
+ *  Executes the command with the given arguments (objc,objv) and
+ *  returns an integer status code (TCL_OK/TCL_ERROR).  Returns the
+ *  result string or an error message in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_EvalMemberCode(interp, mfunc, member, contextObj, objc, objv)
+    Tcl_Interp *interp;       /* current interpreter */
+    ItclMemberFunc *mfunc;    /* member func, or NULL (for error messages) */
+    ItclMember *member;       /* command member containing code */
+    ItclObject *contextObj;   /* object context, or NULL */
+    int objc;                 /* number of arguments */
+    Tcl_Obj *CONST objv[];    /* argument objects */
+{
+    int result = TCL_OK;
+    Itcl_CallFrame *oldFramePtr = NULL;
+
+    int i, transparent, newEntry;
+    ItclObjectInfo *info;
+    ItclMemberCode *mcode;
+    ItclContext context;
+    Itcl_CallFrame *framePtr, *transFramePtr;
+
+    /*
+     *  If this code does not have an implementation yet, then
+     *  try to autoload one.  Also, if this is Tcl code, make sure
+     *  that it's compiled and ready to use.
+     */
+    if (Itcl_GetMemberCode(interp, member) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    mcode = member->code;
+
+    /*
+     *  Bump the reference count on this code, in case it is
+     *  redefined or deleted during execution.
+     */
+    Itcl_PreserveData((ClientData)mcode);
+
+    /*
+     *  Install a new call frame context for the current code.
+     *  If the current call frame is marked as "transparent", then
+     *  do an "uplevel" operation to move past it.  Transparent
+     *  call frames are installed by Itcl_HandleInstance.  They
+     *  provide a way of entering an object context without
+     *  interfering with the normal call stack.
+     */
+    transparent = 0;
+
+    info = member->classDefn->info;
+    framePtr = _Tcl_GetCallFrame(interp, 0);
+    for (i = Itcl_GetStackSize(&info->transparentFrames)-1; i >= 0; i--) {
+        transFramePtr = (Itcl_CallFrame*)
+            Itcl_GetStackValue(&info->transparentFrames, i);
+
+        if (framePtr == transFramePtr) {
+            transparent = 1;
+            break;
+        }
+    }
+
+    if (transparent) {
+        framePtr = _Tcl_GetCallFrame(interp, 1);
+        oldFramePtr = _Tcl_ActivateCallFrame(interp, framePtr);
+    }
+
+    if (Itcl_PushContext(interp, member, member->classDefn, contextObj,
+        &context) != TCL_OK) {
+
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If this is a method with a Tcl implementation, or a
+     *  constructor with initCode, then parse its arguments now.
+     */
+    if (mfunc && objc > 0) {
+        if ((mcode->flags & ITCL_IMPLEMENT_TCL) != 0 ||
+            ( (member->flags & ITCL_CONSTRUCTOR) != 0 &&
+              (member->classDefn->initCode != NULL) ) ) {
+
+            if (Itcl_AssignArgs(interp, objc, objv, mfunc) != TCL_OK) {
+                result = TCL_ERROR;
+                goto evalMemberCodeDone;
+            }
+        }
+    }
+
+    /*
+     *  If this code is a constructor, and if it is being invoked
+     *  when an object is first constructed (i.e., the "constructed"
+     *  table is still active within the object), then handle the
+     *  "initCode" associated with the constructor and make sure that
+     *  all base classes are properly constructed.
+     *
+     *  TRICKY NOTE:
+     *    The "initCode" must be executed here.  This is the only
+     *    opportunity where the arguments of the constructor are
+     *    available in a call frame.
+     */
+    if ((member->flags & ITCL_CONSTRUCTOR) && contextObj &&
+        contextObj->constructed) {
+
+        result = Itcl_ConstructBase(interp, contextObj, member->classDefn);
+
+        if (result != TCL_OK) {
+            goto evalMemberCodeDone;
+        }
+    }
+
+    /*
+     *  Execute the code body...
+     */
+    if ((mcode->flags & ITCL_IMPLEMENT_OBJCMD) != 0) {
+        result = (*mcode->cfunc.objCmd)(mcode->clientData,
+            interp, objc, objv);
+    }
+    else if ((mcode->flags & ITCL_IMPLEMENT_ARGCMD) != 0) {
+        char **argv;
+        argv = (char**)ckalloc( (unsigned)(objc*sizeof(char*)) );
+        for (i=0; i < objc; i++) {
+            argv[i] = Tcl_GetStringFromObj(objv[i], (int*)NULL);
+        }
+
+        result = (*mcode->cfunc.argCmd)(mcode->clientData,
+            interp, objc, argv);
+
+        ckfree((char*)argv);
+    }
+    else if ((mcode->flags & ITCL_IMPLEMENT_TCL) != 0) {
+        result = Tcl_EvalObj(interp, mcode->procPtr->bodyPtr);
+    }
+    else {
+        Tcl_Panic("itcl: bad implementation flag for %s", member->fullname);
+    }
+
+    /*
+     *  If this is a constructor or destructor, and if it is being
+     *  invoked at the appropriate time, keep track of which methods
+     *  have been called.  This information is used to implicitly
+     *  invoke constructors/destructors as needed.
+     */
+    if ((member->flags & ITCL_DESTRUCTOR) && contextObj &&
+         contextObj->destructed) {
+
+        Tcl_CreateHashEntry(contextObj->destructed,
+            member->classDefn->fullname, &newEntry);
+    }
+    if ((member->flags & ITCL_CONSTRUCTOR) && contextObj &&
+         contextObj->constructed) {
+
+        Tcl_CreateHashEntry(contextObj->constructed,
+            member->classDefn->name, &newEntry);
+    }
+
+evalMemberCodeDone:
+    Itcl_PopContext(interp, &context);
+
+    if (transparent) {
+        (void) _Tcl_ActivateCallFrame(interp, oldFramePtr);
+    }
+    Itcl_ReleaseData((ClientData)mcode);
+
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateArgList()
+ *
+ *  Parses a Tcl list representing an argument declaration and returns
+ *  a linked list of CompiledLocal values.  Usually invoked as part
+ *  of Itcl_CreateMemberFunc() when a new method or procedure is being
+ *  defined.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CreateArgList(interp, decl, argcPtr, argPtr)
+    Tcl_Interp* interp;       /* interpreter managing this function */
+    CONST char* decl;         /* string representing argument list */
+    int* argcPtr;             /* returns number of args in argument list */
+    CompiledLocal** argPtr;   /* returns pointer to parsed argument list */
+{
+    int status = TCL_OK;  /* assume that this will succeed */
+
+    int i, argc, fargc;
+    char **argv, **fargv;
+    CompiledLocal *localPtr, *last;
+
+    *argPtr = last = NULL;
+    *argcPtr = 0;
+
+    if (decl) {
+        if (Tcl_SplitList(interp, (CONST84 char *)decl, &argc, &argv)
+               != TCL_OK) {
+            return TCL_ERROR;
+        }
+
+        for (i=0; i < argc && status == TCL_OK; i++) {
+            if (Tcl_SplitList(interp, argv[i], &fargc, &fargv) != TCL_OK) {
+                status = TCL_ERROR;
+            }
+            else {
+                localPtr = NULL;
+
+                if (fargc == 0 || *fargv[0] == '\0') {
+                    char mesg[100];
+                    sprintf(mesg, "argument #%d has no name", i);
+                    Tcl_SetResult(interp, mesg, TCL_VOLATILE);
+                    status = TCL_ERROR;
+                }
+                else if (fargc > 2) {
+                    Tcl_AppendResult(interp,
+                        "too many fields in argument specifier \"",
+                        argv[i], "\"",
+                        (char*)NULL);
+                    status = TCL_ERROR;
+                }
+                else if (strstr(fargv[0],"::")) {
+                    Tcl_AppendResult(interp,
+                        "bad argument name \"", fargv[0], "\"",
+                        (char*)NULL);
+                    status = TCL_ERROR;
+                }
+                else if (fargc == 1) {
+                    localPtr = Itcl_CreateArg(fargv[0], (char*)NULL);
+                }
+                else {
+                    localPtr = Itcl_CreateArg(fargv[0], fargv[1]);
+                }
+
+                if (localPtr) {
+                    localPtr->frameIndex = i;
+
+                    if (*argPtr == NULL) {
+                        *argPtr = last = localPtr;
+                    }
+                    else {
+                        last->nextPtr = localPtr;
+                        last = localPtr;
+                    }
+                }
+            }
+            ckfree((char*)fargv);
+        }
+        ckfree((char*)argv);
+    }
+
+    /*
+     *  If anything went wrong, destroy whatever arguments were
+     *  created and return an error.
+     */
+    if (status == TCL_OK) {
+        *argcPtr = argc;
+    } else {
+        Itcl_DeleteArgList(*argPtr);
+        *argPtr = NULL;
+    }
+    return status;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateArg()
+ *
+ *  Creates a new Tcl Arg structure and fills it with the given
+ *  information.  Returns a pointer to the new Arg structure.
+ * ------------------------------------------------------------------------
+ */
+CompiledLocal*
+Itcl_CreateArg(name, init)
+    CONST char* name;     /* name of new argument */
+    CONST char* init;     /* initial value */
+{
+    CompiledLocal *localPtr = NULL;
+    int nameLen;
+
+    if (name == NULL) {
+        name = "";
+    }
+    nameLen = strlen(name);
+
+    localPtr = (CompiledLocal*)ckalloc(
+        (unsigned)(sizeof(CompiledLocal)-sizeof(localPtr->name) + nameLen+1)
+    );
+
+    localPtr->nextPtr = NULL;
+    localPtr->nameLength = nameLen;
+    localPtr->frameIndex = 0;  /* set this later */
+    ItclInitVarArgument(localPtr);
+    localPtr->resolveInfo = NULL;
+
+    if (init != NULL) {
+        localPtr->defValuePtr = Tcl_NewStringObj((CONST84 char *)init, -1);
+        Tcl_IncrRefCount(localPtr->defValuePtr);
+    } else {
+        localPtr->defValuePtr = NULL;
+    }
+
+    strcpy(localPtr->name, name);
+
+    return localPtr;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteArgList()
+ *
+ *  Destroys a chain of arguments acting as an argument list.  Usually
+ *  invoked when a method/proc is being destroyed, to discard its
+ *  argument list.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DeleteArgList(arglist)
+    CompiledLocal *arglist;   /* first argument in arg list chain */
+{
+    CompiledLocal *localPtr, *next;
+
+    for (localPtr=arglist; localPtr; localPtr=next) {
+        if (localPtr->defValuePtr != NULL) {
+            Tcl_DecrRefCount(localPtr->defValuePtr);
+        }
+        if (localPtr->resolveInfo) {
+            if (localPtr->resolveInfo->deleteProc) {
+                localPtr->resolveInfo->deleteProc(localPtr->resolveInfo);
+            } else {
+                ckfree((char*)localPtr->resolveInfo);
+            }
+            localPtr->resolveInfo = NULL;
+        }
+        next = localPtr->nextPtr;
+        ckfree((char*)localPtr);
+    }
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ArgList()
+ *
+ *  Returns a Tcl_Obj containing the string representation for the
+ *  given argument list.  This object has a reference count of 1.
+ *  The reference count should be decremented when the string is no
+ *  longer needed, and it will free itself.
+ * ------------------------------------------------------------------------
+ */
+Tcl_Obj*
+Itcl_ArgList(argc, arglist)
+    int argc;                   /* number of arguments */
+    CompiledLocal* arglist;     /* first argument in arglist */
+{
+    char *val;
+    Tcl_Obj *objPtr;
+    Tcl_DString buffer;
+
+    Tcl_DStringInit(&buffer);
+
+    while (arglist && argc-- > 0) {
+        if (arglist->defValuePtr) {
+            val = Tcl_GetStringFromObj(arglist->defValuePtr, (int*)NULL);
+            Tcl_DStringStartSublist(&buffer);
+            Tcl_DStringAppendElement(&buffer, arglist->name);
+            Tcl_DStringAppendElement(&buffer, val);
+            Tcl_DStringEndSublist(&buffer);
+        }
+        else {
+            Tcl_DStringAppendElement(&buffer, arglist->name);
+        }
+        arglist = arglist->nextPtr;
+    }
+
+    objPtr = Tcl_NewStringObj(Tcl_DStringValue(&buffer),
+        Tcl_DStringLength(&buffer));
+
+    Tcl_DStringFree(&buffer);
+
+    return objPtr;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_EquivArgLists()
+ *
+ *  Compares two argument lists to see if they are equivalent.  The
+ *  first list is treated as a prototype, and the second list must
+ *  match it.  Argument names may be different, but they must match in
+ *  meaning.  If one argument is optional, the corresponding argument
+ *  must also be optional.  If the prototype list ends with the magic
+ *  "args" argument, then it matches everything in the other list.
+ *
+ *  Returns non-zero if the argument lists are equivalent.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_EquivArgLists(arg1, arg1c, arg2, arg2c)
+    CompiledLocal* arg1;   /* prototype argument list */
+    int arg1c;             /* number of args in prototype arg list */
+    CompiledLocal* arg2;   /* another argument list to match against */
+    int arg2c;             /* number of args in matching list */
+{
+    char *dval1, *dval2;
+
+    while (arg1 && arg1c > 0 && arg2 && arg2c > 0) {
+        /*
+         *  If the prototype argument list ends with the magic "args"
+         *  argument, then it matches everything in the other list.
+         */
+        if (arg1c == 1 && strcmp(arg1->name,"args") == 0) {
+            return 1;
+        }
+
+        /*
+         *  If one has a default value, then the other must have the
+         *  same default value.
+         */
+        if (arg1->defValuePtr) {
+            if (arg2->defValuePtr == NULL) {
+                return 0;
+            }
+
+            dval1 = Tcl_GetStringFromObj(arg1->defValuePtr, (int*)NULL);
+            dval2 = Tcl_GetStringFromObj(arg2->defValuePtr, (int*)NULL);
+            if (strcmp(dval1, dval2) != 0) {
+                return 0;
+            }
+        }
+        else if (arg2->defValuePtr) {
+            return 0;
+        }
+
+        arg1 = arg1->nextPtr;  arg1c--;
+        arg2 = arg2->nextPtr;  arg2c--;
+    }
+    if (arg1c == 1 && strcmp(arg1->name,"args") == 0) {
+        return 1;
+    }
+    return (arg1c == 0 && arg2c == 0);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_GetMemberFuncUsage()
+ *
+ *  Returns a string showing how a command member should be invoked.
+ *  If the command member is a method, then the specified object name
+ *  is reported as part of the invocation path:
+ *
+ *      obj method arg ?arg arg ...?
+ *
+ *  Otherwise, the "obj" pointer is ignored, and the class name is
+ *  used as the invocation path:
+ *
+ *      class::proc arg ?arg arg ...?
+ *
+ *  Returns the string by appending it onto the Tcl_Obj passed in as
+ *  an argument.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_GetMemberFuncUsage(mfunc, contextObj, objPtr)
+    ItclMemberFunc *mfunc;      /* command member being examined */
+    ItclObject *contextObj;     /* invoked with respect to this object */
+    Tcl_Obj *objPtr;            /* returns: string showing usage */
+{
+    int argcount;
+    char *name;
+    CompiledLocal *arglist, *argPtr;
+    Tcl_HashEntry *entry;
+    ItclMemberFunc *mf;
+    ItclClass *cdefnPtr;
+
+    /*
+     *  If the command is a method and an object context was
+     *  specified, then add the object context.  If the method
+     *  was a constructor, and if the object is being created,
+     *  then report the invocation via the class creation command.
+     */
+    if ((mfunc->member->flags & ITCL_COMMON) == 0) {
+        if ((mfunc->member->flags & ITCL_CONSTRUCTOR) != 0 &&
+            contextObj->constructed) {
+
+            cdefnPtr = (ItclClass*)contextObj->classDefn;
+            mf = NULL;
+            entry = Tcl_FindHashEntry(&cdefnPtr->resolveCmds, "constructor");
+            if (entry) {
+                mf = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+            }
+
+            if (mf == mfunc) {
+                Tcl_GetCommandFullName(contextObj->classDefn->interp,
+                    contextObj->classDefn->accessCmd, objPtr);
+                Tcl_AppendToObj(objPtr, " ", -1);
+                name = (char *) Tcl_GetCommandName(
+                   contextObj->classDefn->interp, contextObj->accessCmd);
+                Tcl_AppendToObj(objPtr, name, -1);
+            } else {
+                Tcl_AppendToObj(objPtr, mfunc->member->fullname, -1);
+            }
+        } else if (contextObj && contextObj->accessCmd) {
+            name = (char *) Tcl_GetCommandName(contextObj->classDefn->interp,
+                contextObj->accessCmd);
+            Tcl_AppendStringsToObj(objPtr, name, " ", mfunc->member->name,
+                (char*)NULL);
+        } else {
+            Tcl_AppendStringsToObj(objPtr, "<object> ", mfunc->member->name,
+                (char*)NULL);
+        }
+    } else {
+        Tcl_AppendToObj(objPtr, mfunc->member->fullname, -1);
+    }
+
+    /*
+     *  Add the argument usage info.
+     */
+    if (mfunc->member->code) {
+        arglist = mfunc->member->code->arglist;
+        argcount = mfunc->member->code->argcount;
+    } else if (mfunc->arglist) {
+        arglist = mfunc->arglist;
+        argcount = mfunc->argcount;
+    } else {
+        arglist = NULL;
+        argcount = 0;
+    }
+
+    if (arglist) {
+        for (argPtr=arglist;
+             argPtr && argcount > 0;
+             argPtr=argPtr->nextPtr, argcount--) {
+
+            if (argcount == 1 && strcmp(argPtr->name, "args") == 0) {
+                Tcl_AppendToObj(objPtr, " ?arg arg ...?", -1);
+            }
+            else if (argPtr->defValuePtr) {
+                Tcl_AppendStringsToObj(objPtr, " ?", argPtr->name, "?",
+                    (char*)NULL);
+            }
+            else {
+                Tcl_AppendStringsToObj(objPtr, " ", argPtr->name,
+                    (char*)NULL);
+            }
+        }
+    }
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ExecMethod()
+ *
+ *  Invoked by Tcl to handle the execution of a user-defined method.
+ *  A method is similar to the usual Tcl proc, but has access to
+ *  object-specific data.  If for some reason there is no current
+ *  object context, then a method call is inappropriate, and an error
+ *  is returned.
+ *
+ *  Methods are implemented either as Tcl code fragments, or as C-coded
+ *  procedures.  For Tcl code fragments, command arguments are parsed
+ *  according to the argument list, and the body is executed in the
+ *  scope of the class where it was defined.  For C procedures, the
+ *  arguments are passed in "as-is", and the procedure is executed in
+ *  the most-specific class scope.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ExecMethod(clientData, interp, objc, objv)
+    ClientData clientData;   /* method definition */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclMemberFunc *mfunc = (ItclMemberFunc*)clientData;
+    ItclMember *member = mfunc->member;
+    int result = TCL_OK;
+
+    char *token;
+    Tcl_HashEntry *entry;
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+
+    /*
+     *  Make sure that the current namespace context includes an
+     *  object that is being manipulated.  Methods can be executed
+     *  only if an object context exists.
+     */
+    if (Itcl_GetContext(interp, &contextClass, &contextObj) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (contextObj == NULL) {
+        Tcl_AppendResult(interp,
+            "cannot access object-specific info without an object context",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Make sure that this command member can be accessed from
+     *  the current namespace context.
+     */
+    if (mfunc->member->protection != ITCL_PUBLIC) {
+        Tcl_Namespace *contextNs = Itcl_GetTrueNamespace(interp,
+            contextClass->info);
+
+        if (!Itcl_CanAccessFunc(mfunc, contextNs)) {
+            Tcl_AppendResult(interp,
+                "can't access \"", member->fullname, "\": ",
+                Itcl_ProtectionStr(member->protection), " function",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+    }
+
+    /*
+     *  All methods should be "virtual" unless they are invoked with
+     *  a "::" scope qualifier.
+     *
+     *  To implement the "virtual" behavior, find the most-specific
+     *  implementation for the method by looking in the "resolveCmds"
+     *  table for this class.
+     */
+    token = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+    if (strstr(token, "::") == NULL) {
+        entry = Tcl_FindHashEntry(&contextObj->classDefn->resolveCmds,
+            member->name);
+
+        if (entry) {
+            mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+            member = mfunc->member;
+        }
+    }
+
+    /*
+     *  Execute the code for the method.  Be careful to protect
+     *  the method in case it gets deleted during execution.
+     */
+    Itcl_PreserveData((ClientData)mfunc);
+
+    result = Itcl_EvalMemberCode(interp, mfunc, member, contextObj,
+        objc, objv);
+
+    result = Itcl_ReportFuncErrors(interp, mfunc, contextObj, result);
+
+    Itcl_ReleaseData((ClientData)mfunc);
+
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ExecProc()
+ *
+ *  Invoked by Tcl to handle the execution of a user-defined proc.
+ *
+ *  Procs are implemented either as Tcl code fragments, or as C-coded
+ *  procedures.  For Tcl code fragments, command arguments are parsed
+ *  according to the argument list, and the body is executed in the
+ *  scope of the class where it was defined.  For C procedures, the
+ *  arguments are passed in "as-is", and the procedure is executed in
+ *  the most-specific class scope.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ExecProc(clientData, interp, objc, objv)
+    ClientData clientData;   /* proc definition */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclMemberFunc *mfunc = (ItclMemberFunc*)clientData;
+    ItclMember *member = mfunc->member;
+    int result = TCL_OK;
+
+    /*
+     *  Make sure that this command member can be accessed from
+     *  the current namespace context.
+     */
+    if (mfunc->member->protection != ITCL_PUBLIC) {
+        Tcl_Namespace *contextNs = Itcl_GetTrueNamespace(interp,
+            mfunc->member->classDefn->info);
+
+        if (!Itcl_CanAccessFunc(mfunc, contextNs)) {
+            Tcl_AppendResult(interp,
+                "can't access \"", member->fullname, "\": ",
+                Itcl_ProtectionStr(member->protection), " function",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+    }
+
+    /*
+     *  Execute the code for the proc.  Be careful to protect
+     *  the proc in case it gets deleted during execution.
+     */
+    Itcl_PreserveData((ClientData)mfunc);
+
+    result = Itcl_EvalMemberCode(interp, mfunc, member, (ItclObject*)NULL,
+        objc, objv);
+
+    result = Itcl_ReportFuncErrors(interp, mfunc, (ItclObject*)NULL, result);
+
+    Itcl_ReleaseData((ClientData)mfunc);
+
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_PushContext()
+ *
+ *  Sets up the class/object context so that a body of [incr Tcl]
+ *  code can be executed.  This procedure pushes a call frame with
+ *  the proper namespace context for the class.  If an object context
+ *  is supplied, the object's instance variables are integrated into
+ *  the call frame so they can be accessed as local variables.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_PushContext(interp, member, contextClass, contextObj, contextPtr)
+    Tcl_Interp *interp;       /* interpreter managing this body of code */
+    ItclMember *member;       /* member containing code body */
+    ItclClass *contextClass;  /* class context */
+    ItclObject *contextObj;   /* object context, or NULL */
+    ItclContext *contextPtr;  /* storage space for class/object context */
+{
+    ItclCallFrame *framePtr = &contextPtr->frame;
+
+    int result, localCt, newEntry;
+    ItclMemberCode *mcode;
+    Proc *procPtr;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  Activate the call frame.  If this fails, we'll bail out
+     *  before allocating any resources.
+     *
+     *  NOTE:  Always push a call frame that looks like a proc.
+     *    This causes global variables to be handled properly
+     *    inside methods/procs.
+     */
+    result = Tcl_PushCallFrame(interp, (Tcl_CallFrame*)framePtr,
+                 contextClass->namesp, /* isProcCallFrame */ 1);
+
+    if (result != TCL_OK) {
+        return result;
+    }
+
+    contextPtr->classDefn = contextClass;
+    contextPtr->compiledLocals = &contextPtr->localStorage[0];
+
+    /*
+     *  If this is an object context, register it in a hash table
+     *  of all known contexts.  We'll need this later if we
+     *  call Itcl_GetContext to get the object context for the
+     *  current call frame.
+     */
+    if (contextObj) {
+        entry = Tcl_CreateHashEntry(&contextClass->info->contextFrames,
+            (char*)framePtr, &newEntry);
+
+        Itcl_PreserveData((ClientData)contextObj);
+        Tcl_SetHashValue(entry, (ClientData)contextObj);
+    }
+
+    /*
+     *  Set up the compiled locals in the call frame and assign
+     *  argument variables.
+     */
+    if (member) {
+        mcode = member->code;
+        procPtr = mcode->procPtr;
+
+        /*
+         * Invoking TclInitCompiledLocals with a framePtr->procPtr->bodyPtr
+         * that is not a compiled byte code type leads to a crash. So
+         * make sure that the body is compiled here. This needs to
+         * be done even if the body of the Itcl method is not implemented
+         * as a Tcl proc or has no implementation. The empty string should
+         * have been defined as the body if no implementation was defined.
+         */
+        assert(mcode->procPtr->bodyPtr != NULL);
+
+        result = TclProcCompileProc(interp, mcode->procPtr,
+            mcode->procPtr->bodyPtr, (Namespace*)member->classDefn->namesp,
+            "body for", member->fullname);
+
+        if (result != TCL_OK) {
+            return result;
+        }
+
+        /*
+         *  If there are too many compiled locals to fit in the default
+         *  storage space for the context, then allocate more space.
+         */
+        localCt = procPtr->numCompiledLocals;
+        if (localCt >
+               (int)(sizeof(contextPtr->localStorage)/itclVarLocalSize)) {
+            contextPtr->compiledLocals = (Var*)ckalloc(
+                (unsigned)(localCt * itclVarLocalSize)
+            );
+        }
+
+        /*
+         * Initialize and resolve compiled variable references.
+         * Class variables will have special resolution rules.
+         * In that case, we call their "resolver" procs to get our
+         * hands on the variable, and we make the compiled local a
+         * link to the real variable.
+         */
+
+        framePtr->procPtr = procPtr;
+        framePtr->numCompiledLocals = localCt;
+        framePtr->compiledLocals = contextPtr->compiledLocals;
+
+        TclInitCompiledLocals(interp, (CallFrame *) framePtr,
+            (Namespace*)contextClass->namesp);
+    }
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_PopContext()
+ *
+ *  Removes a class/object context previously set up by Itcl_PushContext.
+ *  Usually called after an [incr Tcl] code body has been executed,
+ *  to clean up.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_PopContext(interp, contextPtr)
+    Tcl_Interp *interp;       /* interpreter managing this body of code */
+    ItclContext *contextPtr;  /* storage space for class/object context */
+{
+    Itcl_CallFrame *framePtr;
+    ItclObjectInfo *info;
+    ItclObject *contextObj;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  See if the current call frame has an object context
+     *  associated with it.  If so, release the claim on the
+     *  object info.
+     */
+    framePtr = _Tcl_GetCallFrame(interp, 0);
+    info = contextPtr->classDefn->info;
+
+    entry = Tcl_FindHashEntry(&info->contextFrames, (char*)framePtr);
+    if (entry != NULL) {
+        contextObj = (ItclObject*)Tcl_GetHashValue(entry);
+        Itcl_ReleaseData((ClientData)contextObj);
+        Tcl_DeleteHashEntry(entry);
+    }
+
+    /*
+     *  Remove the call frame.
+     */
+    Tcl_PopCallFrame(interp);
+
+    /*
+     * Free the compiledLocals array if malloc'ed storage was used.
+     */
+    if (contextPtr->compiledLocals != &contextPtr->localStorage[0]) {
+        ckfree((char*)contextPtr->compiledLocals);
+    }
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_GetContext()
+ *
+ *  Convenience routine for looking up the current object/class context.
+ *  Useful in implementing methods/procs to see what class, and perhaps
+ *  what object, is active.
+ *
+ *  Returns TCL_OK if the current namespace is a class namespace.
+ *  Also returns pointers to the class definition, and to object
+ *  data if an object context is active.  Returns TCL_ERROR (along
+ *  with an error message in the interpreter) if a class namespace
+ *  is not active.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_GetContext(interp, cdefnPtr, odefnPtr)
+    Tcl_Interp *interp;           /* current interpreter */
+    ItclClass **cdefnPtr;         /* returns:  class definition or NULL */
+    ItclObject **odefnPtr;        /* returns:  object data or NULL */
+{
+    Tcl_Namespace *activeNs = Tcl_GetCurrentNamespace(interp);
+    ItclObjectInfo *info;
+    Itcl_CallFrame *framePtr;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  Return NULL for anything that cannot be found.
+     */
+    *cdefnPtr = NULL;
+    *odefnPtr = NULL;
+
+    /*
+     *  If the active namespace is a class namespace, then return
+     *  all known info.  See if the current call frame is a known
+     *  object context, and if so, return that context.
+     */
+    if (Itcl_IsClassNamespace(activeNs)) {
+        *cdefnPtr = (ItclClass*)activeNs->clientData;
+
+        framePtr = _Tcl_GetCallFrame(interp, 0);
+
+        info = (*cdefnPtr)->info;
+        entry = Tcl_FindHashEntry(&info->contextFrames, (char*)framePtr);
+
+        if (entry != NULL) {
+            *odefnPtr = (ItclObject*)Tcl_GetHashValue(entry);
+        }
+        return TCL_OK;
+    }
+
+    /*
+     *  If there is no class/object context, return an error message.
+     */
+    Tcl_AppendResult(interp,
+        "namespace \"", activeNs->fullName, "\" is not a class namespace",
+        (char*)NULL);
+
+    return TCL_ERROR;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_AssignArgs()
+ *
+ *  Matches a list of arguments against a Tcl argument specification.
+ *  Supports all of the rules regarding arguments for Tcl procs, including
+ *  default arguments and variable-length argument lists.
+ *
+ *  Assumes that a local call frame is already installed.  As variables
+ *  are successfully matched, they are stored as variables in the call
+ *  frame.  Returns TCL_OK on success, or TCL_ERROR (along with an error
+ *  message in interp->result) on error.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_AssignArgs(interp, objc, objv, mfunc)
+    Tcl_Interp *interp;        /* interpreter */
+    int objc;                  /* number of arguments */
+    Tcl_Obj *CONST objv[];     /* argument objects */
+    ItclMemberFunc *mfunc;     /* member function info (for error messages) */
+{
+    ItclMemberCode *mcode = mfunc->member->code;
+
+    int result = TCL_OK;
+
+    int defargc;
+    char **defargv = NULL;
+    Tcl_Obj **defobjv = NULL;
+    int configc = 0;
+    ItclVarDefn **configVars = NULL;
+    char **configVals = NULL;
+
+    int vi, argsLeft;
+    ItclClass *contextClass;
+    ItclObject *contextObj;
+    CompiledLocal *argPtr;
+    ItclCallFrame *framePtr;
+    Var *varPtr;
+    Tcl_Obj *objPtr, *listPtr;
+    char *value;
+
+    framePtr = (ItclCallFrame *) _Tcl_GetCallFrame(interp, 0);
+    framePtr->objc = objc;
+    framePtr->objv = objv;  /* ref counts for args are incremented below */
+
+    /*
+     *  See if there is a current object context.  We may need
+     *  it later on.
+     */
+    (void) Itcl_GetContext(interp, &contextClass, &contextObj);
+    Tcl_ResetResult(interp);
+
+    /*
+     *  Match the actual arguments against the procedure's formal
+     *  parameters to compute local variables.
+     */
+    varPtr = framePtr->compiledLocals;
+
+    for (argsLeft=mcode->argcount, argPtr=mcode->arglist, objv++, objc--;
+         argsLeft > 0;
+         argPtr=argPtr->nextPtr, argsLeft--, ItclNextLocal(varPtr), objv++, objc--)
+    {
+        if (!TclIsVarArgument(argPtr)) {
+            Tcl_Panic("local variable %s is not argument but should be",
+                argPtr->name);
+            return TCL_ERROR;
+        }
+        if (TclIsVarTemporary(argPtr)) {
+            Tcl_Panic("local variable is temporary but should be an argument");
+            return TCL_ERROR;
+        }
+
+        /*
+         *  Handle the special case of the last formal being "args".
+         *  When it occurs, assign it a list consisting of all the
+         *  remaining actual arguments.
+         */
+        if ((argsLeft == 1) && (strcmp(argPtr->name, "args") == 0)) {
+            if (objc < 0) objc = 0;
+
+            listPtr = Tcl_NewListObj(objc, objv);
+            ItclVarObjValue(varPtr) = listPtr;
+            Tcl_IncrRefCount(listPtr); /* local var is a reference */
+           ItclClearVarUndefined(varPtr);
+            objc = 0;
+
+            break;
+        }
+
+        /*
+         *  Handle the special case of the last formal being "config".
+         *  When it occurs, treat all remaining arguments as public
+         *  variable assignments.  Set the local "config" variable
+         *  to the list of public variables assigned.
+         */
+        else if ( (argsLeft == 1) &&
+                  (strcmp(argPtr->name, "config") == 0) &&
+                  contextObj )
+        {
+            /*
+             *  If this is not an old-style method, discourage against
+             *  the use of the "config" argument.
+             */
+            if ((mfunc->member->flags & ITCL_OLD_STYLE) == 0) {
+                Tcl_AppendResult(interp,
+                    "\"config\" argument is an anachronism\n",
+                    "[incr Tcl] no longer supports the \"config\" argument.\n",
+                    "Instead, use the \"args\" argument and then use the\n",
+                    "built-in configure method to handle args like this:\n",
+                    "  eval configure $args",
+                    (char*)NULL);
+                result = TCL_ERROR;
+                goto argErrors;
+            }
+
+            /*
+             *  Otherwise, handle the "config" argument in the usual way...
+             *   - parse all "-name value" assignments
+             *   - set "config" argument to the list of variable names
+             */
+            if (objc > 0) {  /* still have some arguments left? */
+
+                result = ItclParseConfig(interp, objc, objv, contextObj,
+                    &configc, &configVars, &configVals);
+
+                if (result != TCL_OK) {
+                    goto argErrors;
+                }
+
+                listPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+                for (vi=0; vi < configc; vi++) {
+                    objPtr = Tcl_NewStringObj(
+                        configVars[vi]->member->classDefn->name, -1);
+                    Tcl_AppendToObj(objPtr, "::", -1);
+                    Tcl_AppendToObj(objPtr, configVars[vi]->member->name, -1);
+
+                    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
+                }
+
+                ItclVarObjValue(varPtr) = listPtr;
+                Tcl_IncrRefCount(listPtr); /* local var is a reference */
+               ItclClearVarUndefined(varPtr);
+
+                objc = 0;  /* all remaining args handled */
+            }
+
+            else if (argPtr->defValuePtr) {
+                value = Tcl_GetStringFromObj(argPtr->defValuePtr, (int*)NULL);
+
+                result = Tcl_SplitList(interp, value, &defargc, &defargv);
+                if (result != TCL_OK) {
+                    goto argErrors;
+                }
+                defobjv = (Tcl_Obj**)ckalloc(
+                    (unsigned)(defargc*sizeof(Tcl_Obj*))
+                );
+                for (vi=0; vi < defargc; vi++) {
+                    objPtr = Tcl_NewStringObj(defargv[vi], -1);
+                    Tcl_IncrRefCount(objPtr);
+                    defobjv[vi] = objPtr;
+                }
+
+                result = ItclParseConfig(interp, defargc, defobjv, contextObj,
+                    &configc, &configVars, &configVals);
+
+                if (result != TCL_OK) {
+                    goto argErrors;
+                }
+
+                listPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+                for (vi=0; vi < configc; vi++) {
+                    objPtr = Tcl_NewStringObj(
+                        configVars[vi]->member->classDefn->name, -1);
+                    Tcl_AppendToObj(objPtr, "::", -1);
+                    Tcl_AppendToObj(objPtr, configVars[vi]->member->name, -1);
+
+                    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
+                }
+
+                ItclVarObjValue(varPtr) = listPtr;
+                Tcl_IncrRefCount(listPtr); /* local var is a reference */
+               ItclClearVarUndefined(varPtr);
+            }
+            else {
+                objPtr = Tcl_NewStringObj("", 0);
+                ItclVarObjValue(varPtr) = objPtr;
+                Tcl_IncrRefCount(objPtr); /* local var is a reference */
+               ItclClearVarUndefined(varPtr);
+            }
+        }
+
+        /*
+         *  Resume the usual processing of arguments...
+         */
+        else if (objc > 0) {          /* take next arg as value */
+            objPtr = *objv;
+            ItclVarObjValue(varPtr) = objPtr;
+           ItclClearVarUndefined(varPtr);
+            Tcl_IncrRefCount(objPtr);  /* local var is a reference */
+        }
+        else if (argPtr->defValuePtr) {    /* ...or use default value */
+            objPtr = argPtr->defValuePtr;
+            ItclVarObjValue(varPtr) = objPtr;
+           ItclClearVarUndefined(varPtr);
+            Tcl_IncrRefCount(objPtr);  /* local var is a reference */
+        }
+        else {
+            if (mfunc) {
+                objPtr = Tcl_GetObjResult(interp);
+                Tcl_AppendToObj(objPtr, "wrong # args: should be \"", -1);
+                Itcl_GetMemberFuncUsage(mfunc, contextObj, objPtr);
+                Tcl_AppendToObj(objPtr, "\"", -1);
+            } else {
+                Tcl_AppendResult(interp,
+                    "no value given for parameter \"", argPtr->name, "\"",
+                    (char*)NULL);
+            }
+            result = TCL_ERROR;
+            goto argErrors;
+        }
+    }
+
+    if (objc > 0) {
+        if (mfunc) {
+            objPtr = Tcl_GetObjResult(interp);
+            Tcl_AppendToObj(objPtr, "wrong # args: should be \"", -1);
+            Itcl_GetMemberFuncUsage(mfunc, contextObj, objPtr);
+            Tcl_AppendToObj(objPtr, "\"", -1);
+        } else {
+            Tcl_AppendResult(interp,
+                "too many arguments",
+                (char*)NULL);
+        }
+        result = TCL_ERROR;
+        goto argErrors;
+    }
+
+    /*
+     *  Handle any "config" assignments.
+     */
+    if (configc > 0) {
+        if (ItclHandleConfig(interp, configc, configVars, configVals,
+                contextObj) != TCL_OK) {
+
+            result = TCL_ERROR;
+            goto argErrors;
+        }
+    }
+
+    /*
+     *  All arguments were successfully matched.
+     */
+    result = TCL_OK;
+
+    /*
+     *  If any errors were found, clean up and return error status.
+     */
+argErrors:
+    if (defobjv) {
+        for (vi=0; vi < defargc; vi++) {
+            Tcl_DecrRefCount(defobjv[vi]);
+        }
+        ckfree((char*)defobjv);
+    }
+    if (defargv) {
+        ckfree((char*)defargv);
+    }
+    if (configVars) {
+        ckfree((char*)configVars);
+    }
+    if (configVals) {
+        ckfree((char*)configVals);
+    }
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclParseConfig()
+ *
+ *  Parses a set of arguments as "-variable value" assignments.
+ *  Interprets all variable names in the most-specific class scope,
+ *  so that an inherited method with a "config" parameter will work
+ *  correctly.  Returns a list of public variable names and their
+ *  corresponding values; both lists should passed to ItclHandleConfig()
+ *  to perform assignments, and freed when no longer in use.  Returns a
+ *  status TCL_OK/TCL_ERROR and returns error messages in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+static int
+ItclParseConfig(interp, objc, objv, contextObj, rargc, rvars, rvals)
+    Tcl_Interp *interp;      /* interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+    ItclObject *contextObj;  /* object whose public vars are being config'd */
+    int *rargc;              /* return: number of variables accessed */
+    ItclVarDefn ***rvars;    /* return: list of variables */
+    char ***rvals;           /* return: list of values */
+{
+    int result = TCL_OK;
+    ItclVarLookup *vlookup;
+    Tcl_HashEntry *entry;
+    char *varName, *value;
+
+    if (objc < 0) objc = 0;
+    *rargc = 0;
+    *rvars = (ItclVarDefn**)ckalloc((unsigned)(objc*sizeof(ItclVarDefn*)));
+    *rvals = (char**)ckalloc((unsigned)(objc*sizeof(char*)));
+
+    while (objc-- > 0) {
+        /*
+         *  Next argument should be "-variable"
+         */
+        varName = Tcl_GetStringFromObj(*objv, (int*)NULL);
+        if (*varName != '-') {
+            Tcl_AppendResult(interp,
+                "syntax error in config assignment \"",
+                varName, "\": should be \"-variable value\"",
+                (char*)NULL);
+            result = TCL_ERROR;
+            break;
+        }
+        else if (objc-- <= 0) {
+            Tcl_AppendResult(interp,
+                "syntax error in config assignment \"",
+                varName, "\": should be \"-variable value\" (missing value)",
+                (char*)NULL);
+            result = TCL_ERROR;
+            break;
+        }
+
+        entry = Tcl_FindHashEntry(&contextObj->classDefn->resolveVars,
+            varName+1);
+
+        if (entry) {
+            vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+            value = Tcl_GetStringFromObj(*(objv+1), (int*)NULL);
+
+            (*rvars)[*rargc] = vlookup->vdefn;  /* variable definition */
+            (*rvals)[*rargc] = value;           /* config value */
+            (*rargc)++;
+            objv += 2;
+        }
+        else {
+            Tcl_AppendResult(interp,
+                "syntax error in config assignment \"",
+                varName, "\": unrecognized variable",
+                (char*)NULL);
+            result = TCL_ERROR;
+            break;
+        }
+    }
+    return result;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclHandleConfig()
+ *
+ *  Handles the assignment of "config" values to public variables.
+ *  The list of assignments is parsed in ItclParseConfig(), but the
+ *  actual assignments are performed here.  If the variables have any
+ *  associated "config" code, it is invoked here as well.  If errors
+ *  are detected during assignment or "config" code execution, the
+ *  variable is set back to its previous value and an error is returned.
+ *
+ *  Returns a status TCL_OK/TCL_ERROR, and returns any error messages
+ *  in the given interpreter.
+ * ------------------------------------------------------------------------
+ */
+static int
+ItclHandleConfig(interp, argc, vars, vals, contextObj)
+    Tcl_Interp *interp;      /* interpreter currently in control */
+    int argc;                /* number of assignments */
+    ItclVarDefn **vars;      /* list of public variable definitions */
+    char **vals;             /* list of public variable values */
+    ItclObject *contextObj;  /* object whose public vars are being config'd */
+{
+    int result = TCL_OK;
+
+    int i;
+    CONST char *val;
+    Tcl_DString lastval;
+    ItclContext context;
+    Itcl_CallFrame *oldFramePtr, *uplevelFramePtr;
+
+    Tcl_DStringInit(&lastval);
+
+    /*
+     *  All "config" assignments are performed in the most-specific
+     *  class scope, so that inherited methods with "config" arguments
+     *  will work correctly.
+     */
+    result = Itcl_PushContext(interp, (ItclMember*)NULL,
+        contextObj->classDefn, contextObj, &context);
+
+    if (result != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Perform each assignment and execute the "config" code
+     *  associated with each variable.  If any errors are encountered,
+     *  set the variable back to its previous value, and return an error.
+     */
+    for (i=0; i < argc; i++) {
+        val = Tcl_GetVar2(interp, vars[i]->member->fullname, (char*)NULL, 0);
+        if (!val) {
+            val = "";
+        }
+        Tcl_DStringSetLength(&lastval, 0);
+        Tcl_DStringAppend(&lastval, val, -1);
+
+        /*
+         *  Set the variable to the specified value.
+         */
+        if (!Tcl_SetVar2(interp, vars[i]->member->fullname, (char*)NULL,
+            vals[i], 0)) {
+
+            char msg[256];
+            sprintf(msg, "\n    (while configuring public variable \"%.100s\")", vars[i]->member->fullname);
+            Tcl_AddErrorInfo(interp, msg);
+            result = TCL_ERROR;
+            break;
+        }
+
+        /*
+         *  If the variable has a "config" condition, then execute it.
+         *  If it fails, put the variable back the way it was and return
+         *  an error.
+         *
+         *  TRICKY NOTE:  Be careful to evaluate the code one level
+         *    up in the call stack, so that it's executed in the
+         *    calling context, and not in the context that we've
+         *    set up for public variable access.
+         */
+        if (vars[i]->member->code) {
+
+            uplevelFramePtr = _Tcl_GetCallFrame(interp, 1);
+            oldFramePtr = _Tcl_ActivateCallFrame(interp, uplevelFramePtr);
+
+            result = Itcl_EvalMemberCode(interp, (ItclMemberFunc*)NULL,
+                vars[i]->member, contextObj, 0, (Tcl_Obj* CONST*)NULL);
+
+            (void) _Tcl_ActivateCallFrame(interp, oldFramePtr);
+
+            if (result != TCL_OK) {
+                char msg[256];
+                sprintf(msg, "\n    (while configuring public variable \"%.100s\")", vars[i]->member->fullname);
+                Tcl_AddErrorInfo(interp, msg);
+                Tcl_SetVar2(interp, vars[i]->member->fullname, (char*)NULL,
+                    Tcl_DStringValue(&lastval), 0);
+                break;
+            }
+        }
+    }
+
+    /*
+     *  Clean up and return.
+     */
+    Itcl_PopContext(interp, &context);
+    Tcl_DStringFree(&lastval);
+
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ConstructBase()
+ *
+ *  Usually invoked just before executing the body of a constructor
+ *  when an object is first created.  This procedure makes sure that
+ *  all base classes are properly constructed.  If an "initCode" fragment
+ *  was defined with the constructor for the class, then it is invoked.
+ *  After that, the list of base classes is checked for constructors
+ *  that are defined but have not yet been invoked.  Each of these is
+ *  invoked implicitly with no arguments.
+ *
+ *  Assumes that a local call frame is already installed, and that
+ *  constructor arguments have already been matched and are sitting in
+ *  this frame.  Returns TCL_OK on success; otherwise, this procedure
+ *  returns TCL_ERROR, along with an error message in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ConstructBase(interp, contextObj, contextClass)
+    Tcl_Interp *interp;       /* interpreter */
+    ItclObject *contextObj;   /* object being constructed */
+    ItclClass *contextClass;  /* current class being constructed */
+{
+    int result;
+    Itcl_ListElem *elem;
+    ItclClass *cdefn;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  If the class has an "initCode", invoke it in the current context.
+     *
+     *  TRICKY NOTE:
+     *    This context is the call frame containing the arguments
+     *    for the constructor.  The "initCode" makes sense right
+     *    now--just before the body of the constructor is executed.
+     */
+    if (contextClass->initCode) {
+        if (Tcl_EvalObj(interp, contextClass->initCode) != TCL_OK) {
+            return TCL_ERROR;
+        }
+    }
+
+    /*
+     *  Scan through the list of base classes and see if any of these
+     *  have not been constructed.  Invoke base class constructors
+     *  implicitly, as needed.  Go through the list of base classes
+     *  in reverse order, so that least-specific classes are constructed
+     *  first.
+     */
+    elem = Itcl_LastListElem(&contextClass->bases);
+    while (elem) {
+        cdefn = (ItclClass*)Itcl_GetListValue(elem);
+
+        if (!Tcl_FindHashEntry(contextObj->constructed, cdefn->name)) {
+
+            result = Itcl_InvokeMethodIfExists(interp, "constructor",
+                cdefn, contextObj, 0, (Tcl_Obj* CONST*)NULL);
+
+            if (result != TCL_OK) {
+                return TCL_ERROR;
+            }
+
+            /*
+             *  The base class may not have a constructor, but its
+             *  own base classes could have one.  If the constructor
+             *  wasn't found in the last step, then other base classes
+             *  weren't constructed either.  Make sure that all of its
+             *  base classes are properly constructed.
+             */
+            entry = Tcl_FindHashEntry(&cdefn->functions, "constructor");
+            if (entry == NULL) {
+                result = Itcl_ConstructBase(interp, contextObj, cdefn);
+                if (result != TCL_OK) {
+                    return TCL_ERROR;
+                }
+            }
+        }
+        elem = Itcl_PrevListElem(elem);
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_InvokeMethodIfExists()
+ *
+ *  Looks for a particular method in the specified class.  If the
+ *  method is found, it is invoked with the given arguments.  Any
+ *  protection level (protected/private) for the method is ignored.
+ *  If the method does not exist, this procedure does nothing.
+ *
+ *  This procedure is used primarily to invoke the constructor/destructor
+ *  when an object is created/destroyed.
+ *
+ *  Returns TCL_OK on success; otherwise, this procedure returns
+ *  TCL_ERROR along with an error message in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_InvokeMethodIfExists(interp, name, contextClass, contextObj, objc, objv)
+    Tcl_Interp *interp;       /* interpreter */
+    CONST char *name;         /* name of desired method */
+    ItclClass *contextClass;  /* current class being constructed */
+    ItclObject *contextObj;   /* object being constructed */
+    int objc;                 /* number of arguments */
+    Tcl_Obj *CONST objv[];    /* argument objects */
+{
+    int result = TCL_OK;
+
+    ItclMemberFunc *mfunc;
+    ItclMember *member;
+    Tcl_HashEntry *entry;
+    Tcl_Obj *cmdlinePtr;
+    int cmdlinec;
+    Tcl_Obj **cmdlinev;
+
+    /*
+     *  Scan through the list of base classes and see if any of these
+     *  have not been constructed.  Invoke base class constructors
+     *  implicitly, as needed.  Go through the list of base classes
+     *  in reverse order, so that least-specific classes are constructed
+     *  first.
+     */
+    entry = Tcl_FindHashEntry(&contextClass->functions, name);
+
+    if (entry) {
+        mfunc  = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+        member = mfunc->member;
+
+        /*
+         *  Prepend the method name to the list of arguments.
+         */
+        cmdlinePtr = Itcl_CreateArgs(interp, name, objc, objv);
+
+        (void) Tcl_ListObjGetElements((Tcl_Interp*)NULL, cmdlinePtr,
+            &cmdlinec, &cmdlinev);
+
+        /*
+         *  Execute the code for the method.  Be careful to protect
+         *  the method in case it gets deleted during execution.
+         */
+        Itcl_PreserveData((ClientData)mfunc);
+
+        result = Itcl_EvalMemberCode(interp, mfunc, member,
+            contextObj, cmdlinec, cmdlinev);
+
+        result = Itcl_ReportFuncErrors(interp, mfunc,
+            contextObj, result);
+
+        Itcl_ReleaseData((ClientData)mfunc);
+        Tcl_DecrRefCount(cmdlinePtr);
+    }
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ReportFuncErrors()
+ *
+ *  Used to interpret the status code returned when the body of a
+ *  Tcl-style proc is executed.  Handles the "errorInfo" and "errorCode"
+ *  variables properly, and adds error information into the interpreter
+ *  if anything went wrong.  Returns a new status code that should be
+ *  treated as the return status code for the command.
+ *
+ *  This same operation is usually buried in the Tcl InterpProc()
+ *  procedure.  It is defined here so that it can be reused more easily.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ReportFuncErrors(interp, mfunc, contextObj, result)
+    Tcl_Interp* interp;        /* interpreter being modified */
+    ItclMemberFunc *mfunc;     /* command member that was invoked */
+    ItclObject *contextObj;    /* object context for this command */
+    int result;                /* integer status code from proc body */
+{
+    Interp* iPtr = (Interp*)interp;
+    Tcl_Obj *objPtr;
+    char num[20];
+
+    if (result != TCL_OK) {
+        if (result == TCL_RETURN) {
+            result = TclUpdateReturnInfo(iPtr);
+        }
+        else if (result == TCL_ERROR) {
+            objPtr = Tcl_NewStringObj("\n    ", -1);
+            Tcl_IncrRefCount(objPtr);
+
+            if (mfunc->member->flags & ITCL_CONSTRUCTOR) {
+                Tcl_AppendToObj(objPtr, "while constructing object \"", -1);
+                Tcl_GetCommandFullName(contextObj->classDefn->interp,
+                    contextObj->accessCmd, objPtr);
+                Tcl_AppendToObj(objPtr, "\" in ", -1);
+                Tcl_AppendToObj(objPtr, mfunc->member->fullname, -1);
+                if ((mfunc->member->code->flags & ITCL_IMPLEMENT_TCL) != 0) {
+                    Tcl_AppendToObj(objPtr, " (", -1);
+                }
+            }
+
+            else if (mfunc->member->flags & ITCL_DESTRUCTOR) {
+                Tcl_AppendToObj(objPtr, "while deleting object \"", -1);
+                Tcl_GetCommandFullName(contextObj->classDefn->interp,
+                    contextObj->accessCmd, objPtr);
+                Tcl_AppendToObj(objPtr, "\" in ", -1);
+                Tcl_AppendToObj(objPtr, mfunc->member->fullname, -1);
+                if ((mfunc->member->code->flags & ITCL_IMPLEMENT_TCL) != 0) {
+                    Tcl_AppendToObj(objPtr, " (", -1);
+                }
+            }
+
+            else {
+                Tcl_AppendToObj(objPtr, "(", -1);
+
+                if (contextObj && contextObj->accessCmd) {
+                    Tcl_AppendToObj(objPtr, "object \"", -1);
+                    Tcl_GetCommandFullName(contextObj->classDefn->interp,
+                        contextObj->accessCmd, objPtr);
+                    Tcl_AppendToObj(objPtr, "\" ", -1);
+                }
+
+                if ((mfunc->member->flags & ITCL_COMMON) != 0) {
+                    Tcl_AppendToObj(objPtr, "procedure", -1);
+                } else {
+                    Tcl_AppendToObj(objPtr, "method", -1);
+                }
+                Tcl_AppendToObj(objPtr, " \"", -1);
+                Tcl_AppendToObj(objPtr, mfunc->member->fullname, -1);
+                Tcl_AppendToObj(objPtr, "\" ", -1);
+            }
+
+            if ((mfunc->member->code->flags & ITCL_IMPLEMENT_TCL) != 0) {
+                Tcl_AppendToObj(objPtr, "body line ", -1);
+                sprintf(num, "%d", ERRORLINE(iPtr));
+                Tcl_AppendToObj(objPtr, num, -1);
+                Tcl_AppendToObj(objPtr, ")", -1);
+            } else {
+                Tcl_AppendToObj(objPtr, ")", -1);
+            }
+
+            Tcl_AddErrorInfo(interp, Tcl_GetStringFromObj(objPtr, (int*)NULL));
+            Tcl_DecrRefCount(objPtr);
+        }
+
+        else if (result == TCL_BREAK) {
+            Tcl_ResetResult(interp);
+            Tcl_AppendToObj(Tcl_GetObjResult(interp),
+                    "invoked \"break\" outside of a loop", -1);
+            result = TCL_ERROR;
+        }
+
+        else if (result == TCL_CONTINUE) {
+            Tcl_ResetResult(interp);
+            Tcl_AppendToObj(Tcl_GetObjResult(interp),
+                    "invoked \"continue\" outside of a loop", -1);
+            result = TCL_ERROR;
+        }
+    }
+    return result;
+}
diff --git a/8.x/itcl/generic/itcl_migrate.c b/8.x/itcl/generic/itcl_migrate.c
new file mode 100644 (file)
index 0000000..bde69da
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  This file contains procedures that belong in the Tcl/Tk core.
+ *  Hopefully, they'll migrate there soon.
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_migrate.c,v 1.4 2007/08/07 20:05:30 msofer Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * _Tcl_GetCallFrame --
+ *
+ *     Checks the call stack and returns the call frame some number
+ *     of levels up.  It is often useful to know the invocation
+ *     context for a command.
+ *
+ * Results:
+ *     Returns a token for the call frame 0 or more levels up in
+ *     the call stack.
+ *
+ * Side effects:
+ *     None.
+ *
+ *----------------------------------------------------------------------
+ */
+Itcl_CallFrame*
+_Tcl_GetCallFrame(interp, level)
+    Tcl_Interp *interp;  /* interpreter being queried */
+    int level;           /* number of levels up in the call stack (>= 0) */
+{
+    Interp *iPtr = (Interp*)interp;
+    CallFrame *framePtr;
+
+    if (level < 0) {
+        Tcl_Panic("itcl: _Tcl_GetCallFrame called with bad number of levels");
+    }
+
+    framePtr = iPtr->varFramePtr;
+    while (framePtr && level > 0) {
+        framePtr = framePtr->callerVarPtr;
+        level--;
+    }
+    return (Itcl_CallFrame *) framePtr;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * _Tcl_ActivateCallFrame --
+ *
+ *     Makes an existing call frame the current frame on the
+ *     call stack.  Usually called in conjunction with
+ *     _Tcl_GetCallFrame to simulate the effect of an "uplevel"
+ *     command.
+ *
+ *     Note that this procedure is different from Tcl_PushCallFrame,
+ *     which adds a new call frame to the call stack.  This procedure
+ *     assumes that the call frame is already initialized, and it
+ *     merely activates it on the call stack.
+ *
+ * Results:
+ *     Returns a token for the call frame that was in effect before
+ *     activating the new context.  That call frame can be restored
+ *     by calling _Tcl_ActivateCallFrame again.
+ *
+ * Side effects:
+ *     None.
+ *
+ *----------------------------------------------------------------------
+ */
+Itcl_CallFrame*
+_Tcl_ActivateCallFrame(interp, framePtr)
+    Tcl_Interp *interp;        /* interpreter being queried */
+    Itcl_CallFrame *framePtr;   /* call frame to be activated */
+{
+    Interp *iPtr = (Interp*)interp;
+    CallFrame *oldFramePtr;
+
+    oldFramePtr = iPtr->varFramePtr;
+    iPtr->varFramePtr = (CallFrame *) framePtr;
+
+    return (Itcl_CallFrame *) oldFramePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * _TclNewVar --
+ *
+ *      Create a new heap-allocated variable that will eventually be
+ *      entered into a hashtable.
+ *
+ * Results:
+ *      The return value is a pointer to the new variable structure. It is
+ *      marked as a scalar variable (and not a link or array variable). Its
+ *      value initially is NULL. The variable is not part of any hash table
+ *      yet. Since it will be in a hashtable and not in a call frame, its
+ *      name field is set NULL. It is initially marked as undefined.
+ *
+ * Side effects:
+ *      Storage gets allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Var *
+_TclNewVar()
+{
+    Var *varPtr;
+
+    varPtr = (Var *) ckalloc(itclVarLocalSize);
+    ItclInitVarFlags(varPtr);
+    ItclVarObjValue(varPtr) = NULL;
+#if ITCL_TCL_PRE_8_5
+    if (itclOldRuntime) {
+       varPtr->name = NULL;
+       varPtr->nsPtr = NULL;
+       varPtr->hPtr = NULL;
+       varPtr->refCount = 0;
+       varPtr->tracePtr = NULL;
+       varPtr->searchPtr = NULL;
+    }
+#endif
+    return varPtr;
+}
+
+#if ITCL_TCL_PRE_8_5
+Var *
+ItclVarHashCreateVar(
+    TclVarHashTable *tablePtr,
+    const char *key,
+    int *newPtr)
+{
+#if (USE_TCL_STUBS)
+    if (itclOldRuntime) {
+#endif
+       Tcl_HashEntry *hPtr;
+       
+       if (newPtr) {
+           Var *varPtr = _TclNewVar();
+
+           hPtr = Tcl_CreateHashEntry(tablePtr, key, newPtr);
+           varPtr->hPtr = hPtr;
+           Tcl_SetHashValue(hPtr, varPtr);     
+       } else {
+           hPtr = Tcl_FindHashEntry(tablePtr, key);
+       }       
+       
+       if (hPtr) {
+           return (Var *) Tcl_GetHashValue(hPtr);
+       } else {
+           return NULL;
+       }
+#if (USE_TCL_STUBS)
+    } else {
+       /*
+        * An 8.5 runtime: TclVarHashCreateVar is at position 234 in the
+        * internal stubs table: call it.
+        */
+       
+       Var * (*TclVarHashCreateVar)(Tcl_HashTable *, const char *, int *) =
+           (Var * (*)(Tcl_HashTable *, const char *, int *)) *((&tclIntStubsPtr->reserved0)+234);
+       return (*TclVarHashCreateVar)(tablePtr, key, newPtr);
+    }
+#endif
+}
+#endif
diff --git a/8.x/itcl/generic/itcl_objects.c b/8.x/itcl/generic/itcl_objects.c
new file mode 100644 (file)
index 0000000..ec0fb61
--- /dev/null
@@ -0,0 +1,1234 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  This segment handles "objects" which are instantiated from class
+ *  definitions.  Objects contain public/protected/private data members
+ *  from all classes in a derivation hierarchy.
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_objects.c,v 1.17 2007/08/07 20:05:30 msofer Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ *  FORWARD DECLARATIONS
+ */
+static void ItclReportObjectUsage _ANSI_ARGS_((Tcl_Interp *interp,
+    ItclObject* obj));
+
+static char* ItclTraceThisVar _ANSI_ARGS_((ClientData cdata,
+    Tcl_Interp *interp, CONST char *name1, CONST char *name2, int flags));
+
+static void ItclDestroyObject _ANSI_ARGS_((ClientData cdata));
+static void ItclFreeObject _ANSI_ARGS_((char* cdata));
+
+static int ItclDestructBase _ANSI_ARGS_((Tcl_Interp *interp,
+    ItclObject* obj, ItclClass* cdefn, int flags));
+
+static void ItclCreateObjVar _ANSI_ARGS_((Tcl_Interp *interp,
+    ItclVarDefn* vdefn, ItclObject* obj));
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateObject()
+ *
+ *  Creates a new object instance belonging to the given class.
+ *  Supports complex object names like "namesp::namesp::name" by
+ *  following the namespace path and creating the object in the
+ *  desired namespace.
+ *
+ *  Automatically creates and initializes data members, including the
+ *  built-in protected "this" variable containing the object name.
+ *  Installs an access command in the current namespace, and invokes
+ *  the constructor to initialize the object.
+ *
+ *  If any errors are encountered, the object is destroyed and this
+ *  procedure returns TCL_ERROR (along with an error message in the
+ *  interpreter).  Otherwise, it returns TCL_OK, along with a pointer
+ *  to the new object data in roPtr.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CreateObject(interp, name, cdefn, objc, objv, roPtr)
+    Tcl_Interp *interp;      /* interpreter mananging new object */
+    CONST char* name;        /* name of new object */
+    ItclClass *cdefn;        /* class for new object */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+    ItclObject **roPtr;      /* returns: pointer to object data */
+{
+    ItclClass *cdefnPtr = (ItclClass*)cdefn;
+    int result = TCL_OK;
+
+    char *head, *tail;
+    Tcl_DString buffer, objName;
+    Tcl_Namespace *parentNs;
+    ItclContext context;
+    Tcl_Command cmd;
+    ItclObject *newObj;
+    ItclClass *cdPtr;
+    ItclVarDefn *vdefn;
+    ItclHierIter hier;
+    Tcl_HashEntry *entry;
+    Tcl_HashSearch place;
+    int newEntry;
+    Itcl_InterpState istate;
+
+    /*
+     *  If installing an object access command will clobber another
+     *  command, signal an error.  Be careful to look for the object
+     *  only in the current namespace context.  Otherwise, we might
+     *  find a global command, but that wouldn't be clobbered!
+     */
+    cmd = Tcl_FindCommand(interp, (CONST84 char *)name,
+       (Tcl_Namespace*)NULL, TCL_NAMESPACE_ONLY);
+
+    if (cmd != NULL && !Itcl_IsStub(cmd)) {
+        Tcl_AppendResult(interp,
+               "command \"", name, "\" already exists in namespace \"",
+               Tcl_GetCurrentNamespace(interp)->fullName, "\"",
+               (char*) NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Extract the namespace context and the simple object
+     *  name for the new object.
+     */
+    Itcl_ParseNamespPath(name, &buffer, &head, &tail);
+    if (head) {
+        parentNs = Itcl_FindClassNamespace(interp, head);
+
+        if (!parentNs) {
+            Tcl_AppendResult(interp,
+                   "namespace \"", head, "\" not found in context \"",
+                   Tcl_GetCurrentNamespace(interp)->fullName, "\"",
+                   (char *) NULL);
+            Tcl_DStringFree(&buffer);
+            return TCL_ERROR;
+        }
+    } else {
+        parentNs = Tcl_GetCurrentNamespace(interp);
+    }
+
+    Tcl_DStringInit(&objName);
+    if (parentNs != Tcl_GetGlobalNamespace(interp)) {
+        Tcl_DStringAppend(&objName, parentNs->fullName, -1);
+    }
+    Tcl_DStringAppend(&objName, "::", -1);
+    Tcl_DStringAppend(&objName, tail, -1);
+
+    /*
+     *  Create a new object and initialize it.
+     */
+    newObj = (ItclObject*)ckalloc(sizeof(ItclObject));
+    newObj->classDefn = cdefnPtr;
+    Itcl_PreserveData((ClientData)cdefnPtr);
+
+    newObj->dataSize = cdefnPtr->numInstanceVars;
+    newObj->data = (Var**)ckalloc((unsigned)(newObj->dataSize*sizeof(Var*)));
+
+    newObj->constructed = (Tcl_HashTable*)ckalloc(sizeof(Tcl_HashTable));
+    Tcl_InitHashTable(newObj->constructed, TCL_STRING_KEYS);
+    newObj->destructed = NULL;
+
+    /*
+     *  Add a command to the current namespace with the object name.
+     *  This is done before invoking the constructors so that the
+     *  command can be used during construction to query info.
+     */
+    Itcl_PreserveData((ClientData)newObj);
+    newObj->accessCmd = Tcl_CreateObjCommand(interp,
+        Tcl_DStringValue(&objName), Itcl_HandleInstance,
+        (ClientData)newObj, ItclDestroyObject);
+
+    Itcl_PreserveData((ClientData)newObj);  /* while we're using this... */
+    Itcl_EventuallyFree((ClientData)newObj, ItclFreeObject);
+
+    Tcl_DStringFree(&buffer);
+    Tcl_DStringFree(&objName);
+
+    /*
+     *  Install the class namespace and object context so that
+     *  the object's data members can be initialized via simple
+     *  "set" commands.
+     */
+    if (Itcl_PushContext(interp, (ItclMember*)NULL, cdefnPtr, newObj,
+        &context) != TCL_OK) {
+
+        return TCL_ERROR;
+    }
+
+    Itcl_InitHierIter(&hier, cdefn);
+
+    cdPtr = Itcl_AdvanceHierIter(&hier);
+    while (cdPtr != NULL) {
+        entry = Tcl_FirstHashEntry(&cdPtr->variables, &place);
+        while (entry) {
+            vdefn = (ItclVarDefn*)Tcl_GetHashValue(entry);
+            if ((vdefn->member->flags & ITCL_THIS_VAR) != 0) {
+                if (cdPtr == cdefnPtr) {
+                    ItclCreateObjVar(interp, vdefn, newObj);
+                    Tcl_SetVar2(interp, "this", (char*)NULL, "", 0);
+                    Tcl_TraceVar2(interp, "this", NULL,
+                        TCL_TRACE_READS|TCL_TRACE_WRITES, ItclTraceThisVar,
+                        (ClientData)newObj);
+                }
+            }
+            else if ( (vdefn->member->flags & ITCL_COMMON) == 0) {
+                ItclCreateObjVar(interp, vdefn, newObj);
+            }
+            entry = Tcl_NextHashEntry(&place);
+        }
+        cdPtr = Itcl_AdvanceHierIter(&hier);
+    }
+    Itcl_DeleteHierIter(&hier);
+
+    Itcl_PopContext(interp, &context);  /* back to calling context */
+
+    /*
+     *  Now construct the object.  Look for a constructor in the
+     *  most-specific class, and if there is one, invoke it.
+     *  This will cause a chain reaction, making sure that all
+     *  base classes constructors are invoked as well, in order
+     *  from least- to most-specific.  Any constructors that are
+     *  not called out explicitly in "initCode" code fragments are
+     *  invoked implicitly without arguments.
+     */
+    result = Itcl_InvokeMethodIfExists(interp, "constructor",
+        cdefn, newObj, objc, objv);
+
+    /*
+     *  If there is no constructor, construct the base classes
+     *  in case they have constructors.  This will cause the
+     *  same chain reaction.
+     */
+    if (!Tcl_FindHashEntry(&cdefn->functions, "constructor")) {
+        result = Itcl_ConstructBase(interp, newObj, cdefn);
+    }
+
+    /*
+     *  If construction failed, then delete the object access
+     *  command.  This will destruct the object and delete the
+     *  object data.  Be careful to save and restore the interpreter
+     *  state, since the destructors may generate errors of their own.
+     */
+    if (result != TCL_OK) {
+        istate = Itcl_SaveInterpState(interp, result);
+
+       /* Bug 227824.
+        * The constructor may destroy the object, possibly indirectly
+        * through the destruction of the main widget in the iTk
+        * megawidget it tried to construct. If this happens we must
+        * not try to destroy the access command a second time.
+        */
+       if (newObj->accessCmd != (Tcl_Command) NULL) {
+           Tcl_DeleteCommandFromToken(interp, newObj->accessCmd);
+           newObj->accessCmd = NULL;
+       }
+        result = Itcl_RestoreInterpState(interp, istate);
+    }
+
+    /*
+     *  At this point, the object is fully constructed.
+     *  Destroy the "constructed" table in the object data, since
+     *  it is no longer needed.
+     */
+    Tcl_DeleteHashTable(newObj->constructed);
+    ckfree((char*)newObj->constructed);
+    newObj->constructed = NULL;
+
+    /*
+     *  Add it to the list of all known objects. The only
+     *  tricky thing to watch out for is the case where the
+     *  object deleted itself inside its own constructor.
+     *  In that case, we don't want to add the object to
+     *  the list of valid objects. We can determine that
+     *  the object deleted itself by checking to see if
+     *  its accessCmd member is NULL.
+     */
+    if (result == TCL_OK && (newObj->accessCmd != NULL))  {
+        entry = Tcl_CreateHashEntry(&cdefnPtr->info->objects,
+            (char*)newObj->accessCmd, &newEntry);
+
+        Tcl_SetHashValue(entry, (ClientData)newObj);
+    }
+
+    /*
+     *  Release the object.  If it was destructed above, it will
+     *  die at this point.
+     */
+    Itcl_ReleaseData((ClientData)newObj);
+
+    *roPtr = newObj;
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteObject()
+ *
+ *  Attempts to delete an object by invoking its destructor.
+ *
+ *  If the destructor is successful, then the object is deleted by
+ *  removing its access command, and this procedure returns TCL_OK.
+ *  Otherwise, the object will remain alive, and this procedure
+ *  returns TCL_ERROR (along with an error message in the interpreter).
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_DeleteObject(interp, contextObj)
+    Tcl_Interp *interp;      /* interpreter mananging object */
+    ItclObject *contextObj;  /* object to be deleted */
+{
+    ItclClass *cdefnPtr = (ItclClass*)contextObj->classDefn;
+
+    Tcl_HashEntry *entry;
+    Command *cmdPtr;
+
+    Itcl_PreserveData((ClientData)contextObj);
+
+    /*
+     *  Invoke the object's destructors.
+     */
+    if (Itcl_DestructObject(interp, contextObj, 0) != TCL_OK) {
+        Itcl_ReleaseData((ClientData)contextObj);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Remove the object from the global list.
+     */
+    entry = Tcl_FindHashEntry(&cdefnPtr->info->objects,
+        (char*)contextObj->accessCmd);
+
+    if (entry) {
+        Tcl_DeleteHashEntry(entry);
+    }
+
+    /*
+     *  Change the object's access command so that it can be
+     *  safely deleted without attempting to destruct the object
+     *  again.  Then delete the access command.  If this is
+     *  the last use of the object data, the object will die here.
+     */
+    cmdPtr = (Command*)contextObj->accessCmd;
+    cmdPtr->deleteProc = Itcl_ReleaseData;
+
+    Tcl_DeleteCommandFromToken(interp, contextObj->accessCmd);
+    contextObj->accessCmd = NULL;
+
+    Itcl_ReleaseData((ClientData)contextObj);  /* object should die here */
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DestructObject()
+ *
+ *  Invokes the destructor for a particular object.  Usually invoked
+ *  by Itcl_DeleteObject() or Itcl_DestroyObject() as a part of the
+ *  object destruction process.  If the ITCL_IGNORE_ERRS flag is
+ *  included, all destructors are invoked even if errors are
+ *  encountered, and the result will always be TCL_OK.
+ *
+ *  Returns TCL_OK on success, or TCL_ERROR (along with an error
+ *  message in the interpreter) if anything goes wrong.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_DestructObject(interp, contextObj, flags)
+    Tcl_Interp *interp;      /* interpreter mananging new object */
+    ItclObject *contextObj;  /* object to be destructed */
+    int flags;               /* flags: ITCL_IGNORE_ERRS */
+{
+    int result;
+
+    /*
+     *  If there is a "destructed" table, then this object is already
+     *  being destructed.  Flag an error, unless errors are being
+     *  ignored.
+     */
+    if (contextObj->destructed) {
+        if ((flags & ITCL_IGNORE_ERRS) == 0) {
+            Tcl_AppendResult(interp,
+                   "can't delete an object while it is being destructed",
+                   (char*)NULL);
+            return TCL_ERROR;
+        }
+        return TCL_OK;
+    }
+
+    /*
+     *  Create a "destructed" table to keep track of which destructors
+     *  have been invoked.  This is used in ItclDestructBase to make
+     *  sure that all base class destructors have been called,
+     *  explicitly or implicitly.
+     */
+    contextObj->destructed = (Tcl_HashTable*)ckalloc(sizeof(Tcl_HashTable));
+    Tcl_InitHashTable(contextObj->destructed, TCL_STRING_KEYS);
+
+    /*
+     *  Destruct the object starting from the most-specific class.
+     *  If all goes well, return the null string as the result.
+     */
+    result = ItclDestructBase(interp, contextObj, contextObj->classDefn, flags);
+
+    if (result == TCL_OK) {
+        Tcl_ResetResult(interp);
+    }
+
+    Tcl_DeleteHashTable(contextObj->destructed);
+    ckfree((char*)contextObj->destructed);
+    contextObj->destructed = NULL;
+
+    return result;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclDestructBase()
+ *
+ *  Invoked by Itcl_DestructObject() to recursively destruct an object
+ *  from the specified class level.  Finds and invokes the destructor
+ *  for the specified class, and then recursively destructs all base
+ *  classes.  If the ITCL_IGNORE_ERRS flag is included, all destructors
+ *  are invoked even if errors are encountered, and the result will
+ *  always be TCL_OK.
+ *
+ *  Returns TCL_OK on success, or TCL_ERROR (along with an error message
+ *  in interp->result) on error.
+ * ------------------------------------------------------------------------
+ */
+static int
+ItclDestructBase(interp, contextObj, contextClass, flags)
+    Tcl_Interp *interp;       /* interpreter */
+    ItclObject *contextObj;   /* object being destructed */
+    ItclClass *contextClass;  /* current class being destructed */
+    int flags;                /* flags: ITCL_IGNORE_ERRS */
+{
+    int result;
+    Itcl_ListElem *elem;
+    ItclClass *cdefn;
+
+    /*
+     *  Look for a destructor in this class, and if found,
+     *  invoke it.
+     */
+    if (!Tcl_FindHashEntry(contextObj->destructed, contextClass->fullname)) {
+
+        result = Itcl_InvokeMethodIfExists(interp, "destructor",
+            contextClass, contextObj, 0, (Tcl_Obj* CONST*)NULL);
+
+        if (result != TCL_OK) {
+            return TCL_ERROR;
+        }
+    }
+
+    /*
+     *  Scan through the list of base classes recursively and destruct
+     *  them.  Traverse the list in normal order, so that we destruct
+     *  from most- to least-specific.
+     */
+    elem = Itcl_FirstListElem(&contextClass->bases);
+    while (elem) {
+        cdefn = (ItclClass*)Itcl_GetListValue(elem);
+
+        if (ItclDestructBase(interp, contextObj, cdefn, flags) != TCL_OK) {
+            return TCL_ERROR;
+        }
+        elem = Itcl_NextListElem(elem);
+    }
+
+    /*
+     *  Throw away any result from the destructors and return.
+     */
+    Tcl_ResetResult(interp);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_FindObject()
+ *
+ *  Searches for an object with the specified name, which have
+ *  namespace scope qualifiers like "namesp::namesp::name", or may
+ *  be a scoped value such as "namespace inscope ::foo obj".
+ *
+ *  If an error is encountered, this procedure returns TCL_ERROR
+ *  along with an error message in the interpreter.  Otherwise, it
+ *  returns TCL_OK.  If an object was found, "roPtr" returns a
+ *  pointer to the object data.  Otherwise, it returns NULL.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_FindObject(interp, name, roPtr)
+    Tcl_Interp *interp;      /* interpreter containing this object */
+    CONST char *name;        /* name of the object */
+    ItclObject **roPtr;      /* returns: object data or NULL */
+{
+    Tcl_Namespace *contextNs = NULL;
+
+    char *cmdName;
+    Tcl_Command cmd;
+    Command *cmdPtr;
+
+    /*
+     *  The object name may be a scoped value of the form
+     *  "namespace inscope <namesp> <command>".  If it is,
+     *  decode it.
+     */
+    if (Itcl_DecodeScopedCommand(interp, name, &contextNs, &cmdName)
+        != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Look for the object's access command, and see if it has
+     *  the appropriate command handler.
+     */
+    cmd = Tcl_FindCommand(interp, cmdName, contextNs, /* flags */ 0);
+    if (cmd != NULL && Itcl_IsObject(cmd)) {
+        cmdPtr = (Command*)cmd;
+        *roPtr = (ItclObject*)cmdPtr->objClientData;
+    }
+    else {
+        *roPtr = NULL;
+    }
+
+    ckfree(cmdName);
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_IsObject()
+ *
+ *  Checks the given Tcl command to see if it represents an itcl object.
+ *  Returns non-zero if the command is associated with an object.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_IsObject(cmd)
+    Tcl_Command cmd;         /* command being tested */
+{
+    Command *cmdPtr = (Command*)cmd;
+
+    if (cmdPtr->deleteProc == ItclDestroyObject) {
+        return 1;
+    }
+
+    /*
+     *  This may be an imported command.  Try to get the real
+     *  command and see if it represents an object.
+     */
+    cmdPtr = (Command*)TclGetOriginalCommand(cmd);
+    if (cmdPtr && cmdPtr->deleteProc == ItclDestroyObject) {
+        return 1;
+    }
+    return 0;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ObjectIsa()
+ *
+ *  Checks to see if an object belongs to the given class.  An object
+ *  "is-a" member of the class if the class appears anywhere in its
+ *  inheritance hierarchy.  Returns non-zero if the object belongs to
+ *  the class, and zero otherwise.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ObjectIsa(contextObj, cdefn)
+    ItclObject *contextObj;   /* object being tested */
+    ItclClass *cdefn;         /* class to test for "is-a" relationship */
+{
+    Tcl_HashEntry *entry;
+    entry = Tcl_FindHashEntry(&contextObj->classDefn->heritage, (char*)cdefn);
+    return (entry != NULL);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_HandleInstance()
+ *
+ *  Invoked by Tcl whenever the user issues a command associated with
+ *  an object instance.  Handles the following syntax:
+ *
+ *    <objName> <method> <args>...
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_HandleInstance(clientData, interp, objc, objv)
+    ClientData clientData;   /* object definition */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObject *contextObj = (ItclObject*)clientData;
+
+    int result;
+    char *token;
+    Tcl_HashEntry *entry;
+    ItclMemberFunc *mfunc;
+    ItclObjectInfo *info;
+    ItclContext context;
+    ItclCallFrame *framePtr;
+
+    if (objc < 2) {
+        Tcl_AppendResult(interp,
+               "wrong # args: should be one of...",
+               (char *) NULL);
+        ItclReportObjectUsage(interp, contextObj);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Make sure that the specified operation is really an
+     *  object method, and it is accessible.  If not, return usage
+     *  information for the object.
+     */
+    token = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    mfunc = NULL;
+
+    entry = Tcl_FindHashEntry(&contextObj->classDefn->resolveCmds, token);
+    if (entry) {
+        mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+
+        if ((mfunc->member->flags & ITCL_COMMON) != 0) {
+            mfunc = NULL;
+        }
+        else if (mfunc->member->protection != ITCL_PUBLIC) {
+            Tcl_Namespace *contextNs = Itcl_GetTrueNamespace(interp,
+                mfunc->member->classDefn->info);
+
+            if (!Itcl_CanAccessFunc(mfunc, contextNs)) {
+                mfunc = NULL;
+            }
+        }
+    }
+
+    if ( !mfunc && (*token != 'i' || strcmp(token,"info") != 0) ) {
+        Tcl_AppendResult(interp,
+               "bad option \"", token, "\": should be one of...",
+               (char*)NULL);
+        ItclReportObjectUsage(interp, contextObj);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Install an object context and invoke the method.
+     *
+     *  TRICKY NOTE:  We need to pass the object context into the
+     *    method, but activating the context here puts us one level
+     *    down, and when the method is called, it will activate its
+     *    own context, putting us another level down.  If anyone
+     *    were to execute an "uplevel" command in the method, they
+     *    would notice the extra call frame.  So we mark this frame
+     *    as "transparent" and Itcl_EvalMemberCode will automatically
+     *    do an "uplevel" operation to correct the problem.
+     */
+    info = contextObj->classDefn->info;
+
+    if (Itcl_PushContext(interp, (ItclMember*)NULL, contextObj->classDefn,
+        contextObj, &context) != TCL_OK) {
+
+        return TCL_ERROR;
+    }
+
+    framePtr = &context.frame;
+    Itcl_PushStack((ClientData)framePtr, &info->transparentFrames);
+
+    /* Bug 227824
+     * The tcl core will blow up in 'TclLookupVar' if we don't reset
+     * the 'isProcCallFrame'. This happens because without the
+     * callframe refered to by 'framePtr' will be inconsistent
+     * ('isProcCallFrame' set, but 'procPtr' not set).
+     */
+    if (*token == 'i' && strcmp(token,"info") == 0) {
+        framePtr->isProcCallFrame = 0;
+    }
+
+    result = Itcl_EvalArgs(interp, objc-1, objv+1);
+
+    Itcl_PopStack(&info->transparentFrames);
+    Itcl_PopContext(interp, &context);
+
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_GetInstanceVar()
+ *
+ *  Returns the current value for an object data member.  The member
+ *  name is interpreted with respect to the given class scope, which
+ *  is usually the most-specific class for the object.
+ *
+ *  If successful, this procedure returns a pointer to a string value
+ *  which remains alive until the variable changes it value.  If
+ *  anything goes wrong, this returns NULL.
+ * ------------------------------------------------------------------------
+ */
+CONST char*
+Itcl_GetInstanceVar(interp, name, contextObj, contextClass)
+    Tcl_Interp *interp;       /* current interpreter */
+    CONST char *name;         /* name of desired instance variable */
+    ItclObject *contextObj;   /* current object */
+    ItclClass *contextClass;  /* name is interpreted in this scope */
+{
+    ItclContext context;
+    CONST char *val;
+
+    /*
+     *  Make sure that the current namespace context includes an
+     *  object that is being manipulated.
+     */
+    if (contextObj == NULL) {
+        Tcl_ResetResult(interp);
+        Tcl_SetResult(interp,
+               "cannot access object-specific info without an object context",
+               TCL_STATIC);
+        return NULL;
+    }
+
+    /*
+     *  Install the object context and access the data member
+     *  like any other variable.
+     */
+    if (Itcl_PushContext(interp, (ItclMember*)NULL, contextClass,
+        contextObj, &context) != TCL_OK) {
+
+        return NULL;
+    }
+
+    val = Tcl_GetVar2(interp, (CONST84 char *)name, (char*)NULL,
+           TCL_LEAVE_ERR_MSG);
+    Itcl_PopContext(interp, &context);
+
+    return val;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclReportObjectUsage()
+ *
+ *  Appends information to the given interp summarizing the usage
+ *  for all of the methods available for this object.  Useful when
+ *  reporting errors in Itcl_HandleInstance().
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclReportObjectUsage(interp, contextObj)
+    Tcl_Interp *interp;      /* current interpreter */
+    ItclObject *contextObj;  /* current object */
+{
+    ItclClass *cdefnPtr = (ItclClass*)contextObj->classDefn;
+    int ignore = ITCL_CONSTRUCTOR | ITCL_DESTRUCTOR | ITCL_COMMON;
+
+    int cmp;
+    char *name;
+    Itcl_List cmdList;
+    Itcl_ListElem *elem;
+    Tcl_HashEntry *entry;
+    Tcl_HashSearch place;
+    ItclMemberFunc *mfunc, *cmpDefn;
+    Tcl_Obj *resultPtr;
+
+    /*
+     *  Scan through all methods in the virtual table and sort
+     *  them in alphabetical order.  Report only the methods
+     *  that have simple names (no ::'s) and are accessible.
+     */
+    Itcl_InitList(&cmdList);
+    entry = Tcl_FirstHashEntry(&cdefnPtr->resolveCmds, &place);
+    while (entry) {
+        name  = Tcl_GetHashKey(&cdefnPtr->resolveCmds, entry);
+        mfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+
+        if (strstr(name,"::") || (mfunc->member->flags & ignore) != 0) {
+            mfunc = NULL;
+        }
+        else if (mfunc->member->protection != ITCL_PUBLIC) {
+            Tcl_Namespace *contextNs = Itcl_GetTrueNamespace(interp,
+                mfunc->member->classDefn->info);
+
+            if (!Itcl_CanAccessFunc(mfunc, contextNs)) {
+                mfunc = NULL;
+            }
+        }
+
+        if (mfunc) {
+            elem = Itcl_FirstListElem(&cmdList);
+            while (elem) {
+                cmpDefn = (ItclMemberFunc*)Itcl_GetListValue(elem);
+                cmp = strcmp(mfunc->member->name, cmpDefn->member->name);
+                if (cmp < 0) {
+                    Itcl_InsertListElem(elem, (ClientData)mfunc);
+                    mfunc = NULL;
+                    break;
+                }
+                else if (cmp == 0) {
+                    mfunc = NULL;
+                    break;
+                }
+                elem = Itcl_NextListElem(elem);
+            }
+            if (mfunc) {
+                Itcl_AppendList(&cmdList, (ClientData)mfunc);
+            }
+        }
+        entry = Tcl_NextHashEntry(&place);
+    }
+
+    /*
+     *  Add a series of statements showing usage info.
+     */
+    resultPtr = Tcl_GetObjResult(interp);
+    elem = Itcl_FirstListElem(&cmdList);
+    while (elem) {
+        mfunc = (ItclMemberFunc*)Itcl_GetListValue(elem);
+        Tcl_AppendToObj(resultPtr, "\n  ", -1);
+        Itcl_GetMemberFuncUsage(mfunc, contextObj, resultPtr);
+
+        elem = Itcl_NextListElem(elem);
+    }
+    Itcl_DeleteList(&cmdList);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclTraceThisVar()
+ *
+ *  Invoked to handle read/write traces on the "this" variable built
+ *  into each object.
+ *
+ *  On read, this procedure updates the "this" variable to contain the
+ *  current object name.  This is done dynamically, since an object's
+ *  identity can change if its access command is renamed.
+ *
+ *  On write, this procedure returns an error string, warning that
+ *  the "this" variable cannot be set.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static char*
+ItclTraceThisVar(cdata, interp, name1, name2, flags)
+    ClientData cdata;      /* object instance data */
+    Tcl_Interp *interp;            /* interpreter managing this variable */
+    CONST char *name1;     /* variable name */
+    CONST char *name2;     /* unused */
+    int flags;             /* flags indicating read/write */
+{
+    ItclObject *contextObj = (ItclObject*)cdata;
+    char *objName;
+    Tcl_Obj *objPtr;
+
+    /*
+     *  Handle read traces on "this"
+     */
+    if ((flags & TCL_TRACE_READS) != 0) {
+        objPtr = Tcl_NewStringObj("", -1);
+        Tcl_IncrRefCount(objPtr);
+
+        if (contextObj->accessCmd) {
+            Tcl_GetCommandFullName(contextObj->classDefn->interp,
+                contextObj->accessCmd, objPtr);
+        }
+
+        objName = Tcl_GetString(objPtr);
+        Tcl_SetVar(interp, (CONST84 char *)name1, objName, 0);
+
+        Tcl_DecrRefCount(objPtr);
+        return NULL;
+    }
+
+    /*
+     *  Handle write traces on "this"
+     */
+    if ((flags & TCL_TRACE_WRITES) != 0) {
+        return "variable \"this\" cannot be modified";
+    }
+    return NULL;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclDestroyObject()
+ *
+ *  Invoked when the object access command is deleted to implicitly
+ *  destroy the object.  Invokes the object's destructors, ignoring
+ *  any errors encountered along the way.  Removes the object from
+ *  the list of all known objects and releases the access command's
+ *  claim to the object data.
+ *
+ *  Note that the usual way to delete an object is via Itcl_DeleteObject().
+ *  This procedure is provided as a back-up, to handle the case when
+ *  an object is deleted by removing its access command.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclDestroyObject(cdata)
+    ClientData cdata;  /* object instance data */
+{
+    ItclObject *contextObj = (ItclObject*)cdata;
+    ItclClass *cdefnPtr = (ItclClass*)contextObj->classDefn;
+    Tcl_HashEntry *entry;
+    Itcl_InterpState istate;
+
+    /*
+     *  Attempt to destruct the object, but ignore any errors.
+     */
+    istate = Itcl_SaveInterpState(cdefnPtr->interp, 0);
+    Itcl_DestructObject(cdefnPtr->interp, contextObj, ITCL_IGNORE_ERRS);
+    Itcl_RestoreInterpState(cdefnPtr->interp, istate);
+
+    /*
+     *  Now, remove the object from the global object list.
+     *  We're careful to do this here, after calling the destructors.
+     *  Once the access command is nulled out, the "this" variable
+     *  won't work properly.
+     */
+    if (contextObj->accessCmd) {
+        entry = Tcl_FindHashEntry(&cdefnPtr->info->objects,
+            (char*)contextObj->accessCmd);
+
+        if (entry) {
+            Tcl_DeleteHashEntry(entry);
+        }
+        contextObj->accessCmd = NULL;
+    }
+
+    Itcl_ReleaseData((ClientData)contextObj);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclFreeObject()
+ *
+ *  Deletes all instance variables and frees all memory associated with
+ *  the given object instance.  This is usually invoked automatically
+ *  by Itcl_ReleaseData(), when an object's data is no longer being used.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclFreeObject(cdata)
+    char* cdata;  /* object instance data */
+{
+    ItclObject *contextObj = (ItclObject*)cdata;
+    Tcl_Interp *interp = contextObj->classDefn->interp;
+
+    int i;
+    ItclClass *cdPtr;
+    ItclHierIter hier;
+    Tcl_HashSearch place;
+    Tcl_HashEntry *entry;
+    ItclVarDefn *vdefn;
+    ItclContext context;
+    Itcl_InterpState istate;
+
+    /*
+     *  Install the class namespace and object context so that
+     *  the object's data members can be destroyed via simple
+     *  "unset" commands.  This makes sure that traces work properly
+     *  and all memory gets cleaned up.
+     *
+     *  NOTE:  Be careful to save and restore the interpreter state.
+     *    Data can get freed in the middle of any operation, and
+     *    we can't affort to clobber the interpreter with any errors
+     *    from below.
+     */
+    istate = Itcl_SaveInterpState(interp, 0);
+
+    /*
+     *  Scan through all object-specific data members and destroy the
+     *  actual variables that maintain the object state.  Do this
+     *  by unsetting each variable, so that traces are fired off
+     *  correctly.  Make sure that the built-in "this" variable is
+     *  only destroyed once.  Also, be careful to activate the
+     *  namespace for each class, so that private variables can
+     *  be accessed.
+     */
+    Itcl_InitHierIter(&hier, contextObj->classDefn);
+    cdPtr = Itcl_AdvanceHierIter(&hier);
+    while (cdPtr != NULL) {
+
+        if (Itcl_PushContext(interp, (ItclMember*)NULL, cdPtr,
+            contextObj, &context) == TCL_OK) {
+
+            entry = Tcl_FirstHashEntry(&cdPtr->variables, &place);
+            while (entry) {
+                vdefn = (ItclVarDefn*)Tcl_GetHashValue(entry);
+                if ((vdefn->member->flags & ITCL_THIS_VAR) != 0) {
+                    if (cdPtr == contextObj->classDefn) {
+                        Tcl_UnsetVar2(interp, vdefn->member->fullname,
+                            (char*)NULL, 0);
+                    }
+                }
+                else if ((vdefn->member->flags & ITCL_COMMON) == 0) {
+                    Tcl_UnsetVar2(interp, vdefn->member->fullname,
+                        (char*)NULL, 0);
+                }
+                entry = Tcl_NextHashEntry(&place);
+            }
+            Itcl_PopContext(interp, &context);
+        }
+
+        cdPtr = Itcl_AdvanceHierIter(&hier);
+    }
+    Itcl_DeleteHierIter(&hier);
+
+    /*
+     *  Free the memory associated with object-specific variables.
+     *  For normal variables this would be done automatically by
+     *  CleanupVar() when the variable is unset.  But object-specific
+     *  variables are protected by an extra reference count, and they
+     *  must be deleted explicitly here.
+     */
+    for (i=0; i < contextObj->dataSize; i++) {
+        if (contextObj->data[i]) {
+            ckfree((char*)contextObj->data[i]);
+        }
+    }
+
+    Itcl_RestoreInterpState(interp, istate);
+
+    /*
+     *  Free any remaining memory associated with the object.
+     */
+    ckfree((char*)contextObj->data);
+
+    if (contextObj->constructed) {
+        Tcl_DeleteHashTable(contextObj->constructed);
+        ckfree((char*)contextObj->constructed);
+    }
+    if (contextObj->destructed) {
+        Tcl_DeleteHashTable(contextObj->destructed);
+        ckfree((char*)contextObj->destructed);
+    }
+    Itcl_ReleaseData((ClientData)contextObj->classDefn);
+
+    ckfree((char*)contextObj);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclCreateObjVar()
+ *
+ *  Creates one variable acting as a data member for a specific
+ *  object.  Initializes the variable according to its definition,
+ *  and sets up its reference count so that it cannot be deleted
+ *  by ordinary means.  Installs the new variable directly into
+ *  the data array for the specified object.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclCreateObjVar(interp, vdefn, contextObj)
+    Tcl_Interp* interp;       /* interpreter managing this object */
+    ItclVarDefn* vdefn;       /* variable definition */
+    ItclObject* contextObj;   /* object being updated */
+{
+    Var *varPtr;
+    Tcl_HashEntry *entry;
+    ItclVarLookup *vlookup;
+    ItclContext context;
+
+    varPtr = _TclNewVar();
+#if ITCL_TCL_PRE_8_5
+    if (itclOldRuntime) {    
+       varPtr->name = vdefn->member->name;
+       varPtr->nsPtr = (Namespace*)vdefn->member->classDefn->namesp;
+
+       /*
+        *  NOTE:  Tcl reports a "dangling upvar" error for variables
+        *         with a null "hPtr" field.  Put something non-zero
+        *         in here to keep Tcl_SetVar2() happy.  The only time
+        *         this field is really used is it remove a variable
+        *         from the hash table that contains it in CleanupVar,
+        *         but since these variables are protected by their
+        *         higher refCount, they will not be deleted by CleanupVar
+        *         anyway.  These variables are unset and removed in
+        *         ItclFreeObject().
+        */
+       varPtr->hPtr = (Tcl_HashEntry*)0x1;
+       ItclVarRefCount(varPtr) = 1;  /* protect from being deleted */
+    }
+#endif
+
+    /*
+     *  Install the new variable in the object's data array.
+     *  Look up the appropriate index for the object using
+     *  the data table in the class definition.
+     */
+    entry = Tcl_FindHashEntry(&contextObj->classDefn->resolveVars,
+        vdefn->member->fullname);
+
+    if (entry) {
+        vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+        contextObj->data[vlookup->var.index] = varPtr;
+    }
+
+    /*
+     *  If this variable has an initial value, initialize it
+     *  here using a "set" command.
+     *
+     *  TRICKY NOTE:  We push an object context for the class that
+     *    owns the variable, so that we don't have any trouble
+     *    accessing it.
+     */
+    if (vdefn->init) {
+        if (Itcl_PushContext(interp, (ItclMember*)NULL,
+            vdefn->member->classDefn, contextObj, &context) == TCL_OK) {
+
+            Tcl_SetVar2(interp, vdefn->member->fullname,
+                (char*)NULL, vdefn->init, 0);
+            Itcl_PopContext(interp, &context);
+        }
+    }
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ScopedVarResolver()
+ *
+ *  This procedure is installed to handle variable resolution throughout
+ *  an entire interpreter.  It looks for scoped variable references of
+ *  the form:
+ *
+ *    @itcl ::namesp::namesp::object variable
+ *
+ *  If a reference like this is recognized, this procedure finds the
+ *  desired variable in the object and returns the variable, along with
+ *  the status code TCL_OK.  If the variable does not start with
+ *  "@itcl", this procedure returns TCL_CONTINUE, and variable
+ *  resolution continues using the normal rules.  If anything goes
+ *  wrong, this procedure returns TCL_ERROR, and access to the
+ *  variable is denied.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ScopedVarResolver(interp, name, contextNs, flags, rPtr)
+    Tcl_Interp *interp;        /* current interpreter */
+    CONST char *name;                /* variable name being resolved */
+    Tcl_Namespace *contextNs;  /* current namespace context */
+    int flags;                 /* TCL_LEAVE_ERR_MSG => leave error message */
+    Tcl_Var *rPtr;             /* returns: resolved variable */
+{
+    int namec;
+    char **namev;
+    Tcl_Interp *errs;
+    Tcl_CmdInfo cmdInfo;
+    ItclObject *contextObj;
+    ItclVarLookup *vlookup;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  See if the variable starts with "@itcl".  If not, then
+     *  let the variable resolution process continue.
+     */
+    if (*name != '@' || strncmp(name, "@itcl", 5) != 0) {
+        return TCL_CONTINUE;
+    }
+
+    /*
+     *  Break the variable name into parts and extract the object
+     *  name and the variable name.
+     */
+    if (flags & TCL_LEAVE_ERR_MSG) {
+        errs = interp;
+    } else {
+        errs = NULL;
+    }
+
+    if (Tcl_SplitList(errs, (CONST84 char *)name, &namec, &namev)
+           != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (namec != 3) {
+        if (errs) {
+            Tcl_AppendResult(errs,
+                   "scoped variable \"", name, "\" is malformed: ",
+                   "should be: @itcl object variable",
+                   (char*) NULL);
+        }
+        ckfree((char*)namev);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Look for the command representing the object and extract
+     *  the object context.
+     */
+    if (!Tcl_GetCommandInfo(interp, namev[1], &cmdInfo)) {
+        if (errs) {
+            Tcl_AppendResult(errs,
+                "can't resolve scoped variable \"", name, "\": ",
+                "can't find object ", namev[1],
+                (char*)NULL);
+        }
+        ckfree((char*)namev);
+        return TCL_ERROR;
+    }
+    contextObj = (ItclObject*)cmdInfo.objClientData;
+
+    /*
+     *  Resolve the variable with respect to the most-specific
+     *  class definition.
+     */
+    entry = Tcl_FindHashEntry(&contextObj->classDefn->resolveVars, namev[2]);
+    if (!entry) {
+        if (errs) {
+            Tcl_AppendResult(errs,
+                "can't resolve scoped variable \"", name, "\": ",
+                "no such data member ", namev[2],
+                (char*)NULL);
+        }
+        ckfree((char*)namev);
+        return TCL_ERROR;
+    }
+
+    vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+    *rPtr = (Tcl_Var) contextObj->data[vlookup->var.index];
+
+    ckfree((char*)namev);
+    return TCL_OK;
+}
diff --git a/8.x/itcl/generic/itcl_parse.c b/8.x/itcl/generic/itcl_parse.c
new file mode 100644 (file)
index 0000000..c475307
--- /dev/null
@@ -0,0 +1,1076 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  Procedures in this file support the new syntax for [incr Tcl]
+ *  class definitions:
+ *
+ *    itcl_class <className> {
+ *        inherit <base-class>...
+ *
+ *        constructor {<arglist>} ?{<init>}? {<body>}
+ *        destructor {<body>}
+ *
+ *        method <name> {<arglist>} {<body>}
+ *        proc <name> {<arglist>} {<body>}
+ *        variable <name> ?<init>? ?<config>?
+ *        common <name> ?<init>?
+ *
+ *        public <thing> ?<args>...?
+ *        protected <thing> ?<args>...?
+ *        private <thing> ?<args>...?
+ *    }
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_parse.c,v 1.13 2008/12/15 20:02:58 andreas_kupries Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ *  Info needed for public/protected/private commands:
+ */
+typedef struct ProtectionCmdInfo {
+    int pLevel;               /* protection level */
+    ItclObjectInfo *info;     /* info regarding all known objects */
+} ProtectionCmdInfo;
+
+/*
+ *  FORWARD DECLARATIONS
+ */
+static void ItclFreeParserCommandData _ANSI_ARGS_((char* cdata));
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ParseInit()
+ *
+ *  Invoked by Itcl_Init() whenever a new interpeter is created to add
+ *  [incr Tcl] facilities.  Adds the commands needed to parse class
+ *  definitions.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ParseInit(interp, info)
+    Tcl_Interp *interp;     /* interpreter to be updated */
+    ItclObjectInfo *info;   /* info regarding all known objects */
+{
+    Tcl_Namespace *parserNs;
+    ProtectionCmdInfo *pInfo;
+
+    /*
+     *  Create the "itcl::parser" namespace used to parse class
+     *  definitions.
+     */
+    parserNs = Tcl_CreateNamespace(interp, "::itcl::parser",
+        (ClientData)info, Itcl_ReleaseData);
+
+    if (!parserNs) {
+        Tcl_AppendResult(interp,
+            " (cannot initialize itcl parser)",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+    Itcl_PreserveData((ClientData)info);
+
+    /*
+     *  Add commands for parsing class definitions.
+     */
+    Tcl_CreateObjCommand(interp, "::itcl::parser::inherit",
+        Itcl_ClassInheritCmd, (ClientData)info, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::constructor",
+        Itcl_ClassConstructorCmd, (ClientData)info, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::destructor",
+        Itcl_ClassDestructorCmd, (ClientData)info, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::method",
+        Itcl_ClassMethodCmd, (ClientData)info, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::proc",
+        Itcl_ClassProcCmd, (ClientData)info, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::common",
+        Itcl_ClassCommonCmd, (ClientData)info, (Tcl_CmdDeleteProc*)NULL);
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::variable",
+        Itcl_ClassVariableCmd, (ClientData)info, (Tcl_CmdDeleteProc*)NULL);
+
+    pInfo = (ProtectionCmdInfo*)ckalloc(sizeof(ProtectionCmdInfo));
+    pInfo->pLevel = ITCL_PUBLIC;
+    pInfo->info = info;
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::public",
+        Itcl_ClassProtectionCmd, (ClientData)pInfo,
+           (Tcl_CmdDeleteProc*) ItclFreeParserCommandData);
+
+    pInfo = (ProtectionCmdInfo*)ckalloc(sizeof(ProtectionCmdInfo));
+    pInfo->pLevel = ITCL_PROTECTED;
+    pInfo->info = info;
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::protected",
+        Itcl_ClassProtectionCmd, (ClientData)pInfo,
+           (Tcl_CmdDeleteProc*) ItclFreeParserCommandData);
+
+    pInfo = (ProtectionCmdInfo*)ckalloc(sizeof(ProtectionCmdInfo));
+    pInfo->pLevel = ITCL_PRIVATE;
+    pInfo->info = info;
+
+    Tcl_CreateObjCommand(interp, "::itcl::parser::private",
+        Itcl_ClassProtectionCmd, (ClientData)pInfo,
+           (Tcl_CmdDeleteProc*) ItclFreeParserCommandData);
+
+    /*
+     *  Set the runtime variable resolver for the parser namespace,
+     *  to control access to "common" data members while parsing
+     *  the class definition.
+     */
+    Tcl_SetNamespaceResolvers(parserNs, (Tcl_ResolveCmdProc*)NULL,
+        Itcl_ParseVarResolver, (Tcl_ResolveCompiledVarProc*)NULL);
+
+    /*
+     *  Install the "class" command for defining new classes.
+     */
+    Tcl_CreateObjCommand(interp, "::itcl::class", Itcl_ClassCmd,
+        (ClientData)info, Itcl_ReleaseData);
+    Itcl_PreserveData((ClientData)info);
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassCmd()
+ *
+ *  Invoked by Tcl whenever the user issues an "itcl::class" command to
+ *  specify a class definition.  Handles the following syntax:
+ *
+ *    itcl::class <className> {
+ *        inherit <base-class>...
+ *
+ *        constructor {<arglist>} ?{<init>}? {<body>}
+ *        destructor {<body>}
+ *
+ *        method <name> {<arglist>} {<body>}
+ *        proc <name> {<arglist>} {<body>}
+ *        variable <varname> ?<init>? ?<config>?
+ *        common <varname> ?<init>?
+ *
+ *        public <args>...
+ *        protected <args>...
+ *        private <args>...
+ *    }
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* info for all known objects */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObjectInfo* info = (ItclObjectInfo*)clientData;
+
+    int result, len;
+    char *className;
+    Tcl_Namespace *parserNs;
+    ItclClass *cdefnPtr;
+    Itcl_CallFrame frame;
+
+    if (objc != 3) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name { definition }");
+        return TCL_ERROR;
+    }
+    className = Tcl_GetStringFromObj(objv[1], &len);
+    if (len == 0) {
+        Tcl_AppendResult(interp, "invalid class name \"\"", (char *) NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Find the namespace to use as a parser for the class definition.
+     *  If for some reason it is destroyed, bail out here.
+     */
+    parserNs = Tcl_FindNamespace(interp, "::itcl::parser",
+        (Tcl_Namespace*)NULL, TCL_LEAVE_ERR_MSG);
+
+    if (parserNs == NULL) {
+        char msg[256];
+        sprintf(msg, "\n    (while parsing class definition for \"%.100s\")",
+            className);
+        Tcl_AddErrorInfo(interp, msg);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Try to create the specified class and its namespace.
+     */
+    if (Itcl_CreateClass(interp, className, info, &cdefnPtr) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Import the built-in commands from the itcl::builtin namespace.
+     *  Do this before parsing the class definition, so methods/procs
+     *  can override the built-in commands.
+     */
+    result = Tcl_Import(interp, cdefnPtr->namesp, "::itcl::builtin::*",
+        /* allowOverwrite */ 1);
+
+    if (result != TCL_OK) {
+        char msg[256];
+        sprintf(msg, "\n    (while installing built-in commands for class \"%.100s\")", className);
+        Tcl_AddErrorInfo(interp, msg);
+
+        Tcl_DeleteNamespace(cdefnPtr->namesp);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Push this class onto the class definition stack so that it
+     *  becomes the current context for all commands in the parser.
+     *  Activate the parser and evaluate the class definition.
+     */
+    Itcl_PushStack((ClientData)cdefnPtr, &info->cdefnStack);
+
+    result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) &frame, parserNs,
+        /* isProcCallFrame */ 0);
+
+    if (result == TCL_OK) {
+        result = Tcl_EvalObj(interp, objv[2]);
+        Tcl_PopCallFrame(interp);
+    }
+    Itcl_PopStack(&info->cdefnStack);
+
+    if (result != TCL_OK) {
+        char msg[256];
+        sprintf(msg, "\n    (class \"%.200s\" body line %d)",
+            className, ERRORLINE(interp));
+        Tcl_AddErrorInfo(interp, msg);
+
+        Tcl_DeleteNamespace(cdefnPtr->namesp);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  At this point, parsing of the class definition has succeeded.
+     *  Add built-in methods such as "configure" and "cget"--as long
+     *  as they don't conflict with those defined in the class.
+     */
+    if (Itcl_InstallBiMethods(interp, cdefnPtr) != TCL_OK) {
+        Tcl_DeleteNamespace(cdefnPtr->namesp);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Build the name resolution tables for all data members.
+     */
+    Itcl_BuildVirtualTables(cdefnPtr);
+
+    Tcl_ResetResult(interp);
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassInheritCmd()
+ *
+ *  Invoked by Tcl during the parsing of a class definition whenever
+ *  the "inherit" command is invoked to define one or more base classes.
+ *  Handles the following syntax:
+ *
+ *      inherit <baseclass> ?<baseclass>...?
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassInheritCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* info for all known objects */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)clientData;
+    ItclClass *cdefnPtr = (ItclClass*)Itcl_PeekStack(&info->cdefnStack);
+
+    int result, i, newEntry = 1;
+    char *token;
+    Itcl_ListElem *elem, *elem2;
+    ItclClass *cdPtr, *baseCdefnPtr, *badCdPtr;
+    ItclHierIter hier;
+    Itcl_Stack stack;
+    Itcl_CallFrame frame;
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "class ?class...?");
+        return TCL_ERROR;
+    }
+
+    /*
+     *  In "inherit" statement can only be included once in a
+     *  class definition.
+     */
+    elem = Itcl_FirstListElem(&cdefnPtr->bases);
+    if (elem != NULL) {
+        Tcl_AppendToObj(Tcl_GetObjResult(interp), "inheritance \"", -1);
+
+        while (elem) {
+            cdPtr = (ItclClass*)Itcl_GetListValue(elem);
+            Tcl_AppendResult(interp,
+                cdPtr->name, " ", (char*)NULL);
+
+            elem = Itcl_NextListElem(elem);
+        }
+
+        Tcl_AppendResult(interp,
+            "\" already defined for class \"", cdefnPtr->fullname, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Validate each base class and add it to the "bases" list.
+     */
+    result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) &frame,
+           cdefnPtr->namesp->parentPtr, /* isProcCallFrame */ 0);
+
+    if (result != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    for (objc--,objv++; objc > 0; objc--,objv++) {
+
+        /*
+         *  Make sure that the base class name is known in the
+         *  parent namespace (currently active).  If not, try
+         *  to autoload its definition.
+         */
+        token = Tcl_GetString(*objv);
+        baseCdefnPtr = Itcl_FindClass(interp, token, /* autoload */ 1);
+        if (!baseCdefnPtr) {
+            Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
+            int errlen;
+            char *errmsg;
+
+            Tcl_IncrRefCount(resultPtr);
+            errmsg = Tcl_GetStringFromObj(resultPtr, &errlen);
+
+            Tcl_ResetResult(interp);
+            Tcl_AppendResult(interp,
+                "cannot inherit from \"", token, "\"",
+                (char*)NULL);
+
+            if (errlen > 0) {
+                Tcl_AppendResult(interp,
+                    " (", errmsg, ")", (char*)NULL);
+            }
+            Tcl_DecrRefCount(resultPtr);
+            goto inheritError;
+        }
+
+        /*
+         *  Make sure that the base class is not the same as the
+         *  class that is being built.
+         */
+        if (baseCdefnPtr == cdefnPtr) {
+            Tcl_AppendResult(interp,
+                "class \"", cdefnPtr->name, "\" cannot inherit from itself",
+                (char*)NULL);
+            goto inheritError;
+        }
+
+        Itcl_AppendList(&cdefnPtr->bases, (ClientData)baseCdefnPtr);
+        Itcl_PreserveData((ClientData)baseCdefnPtr);
+    }
+
+    /*
+     *  Scan through the inheritance list to make sure that no
+     *  class appears twice.
+     */
+    elem = Itcl_FirstListElem(&cdefnPtr->bases);
+    while (elem) {
+        elem2 = Itcl_NextListElem(elem);
+        while (elem2) {
+            if (Itcl_GetListValue(elem) == Itcl_GetListValue(elem2)) {
+                cdPtr = (ItclClass*)Itcl_GetListValue(elem);
+                Tcl_AppendResult(interp,
+                    "class \"", cdefnPtr->fullname,
+                    "\" cannot inherit base class \"",
+                    cdPtr->fullname, "\" more than once",
+                    (char*)NULL);
+                goto inheritError;
+            }
+            elem2 = Itcl_NextListElem(elem2);
+        }
+        elem = Itcl_NextListElem(elem);
+    }
+
+    /*
+     *  Add each base class and all of its base classes into
+     *  the heritage for the current class.  Along the way, make
+     *  sure that no class appears twice in the heritage.
+     */
+    Itcl_InitHierIter(&hier, cdefnPtr);
+    cdPtr = Itcl_AdvanceHierIter(&hier);  /* skip the class itself */
+    cdPtr = Itcl_AdvanceHierIter(&hier);
+    while (cdPtr != NULL) {
+        (void) Tcl_CreateHashEntry(&cdefnPtr->heritage,
+            (char*)cdPtr, &newEntry);
+
+        if (!newEntry) {
+            break;
+        }
+        cdPtr = Itcl_AdvanceHierIter(&hier);
+    }
+    Itcl_DeleteHierIter(&hier);
+
+    /*
+     *  Same base class found twice in the hierarchy?
+     *  Then flag error.  Show the list of multiple paths
+     *  leading to the same base class.
+     */
+    if (!newEntry) {
+        badCdPtr = cdPtr;
+        Tcl_AppendResult(interp,
+            "class \"", cdefnPtr->fullname, "\" inherits base class \"",
+            badCdPtr->fullname, "\" more than once:",
+            (char*)NULL);
+
+        cdPtr = cdefnPtr;
+        Itcl_InitStack(&stack);
+        Itcl_PushStack((ClientData)cdPtr, &stack);
+
+        /*
+         *  Show paths leading to bad base class
+         */
+        while (Itcl_GetStackSize(&stack) > 0) {
+            cdPtr = (ItclClass*)Itcl_PopStack(&stack);
+
+            if (cdPtr == badCdPtr) {
+                Tcl_AppendResult(interp, "\n  ", (char *) NULL);
+                for (i=0; i < Itcl_GetStackSize(&stack); i++) {
+                    if (Itcl_GetStackValue(&stack, i) == NULL) {
+                        cdPtr = (ItclClass*)Itcl_GetStackValue(&stack, i-1);
+                        Tcl_AppendResult(interp, cdPtr->name, "->",
+                               (char*)NULL);
+                    }
+                }
+                Tcl_AppendResult(interp, badCdPtr->name, (char *) NULL);
+            }
+            else if (!cdPtr) {
+                (void)Itcl_PopStack(&stack);
+            }
+            else {
+                elem = Itcl_LastListElem(&cdPtr->bases);
+                if (elem) {
+                    Itcl_PushStack((ClientData)cdPtr, &stack);
+                    Itcl_PushStack((ClientData)NULL, &stack);
+                    while (elem) {
+                        Itcl_PushStack(Itcl_GetListValue(elem), &stack);
+                        elem = Itcl_PrevListElem(elem);
+                    }
+                }
+            }
+        }
+        Itcl_DeleteStack(&stack);
+        goto inheritError;
+    }
+
+    /*
+     *  At this point, everything looks good.
+     *  Finish the installation of the base classes.  Update
+     *  each base class to recognize the current class as a
+     *  derived class.
+     */
+    elem = Itcl_FirstListElem(&cdefnPtr->bases);
+    while (elem) {
+        baseCdefnPtr = (ItclClass*)Itcl_GetListValue(elem);
+
+        Itcl_AppendList(&baseCdefnPtr->derived, (ClientData)cdefnPtr);
+        Itcl_PreserveData((ClientData)cdefnPtr);
+
+        elem = Itcl_NextListElem(elem);
+    }
+
+    Tcl_PopCallFrame(interp);
+    return TCL_OK;
+
+
+    /*
+     *  If the "inherit" list cannot be built properly, tear it
+     *  down and return an error.
+     */
+inheritError:
+    Tcl_PopCallFrame(interp);
+
+    elem = Itcl_FirstListElem(&cdefnPtr->bases);
+    while (elem) {
+        Itcl_ReleaseData( Itcl_GetListValue(elem) );
+        elem = Itcl_DeleteListElem(elem);
+    }
+    return TCL_ERROR;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassProtectionCmd()
+ *
+ *  Invoked by Tcl whenever the user issues a protection setting
+ *  command like "public" or "private".  Creates commands and
+ *  variables, and assigns a protection level to them.  Protection
+ *  levels are defined as follows:
+ *
+ *    public    => accessible from any namespace
+ *    protected => accessible from selected namespaces
+ *    private   => accessible only in the namespace where it was defined
+ *
+ *  Handles the following syntax:
+ *
+ *    public <command> ?<arg> <arg>...?
+ *
+ *  Returns TCL_OK/TCL_ERROR to indicate success/failure.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassProtectionCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* protection level (public/protected/private) */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ProtectionCmdInfo *pInfo = (ProtectionCmdInfo*)clientData;
+
+    int result;
+    int oldLevel;
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "command ?arg arg...?");
+        return TCL_ERROR;
+    }
+
+    oldLevel = Itcl_Protection(interp, pInfo->pLevel);
+
+    if (objc == 2) {
+        result = Tcl_EvalObj(interp, objv[1]);
+    } else {
+        result = Itcl_EvalArgs(interp, objc-1, objv+1);
+    }
+
+    if (result == TCL_BREAK) {
+        Tcl_SetResult(interp, "invoked \"break\" outside of a loop",
+            TCL_STATIC);
+        result = TCL_ERROR;
+    }
+    else if (result == TCL_CONTINUE) {
+        Tcl_SetResult(interp, "invoked \"continue\" outside of a loop",
+            TCL_STATIC);
+        result = TCL_ERROR;
+    }
+    else if (result != TCL_OK) {
+        char mesg[256], *token;
+        token = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+        sprintf(mesg, "\n    (%.100s body line %d)", token, ERRORLINE(interp));
+        Tcl_AddErrorInfo(interp, mesg);
+    }
+
+    Itcl_Protection(interp, oldLevel);
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassConstructorCmd()
+ *
+ *  Invoked by Tcl during the parsing of a class definition whenever
+ *  the "constructor" command is invoked to define the constructor
+ *  for an object.  Handles the following syntax:
+ *
+ *      constructor <arglist> ?<init>? <body>
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassConstructorCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* info for all known objects */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)clientData;
+    ItclClass *cdefnPtr = (ItclClass*)Itcl_PeekStack(&info->cdefnStack);
+
+    char *name, *arglist, *body;
+
+    if (objc < 3 || objc > 4) {
+        Tcl_WrongNumArgs(interp, 1, objv, "args ?init? body");
+        return TCL_ERROR;
+    }
+
+    name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+    if (Tcl_FindHashEntry(&cdefnPtr->functions, name)) {
+        Tcl_AppendResult(interp,
+            "\"", name, "\" already defined in class \"",
+            cdefnPtr->fullname, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  If there is an object initialization statement, pick this
+     *  out and take the last argument as the constructor body.
+     */
+    arglist = Tcl_GetString(objv[1]);
+    if (objc == 3) {
+        body = Tcl_GetString(objv[2]);
+    } else {
+        cdefnPtr->initCode = objv[2];
+        Tcl_IncrRefCount(cdefnPtr->initCode);
+        body = Tcl_GetString(objv[3]);
+    }
+
+    if (Itcl_CreateMethod(interp, cdefnPtr, name, arglist, body) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassDestructorCmd()
+ *
+ *  Invoked by Tcl during the parsing of a class definition whenever
+ *  the "destructor" command is invoked to define the destructor
+ *  for an object.  Handles the following syntax:
+ *
+ *      destructor <body>
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassDestructorCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* info for all known objects */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)clientData;
+    ItclClass *cdefnPtr = (ItclClass*)Itcl_PeekStack(&info->cdefnStack);
+
+    char *name, *body;
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "body");
+        return TCL_ERROR;
+    }
+
+    name = Tcl_GetStringFromObj(objv[0], (int*)NULL);
+    body = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+
+    if (Tcl_FindHashEntry(&cdefnPtr->functions, name)) {
+        Tcl_AppendResult(interp,
+            "\"", name, "\" already defined in class \"",
+            cdefnPtr->fullname, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    if (Itcl_CreateMethod(interp, cdefnPtr, name, (char*)NULL, body)
+        != TCL_OK) {
+        return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassMethodCmd()
+ *
+ *  Invoked by Tcl during the parsing of a class definition whenever
+ *  the "method" command is invoked to define an object method.
+ *  Handles the following syntax:
+ *
+ *      method <name> ?<arglist>? ?<body>?
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassMethodCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* info for all known objects */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)clientData;
+    ItclClass *cdefnPtr = (ItclClass*)Itcl_PeekStack(&info->cdefnStack);
+
+    char *name, *arglist, *body;
+
+    if (objc < 2 || objc > 4) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name ?args? ?body?");
+        return TCL_ERROR;
+    }
+
+    name = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+
+    arglist = NULL;
+    body = NULL;
+    if (objc >= 3) {
+        arglist = Tcl_GetStringFromObj(objv[2], (int*)NULL);
+    }
+    if (objc >= 4) {
+        body = Tcl_GetStringFromObj(objv[3], (int*)NULL);
+    }
+
+    if (Itcl_CreateMethod(interp, cdefnPtr, name, arglist, body) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassProcCmd()
+ *
+ *  Invoked by Tcl during the parsing of a class definition whenever
+ *  the "proc" command is invoked to define a common class proc.
+ *  A "proc" is like a "method", but only has access to "common"
+ *  class variables.  Handles the following syntax:
+ *
+ *      proc <name> ?<arglist>? ?<body>?
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassProcCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* info for all known objects */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)clientData;
+    ItclClass *cdefnPtr = (ItclClass*)Itcl_PeekStack(&info->cdefnStack);
+    char *name, *arglist, *body;
+
+    if (objc < 2 || objc > 4) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name ?args? ?body?");
+        return TCL_ERROR;
+    }
+
+    name = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+
+    arglist = NULL;
+    body = NULL;
+    if (objc >= 3) {
+        arglist = Tcl_GetStringFromObj(objv[2], (int*)NULL);
+    }
+    if (objc >= 4) {
+        body = Tcl_GetStringFromObj(objv[3], (int*)NULL);
+    }
+
+    if (Itcl_CreateProc(interp, cdefnPtr, name, arglist, body) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassVariableCmd()
+ *
+ *  Invoked by Tcl during the parsing of a class definition whenever
+ *  the "variable" command is invoked to define an instance variable.
+ *  Handles the following syntax:
+ *
+ *      variable <varname> ?<init>? ?<config>?
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassVariableCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* info for all known objects */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)clientData;
+    ItclClass *cdefnPtr = (ItclClass*)Itcl_PeekStack(&info->cdefnStack);
+
+    int pLevel;
+    ItclVarDefn *vdefn;
+    char *name, *init, *config;
+
+    pLevel = Itcl_Protection(interp, 0);
+
+    if (pLevel == ITCL_PUBLIC) {
+        if (objc < 2 || objc > 4) {
+            Tcl_WrongNumArgs(interp, 1, objv, "name ?init? ?config?");
+            return TCL_ERROR;
+        }
+    }
+    else if ((objc < 2) || (objc > 3)) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name ?init?");
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Make sure that the variable name does not contain anything
+     *  goofy like a "::" scope qualifier.
+     */
+    name = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    if (strstr(name, "::")) {
+        Tcl_AppendResult(interp,
+            "bad variable name \"", name, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    init   = NULL;
+    config = NULL;
+    if (objc >= 3) {
+        init = Tcl_GetStringFromObj(objv[2], (int*)NULL);
+    }
+    if (objc >= 4) {
+        config = Tcl_GetStringFromObj(objv[3], (int*)NULL);
+    }
+
+    if (Itcl_CreateVarDefn(interp, cdefnPtr, name, init, config,
+        &vdefn) != TCL_OK) {
+
+        return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ClassCommonCmd()
+ *
+ *  Invoked by Tcl during the parsing of a class definition whenever
+ *  the "common" command is invoked to define a variable that is
+ *  common to all objects in the class.  Handles the following syntax:
+ *
+ *      common <varname> ?<init>?
+ *
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_ClassCommonCmd(clientData, interp, objc, objv)
+    ClientData clientData;   /* info for all known objects */
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)clientData;
+    ItclClass *cdefnPtr = (ItclClass*)Itcl_PeekStack(&info->cdefnStack);
+
+    int newEntry;
+    char *name, *init;
+    ItclVarDefn *vdefn;
+    Namespace *nsPtr;
+    Var *varPtr;
+
+    if ((objc < 2) || (objc > 3)) {
+        Tcl_WrongNumArgs(interp, 1, objv, "varname ?init?");
+        return TCL_ERROR;
+    }
+
+    /*
+     *  Make sure that the variable name does not contain anything
+     *  goofy like a "::" scope qualifier.
+     */
+    name = Tcl_GetStringFromObj(objv[1], (int*)NULL);
+    if (strstr(name, "::")) {
+        Tcl_AppendResult(interp,
+            "bad variable name \"", name, "\"",
+            (char*)NULL);
+        return TCL_ERROR;
+    }
+
+    init = NULL;
+    if (objc >= 3) {
+        init = Tcl_GetStringFromObj(objv[2], (int*)NULL);
+    }
+
+    if (Itcl_CreateVarDefn(interp, cdefnPtr, name, init, (char*)NULL,
+        &vdefn) != TCL_OK) {
+
+        return TCL_ERROR;
+    }
+    vdefn->member->flags |= ITCL_COMMON;
+
+    /*
+     *  Create the variable in the namespace associated with the
+     *  class.  Do this the hard way, to avoid the variable resolver
+     *  procedures.  These procedures won't work until we rebuild
+     *  the virtual tables below.
+     */
+    nsPtr = (Namespace*)cdefnPtr->namesp;
+    varPtr = ItclVarHashCreateVar(&nsPtr->varTable,
+        vdefn->member->name, &newEntry);
+
+#if ITCL_TCL_PRE_8_5
+    if (newEntry && itclOldRuntime) {
+       varPtr->nsPtr = nsPtr;
+    }
+#endif
+    TclSetVarNamespaceVar(varPtr);
+    ItclVarRefCount(varPtr)++;    /* another use by class */
+
+
+    /*
+     *  TRICKY NOTE:  Make sure to rebuild the virtual tables for this
+     *    class so that this variable is ready to access.  The variable
+     *    resolver for the parser namespace needs this info to find the
+     *    variable if the developer tries to set it within the class
+     *    definition.
+     *
+     *  If an initialization value was specified, then initialize
+     *  the variable now.
+     */
+    Itcl_BuildVirtualTables(cdefnPtr);
+
+    if (init) {
+        CONST char *val = Tcl_SetVar(interp, vdefn->member->name, init,
+            TCL_NAMESPACE_ONLY);
+
+        if (!val) {
+            Tcl_AppendResult(interp,
+                "cannot initialize common variable \"",
+                vdefn->member->name, "\"",
+                (char*)NULL);
+            return TCL_ERROR;
+        }
+    }
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ParseVarResolver()
+ *
+ *  Used by the "parser" namespace to resolve variable accesses to
+ *  common variables.  The runtime resolver procedure is consulted
+ *  whenever a variable is accessed within the namespace.  It can
+ *  deny access to certain variables, or perform special lookups itself.
+ *
+ *  This procedure allows access only to "common" class variables that
+ *  have been declared within the class or inherited from another class.
+ *  A "set" command can be used to initialized common data members within
+ *  the body of the class definition itself:
+ *
+ *    itcl::class Foo {
+ *        common colors
+ *        set colors(red)   #ff0000
+ *        set colors(green) #00ff00
+ *        set colors(blue)  #0000ff
+ *        ...
+ *    }
+ *
+ *    itcl::class Bar {
+ *        inherit Foo
+ *        set colors(gray)  #a0a0a0
+ *        set colors(white) #ffffff
+ *
+ *        common numbers
+ *        set numbers(0) zero
+ *        set numbers(1) one
+ *    }
+ *
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+int
+Itcl_ParseVarResolver(interp, name, contextNs, flags, rPtr)
+    Tcl_Interp *interp;        /* current interpreter */
+    CONST char* name;                /* name of the variable being accessed */
+    Tcl_Namespace *contextNs;  /* namespace context */
+    int flags;                 /* TCL_GLOBAL_ONLY => global variable
+                                * TCL_NAMESPACE_ONLY => namespace variable */
+    Tcl_Var* rPtr;             /* returns: Tcl_Var for desired variable */
+{
+    ItclObjectInfo *info = (ItclObjectInfo*)contextNs->clientData;
+    ItclClass *cdefnPtr = (ItclClass*)Itcl_PeekStack(&info->cdefnStack);
+
+    Tcl_HashEntry *entry;
+    ItclVarLookup *vlookup;
+
+    /*
+     *  See if the requested variable is a recognized "common" member.
+     *  If it is, make sure that access is allowed.
+     */
+    entry = Tcl_FindHashEntry(&cdefnPtr->resolveVars, name);
+    if (entry) {
+        vlookup = (ItclVarLookup*)Tcl_GetHashValue(entry);
+
+        if ((vlookup->vdefn->member->flags & ITCL_COMMON) != 0) {
+            if (!vlookup->accessible) {
+                Tcl_AppendResult(interp,
+                    "can't access \"", name, "\": ",
+                    Itcl_ProtectionStr(vlookup->vdefn->member->protection),
+                    " variable",
+                    (char*)NULL);
+                return TCL_ERROR;
+            }
+            *rPtr = vlookup->var.common;
+            return TCL_OK;
+        }
+    }
+
+    /*
+     *  If the variable is not recognized, return TCL_CONTINUE and
+     *  let lookup continue via the normal name resolution rules.
+     *  This is important for variables like "errorInfo"
+     *  that might get set while the parser namespace is active.
+     */
+    return TCL_CONTINUE;
+}
+
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclFreeParserCommandData()
+ *
+ *  This callback will free() up memory dynamically allocated
+ *  and passed as the ClientData argument to Tcl_CreateObjCommand.
+ *  This callback is required because one can not simply pass
+ *  a pointer to the free() or ckfree() to Tcl_CreateObjCommand.
+ * ------------------------------------------------------------------------
+ */
+static void
+ItclFreeParserCommandData(cdata)
+    char* cdata;  /* client data to be destroyed */
+{
+    ckfree(cdata);
+}
diff --git a/8.x/itcl/generic/itcl_util.c b/8.x/itcl/generic/itcl_util.c
new file mode 100644 (file)
index 0000000..bf3c9d7
--- /dev/null
@@ -0,0 +1,1437 @@
+/*
+ * ------------------------------------------------------------------------
+ *      PACKAGE:  [incr Tcl]
+ *  DESCRIPTION:  Object-Oriented Extensions to Tcl
+ *
+ *  [incr Tcl] provides object-oriented extensions to Tcl, much as
+ *  C++ provides object-oriented extensions to C.  It provides a means
+ *  of encapsulating related procedures together with their shared data
+ *  in a local namespace that is hidden from the outside world.  It
+ *  promotes code re-use through inheritance.  More than anything else,
+ *  it encourages better organization of Tcl applications through the
+ *  object-oriented paradigm, leading to code that is easier to
+ *  understand and maintain.
+ *
+ *  This segment provides common utility functions used throughout
+ *  the other [incr Tcl] source files.
+ *
+ * ========================================================================
+ *  AUTHOR:  Michael J. McLennan
+ *           Bell Labs Innovations for Lucent Technologies
+ *           mmclennan@lucent.com
+ *           http://www.tcltk.com/itcl
+ *
+ *     RCS:  $Id: itcl_util.c,v 1.18 2007/08/07 20:05:30 msofer Exp $
+ * ========================================================================
+ *           Copyright (c) 1993-1998  Lucent Technologies, Inc.
+ * ------------------------------------------------------------------------
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "itclInt.h"
+
+/*
+ *  POOL OF LIST ELEMENTS FOR LINKED LIST
+ */
+static Itcl_ListElem *listPool = NULL;
+static int listPoolLen = 0;
+
+#define ITCL_VALID_LIST 0x01face10  /* magic bit pattern for validation */
+#define ITCL_LIST_POOL_SIZE 200     /* max number of elements in listPool */
+
+
+/*
+ *  These records are used to keep track of reference-counted data
+ *  for Itcl_PreserveData and Itcl_ReleaseData.
+ */
+typedef struct ItclPreservedData {
+    ClientData data;                /* reference to data */
+    int usage;                      /* number of active uses */
+    Tcl_FreeProc *fproc;            /* procedure used to free data */
+} ItclPreservedData;
+
+static Tcl_HashTable *ItclPreservedList = NULL;
+TCL_DECLARE_MUTEX(ItclPreservedListLock)
+
+/*
+ *  This structure is used to take a snapshot of the interpreter
+ *  state in Itcl_SaveInterpState.  You can snapshot the state,
+ *  execute a command, and then back up to the result or the
+ *  error that was previously in progress.
+ */
+typedef struct InterpState {
+    int validate;                   /* validation stamp */
+    int status;                     /* return code status */
+    Tcl_Obj *objResult;             /* result object */
+    char *errorInfo;                /* contents of errorInfo variable */
+    char *errorCode;                /* contents of errorCode variable */
+} InterpState;
+
+#define TCL_STATE_VALID 0x01233210  /* magic bit pattern for validation */
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_Assert()
+ *
+ *  Called whenever an assert() test fails.  Prints a diagnostic
+ *  message and abruptly exits.
+ * ------------------------------------------------------------------------
+ */
+
+void
+Itcl_Assert(testExpr, fileName, lineNumber)
+    CONST char *testExpr;   /* string representing test expression */
+    CONST char *fileName;   /* file name containing this call */
+    int lineNumber;        /* line number containing this call */
+{
+    Tcl_Panic("Itcl Assertion failed: \"%s\" (line %d of %s)",
+       testExpr, lineNumber, fileName);
+}
+
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_InitStack()
+ *
+ *  Initializes a stack structure, allocating a certain amount of memory
+ *  for the stack and setting the stack length to zero.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_InitStack(stack)
+    Itcl_Stack *stack;     /* stack to be initialized */
+{
+    stack->values = stack->space;
+    stack->max = sizeof(stack->space)/sizeof(ClientData);
+    stack->len = 0;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteStack()
+ *
+ *  Destroys a stack structure, freeing any memory that may have been
+ *  allocated to represent it.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DeleteStack(stack)
+    Itcl_Stack *stack;     /* stack to be deleted */
+{
+    /*
+     *  If memory was explicitly allocated (instead of using the
+     *  built-in buffer) then free it.
+     */
+    if (stack->values != stack->space) {
+        ckfree((char*)stack->values);
+    }
+    stack->values = NULL;
+    stack->len = stack->max = 0;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_PushStack()
+ *
+ *  Pushes a piece of client data onto the top of the given stack.
+ *  If the stack is not large enough, it is automatically resized.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_PushStack(cdata,stack)
+    ClientData cdata;      /* data to be pushed onto stack */
+    Itcl_Stack *stack;     /* stack */
+{
+    ClientData *newStack;
+
+    if (stack->len+1 >= stack->max) {
+        stack->max = 2*stack->max;
+        newStack = (ClientData*)
+            ckalloc((unsigned)(stack->max*sizeof(ClientData)));
+
+        if (stack->values) {
+            memcpy((char*)newStack, (char*)stack->values,
+                (size_t)(stack->len*sizeof(ClientData)));
+
+            if (stack->values != stack->space)
+                ckfree((char*)stack->values);
+        }
+        stack->values = newStack;
+    }
+    stack->values[stack->len++] = cdata;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_PopStack()
+ *
+ *  Pops a bit of client data from the top of the given stack.
+ * ------------------------------------------------------------------------
+ */
+ClientData
+Itcl_PopStack(stack)
+    Itcl_Stack *stack;  /* stack to be manipulated */
+{
+    if (stack->values && (stack->len > 0)) {
+        stack->len--;
+        return stack->values[stack->len];
+    }
+    return (ClientData)NULL;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_PeekStack()
+ *
+ *  Gets the current value from the top of the given stack.
+ * ------------------------------------------------------------------------
+ */
+ClientData
+Itcl_PeekStack(stack)
+    Itcl_Stack *stack;  /* stack to be examined */
+{
+    if (stack->values && (stack->len > 0)) {
+        return stack->values[stack->len-1];
+    }
+    return (ClientData)NULL;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_GetStackValue()
+ *
+ *  Gets a value at some index within the stack.  Index "0" is the
+ *  first value pushed onto the stack.
+ * ------------------------------------------------------------------------
+ */
+ClientData
+Itcl_GetStackValue(stack,pos)
+    Itcl_Stack *stack;  /* stack to be examined */
+    int pos;            /* get value at this index */
+{
+    if (stack->values && (stack->len > 0)) {
+        assert(pos < stack->len);
+        return stack->values[pos];
+    }
+    return (ClientData)NULL;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_InitList()
+ *
+ *  Initializes a linked list structure, setting the list to the empty
+ *  state.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_InitList(listPtr)
+    Itcl_List *listPtr;     /* list to be initialized */
+{
+    listPtr->validate = ITCL_VALID_LIST;
+    listPtr->num      = 0;
+    listPtr->head     = NULL;
+    listPtr->tail     = NULL;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteList()
+ *
+ *  Destroys a linked list structure, deleting all of its elements and
+ *  setting it to an empty state.  If the elements have memory associated
+ *  with them, this memory must be freed before deleting the list or it
+ *  will be lost.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DeleteList(listPtr)
+    Itcl_List *listPtr;     /* list to be deleted */
+{
+    Itcl_ListElem *elemPtr;
+
+    assert(listPtr->validate == ITCL_VALID_LIST);
+
+    elemPtr = listPtr->head;
+    while (elemPtr) {
+        elemPtr = Itcl_DeleteListElem(elemPtr);
+    }
+    listPtr->validate = 0;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateListElem()
+ *
+ *  Low-level routined used by procedures like Itcl_InsertList() and
+ *  Itcl_AppendList() to create new list elements.  If elements are
+ *  available, one is taken from the list element pool.  Otherwise,
+ *  a new one is allocated.
+ * ------------------------------------------------------------------------
+ */
+Itcl_ListElem*
+Itcl_CreateListElem(listPtr)
+    Itcl_List *listPtr;     /* list that will contain this new element */
+{
+    Itcl_ListElem *elemPtr;
+
+    if (listPoolLen > 0) {
+        elemPtr = listPool;
+        listPool = elemPtr->next;
+        --listPoolLen;
+    }
+    else {
+        elemPtr = (Itcl_ListElem*)ckalloc((unsigned)sizeof(Itcl_ListElem));
+    }
+    elemPtr->owner = listPtr;
+    elemPtr->value = NULL;
+    elemPtr->next  = NULL;
+    elemPtr->prev  = NULL;
+
+    return elemPtr;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DeleteListElem()
+ *
+ *  Destroys a single element in a linked list, returning it to a pool of
+ *  elements that can be later reused.  Returns a pointer to the next
+ *  element in the list.
+ * ------------------------------------------------------------------------
+ */
+Itcl_ListElem*
+Itcl_DeleteListElem(elemPtr)
+    Itcl_ListElem *elemPtr;     /* list element to be deleted */
+{
+    Itcl_List *listPtr;
+    Itcl_ListElem *nextPtr;
+
+    nextPtr = elemPtr->next;
+
+    if (elemPtr->prev) {
+        elemPtr->prev->next = elemPtr->next;
+    }
+    if (elemPtr->next) {
+        elemPtr->next->prev = elemPtr->prev;
+    }
+
+    listPtr = elemPtr->owner;
+    if (elemPtr == listPtr->head)
+        listPtr->head = elemPtr->next;
+    if (elemPtr == listPtr->tail)
+        listPtr->tail = elemPtr->prev;
+    --listPtr->num;
+
+    if (listPoolLen < ITCL_LIST_POOL_SIZE) {
+        elemPtr->next = listPool;
+        listPool = elemPtr;
+        ++listPoolLen;
+    }
+    else {
+        ckfree((char*)elemPtr);
+    }
+    return nextPtr;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_InsertList()
+ *
+ *  Creates a new list element containing the given value and returns
+ *  a pointer to it.  The element is inserted at the beginning of the
+ *  specified list.
+ * ------------------------------------------------------------------------
+ */
+Itcl_ListElem*
+Itcl_InsertList(listPtr,val)
+    Itcl_List *listPtr;     /* list being modified */
+    ClientData val;         /* value associated with new element */
+{
+    Itcl_ListElem *elemPtr;
+    assert(listPtr->validate == ITCL_VALID_LIST);
+
+    elemPtr = Itcl_CreateListElem(listPtr);
+
+    elemPtr->value = val;
+    elemPtr->next  = listPtr->head;
+    elemPtr->prev  = NULL;
+    if (listPtr->head) {
+        listPtr->head->prev = elemPtr;
+    }
+    listPtr->head  = elemPtr;
+    if (listPtr->tail == NULL) {
+        listPtr->tail = elemPtr;
+    }
+    ++listPtr->num;
+
+    return elemPtr;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_InsertListElem()
+ *
+ *  Creates a new list element containing the given value and returns
+ *  a pointer to it.  The element is inserted in the list just before
+ *  the specified element.
+ * ------------------------------------------------------------------------
+ */
+Itcl_ListElem*
+Itcl_InsertListElem(pos,val)
+    Itcl_ListElem *pos;     /* insert just before this element */
+    ClientData val;         /* value associated with new element */
+{
+    Itcl_List *listPtr;
+    Itcl_ListElem *elemPtr;
+
+    listPtr = pos->owner;
+    assert(listPtr->validate == ITCL_VALID_LIST);
+    assert(pos != NULL);
+
+    elemPtr = Itcl_CreateListElem(listPtr);
+    elemPtr->value = val;
+
+    elemPtr->prev = pos->prev;
+    if (elemPtr->prev) {
+        elemPtr->prev->next = elemPtr;
+    }
+    elemPtr->next = pos;
+    pos->prev     = elemPtr;
+
+    if (listPtr->head == pos) {
+        listPtr->head = elemPtr;
+    }
+    if (listPtr->tail == NULL) {
+        listPtr->tail = elemPtr;
+    }
+    ++listPtr->num;
+
+    return elemPtr;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_AppendList()
+ *
+ *  Creates a new list element containing the given value and returns
+ *  a pointer to it.  The element is appended at the end of the
+ *  specified list.
+ * ------------------------------------------------------------------------
+ */
+Itcl_ListElem*
+Itcl_AppendList(listPtr,val)
+    Itcl_List *listPtr;     /* list being modified */
+    ClientData val;         /* value associated with new element */
+{
+    Itcl_ListElem *elemPtr;
+    assert(listPtr->validate == ITCL_VALID_LIST);
+
+    elemPtr = Itcl_CreateListElem(listPtr);
+
+    elemPtr->value = val;
+    elemPtr->prev  = listPtr->tail;
+    elemPtr->next  = NULL;
+    if (listPtr->tail) {
+        listPtr->tail->next = elemPtr;
+    }
+    listPtr->tail  = elemPtr;
+    if (listPtr->head == NULL) {
+        listPtr->head = elemPtr;
+    }
+    ++listPtr->num;
+
+    return elemPtr;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_AppendListElem()
+ *
+ *  Creates a new list element containing the given value and returns
+ *  a pointer to it.  The element is inserted in the list just after
+ *  the specified element.
+ * ------------------------------------------------------------------------
+ */
+Itcl_ListElem*
+Itcl_AppendListElem(pos,val)
+    Itcl_ListElem *pos;     /* insert just after this element */
+    ClientData val;         /* value associated with new element */
+{
+    Itcl_List *listPtr;
+    Itcl_ListElem *elemPtr;
+
+    listPtr = pos->owner;
+    assert(listPtr->validate == ITCL_VALID_LIST);
+    assert(pos != NULL);
+
+    elemPtr = Itcl_CreateListElem(listPtr);
+    elemPtr->value = val;
+
+    elemPtr->next = pos->next;
+    if (elemPtr->next) {
+        elemPtr->next->prev = elemPtr;
+    }
+    elemPtr->prev = pos;
+    pos->next     = elemPtr;
+
+    if (listPtr->tail == pos) {
+        listPtr->tail = elemPtr;
+    }
+    if (listPtr->head == NULL) {
+        listPtr->head = elemPtr;
+    }
+    ++listPtr->num;
+
+    return elemPtr;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_SetListValue()
+ *
+ *  Modifies the value associated with a list element.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_SetListValue(elemPtr,val)
+    Itcl_ListElem *elemPtr; /* list element being modified */
+    ClientData val;         /* new value associated with element */
+{
+    Itcl_List *listPtr = elemPtr->owner;
+    assert(listPtr->validate == ITCL_VALID_LIST);
+    assert(elemPtr != NULL);
+
+    elemPtr->value = val;
+}
+
+\f
+/*
+ * ========================================================================
+ *  REFERENCE-COUNTED DATA
+ *
+ *  The following procedures manage generic reference-counted data.
+ *  They are similar in spirit to the Tcl_Preserve/Tcl_Release
+ *  procedures defined in the Tcl/Tk core.  But these procedures use
+ *  a hash table instead of a linked list to maintain the references,
+ *  so they scale better.  Also, the Tcl procedures have a bad behavior
+ *  during the "exit" command.  Their exit handler shuts them down
+ *  when other data is still being reference-counted and cleaned up.
+ *
+ * ------------------------------------------------------------------------
+ *  Itcl_EventuallyFree()
+ *
+ *  Registers a piece of data so that it will be freed when no longer
+ *  in use.  The data is registered with an initial usage count of "0".
+ *  Future calls to Itcl_PreserveData() increase this usage count, and
+ *  calls to Itcl_ReleaseData() decrease the count until it reaches
+ *  zero and the data is freed.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_EventuallyFree(cdata, fproc)
+    ClientData cdata;          /* data to be freed when not in use */
+    Tcl_FreeProc *fproc;       /* procedure called to free data */
+{
+    int newEntry;
+    Tcl_HashEntry *entry;
+    ItclPreservedData *chunk;
+
+    /*
+     *  If the clientData value is NULL, do nothing.
+     */
+    if (cdata == NULL) {
+        return;
+    }
+
+    /*
+     *  If a list has not yet been created to manage bits of
+     *  preserved data, then create it.
+     */
+    Tcl_MutexLock(&ItclPreservedListLock);
+    if (!ItclPreservedList) {
+        ItclPreservedList = (Tcl_HashTable*)ckalloc(
+            (unsigned)sizeof(Tcl_HashTable)
+        );
+        Tcl_InitHashTable(ItclPreservedList, TCL_ONE_WORD_KEYS);
+    }
+
+    /*
+     *  Find or create the data in the global list.
+     */
+    entry = Tcl_CreateHashEntry(ItclPreservedList,(char*)cdata, &newEntry);
+    if (newEntry) {
+        chunk = (ItclPreservedData*)ckalloc(
+            (unsigned)sizeof(ItclPreservedData)
+        );
+        chunk->data  = cdata;
+        chunk->usage = 0;
+        chunk->fproc = fproc;
+        Tcl_SetHashValue(entry, (ClientData)chunk);
+    }
+    else {
+        chunk = (ItclPreservedData*)Tcl_GetHashValue(entry);
+        chunk->fproc = fproc;
+    }
+
+    /*
+     *  If the usage count is zero, then delete the data now.
+     */
+    if (chunk->usage == 0) {
+       chunk->usage = -1;  /* cannot preserve/release anymore */
+
+       Tcl_MutexUnlock(&ItclPreservedListLock);
+       (*chunk->fproc)((char*)chunk->data);
+       Tcl_MutexLock(&ItclPreservedListLock);
+       Tcl_DeleteHashEntry(entry);
+       ckfree((char*)chunk);
+    }
+    Tcl_MutexUnlock(&ItclPreservedListLock);
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_PreserveData()
+ *
+ *  Increases the usage count for a piece of data that will be freed
+ *  later when no longer needed.  Each call to Itcl_PreserveData()
+ *  puts one claim on a piece of data, and subsequent calls to
+ *  Itcl_ReleaseData() remove those claims.  When Itcl_EventuallyFree()
+ *  is called, and when the usage count reaches zero, the data is
+ *  freed.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_PreserveData(cdata)
+    ClientData cdata;      /* data to be preserved */
+{
+    Tcl_HashEntry *entry;
+    ItclPreservedData *chunk;
+    int newEntry;
+
+    /*
+     *  If the clientData value is NULL, do nothing.
+     */
+    if (cdata == NULL) {
+        return;
+    }
+
+    /*
+     *  If a list has not yet been created to manage bits of
+     *  preserved data, then create it.
+     */
+    Tcl_MutexLock(&ItclPreservedListLock);
+    if (!ItclPreservedList) {
+        ItclPreservedList = (Tcl_HashTable*)ckalloc(
+            (unsigned)sizeof(Tcl_HashTable)
+        );
+        Tcl_InitHashTable(ItclPreservedList,TCL_ONE_WORD_KEYS);
+    }
+
+    /*
+     *  Find the data in the global list and bump its usage count.
+     */
+    entry = Tcl_CreateHashEntry(ItclPreservedList,(char*)cdata, &newEntry);
+    if (newEntry) {
+        chunk = (ItclPreservedData*)ckalloc(
+            (unsigned)sizeof(ItclPreservedData)
+        );
+        chunk->data  = cdata;
+        chunk->usage = 0;
+        chunk->fproc = NULL;
+        Tcl_SetHashValue(entry, (ClientData)chunk);
+    }
+    else {
+        chunk = (ItclPreservedData*)Tcl_GetHashValue(entry);
+    }
+
+    /*
+     *  Only increment the usage if it is non-negative.
+     *  Negative numbers mean that the data is in the process
+     *  of being destroyed by Itcl_ReleaseData(), and should
+     *  not be further preserved.
+     */
+    if (chunk->usage >= 0) {
+        chunk->usage++;
+    }
+    Tcl_MutexUnlock(&ItclPreservedListLock);
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ReleaseData()
+ *
+ *  Decreases the usage count for a piece of data that was registered
+ *  previously via Itcl_PreserveData().  After Itcl_EventuallyFree()
+ *  is called and the usage count reaches zero, the data is
+ *  automatically freed.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_ReleaseData(cdata)
+    ClientData cdata;      /* data to be released */
+{
+    Tcl_HashEntry *entry;
+    ItclPreservedData *chunk;
+
+    /*
+     *  If the clientData value is NULL, do nothing.
+     */
+    if (cdata == NULL) {
+        return;
+    }
+
+    /*
+     *  Otherwise, find the data in the global list and
+     *  decrement its usage count.
+     */
+    entry = NULL;
+    Tcl_MutexLock(&ItclPreservedListLock);
+    if (ItclPreservedList) {
+        entry = Tcl_FindHashEntry(ItclPreservedList,(char*)cdata);
+    }
+    if (!entry) {
+       Tcl_MutexUnlock(&ItclPreservedListLock);
+        Tcl_Panic("Itcl_ReleaseData can't find reference for 0x%x", cdata);
+    }
+
+    /*
+     *  Only decrement the usage if it is non-negative.
+     *  When the usage reaches zero, set it to a negative number
+     *  to indicate that data is being destroyed, and then
+     *  invoke the client delete proc.  When the data is deleted,
+     *  remove the entry from the preservation list.
+     */
+    chunk = (ItclPreservedData*)Tcl_GetHashValue(entry);
+    if (chunk->usage > 0 && --chunk->usage == 0) {
+
+       if (chunk->fproc) {
+           chunk->usage = -1;  /* cannot preserve/release anymore */
+           Tcl_MutexUnlock(&ItclPreservedListLock);
+           (*chunk->fproc)((char*)chunk->data);
+           Tcl_MutexLock(&ItclPreservedListLock);
+        }
+
+        Tcl_DeleteHashEntry(entry);
+        ckfree((char*)chunk);
+    }
+    Tcl_MutexUnlock(&ItclPreservedListLock);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_SaveInterpState()
+ *
+ *  Takes a snapshot of the current result state of the interpreter.
+ *  The snapshot can be restored at any point by Itcl_RestoreInterpState.
+ *  So if you are in the middle of building a return result, you can
+ *  snapshot the interpreter, execute a command that might generate an
+ *  error, restore the snapshot, and continue building the result string.
+ *
+ *  Once a snapshot is saved, it must be restored by calling
+ *  Itcl_RestoreInterpState, or discarded by calling
+ *  Itcl_DiscardInterpState.  Otherwise, memory will be leaked.
+ *
+ *  Returns a token representing the state of the interpreter.
+ * ------------------------------------------------------------------------
+ */
+Itcl_InterpState
+Itcl_SaveInterpState(interp, status)
+    Tcl_Interp* interp;     /* interpreter being modified */
+    int status;             /* integer status code for current operation */
+{
+    Interp *iPtr = (Interp*)interp;
+
+    InterpState *info;
+    CONST char *val;
+
+    /*
+     * ERR_IN_PROGRESS was replaced by new APIs in 8.5a2.  Call them if they
+     * are available, or somehow magic them in from the stubs table.
+     * Tcl_ChannelThreadActionProc is a stubs slot higher than the APIs we
+     * need, so its existence indicates slot-y goodness.
+     */
+#ifndef ERR_IN_PROGRESS
+    return (Itcl_InterpState) Tcl_SaveInterpState(interp, status);
+#elif defined(USE_TCL_STUBS) && defined(Tcl_ChannelThreadActionProc)
+    if (itclCompatFlags & ITCL_COMPAT_USE_ISTATE_API) {
+       Itcl_InterpState (*tcl_SaveInterpState)(Tcl_Interp *, int) =
+           (Itcl_InterpState (*)(Tcl_Interp *, int)) tclStubsPtr->reserved535;
+       return (*tcl_SaveInterpState)(interp, status);
+    }
+#endif
+
+    info = (InterpState*)ckalloc(sizeof(InterpState));
+    info->validate = TCL_STATE_VALID;
+    info->status = status;
+    info->errorInfo = NULL;
+    info->errorCode = NULL;
+
+    /*
+     *  Get the result object from the interpreter.  This synchronizes
+     *  the old-style result, so we don't have to worry about it.
+     *  Keeping the object result is enough.
+     */
+    info->objResult = Tcl_GetObjResult(interp);
+    Tcl_IncrRefCount(info->objResult);
+
+    /*
+     *  If an error is in progress, preserve its state.
+     */
+#ifdef ERR_IN_PROGRESS   /* this disappeared in 8.5a2 */
+    if ((iPtr->flags & ERR_IN_PROGRESS) != 0) {
+#else
+    if (iPtr->errorInfo != NULL) {
+#endif
+        val = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
+        if (val) {
+            info->errorInfo = ckalloc((unsigned)(strlen(val)+1));
+            strcpy(info->errorInfo, val);
+        }
+
+        val = Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);
+        if (val) {
+            info->errorCode = ckalloc((unsigned)(strlen(val)+1));
+            strcpy(info->errorCode, val);
+        }
+    }
+
+    /*
+     *  Now, reset the interpreter to a clean state.
+     */
+    Tcl_ResetResult(interp);
+
+    return (Itcl_InterpState)info;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_RestoreInterpState()
+ *
+ *  Restores the state of the interpreter to a snapshot taken by
+ *  Itcl_SaveInterpState.  This affects variables such as "errorInfo"
+ *  and "errorCode".  After this call, the token for the interpreter
+ *  state is no longer valid.
+ *
+ *  Returns the status code that was pending at the time the state was
+ *  captured.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_RestoreInterpState(interp, state)
+    Tcl_Interp* interp;       /* interpreter being modified */
+    Itcl_InterpState state;   /* token representing interpreter state */
+{
+    InterpState *info = (InterpState*)state;
+    int status;
+
+    /*
+     * ERR_IN_PROGRESS was replaced by new APIs in 8.5a2.  Call them if they
+     * are available, or somehow magic them in from the stubs table.
+     * Tcl_ChannelThreadActionProc is a stubs slot higher than the APIs we
+     * need, so its existence indicates slot-y goodness.
+     */
+#ifndef ERR_IN_PROGRESS
+    return Tcl_RestoreInterpState(interp, (Tcl_InterpState)state);
+#elif defined(USE_TCL_STUBS) && defined(Tcl_ChannelThreadActionProc)
+    if (itclCompatFlags & ITCL_COMPAT_USE_ISTATE_API) {
+       int (*tcl_RestoreInterpState)() = (int (*)()) tclStubsPtr->reserved536;
+       return (*tcl_RestoreInterpState)(interp, state);
+    }
+#endif
+
+    if (info->validate != TCL_STATE_VALID) {
+        Tcl_Panic("bad token in Itcl_RestoreInterpState");
+    }
+    Tcl_ResetResult(interp);
+
+    /*
+     *  If an error is in progress, restore its state.
+     *  Set the error code the hard way--set the variable directly
+     *  and fix the interpreter flags.  Otherwise, if the error code
+     *  string is really a list, it will get wrapped in extra {}'s.
+     */
+    if (info->errorInfo) {
+        Tcl_AddErrorInfo(interp, info->errorInfo);
+        ckfree(info->errorInfo);
+    }
+
+    if (info->errorCode) {
+        Tcl_SetObjErrorCode(interp, Tcl_NewStringObj(info->errorCode, -1));
+        ckfree(info->errorCode);
+    }
+
+    /*
+     *  Assign the object result back to the interpreter, then
+     *  release our hold on it.
+     */
+    Tcl_SetObjResult(interp, info->objResult);
+    Tcl_DecrRefCount(info->objResult);
+
+    status = info->status;
+    info->validate = 0;
+    ckfree((char*)info);
+
+    return status;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DiscardInterpState()
+ *
+ *  Frees the memory associated with an interpreter snapshot taken by
+ *  Itcl_SaveInterpState.  If the snapshot is not restored, this
+ *  procedure must be called to discard it, or the memory will be lost.
+ *  After this call, the token for the interpreter state is no longer
+ *  valid.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_DiscardInterpState(state)
+    Itcl_InterpState state;  /* token representing interpreter state */
+{
+    InterpState *info = (InterpState*)state;
+
+    /*
+     * ERR_IN_PROGRESS was replaced by new APIs in 8.5a2.  Call them if they
+     * are available, or somehow magic them in from the stubs table.
+     * Tcl_ChannelThreadActionProc is a stubs slot higher than the APIs we
+     * need, so its existence indicates slot-y goodness.
+     */
+#ifndef ERR_IN_PROGRESS
+    Tcl_DiscardInterpState((Tcl_InterpState)state);
+    return;
+#elif defined(USE_TCL_STUBS) && defined(Tcl_ChannelThreadActionProc)
+    if (itclCompatFlags & ITCL_COMPAT_USE_ISTATE_API) {
+       void (* tcl_DiscardInterpState)() = (void (*)())
+           tclStubsPtr->reserved537;
+       (*tcl_DiscardInterpState)(state);
+       return;
+    }
+#endif
+
+    if (info->validate != TCL_STATE_VALID) {
+        Tcl_Panic("bad token in Itcl_DiscardInterpState");
+    }
+
+    if (info->errorInfo) {
+        ckfree(info->errorInfo);
+    }
+    if (info->errorCode) {
+        ckfree(info->errorCode);
+    }
+    Tcl_DecrRefCount(info->objResult);
+
+    info->validate = 0;
+    ckfree((char*)info);
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_Protection()
+ *
+ *  Used to query/set the protection level used when commands/variables
+ *  are defined within a class.  The default protection level (when
+ *  no public/protected/private command is active) is ITCL_DEFAULT_PROTECT.
+ *  In the default case, new commands are treated as public, while new
+ *  variables are treated as protected.
+ *
+ *  If the specified level is 0, then this procedure returns the
+ *  current value without changing it.  Otherwise, it sets the current
+ *  value to the specified protection level, and returns the previous
+ *  value.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_Protection(interp, newLevel)
+    Tcl_Interp *interp;  /* interpreter being queried */
+    int newLevel;        /* new protection level or 0 */
+{
+    int oldVal;
+    ItclObjectInfo *info;
+
+    /*
+     *  If a new level was specified, then set the protection level.
+     *  In any case, return the protection level as it stands right now.
+     */
+    info = (ItclObjectInfo*) Tcl_GetAssocData(interp, ITCL_INTERP_DATA,
+        (Tcl_InterpDeleteProc**)NULL);
+
+    assert(info != NULL);
+    oldVal = info->protection;
+
+    if (newLevel != 0) {
+        assert(newLevel == ITCL_PUBLIC ||
+            newLevel == ITCL_PROTECTED ||
+            newLevel == ITCL_PRIVATE ||
+            newLevel == ITCL_DEFAULT_PROTECT);
+        info->protection = newLevel;
+    }
+    return oldVal;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ProtectionStr()
+ *
+ *  Converts an integer protection code (ITCL_PUBLIC, ITCL_PROTECTED,
+ *  or ITCL_PRIVATE) into a human-readable character string.  Returns
+ *  a pointer to this string.
+ * ------------------------------------------------------------------------
+ */
+char*
+Itcl_ProtectionStr(pLevel)
+    int pLevel;     /* protection level */
+{
+    switch (pLevel) {
+    case ITCL_PUBLIC:
+        return "public";
+    case ITCL_PROTECTED:
+        return "protected";
+    case ITCL_PRIVATE:
+        return "private";
+    }
+    return "<bad-protection-code>";
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CanAccess()
+ *
+ *  Checks to see if a class member can be accessed from a particular
+ *  namespace context.  Public things can always be accessed.  Protected
+ *  things can be accessed if the "from" namespace appears in the
+ *  inheritance hierarchy of the class namespace.  Private things
+ *  can be accessed only if the "from" namespace is the same as the
+ *  class that contains them.
+ *
+ *  Returns 1/0 indicating true/false.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CanAccess(memberPtr, fromNsPtr)
+    ItclMember* memberPtr;     /* class member being tested */
+    Tcl_Namespace* fromNsPtr;  /* namespace requesting access */
+{
+    ItclClass* fromCdPtr;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  If the protection level is "public" or "private", then the
+     *  answer is known immediately.
+     */
+    if (memberPtr->protection == ITCL_PUBLIC) {
+        return 1;
+    }
+    else if (memberPtr->protection == ITCL_PRIVATE) {
+        return (memberPtr->classDefn->namesp == fromNsPtr);
+    }
+
+    /*
+     *  If the protection level is "protected", then check the
+     *  heritage of the namespace requesting access.  If cdefnPtr
+     *  is in the heritage, then access is allowed.
+     */
+    assert (memberPtr->protection == ITCL_PROTECTED);
+
+    if (Itcl_IsClassNamespace(fromNsPtr)) {
+        fromCdPtr = (ItclClass*)fromNsPtr->clientData;
+
+        entry = Tcl_FindHashEntry(&fromCdPtr->heritage,
+            (char*)memberPtr->classDefn);
+
+        if (entry) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CanAccessFunc()
+ *
+ *  Checks to see if a member function with the specified protection
+ *  level can be accessed from a particular namespace context.  This
+ *  follows the same rules enforced by Itcl_CanAccess, but adds one
+ *  special case:  If the function is a protected method, and if the
+ *  current context is a base class that has the same method, then
+ *  access is allowed.
+ *
+ *  Returns 1/0 indicating true/false.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_CanAccessFunc(mfunc, fromNsPtr)
+    ItclMemberFunc* mfunc;     /* member function being tested */
+    Tcl_Namespace* fromNsPtr;  /* namespace requesting access */
+{
+    ItclClass *cdPtr, *fromCdPtr;
+    ItclMemberFunc *ovlfunc;
+    Tcl_HashEntry *entry;
+
+    /*
+     *  Apply the usual rules first.
+     */
+    if (Itcl_CanAccess(mfunc->member, fromNsPtr)) {
+        return 1;
+    }
+
+    /*
+     *  As a last resort, see if the namespace is really a base
+     *  class of the class containing the method.  Look for a
+     *  method with the same name in the base class.  If there
+     *  is one, then this method overrides it, and the base class
+     *  has access.
+     */
+    if ((mfunc->member->flags & ITCL_COMMON) == 0 &&
+        Itcl_IsClassNamespace(fromNsPtr)) {
+
+        cdPtr = mfunc->member->classDefn;
+        fromCdPtr = (ItclClass*)fromNsPtr->clientData;
+
+        if (Tcl_FindHashEntry(&cdPtr->heritage, (char*)fromCdPtr)) {
+            entry = Tcl_FindHashEntry(&fromCdPtr->resolveCmds,
+                mfunc->member->name);
+
+            if (entry) {
+                ovlfunc = (ItclMemberFunc*)Tcl_GetHashValue(entry);
+                if ((ovlfunc->member->flags & ITCL_COMMON) == 0 &&
+                     ovlfunc->member->protection < ITCL_PRIVATE) {
+                    return 1;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_GetTrueNamespace()
+ *
+ *  Returns the current namespace context.  This procedure is similar
+ *  to Tcl_GetCurrentNamespace, but it supports the notion of
+ *  "transparent" call frames installed by Itcl_HandleInstance.
+ *
+ *  Returns a pointer to the current namespace calling context.
+ * ------------------------------------------------------------------------
+ */
+Tcl_Namespace*
+Itcl_GetTrueNamespace(interp, info)
+    Tcl_Interp *interp;        /* interpreter being queried */
+    ItclObjectInfo *info;      /* object info associated with interp */
+{
+    int i, transparent;
+    Itcl_CallFrame *framePtr, *transFramePtr;
+    Tcl_Namespace *contextNs;
+
+    /*
+     *  See if the current call frame is on the list of transparent
+     *  call frames.
+     */
+    transparent = 0;
+
+    framePtr = _Tcl_GetCallFrame(interp, 0);
+    for (i = Itcl_GetStackSize(&info->transparentFrames)-1; i >= 0; i--) {
+        transFramePtr = (Itcl_CallFrame*)
+            Itcl_GetStackValue(&info->transparentFrames, i);
+
+        if (framePtr == transFramePtr) {
+            transparent = 1;
+            break;
+        }
+    }
+
+    /*
+     *  If this is a transparent call frame, return the namespace
+     *  context one level up.
+     */
+    if (transparent) {
+        framePtr = _Tcl_GetCallFrame(interp, 1);
+        if (framePtr) {
+            contextNs = framePtr->nsPtr;
+        } else {
+            contextNs = Tcl_GetGlobalNamespace(interp);
+        }
+    }
+    else {
+        contextNs = Tcl_GetCurrentNamespace(interp);
+    }
+    return contextNs;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_ParseNamespPath()
+ *
+ *  Parses a reference to a namespace element of the form:
+ *
+ *      namesp::namesp::namesp::element
+ *
+ *  Returns pointers to the head part ("namesp::namesp::namesp")
+ *  and the tail part ("element").  If the head part is missing,
+ *  a NULL pointer is returned and the rest of the string is taken
+ *  as the tail.
+ *
+ *  Both head and tail point to locations within the given dynamic
+ *  string buffer.  This buffer must be uninitialized when passed
+ *  into this procedure, and it must be freed later on, when the
+ *  strings are no longer needed.
+ * ------------------------------------------------------------------------
+ */
+void
+Itcl_ParseNamespPath(name, buffer, head, tail)
+    CONST char *name;    /* path name to class member */
+    Tcl_DString *buffer; /* dynamic string buffer (uninitialized) */
+    char **head;         /* returns "namesp::namesp::namesp" part */
+    char **tail;         /* returns "element" part */
+{
+    register char *sep, *newname;
+
+    Tcl_DStringInit(buffer);
+
+    /*
+     *  Copy the name into the buffer and parse it.  Look
+     *  backward from the end of the string to the first '::'
+     *  scope qualifier.
+     */
+    Tcl_DStringAppend(buffer, name, -1);
+    newname = Tcl_DStringValue(buffer);
+
+    for (sep=newname; *sep != '\0'; sep++)
+        ;
+
+    while (--sep > newname) {
+        if (*sep == ':' && *(sep-1) == ':') {
+            break;
+        }
+    }
+
+    /*
+     *  Found head/tail parts.  If there are extra :'s, keep backing
+     *  up until the head is found.  This supports the Tcl namespace
+     *  behavior, which allows names like "foo:::bar".
+     */
+    if (sep > newname) {
+        *tail = sep+1;
+        while (sep > newname && *(sep-1) == ':') {
+            sep--;
+        }
+        *sep = '\0';
+        *head = newname;
+    }
+
+    /*
+     *  No :: separators--the whole name is treated as a tail.
+     */
+    else {
+        *tail = newname;
+        *head = NULL;
+    }
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_DecodeScopedCommand()
+ *
+ *  Decodes a scoped command of the form:
+ *
+ *      namespace inscope <namesp> <command>
+ *
+ *  If the given string is not a scoped value, this procedure does
+ *  nothing and returns TCL_OK.  If the string is a scoped value,
+ *  then it is decoded, and the namespace, and the simple command
+ *  string are returned as arguments; the simple command should
+ *  be freed when no longer in use.  If anything goes wrong, this
+ *  procedure returns TCL_ERROR, along with an error message in
+ *  the interpreter.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_DecodeScopedCommand(interp, name, rNsPtr, rCmdPtr)
+    Tcl_Interp *interp;                /* current interpreter */
+    CONST char *name;          /* string to be decoded */
+    Tcl_Namespace **rNsPtr;    /* returns: namespace for scoped value */
+    char **rCmdPtr;            /* returns: simple command word */
+{
+    Tcl_Namespace *nsPtr = NULL;
+    char *cmdName;
+    int len = strlen(name);
+    CONST char *pos;
+    int listc, result;
+    char **listv;
+
+    cmdName = ckalloc((unsigned)strlen(name)+1);
+    strcpy(cmdName, name);
+
+    if ((*name == 'n') && (len > 17) && (strncmp(name, "namespace", 9) == 0)) {
+       for (pos = (name + 9);  (*pos == ' ');  pos++) {
+           /* empty body: skip over spaces */
+       }
+       if ((*pos == 'i') && ((pos + 7) <= (name + len))
+               && (strncmp(pos, "inscope", 7) == 0)) {
+
+            result = Tcl_SplitList(interp, (CONST84 char *)name, &listc,
+                   &listv);
+            if (result == TCL_OK) {
+                if (listc != 4) {
+                    Tcl_AppendResult(interp,
+                        "malformed command \"", name, "\": should be \"",
+                        "namespace inscope namesp command\"",
+                        (char*)NULL);
+                    result = TCL_ERROR;
+                } else {
+                    nsPtr = Tcl_FindNamespace(interp, listv[2],
+                        (Tcl_Namespace*)NULL, TCL_LEAVE_ERR_MSG);
+
+                    if (!nsPtr) {
+                        result = TCL_ERROR;
+                    } else {
+                       ckfree(cmdName);
+                        cmdName = ckalloc((unsigned)(strlen(listv[3])+1));
+                        strcpy(cmdName, listv[3]);
+                    }
+                }
+            }
+            ckfree((char*)listv);
+
+            if (result != TCL_OK) {
+                char msg[512];
+                sprintf(msg, "\n    (while decoding scoped command \"%.400s\")", name);
+                Tcl_AddObjErrorInfo(interp, msg, -1);
+                return TCL_ERROR;
+            }
+       }
+    }
+
+    *rNsPtr = nsPtr;
+    *rCmdPtr = cmdName;
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_EvalArgs()
+ *
+ *  This procedure invokes a list of (objc,objv) arguments as a
+ *  single command.  It is similar to Tcl_EvalObj, but it doesn't
+ *  do any parsing or compilation.  It simply treats the first
+ *  argument as a command and invokes that command in the current
+ *  context.
+ *
+ *  Returns TCL_OK if successful.  Otherwise, this procedure returns
+ *  TCL_ERROR along with an error message in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_EvalArgs(interp, objc, objv)
+    Tcl_Interp *interp;      /* current interpreter */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int result;
+    Tcl_Command cmd;
+    Command *cmdPtr;
+    int cmdlinec;
+    Tcl_Obj **cmdlinev;
+    Tcl_Obj *cmdlinePtr = NULL;
+
+    /*
+     * Resolve the command by converting it to a CmdName object.
+     * This caches a pointer to the Command structure for the
+     * command, so if we need it again, it's ready to use.
+     */
+    cmd = Tcl_GetCommandFromObj(interp, objv[0]);
+    cmdPtr = (Command*)cmd;
+
+    cmdlinec = objc;
+    cmdlinev = (Tcl_Obj        **) objv;
+
+    /*
+     * If the command is still not found, handle it with the
+     * "unknown" proc.
+     */
+    if (cmdPtr == NULL) {
+        cmd = Tcl_FindCommand(interp, "unknown",
+            (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
+
+        if (cmd == NULL) {
+            Tcl_ResetResult(interp);
+            Tcl_AppendResult(interp,
+                "invalid command name \"",
+                Tcl_GetStringFromObj(objv[0], NULL), "\"", NULL);
+            return TCL_ERROR;
+        }
+        cmdPtr = (Command*)cmd;
+
+        cmdlinePtr = Itcl_CreateArgs(interp, "unknown", objc, objv);
+        Tcl_ListObjGetElements(NULL, cmdlinePtr, &cmdlinec, &cmdlinev);
+    }
+
+    /*
+     *  Finally, invoke the command's Tcl_ObjCmdProc.  Be careful
+     *  to pass in the proper client data.
+     */
+    Tcl_ResetResult(interp);
+    result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp,
+        cmdlinec, cmdlinev);
+
+    if (cmdlinePtr) {
+        Tcl_DecrRefCount(cmdlinePtr);
+    }
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_CreateArgs()
+ *
+ *  This procedure takes a string and a list of (objc,objv) arguments,
+ *  and glues them together in a single list.  This is useful when
+ *  a command word needs to be prepended or substituted into a command
+ *  line before it is executed.  The arguments are returned in a single
+ *  list object, and they can be retrieved by calling
+ *  Tcl_ListObjGetElements.  When the arguments are no longer needed,
+ *  they should be discarded by decrementing the reference count for
+ *  the list object.
+ *
+ *  Returns a pointer to the list object containing the arguments.
+ * ------------------------------------------------------------------------
+ */
+Tcl_Obj*
+Itcl_CreateArgs(interp, string, objc, objv)
+    Tcl_Interp *interp;      /* current interpreter */
+    CONST char *string;      /* first command word */
+    int objc;                /* number of arguments */
+    Tcl_Obj *CONST objv[];   /* argument objects */
+{
+    int i;
+    Tcl_Obj *listPtr;
+
+    listPtr = Tcl_NewListObj(0, (Tcl_Obj**)NULL);
+    Tcl_ListObjAppendElement((Tcl_Interp*)NULL, listPtr,
+        Tcl_NewStringObj((CONST84 char *)string, -1));
+
+    for (i=0; i < objc; i++) {
+        Tcl_ListObjAppendElement((Tcl_Interp*)NULL, listPtr, objv[i]);
+    }
+
+    Tcl_IncrRefCount(listPtr);
+    return listPtr;
+}
diff --git a/8.x/itcl/itclConfig.sh.in b/8.x/itcl/itclConfig.sh.in
new file mode 100644 (file)
index 0000000..8ef9b06
--- /dev/null
@@ -0,0 +1,62 @@
+# itclConfig.sh --
+# 
+# This shell script (for sh) is generated automatically by Itcl's
+# configure script.  It will create shell variables for most of
+# the configuration options discovered by the configure script.
+# This script is intended to be included by the configure scripts
+# for Itcl extensions so that they don't have to figure this all
+# out for themselves.  This file does not duplicate information
+# already provided by tclConfig.sh, so you may need to use that
+# file in addition to this one.
+#
+# The information in this file is specific to a single platform.
+
+# Itcl's version number.
+itcl_VERSION='@PACKAGE_VERSION@'
+ITCL_VERSION='@PACKAGE_VERSION@'
+
+# The name of the Itcl library (may be either a .a file or a shared library):
+itcl_LIB_FILE=@itcl_LIB_FILE@
+ITCL_LIB_FILE=@itcl_LIB_FILE@
+
+# String to pass to linker to pick up the Itcl library from its
+# build directory.
+itcl_BUILD_LIB_SPEC='@itcl_BUILD_LIB_SPEC@'
+ITCL_BUILD_LIB_SPEC='@itcl_BUILD_LIB_SPEC@'
+
+# String to pass to linker to pick up the Itcl library from its
+# installed directory.
+itcl_LIB_SPEC='@itcl_LIB_SPEC@'
+ITCL_LIB_SPEC='@itcl_LIB_SPEC@'
+
+# The name of the Itcl stub library (a .a file):
+itcl_STUB_LIB_FILE=@itcl_STUB_LIB_FILE@
+ITCL_STUB_LIB_FILE=@itcl_STUB_LIB_FILE@
+
+# String to pass to linker to pick up the Itcl stub library from its
+# build directory.
+itcl_BUILD_STUB_LIB_SPEC='@itcl_BUILD_STUB_LIB_SPEC@'
+ITCL_BUILD_STUB_LIB_SPEC='@itcl_BUILD_STUB_LIB_SPEC@'
+
+# String to pass to linker to pick up the Itcl stub library from its
+# installed directory.
+itcl_STUB_LIB_SPEC='@itcl_STUB_LIB_SPEC@'
+ITCL_STUB_LIB_SPEC='@itcl_STUB_LIB_SPEC@'
+
+# String to pass to linker to pick up the Itcl stub library from its
+# build directory.
+itcl_BUILD_STUB_LIB_PATH='@itcl_BUILD_STUB_LIB_PATH@'
+ITCL_BUILD_STUB_LIB_PATH='@itcl_BUILD_STUB_LIB_PATH@'
+
+# String to pass to linker to pick up the Itcl stub library from its
+# installed directory.
+itcl_STUB_LIB_PATH='@itcl_STUB_LIB_PATH@'
+ITCL_STUB_LIB_PATH='@itcl_STUB_LIB_PATH@'
+
+# Location of the top-level source directories from which [incr Tcl]
+# was built.  This is the directory that contains generic, unix, etc.
+# If [incr Tcl] was compiled in a different place than the directory
+# containing the source files, this points to the location of the sources,
+# not the location where [incr Tcl] was compiled.
+itcl_SRC_DIR='@itcl_SRC_DIR@'
+ITCL_SRC_DIR='@itcl_SRC_DIR@'
diff --git a/8.x/itcl/library/itcl.tcl b/8.x/itcl/library/itcl.tcl
new file mode 100644 (file)
index 0000000..db5698c
--- /dev/null
@@ -0,0 +1,278 @@
+#
+# itcl.tcl
+# ----------------------------------------------------------------------
+# Invoked automatically upon startup to customize the interpreter
+# for [incr Tcl].
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: itcl.tcl,v 1.12 2009/10/14 20:53:34 hobbs Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+proc ::itcl::delete_helper { name args } {
+    ::itcl::delete object $name
+}
+
+# ----------------------------------------------------------------------
+#  USAGE:  local <className> <objName> ?<arg> <arg>...?
+#
+#  Creates a new object called <objName> in class <className>, passing
+#  the remaining <arg>'s to the constructor.  Unlike the usual
+#  [incr Tcl] objects, however, an object created by this procedure
+#  will be automatically deleted when the local call frame is destroyed.
+#  This command is useful for creating objects that should only remain
+#  alive until a procedure exits.
+# ----------------------------------------------------------------------
+proc ::itcl::local {class name args} {
+    set ptr [uplevel [list $class $name] $args]
+    uplevel [list set itcl-local-$ptr $ptr]
+    set cmd [uplevel namespace which -command $ptr]
+    uplevel [list trace variable itcl-local-$ptr u \
+        "::itcl::delete_helper $cmd"]
+    return $ptr
+}
+
+# ----------------------------------------------------------------------
+# auto_mkindex
+# ----------------------------------------------------------------------
+# Define Itcl commands that will be recognized by the auto_mkindex
+# parser in Tcl...
+#
+
+#
+# USAGE:  itcl::class name body
+# Adds an entry for the given class declaration.
+#
+foreach cmd {itcl::class class} {
+    auto_mkindex_parser::command $cmd {name body} {
+       variable index
+       variable scriptFile
+       append index "set [list auto_index([fullname $name])]"
+       append index " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+
+       variable parser
+       variable contextStack
+       set contextStack [linsert $contextStack 0 $name]
+       $parser eval $body
+       set contextStack [lrange $contextStack 1 end]
+    }
+}
+
+#
+# USAGE:  itcl::body name arglist body
+# Adds an entry for the given method/proc body.
+#
+foreach cmd {itcl::body body} {
+    auto_mkindex_parser::command $cmd {name arglist body} {
+       variable index
+       variable scriptFile
+       append index "set [list auto_index([fullname $name])]"
+       append index " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+    }
+}
+
+#
+# USAGE:  itcl::configbody name arglist body
+# Adds an entry for the given method/proc body.
+#
+foreach cmd {itcl::configbody configbody} {
+    auto_mkindex_parser::command $cmd {name body} {
+       variable index
+       variable scriptFile
+       append index "set [list auto_index([fullname $name])]"
+       append index " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+    }
+}
+
+#
+# USAGE:  ensemble name ?body?
+# Adds an entry to the auto index list for the given ensemble name.
+#
+foreach cmd {itcl::ensemble ensemble} {
+    auto_mkindex_parser::command $cmd {name {body ""}} {
+       variable index
+       variable scriptFile
+       append index "set [list auto_index([fullname $name])]"
+       append index " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+    }
+}
+
+#
+# USAGE:  public arg ?arg arg...?
+#         protected arg ?arg arg...?
+#         private arg ?arg arg...?
+#
+# Evaluates the arguments as commands, so we can recognize proc
+# declarations within classes.
+#
+foreach cmd {public protected private} {
+    auto_mkindex_parser::command $cmd {args} {
+        variable parser
+        $parser eval $args
+    }
+}
+
+# ----------------------------------------------------------------------
+# auto_import
+# ----------------------------------------------------------------------
+# This procedure overrides the usual "auto_import" function in the
+# Tcl library.  It is invoked during "namespace import" to make see
+# if the imported commands reside in an autoloaded library.  If so,
+# stubs are created to represent the commands.  Executing a stub
+# later on causes the real implementation to be autoloaded.
+#
+# Arguments -
+# pattern      The pattern of commands being imported (like "foo::*")
+#               a canonical namespace as returned by [namespace current]
+
+proc auto_import {pattern} {
+    global auto_index
+
+    set ns [uplevel namespace current]
+    set patternList [auto_qualify $pattern $ns]
+
+    auto_load_index
+
+    foreach pattern $patternList {
+        foreach name [array names auto_index $pattern] {
+            if {"" == [info commands $name]} {
+                ::itcl::import::stub create $name
+            }
+        }
+    }
+}
+
+# ----------------------------------------------------------------------
+# itcl_class, itcl_info
+# ----------------------------------------------------------------------
+# Compat handling for itcl_class/info, set for auto_index loading only
+#
+# Only need to convert public/protected usage.
+# Uses Tcl 8.4+ coding style
+#
+
+if {([llength [info commands itcl_class]] == 0)
+    && [package vsatisfies $::tcl_version 8.4]} {
+    proc ::itcl::CmdSplit {body} {
+       # DGP's command split
+       set commands {}
+       set chunk ""
+       foreach line [split $body "\n"] {
+           append chunk $line
+           if {[info complete "$chunk\n"]} {
+               # $chunk ends in a complete Tcl command, and none of the
+               # newlines within it end a complete Tcl command.  If there
+               # are multiple Tcl commands in $chunk, they must be
+               # separated by semi-colons.
+               set cmd ""
+               foreach part [split $chunk ";"] {
+                   append cmd $part
+                   if {[info complete "$cmd\n"]} {
+                       set cmd [string trimleft $cmd]
+                       # Drop empty commands and comments
+                       if {($cmd ne "") && ![string match #* $cmd]} {
+                           lappend commands $cmd
+                       }
+                       if {[string match #* $cmd]} {
+                           set cmd "#;"
+                       } else {
+                           set cmd ""
+                       }
+                   } else {
+                       # No complete command yet.
+                       # Replace semicolon and continue
+                       append cmd ";"
+                   }
+               }
+               set chunk ""
+           } else {
+               # No end of command yet.  Put the newline back and continue
+               append chunk "\n"
+           }
+       }
+       if {[string trim $chunk] ne ""} {
+           return -code error "Can't parse body into a\
+                sequence of commands.\n\tIncomplete command:\n$chunk"
+       }
+       return $commands
+    }
+
+    proc ::itcl::itcl_class {className body} {
+       # inherit baseClass ?baseClass...? ; # no change
+       # constructor args ?init? body     ; # no change
+       # destructor body                  ; # no change
+       # method name args body            ; # no change
+       # proc name args body              ; # no change
+       # common varName ?init?            ; # no change
+       # public varName ?init? ?config?   ; # variable ...
+       # protected varName ?init?         ; # variable ... (?)
+       set cmds [::itcl::CmdSplit $body]
+       set newcmds [list]
+       foreach cmd $cmds {
+           if {![catch {lindex $cmd 0} firstcmd]} {
+               if {$firstcmd eq "public" || $firstcmd eq "protected"} {
+                   set cmd [linsert $cmd 1 "variable"]
+               }
+           }
+           append newcmds "$cmd\n"
+       }
+       return [uplevel 1 [list ::itcl::class $className $newcmds]]
+    }
+    set ::auto_index(itcl_class) [list interp alias {} ::itcl_class {} ::itcl::itcl_class]
+    set ::auto_index(itcl_info) [list interp alias {} ::itcl_info {} ::itcl::find]
+}
+
+# ----------------------------------------------------------------------
+# [namespace inscope]
+# ----------------------------------------------------------------------
+# Modify [unknown] to handle Itcl's usage of [namespace inscope]
+#
+
+namespace eval ::itcl {
+    variable UNKNOWN_ADD_84 {
+       #######################################################################
+       # ADDED BY Itcl
+       # Itcl requires special handling for [namespace inscope]
+       #
+       set cmd [lindex $args 0]
+       if {[regexp "^:*namespace\[ \t\n\]+inscope" $cmd] && [llength $cmd] == 4} {
+
+           set arglist [lrange $args 1 end]
+           set ret [catch {uplevel 1 ::$cmd $arglist} result]
+           if {$ret == 0} {
+               return $result
+           } else {
+               return -code $ret -errorcode $::errorCode $result
+           }
+       }
+       #######################################################################
+    }
+    variable UNKNOWN_ADD_85 {
+       #######################################################################
+       # ADDED BY Itcl
+       # Itcl requires special handling for [namespace inscope]
+       #
+       set cmd [lindex $args 0]
+       if {[regexp "^:*namespace\[ \t\n\]+inscope" $cmd] && [llength $cmd] == 4} {
+           #return -code error "You need an {*}"
+           set arglist [lrange $args 1 end]
+           set ret [catch {uplevel 1 ::$cmd $arglist} result opts]
+           dict unset opts -errorinfo
+           dict incr opts -level
+           return -options $opts $result
+       }
+       #######################################################################
+    }
+    if {[package vsatisfies [package provide Tcl] 8.5]} {
+       proc ::unknown args "$UNKNOWN_ADD_85\n[info body ::unknown]"
+    } else {
+       proc ::unknown args "$UNKNOWN_ADD_84\n[info body ::unknown]"
+    }
+}
diff --git a/8.x/itcl/license.terms b/8.x/itcl/license.terms
new file mode 100644 (file)
index 0000000..b76171b
--- /dev/null
@@ -0,0 +1,38 @@
+This software is copyrighted by Lucent Technologies, Inc., and other
+parties.  The following terms apply to all files associated with the
+software unless explicitly disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+GOVERNMENT USE: If you are acquiring this software on behalf of the
+U.S. government, the Government shall have only "Restricted Rights"
+in the software and related documentation as defined in the Federal 
+Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
+are acquiring the software on behalf of the Department of Defense, the
+software shall be classified as "Commercial Computer Software" and the
+Government shall have only "Restricted Rights" as defined in Clause
+252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
+authors grant the U.S. Government and others acting in its behalf
+permission to use and distribute the software in accordance with the
+terms specified in this license. 
diff --git a/8.x/itcl/pkgIndex.tcl.in b/8.x/itcl/pkgIndex.tcl.in
new file mode 100644 (file)
index 0000000..c8d3d0e
--- /dev/null
@@ -0,0 +1,3 @@
+# Tcl package index file, version 1.0
+
+package ifneeded Itcl @PACKAGE_VERSION@ [list load [file join $dir "@PKG_LIB_FILE@"] Itcl]
diff --git a/8.x/itcl/tclconfig/install-sh b/8.x/itcl/tclconfig/install-sh
new file mode 100755 (executable)
index 0000000..0ff4b6a
--- /dev/null
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+       echo "install:  no destination specified"
+       exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+       dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/8.x/itcl/tclconfig/tcl.m4 b/8.x/itcl/tclconfig/tcl.m4
new file mode 100644 (file)
index 0000000..d0fd999
--- /dev/null
@@ -0,0 +1,4031 @@
+# tcl.m4 --
+#
+#      This file provides a set of autoconf macros to help TEA-enable
+#      a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: tcl.m4,v 1.9 2007/02/15 23:32:40 hobbs Exp $
+
+AC_PREREQ(2.57)
+
+dnl TEA extensions pass us the version of TEA they think they
+dnl are compatible with (must be set in TEA_INIT below)
+dnl TEA_VERSION="3.6"
+
+# Possible values for key variables defined:
+#
+# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
+# TEA_PLATFORM        - windows unix
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+#      Locate the tclConfig.sh file and perform a sanity check on
+#      the Tcl compile flags
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tcl=...
+#
+#      Defines the following vars:
+#              TCL_BIN_DIR     Full path to the directory containing
+#                              the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+       AC_ARG_WITH(tcl,
+           AC_HELP_STRING([--with-tcl],
+               [directory containing tcl configuration (tclConfig.sh)]),
+           with_tclconfig=${withval})
+       AC_MSG_CHECKING([for Tcl configuration])
+       AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           AC_MSG_WARN([Can't find Tcl configuration definitions])
+           exit 0
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+#      Locate the tkConfig.sh file
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tk=...
+#
+#      Defines the following vars:
+#              TK_BIN_DIR      Full path to the directory containing
+#                              the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+    #
+    # Ok, lets find the tk configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tk
+    #
+
+    if test x"${no_tk}" = x ; then
+       # we reset no_tk in case something fails here
+       no_tk=true
+       AC_ARG_WITH(tk,
+           AC_HELP_STRING([--with-tk],
+               [directory containing tk configuration (tkConfig.sh)]),
+           with_tkconfig=${withval})
+       AC_MSG_CHECKING([for Tk configuration])
+       AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+           # First check to see if --with-tkconfig was specified.
+           if test x"${with_tkconfig}" != x ; then
+               case ${with_tkconfig} in
+                   */tkConfig.sh )
+                       if test -f ${with_tkconfig}; then
+                           AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+                           with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tkconfig}/tkConfig.sh" ; then
+                   ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tk library
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ../tk \
+                       `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tk \
+                       `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tk \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tk.framework/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tk \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tkconfig}" = x ; then
+           TK_BIN_DIR="# no Tk configs found"
+           AC_MSG_WARN([Can't find Tk configuration definitions])
+           exit 0
+       else
+           no_tk=
+           TK_BIN_DIR=${ac_cv_c_tkconfig}
+           AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+#      Load the tclConfig.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              TCL_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              TCL_BIN_DIR
+#              TCL_SRC_DIR
+#              TCL_LIB_FILE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . ${TCL_BIN_DIR}/tclConfig.sh
+    else
+        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f ${TCL_BIN_DIR}/Makefile ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f ${TCL_BIN_DIR}/${TCL_LIB_FILE}; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+    AC_SUBST(TCL_VERSION)
+    AC_SUBST(TCL_BIN_DIR)
+    AC_SUBST(TCL_SRC_DIR)
+
+    AC_SUBST(TCL_LIB_FILE)
+    AC_SUBST(TCL_LIB_FLAG)
+    AC_SUBST(TCL_LIB_SPEC)
+
+    AC_SUBST(TCL_STUB_LIB_FILE)
+    AC_SUBST(TCL_STUB_LIB_FLAG)
+    AC_SUBST(TCL_STUB_LIB_SPEC)
+
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(TCL_DEFS)
+    AC_SUBST(TCL_EXTRA_CFLAGS)
+    AC_SUBST(TCL_LD_FLAGS)
+    AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+#      Load the tkConfig.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              TK_BIN_DIR
+#
+# Results:
+#
+#      Sets the following vars that should be in tkConfig.sh:
+#              TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . ${TK_BIN_DIR}/tkConfig.sh
+    else
+        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+    # If the TK_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TK_LIB_SPEC will be set to the value
+    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+    # instead of TK_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f ${TK_BIN_DIR}/Makefile ; then
+        TK_LIB_SPEC=${TK_BUILD_LIB_SPEC}
+        TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC}
+        TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tk was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tk.framework installed in an arbitary location.
+       case ${TK_DEFS} in
+           *TK_FRAMEWORK*)
+               if test -f ${TK_BIN_DIR}/${TK_LIB_FILE}; then
+                   for i in "`cd ${TK_BIN_DIR}; pwd`" \
+                            "`cd ${TK_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+                           TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}; then
+                   TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}"
+                   TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+    # Ensure windowingsystem is defined
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       case ${TK_DEFS} in
+           *MAC_OSX_TK*)
+               AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+               TEA_WINDOWINGSYSTEM="aqua"
+               ;;
+           *)
+               TEA_WINDOWINGSYSTEM="x11"
+               ;;
+       esac
+    elif test "${TEA_PLATFORM}" = "windows" ; then
+       TEA_WINDOWINGSYSTEM="win32"
+    fi
+
+    AC_SUBST(TK_VERSION)
+    AC_SUBST(TK_BIN_DIR)
+    AC_SUBST(TK_SRC_DIR)
+
+    AC_SUBST(TK_LIB_FILE)
+    AC_SUBST(TK_LIB_FLAG)
+    AC_SUBST(TK_LIB_SPEC)
+
+    AC_SUBST(TK_STUB_LIB_FILE)
+    AC_SUBST(TK_STUB_LIB_FLAG)
+    AC_SUBST(TK_STUB_LIB_SPEC)
+
+    AC_SUBST(TK_LIBS)
+    AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+#      Allows the building of shared libraries
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-shared=yes|no
+#
+#      Defines the following vars:
+#              STATIC_BUILD    Used for building import/export libraries
+#                              on Windows.
+#
+#      Sets the following vars:
+#              SHARED_BUILD    Value of 1 or 0
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SHARED], [
+    AC_MSG_CHECKING([how to build libraries])
+    AC_ARG_ENABLE(shared,
+       AC_HELP_STRING([--enable-shared],
+           [build and link with shared libraries (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       AC_MSG_RESULT([shared])
+       SHARED_BUILD=1
+    else
+       AC_MSG_RESULT([static])
+       SHARED_BUILD=0
+       AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
+    fi
+    AC_SUBST(SHARED_BUILD)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+#      Specify if thread support should be enabled.  If "yes" is specified
+#      as an arg (optional), threads are enabled by default, "no" means
+#      threads are disabled.  "yes" is the default.
+#
+#      TCL_THREADS is checked so that if you are compiling an extension
+#      against a threaded core, your extension must be compiled threaded
+#      as well.
+#
+#      Note that it is legal to have a thread enabled extension run in a
+#      threaded or non-threaded Tcl core, but a non-threaded extension may
+#      only run in a non-threaded Tcl core.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-threads
+#
+#      Sets the following vars:
+#              THREADS_LIBS    Thread library(s)
+#
+#      Defines the following vars:
+#              TCL_THREADS
+#              _REENTRANT
+#              _THREAD_SAFE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+    AC_ARG_ENABLE(threads,
+       AC_HELP_STRING([--enable-threads],
+           [build with threads]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+    
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+           AC_DEFINE(USE_THREAD_ALLOC, 1,
+               [Do we want to use the threaded memory allocator?])
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           if test "`uname -s`" = "SunOS" ; then
+               AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+                       [Do we really want to follow the standard? Yes we do!])
+           fi
+           AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+           AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               AC_CHECK_LIB(pthread, __pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               AC_CHECK_LIB(pthreads, pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   AC_CHECK_LIB(c, pthread_mutex_init,
+                       tcl_ok=yes, tcl_ok=no)
+                   if test "$tcl_ok" = "no"; then
+                       AC_CHECK_LIB(c_r, pthread_mutex_init,
+                           tcl_ok=yes, tcl_ok=no)
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    AC_MSG_CHECKING([for building with threads])
+    if test "${TCL_THREADS}" = 1; then
+       AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+       AC_MSG_RESULT([yes (default)])
+    else
+       AC_MSG_RESULT([no])
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               AC_MSG_WARN([
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads.])
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               AC_MSG_WARN([
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core.])
+           fi
+           ;;
+    esac
+    AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+#      Specify if debugging symbols should be used.
+#      Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+#      none
+#      
+#      TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+#      the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+#      Requires the following vars to be set in the Makefile:
+#              CFLAGS_DEFAULT
+#              LDFLAGS_DEFAULT
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-symbols
+#
+#      Defines the following vars:
+#              CFLAGS_DEFAULT  Sets to $(CFLAGS_DEBUG) if true
+#                              Sets to $(CFLAGS_OPTIMIZE) if false
+#              LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+#                              Sets to $(LDFLAGS_OPTIMIZE) if false
+#              DBGX            Formerly used as debug library extension;
+#                              always blank now.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_CONFIG_CFLAGS])
+    AC_MSG_CHECKING([for build with symbols])
+    AC_ARG_ENABLE(symbols,
+       AC_HELP_STRING([--enable-symbols],
+           [build with debugging symbols (default: off)]),
+       [tcl_ok=$enableval], [tcl_ok=no])
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       AC_MSG_RESULT([no])
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           AC_MSG_RESULT([yes (standard debugging)])
+       fi
+    fi
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+    AC_SUBST(TCL_DBGX)
+    AC_SUBST(CFLAGS_DEFAULT)
+    AC_SUBST(LDFLAGS_DEFAULT)
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+       AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           AC_MSG_RESULT([enabled symbols mem debugging])
+       else
+           AC_MSG_RESULT([enabled $tcl_ok debugging])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+#      Allows use of modern nl_langinfo check for better l10n.
+#      This is only relevant for Unix.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-langinfo=yes|no (default is yes)
+#
+#      Defines the following vars:
+#              HAVE_LANGINFO   Triggers use of nl_langinfo if defined.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+    AC_ARG_ENABLE(langinfo,
+       AC_HELP_STRING([--enable-langinfo],
+           [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+       [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+    HAVE_LANGINFO=0
+    if test "$langinfo_ok" = "yes"; then
+       AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+    fi
+    AC_MSG_CHECKING([whether to use nl_langinfo])
+    if test "$langinfo_ok" = "yes"; then
+       AC_CACHE_VAL(tcl_cv_langinfo_h, [
+           AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+                   [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+       AC_MSG_RESULT([$tcl_cv_langinfo_h])
+       if test $tcl_cv_langinfo_h = yes; then
+           AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+       fi
+    else 
+       AC_MSG_RESULT([$langinfo_ok])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+#      Determine what the system is (some things cannot be easily checked
+#      on a feature-driven basis, alas). This can usually be done via the
+#      "uname" command, but there are a few systems, like Next, where
+#      this doesn't work.
+#
+# Arguments:
+#      none
+#
+# Results:
+#      Defines the following var:
+#
+#      system -        System/platform/version identification code.
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               AC_MSG_WARN([can't find uname command])
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+    ])
+    system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+#      Try to determine the proper flags to pass to the compiler
+#      for building shared libraries and other such nonsense.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substitutes the following vars:
+#
+#       DL_OBJS -       Name of the object file that implements dynamic
+#                       loading for Tcl on this system.
+#       DL_LIBS -       Library file(s) to include in tclsh and other base
+#                       applications in order for the "load" command to work.
+#       LDFLAGS -      Flags to pass to the compiler when linking object
+#                       files into an executable application binary such
+#                       as tclsh.
+#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
+#                       be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+#       CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile.
+#       SHLIB_CFLAGS -  Flags to pass to cc when compiling the components
+#                       of a shared library (may request position-independent
+#                       code, among other things).
+#       SHLIB_LD -      Base command to use for combining object files
+#                       into a shared library.
+#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+#                       creating shared libraries.  This symbol typically
+#                       goes at the end of the "ld" commands that build
+#                       shared libraries. The value of the symbol is
+#                       "${LIBS}" if all of the dependent libraries should
+#                       be specified when creating a shared library.  If
+#                       dependent libraries should not be specified (as on
+#                       SunOS 4.x, where they cause the link to fail, or in
+#                       general if Tcl and Tk aren't themselves shared
+#                       libraries), then this symbol has an empty string
+#                       as its value.
+#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
+#                       extensions.  An empty string means we don't know how
+#                       to use shared libraries on this platform.
+#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
+#                       in a static or shared library name, using the $VERSION variable
+#                       to put the version in the right place.  This is used
+#                       by platforms that need non-standard library names.
+#                       Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
+#                       to have a version after the .so, and ${VERSION}.a
+#                       on AIX, since a shared library needs to have
+#                       a .a extension whereas shared objects for loadable
+#                       extensions have a .so extension.  Defaults to
+#                       ${VERSION}${SHLIB_SUFFIX}.
+#       TCL_NEEDS_EXP_FILE -
+#                       1 means that an export file is needed to link to a
+#                       shared library.
+#       TCL_EXP_FILE -  The name of the installed export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#       TCL_BUILD_EXP_FILE -
+#                       The name of the built export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#      CFLAGS_DEBUG -
+#                      Flags used when running the compiler in debug mode
+#      CFLAGS_OPTIMIZE -
+#                      Flags used when running the compiler in optimize mode
+#      CFLAGS -        Additional CFLAGS added as necessary (usually 64-bit)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+
+    # Step 0.a: Enable 64 bit support?
+
+    AC_MSG_CHECKING([if 64bit support is requested])
+    AC_ARG_ENABLE(64bit,
+       AC_HELP_STRING([--enable-64bit],
+           [enable 64bit support (default: off)]),
+       [do64bit=$enableval], [do64bit=no])
+    AC_MSG_RESULT([$do64bit])
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+    AC_ARG_ENABLE(64bit-vis,
+       AC_HELP_STRING([--enable-64bit-vis],
+           [enable 64bit Sparc VIS support (default: off)]),
+       [do64bitVIS=$enableval], [do64bitVIS=no])
+    AC_MSG_RESULT([$do64bitVIS])
+
+    if test "$do64bitVIS" = "yes"; then
+       # Force 64bit on with VIS
+       do64bit=yes
+    fi
+
+    # Step 0.c: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       AC_MSG_CHECKING([if Windows/CE build is requested])
+       AC_ARG_ENABLE(wince,[  --enable-wince          enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no])
+       AC_MSG_RESULT([$doWince])
+    fi
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+    TEA_CONFIG_SYSTEM
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
+
+    # Require ranlib early so we can override it in special cases below.
+
+    AC_REQUIRE([AC_PROG_RANLIB])
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    if test "$GCC" = "yes" ; then
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall -Wno-implicit-int"
+    else
+       CFLAGS_WARNING=""
+    fi
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
+dnl AC_CHECK_TOOL(AR, ar)
+    AC_CHECK_PROG(AR, ar, ar)
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    case $system in
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+                   AC_MSG_WARN([Ensure latest Platform SDK is installed])
+                   do64bit="no"
+               else
+                   AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+               fi
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+               fi
+               TEA_PATH_CELIB
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+           if ([$]1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+           if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+           if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+                   TEA_ADD_LIBS([bufferoverflowU.lib])
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+                       AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+                   done
+                   AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+                   AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+                   AC_SUBST(CELIB_DIR)
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r)
+                       # ok ...
+                       ;;
+                   *)
+                       CC=${CC}_r
+                       ;;
+               esac
+               AC_MSG_RESULT([Using $CC for compiling with threads])
+           fi
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_WARN([64bit mode not supported with GCC on $system])
+               else 
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+               fi
+           fi
+
+           if test "`uname -m`" = "ia64" ; then
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               if test "$GCC" = "yes" ; then
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               else
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+               fi
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           else
+               if test "$GCC" = "yes" ; then
+                   SHLIB_LD="gcc -shared"
+               else
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+               fi
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+           fi
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
+               AC_LIBOBJ([tclLoadAix])
+               DL_LIBS="-lld"
+           fi
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
+           if test $libbsd = yes; then
+               MATH_LIBS="$MATH_LIBS -lbsd"
+               AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
+           fi
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -nostart"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD="cc -shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+           AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+           # Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           if test "`uname -m`" = "ia64" ; then
+               SHLIB_SUFFIX=".so"
+           else
+               SHLIB_SUFFIX=".sl"
+           fi
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="gcc -shared"
+               SHLIB_LD_LIBS='${LIBS}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+
+           # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+           #CFLAGS="$CFLAGS +DAportable"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   hpux_arch=`${CC} -dumpmachine`
+                   case $hpux_arch in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD="${CC} -shared"
+                           SHLIB_LD_LIBS='${LIBS}'
+                           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           AC_MSG_WARN([64bit mode not supported with GCC on $system])
+                           ;;
+                   esac
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+               fi
+           fi
+           ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+           else
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+           fi
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_WARN([64bit mode not supported by gcc])
+               else
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               fi
+           fi
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           if test $do64bit = yes; then
+               AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+                   CFLAGS=$hold_cflags])
+               if test $tcl_cv_cc_m64 = yes; then
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+               fi
+           fi
+
+           # The combo of gcc + glibc has a bug related
+           # to inlining of functions like strtod(). The
+           # -fno-builtin flag should address this problem
+           # but it does not work. The -fno-inline flag
+           # is kind of overkill but it works.
+           # Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+           if test x"${USE_COMPAT}" != x ; then
+               CFLAGS="$CFLAGS -fno-inline"
+           fi
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD="${CC} -shared"
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD="${CC} -shared "
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-*|FreeBSD-[[1-2]].*)
+           # NetBSD/SPARC needs -fPIC, -fpic will not do.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           if test $tcl_cv_ld_elf = yes; then
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+           else
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           fi
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
+           case `machine` in
+           sparc|sparc64)
+               SHLIB_CFLAGS="-fPIC";;
+           *)
+               SHLIB_CFLAGS="-fpic";;
+           esac
+           SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           if test $tcl_cv_ld_elf = yes; then
+               LDFLAGS=-Wl,-export-dynamic
+           else
+               LDFLAGS=""
+           fi
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       FreeBSD-*)
+           # FreeBSD 3.* and greater have ELF.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "${TCL_THREADS}" = "1" ; then
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+           fi
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           # To avoid discrepancies between what headers configure sees during
+           # preprocessing tests and compiling tests, move any -isysroot and
+           # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+           CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
+           CFLAGS="`echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
+           if test $do64bit = yes; then
+               case `arch` in
+                   ppc)
+                       AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+                               tcl_cv_cc_arch_ppc64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+                                   tcl_cv_cc_arch_ppc64=no)
+                           CFLAGS=$hold_cflags])
+                       if test $tcl_cv_cc_arch_ppc64 = yes; then
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+                       fi;;
+                   i386)
+                       AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+                               tcl_cv_cc_arch_x86_64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+                                   tcl_cv_cc_arch_x86_64=no)
+                           CFLAGS=$hold_cflags])
+                       if test $tcl_cv_cc_arch_x86_64 = yes; then
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+                       fi;;
+                   *)
+                       AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+               esac
+           else
+               # Check for combined 32-bit and 64-bit fat build
+               echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
+                   echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
+                   fat_32_64=yes
+           fi
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_single_module = yes; then
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+           fi
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+               "`echo "${CFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4 && \
+               LDFLAGS="$LDFLAGS -prebind"
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_search_paths_first = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+
+           # TEA specific: for Tk extensions, remove 64-bit arch flags from
+           # CFLAGS for combined 32-bit and 64-bit fat builds as neither TkAqua
+           # nor TkX11 can be built for 64-bit at present.
+           test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}" && \
+               CFLAGS="`echo "$CFLAGS " | sed -e 's/-arch ppc64 / /g' -e 's/-arch x86_64 / /g'`"
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="cc -nostdlib -r"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+           AC_DEFINE(_OE_SOCKETS, 1,   # needed in sys/socket.h
+               [Should OS/390 do the right thing with sockets?])
+           ;;      
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export $@:'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD="ld -shared"
+           else
+               SHLIB_LD="ld -non_shared"
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+           else
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mieee"
+            else
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+           fi
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           if test "${TCL_THREADS}" = "1" ; then
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               if test "$GCC" = "yes" ; then
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+               else
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+               fi
+           fi
+
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           if test "$GCC" = "yes" ; then
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+           else
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+           fi
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[[0-6]])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               arch=`isainfo`
+               if test "$arch" = "sparcv9 sparc" ; then
+                       if test "$GCC" = "yes" ; then
+                           if test "`gcc -dumpversion | awk -F. '{print [$]1}'`" -lt "3" ; then
+                               AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+                           else
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                               LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                               SHLIB_CFLAGS="-fPIC"
+                           fi
+                       else
+                           do64bit_ok=yes
+                           if test "$do64bitVIS" = "yes" ; then
+                               CFLAGS="$CFLAGS -xarch=v9a"
+                               LDFLAGS_ARCH="-xarch=v9a"
+                           else
+                               CFLAGS="$CFLAGS -xarch=v9"
+                               LDFLAGS_ARCH="-xarch=v9"
+                           fi
+                           # Solaris 64 uses this as well
+                           #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+                       fi
+               elif test "$arch" = "amd64 i386" ; then
+                   if test "$GCC" = "yes" ; then
+                       AC_MSG_WARN([64bit mode not supported with GCC on $system])
+                   else
+                       do64bit_ok=yes
+                       CFLAGS="$CFLAGS -xarch=amd64"
+                       LDFLAGS="$LDFLAGS -xarch=amd64"
+                   fi
+               else
+                   AC_MSG_WARN([64bit mode not supported for $arch])
+               fi
+           fi
+           
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               if test "$do64bit_ok" = "yes" ; then
+                   # We need to specify -static-libgcc or we need to
+                   # add the path to the sparv9 libgcc.
+                   # JH: static-libgcc is necessary for core Tcl, but may
+                   # not be necessary for extensions.
+                   SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                   # for finding sparcv9 libgcc, get the regular libgcc
+                   # path, remove so name and append 'sparcv9'
+                   #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                   #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+               fi
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           fi
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_Bexport = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
+       AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+    fi
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    AC_ARG_ENABLE(load,
+       AC_HELP_STRING([--enable-load],
+           [allow dynamic loading and "load" command (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+    if test "$tcl_ok" = "no"; then
+       DL_OBJS=""
+    fi
+
+    if test "x$DL_OBJS" != "x" ; then
+       BUILD_DLTEST="\$(DLTEST_TARGETS)"
+    else
+       echo "Can't figure out how to do dynamic loading or shared libraries"
+       echo "on this system."
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+    fi
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$DL_OBJS" != "tclLoadNone.o" ; then
+       if test "$GCC" = "yes" ; then
+           case $system in
+               AIX-*)
+                   ;;
+               BSD/OS*)
+                   ;;
+               IRIX*)
+                   ;;
+               NetBSD-*|FreeBSD-*)
+                   ;;
+               Darwin-*)
+                   ;;
+               SCO_SV-3.2*)
+                   ;;
+               windows)
+                   ;;
+               *)
+                   SHLIB_CFLAGS="-fPIC"
+                   ;;
+           esac
+       fi
+    fi
+
+    if test "$SHARED_LIB_SUFFIX" = "" ; then
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+    fi
+    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+    fi
+
+    AC_SUBST(DL_LIBS)
+
+    AC_SUBST(CFLAGS_DEBUG)
+    AC_SUBST(CFLAGS_OPTIMIZE)
+    AC_SUBST(CFLAGS_WARNING)
+
+    AC_SUBST(STLIB_LD)
+    AC_SUBST(SHLIB_LD)
+
+    AC_SUBST(SHLIB_LD_LIBS)
+    AC_SUBST(SHLIB_CFLAGS)
+
+    AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+    TEA_TCL_EARLY_FLAGS
+    TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+#      Determine which interface to use to talk to the serial port.
+#      Note that #include lines must begin in leftmost column for
+#      some compilers to recognize them as preprocessor directives,
+#      and some build environments have stdin not pointing at a
+#      pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines only one of the following vars:
+#              HAVE_SYS_MODEM_H
+#              USE_TERMIOS
+#              USE_TERMIO
+#              USE_SGTTY
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+    AC_CHECK_HEADERS(sys/modem.h)
+    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+    AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+    }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+    fi])
+    case $tcl_cv_api_serial in
+       termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+       termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+       sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_MISSING_POSIX_HEADERS
+#
+#      Supply substitutes for missing POSIX header files.  Special
+#      notes:
+#          - stdlib.h doesn't define strtol, strtoul, or
+#            strtod insome versions of SunOS
+#          - some versions of string.h don't declare procedures such
+#            as strstr
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              NO_DIRENT_H
+#              NO_ERRNO_H
+#              NO_VALUES_H
+#              HAVE_LIMITS_H or NO_LIMITS_H
+#              NO_STDLIB_H
+#              NO_STRING_H
+#              NO_SYS_WAIT_H
+#              NO_DLFCN_H
+#              HAVE_SYS_PARAM_H
+#
+#              HAVE_STRING_H ?
+#
+# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+# CHECK on limits.h
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
+    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
+    AC_TRY_LINK([#include <sys/types.h>
+#include <dirent.h>], [
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
+
+    if test $tcl_cv_dirent_h = no; then
+       AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
+    fi
+
+    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
+    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
+    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
+    AC_CHECK_HEADER(limits.h,
+       [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
+       [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
+    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
+    fi
+    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
+    fi
+
+    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
+    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+    AC_HAVE_HEADERS(sys/param.h)
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+#      Locate the X11 header files and the X11 library archive.  Try
+#      the ac_path_x macro first, but if it doesn't find the X stuff
+#      (e.g. because there's no xmkmf program) then check through
+#      a list of possible directories.  Under some conditions the
+#      autoconf macro will return an include directory that contains
+#      no include files, so double-check its result just to be safe.
+#
+#      This should be called after TEA_CONFIG_CFLAGS as setting the
+#      LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Sets the following vars:
+#              XINCLUDES
+#              XLIBSW
+#              PKG_LIBS (appends to)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+       TEA_PATH_UNIX_X
+    fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+    AC_PATH_X
+    not_really_there=""
+    if test "$no_x" = ""; then
+       if test "$x_includes" = ""; then
+           AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
+       else
+           if test ! -r $x_includes/X11/Intrinsic.h; then
+               not_really_there="yes"
+           fi
+       fi
+    fi
+    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+       AC_MSG_CHECKING([for X11 header files])
+       found_xincludes="no"
+       AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
+       if test "$found_xincludes" = "no"; then
+           dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+           for i in $dirs ; do
+               if test -r $i/X11/Intrinsic.h; then
+                   AC_MSG_RESULT([$i])
+                   XINCLUDES=" -I$i"
+                   found_xincludes="yes"
+                   break
+               fi
+           done
+       fi
+    else
+       if test "$x_includes" != ""; then
+           XINCLUDES="-I$x_includes"
+           found_xincludes="yes"
+       fi
+    fi
+    if test found_xincludes = "no"; then
+       AC_MSG_RESULT([couldn't find any!])
+    fi
+
+    if test "$no_x" = yes; then
+       AC_MSG_CHECKING([for X11 libraries])
+       XLIBSW=nope
+       dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+       for i in $dirs ; do
+           if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then
+               AC_MSG_RESULT([$i])
+               XLIBSW="-L$i -lX11"
+               x_libraries="$i"
+               break
+           fi
+       done
+    else
+       if test "$x_libraries" = ""; then
+           XLIBSW=-lX11
+       else
+           XLIBSW="-L$x_libraries -lX11"
+       fi
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_MSG_RESULT([could not find any!  Using -lX11.])
+       XLIBSW=-lX11
+    fi
+    if test x"${XLIBSW}" != x ; then
+       PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+#      The statements below check for systems where POSIX-style
+#      non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
+#      On these systems (mostly older ones), use the old BSD-style
+#      FIONBIO approach instead.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              HAVE_SYS_IOCTL_H
+#              HAVE_SYS_FILIO_H
+#              USE_FIONBIO
+#              O_NONBLOCK
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+    AC_CHECK_HEADERS(sys/ioctl.h)
+    AC_CHECK_HEADERS(sys/filio.h)
+    TEA_CONFIG_SYSTEM
+    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+    case $system in
+       # There used to be code here to use FIONBIO under AIX.  However, it
+       # was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
+       # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
+       # code (JO, 5/31/97).
+
+       OSF*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       SunOS-4*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       *)
+           AC_MSG_RESULT([O_NONBLOCK])
+           ;;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANLDER
+#
+#      Checks how the system deals with time.h, what time structures
+#      are used on the system, and what fields the structures have.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              USE_DELTA_FOR_TZ
+#              HAVE_TM_GMTOFF
+#              HAVE_TM_TZADJ
+#              HAVE_TIMEZONE_VAR
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+    AC_CHECK_HEADERS(sys/time.h)
+    AC_HEADER_TIME
+    AC_STRUCT_TIMEZONE
+
+    AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+           tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+    if test $tcl_cv_member_tm_tzadj = yes ; then
+       AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+    fi
+
+    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+           tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+    if test $tcl_cv_member_tm_gmtoff = yes ; then
+       AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+    fi
+
+    #
+    # Its important to include time.h in this check, as some systems
+    # (like convex) have timezone functions, etc.
+    #
+    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+       AC_TRY_COMPILE([#include <time.h>],
+           [extern long timezone;
+           timezone += 1;
+           exit (0);],
+           tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+    if test $tcl_cv_timezone_long = yes ; then
+       AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+    else
+       #
+       # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+       #
+       AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+           AC_TRY_COMPILE([#include <time.h>],
+               [extern time_t timezone;
+               timezone += 1;
+               exit (0);],
+               tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+       if test $tcl_cv_timezone_time = yes ; then
+           AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+#      Under Solaris 2.4, strtod returns the wrong value for the
+#      terminating character under some conditions.  Check for this
+#      and if the problem exists use a substitute procedure
+#      "fixstrtod" (provided by Tcl) that corrects the error.
+#      Also, on Compaq's Tru64 Unix 5.0,
+#      strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Might defines some of the following vars:
+#              strtod (=fixstrtod)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+    if test "$tcl_strtod" = 1; then
+       AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+           AC_TRY_RUN([
+               extern double strtod();
+               int main() {
+                   char *infString="Inf", *nanString="NaN", *spaceString=" ";
+                   char *term;
+                   double value;
+                   value = strtod(infString, &term);
+                   if ((term != infString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(nanString, &term);
+                   if ((term != nanString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(spaceString, &term);
+                   if (term == (spaceString+1)) {
+                       exit(1);
+                   }
+                   exit(0);
+               }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+                   tcl_cv_strtod_buggy=buggy)])
+       if test "$tcl_cv_strtod_buggy" = buggy; then
+           AC_LIBOBJ([fixstrtod])
+           USE_COMPAT=1
+           AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_LINK_LIBS
+#
+#      Search for the libraries needed to link the Tcl shell.
+#      Things like the math library (-lm) and socket stuff (-lsocket vs.
+#      -lnsl) are dealt with here.
+#
+# Arguments:
+#      Requires the following vars to be set in the Makefile:
+#              DL_LIBS
+#              LIBS
+#              MATH_LIBS
+#      
+# Results:
+#
+#      Subst's the following var:
+#              TCL_LIBS
+#              MATH_LIBS
+#
+#      Might append to the following vars:
+#              LIBS
+#
+#      Might define the following vars:
+#              HAVE_NET_ERRNO_H
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_LINK_LIBS], [
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+    AC_CHECK_HEADER(net/errno.h, [
+       AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+    if test "$tcl_checkSocket" = 1; then
+       AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
+           LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
+    fi
+    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
+           [LIBS="$LIBS -lnsl"])])
+    
+    # Don't perform the eval of the libraries here because DL_LIBS
+    # won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(MATH_LIBS)
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+#      Check for what flags are needed to be passed so the correct OS
+#      features are available.
+#
+# Arguments:
+#      None
+#      
+# Results:
+#
+#      Might define the following vars:
+#              _ISOC99_SOURCE
+#              _LARGEFILE64_SOURCE
+#              _LARGEFILE_SOURCE64
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+       AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+           AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+       AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+       tcl_flags="$tcl_flags $1"
+    fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+    AC_MSG_CHECKING([for required early compiler flags])
+    tcl_flags=""
+    TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+       [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+       [struct stat64 buf; int i = stat64("/", &buf);])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+       [char *p = (char *)open64;])
+    if test "x${tcl_flags}" = "x" ; then
+       AC_MSG_RESULT([none])
+    else
+       AC_MSG_RESULT([${tcl_flags}])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+#      Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+#      None
+#      
+# Results:
+#
+#      Might define the following vars:
+#              TCL_WIDE_INT_IS_LONG
+#              TCL_WIDE_INT_TYPE
+#              HAVE_STRUCT_DIRENT64
+#              HAVE_STRUCT_STAT64
+#              HAVE_TYPE_OFF64_T
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+    AC_MSG_CHECKING([for 64-bit integer type])
+    AC_CACHE_VAL(tcl_cv_type_64bit,[
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+           tcl_type_64bit=__int64, tcl_type_64bit="long long")
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        AC_TRY_COMPILE(,[switch (0) { 
+            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; 
+        }],tcl_cv_type_64bit=${tcl_type_64bit})])
+    if test "${tcl_cv_type_64bit}" = none ; then
+       AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+       AC_MSG_RESULT([using long])
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # We actually want to use the default tcl.h checks in this
+       # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       AC_MSG_RESULT([using Tcl header defaults])
+    else
+       AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+           [What type should be used to define wide integers?])
+       AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+       # Now check for auxiliary declarations
+       AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+           AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/dirent.h>],[struct dirent64 p;],
+               tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+       fi
+
+       AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+           AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+               tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+       fi
+
+       AC_CHECK_FUNCS(open64 lseek64)
+       AC_MSG_CHECKING([for off64_t])
+       AC_CACHE_VAL(tcl_cv_type_off64_t,[
+           AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+               tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+       dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+       dnl functions lseek64 and open64 are defined.
+       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+           AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+           AC_MSG_RESULT([yes])
+       else
+           AC_MSG_RESULT([no])
+       fi
+    fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+#      Init various Tcl Extension Architecture (TEA) variables.
+#      This should be the first called TEA_* macro.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              CYGPATH
+#              EXEEXT
+#      Defines only:
+#              TEA_VERSION
+#              TEA_INITED
+#              TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+#      Select the executable extension based on the host type.  This
+#      is a lightweight replacement for AC_EXEEXT that doesn't require
+#      a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.6"
+
+    AC_MSG_CHECKING([for correct TEA configuration])
+    if test x"${PACKAGE_NAME}" = x ; then
+       AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.in])
+    fi
+    if test x"$1" = x ; then
+       AC_MSG_ERROR([
+TEA version not specified.])
+    elif test "$1" != "${TEA_VERSION}" ; then
+       AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
+    else
+       AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+           AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+    AC_SUBST(EXEEXT)
+    AC_SUBST(CYGPATH)
+
+    # This package name must be replaced statically for AC_SUBST to work
+    AC_SUBST(PKG_LIB_FILE)
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+    AC_SUBST(PKG_STUB_LIB_FILE)
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+    AC_SUBST(PKG_TCL_SOURCES)
+    AC_SUBST(PKG_HEADERS)
+    AC_SUBST(PKG_INCLUDES)
+    AC_SUBST(PKG_LIBS)
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_SOURCES
+#              PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       case $i in
+           [\$]*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   AC_MSG_ERROR([could not find source file '$i'])
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+    AC_SUBST(PKG_SOURCES)
+    AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_STUB_SOURCES
+#              PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           AC_MSG_ERROR([could not find stub source file '$i'])
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+#      Specify one or more Tcl source files.  These should be platform
+#      independent runtime files.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+    AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+#      Specify one or more source headers.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+    AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+#      Specify one or more include dirs.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+    vars="$@"
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+    AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+#      Specify one or more libraries.  Users should check for
+#      the right platform before adding to their list.  For Windows,
+#      libraries provided in "foo.lib" format will be converted to
+#      "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+    vars="$@"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+    AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+#      Specify one or more CFLAGS.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+    PKG_CFLAGS="$PKG_CFLAGS $@"
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+#      Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      If --prefix or --exec-prefix was not specified, $prefix and
+#      $exec_prefix will be set to the values given to Tcl when it was
+#      configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+           prefix=${TCL_PREFIX}
+       else
+           AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+           exec_prefix=$prefix
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+#      Do compiler checks the way we want.  This is just a replacement
+#      for AC_PROG_CC in TEA configure.in files to make them cleaner.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    AC_PROG_CC
+    AC_PROG_CPP
+
+    AC_PROG_INSTALL
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    AC_PROG_MAKE_SET
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    AC_PROG_RANLIB
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+    AC_OBJEXT
+    AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+#      Do compiler checks that use the compiler.  This must go after
+#      TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+    AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       AC_CACHE_CHECK([if the compiler understands -pipe],
+           tcl_cv_cc_pipe, [
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+           CFLAGS=$hold_cflags])
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    AC_C_BIGENDIAN
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       TEA_TCL_LINK_LIBS
+       TEA_MISSING_POSIX_HEADERS
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+#      Generate a line that can be used to build a shared/unshared library
+#      in a platform independent manner.
+#
+# Arguments:
+#      none
+#
+#      Requires:
+#
+# Results:
+#
+#      Defines the following vars:
+#      CFLAGS -        Done late here to note disturb other AC macros
+#       MAKE_LIB -      Command to execute to build the Tcl library;
+#                       differs depending on whether or not Tcl is being
+#                       compiled as a shared library.
+#      MAKE_SHARED_LIB Makefile rule for building a shared library
+#      MAKE_STATIC_LIB Makefile rule for building a static library
+#      MAKE_STUB_LIB   Makefile rule for building a stub library
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+    AC_SUBST(MAKE_LIB)
+    AC_SUBST(MAKE_SHARED_LIB)
+    AC_SUBST(MAKE_STATIC_LIB)
+    AC_SUBST(MAKE_STUB_LIB)
+    AC_SUBST(RANLIB_STUB)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+#      Compute the name of an existing object library located in libdir
+#      from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+#      basename        The base name of the library without version
+#                      numbers, extensions, or "lib" prefixes.
+#      extra_dir       Extra directory in which to search for the
+#                      library.  This location is used first, then
+#                      $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+#      TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+#      Defines the following vars:
+#              ${basename}_LIB_NAME    The computed library name.
+#              ${basename}_LIB_SPEC    The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+    AC_MSG_CHECKING([for $1 library])
+
+    # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+    tea_lib_name_dir="${exec_prefix}/lib"
+
+    # Or in a user-specified location.
+
+    if test x"$2" != x ; then
+       tea_extra_lib_dir=$2
+    else
+       tea_extra_lib_dir=NONE
+    fi
+
+    for i in \
+           `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+       if test -f "$i" ; then
+           tea_lib_name_dir=`dirname $i`
+           $1_LIB_NAME=`basename $i`
+           $1_LIB_PATH_NAME=$i
+           break
+       fi
+    done
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+    else
+       # Strip off the leading "lib" and trailing ".a" or ".so"
+
+       tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+       $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+    fi
+
+    if test "x${$1_LIB_NAME}" = x ; then
+       AC_MSG_ERROR([not found])
+    else
+       AC_MSG_RESULT([${$1_LIB_SPEC}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+#      Locate the private Tcl include files
+#
+# Arguments:
+#
+#      Requires:
+#              TCL_SRC_DIR     Assumes that TEA_LOAD_TCLCONFIG has
+#                               already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TCL_TOP_DIR_NATIVE
+#              TCL_GENERIC_DIR_NATIVE
+#              TCL_UNIX_DIR_NATIVE
+#              TCL_WIN_DIR_NATIVE
+#              TCL_BMAP_DIR_NATIVE
+#              TCL_TOOL_DIR_NATIVE
+#              TCL_PLATFORM_DIR_NATIVE
+#              TCL_BIN_DIR_NATIVE
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl private include files])
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+    TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+    TCL_UNIX_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+    TCL_WIN_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+    TCL_BMAP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/bitmaps\"
+    TCL_TOOL_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/tools\"
+    TCL_COMPAT_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/compat\"
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       TCL_PLATFORM_DIR_NATIVE=${TCL_WIN_DIR_NATIVE}
+    else
+       TCL_PLATFORM_DIR_NATIVE=${TCL_UNIX_DIR_NATIVE}
+    fi
+    # We want to ensure these are substituted so as not to require
+    # any *_NATIVE vars be defined in the Makefile
+    TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+    if test "`uname -s`" = "Darwin"; then
+        # If Tcl was built as a framework, attempt to use
+        # the framework's Headers and PrivateHeaders directories
+        case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -d "${TCL_BIN_DIR}/Headers" -a -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+               TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"; else
+               TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"; fi
+               ;;
+       esac
+    else
+       if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+           AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+       fi
+    fi
+
+
+    AC_SUBST(TCL_TOP_DIR_NATIVE)
+    AC_SUBST(TCL_GENERIC_DIR_NATIVE)
+    AC_SUBST(TCL_UNIX_DIR_NATIVE)
+    AC_SUBST(TCL_WIN_DIR_NATIVE)
+    AC_SUBST(TCL_BMAP_DIR_NATIVE)
+    AC_SUBST(TCL_TOOL_DIR_NATIVE)
+    AC_SUBST(TCL_PLATFORM_DIR_NATIVE)
+
+    AC_SUBST(TCL_INCLUDES)
+    AC_MSG_RESULT([Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+#      Locate the installed public Tcl header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tclinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl public headers])
+
+    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tclh, [
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       AC_MSG_ERROR([tcl.h not found.  Please specify its location with --with-tclinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tclh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+#      Locate the private Tk include files
+#
+# Arguments:
+#
+#      Requires:
+#              TK_SRC_DIR      Assumes that TEA_LOAD_TKCONFIG has
+#                               already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk private include files])
+
+    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+    TK_UNIX_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+    TK_WIN_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+    TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+    TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+    if test "${TEA_PLATFORM}" = "windows"; then
+       TK_PLATFORM_DIR_NATIVE=${TK_WIN_DIR_NATIVE}
+    else
+       TK_PLATFORM_DIR_NATIVE=${TK_UNIX_DIR_NATIVE}
+    fi
+    # We want to ensure these are substituted so as not to require
+    # any *_NATIVE vars be defined in the Makefile
+    TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
+       -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       TK_INCLUDES="${TK_INCLUDES} -I${TK_XLIB_DIR_NATIVE}"
+    fi
+    if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       TK_INCLUDES="${TK_INCLUDES} -I${TK_SRC_DIR_NATIVE}/macosx"
+    fi
+    if test "`uname -s`" = "Darwin"; then
+        # If Tk was built as a framework, attempt to use
+        # the framework's Headers and PrivateHeaders directories
+        case ${TK_DEFS} in
+           *TK_FRAMEWORK*)
+               if test -d "${TK_BIN_DIR}/Headers" -a -d "${TK_BIN_DIR}/PrivateHeaders"; then
+               TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"; fi
+               ;;
+       esac
+    else
+       if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+           AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+       fi
+    fi
+
+    AC_SUBST(TK_TOP_DIR_NATIVE)
+    AC_SUBST(TK_UNIX_DIR_NATIVE)
+    AC_SUBST(TK_WIN_DIR_NATIVE)
+    AC_SUBST(TK_GENERIC_DIR_NATIVE)
+    AC_SUBST(TK_XLIB_DIR_NATIVE)
+    AC_SUBST(TK_PLATFORM_DIR_NATIVE)
+
+    AC_SUBST(TK_INCLUDES)
+    AC_MSG_RESULT([Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+#      Locate the installed public Tk header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tkinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk public headers])
+
+    AC_ARG_WITH(tkinclude, [  --with-tkinclude      directory containing the public Tk header files.], with_tkinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tkh, [
+       # Use the value from --with-tkinclude, if it was given
+
+       if test x"${with_tkinclude}" != x ; then
+           if test -f "${with_tkinclude}/tk.h" ; then
+               ac_cv_c_tkh=${with_tkinclude}
+           else
+               AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tk was built as a framework, attempt to use
+               # the framework's Headers directory.
+               case ${TK_DEFS} in
+                   *TK_FRAMEWORK*)
+                       list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tk is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TK_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tk's --prefix location,
+           # relative to directory of tkConfig.sh, Tcl's --prefix location, 
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TK_PREFIX}/include      2>/dev/null` \
+               `ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+           fi
+           for i in $list ; do
+               if test -f "$i/tk.h" ; then
+                   ac_cv_c_tkh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tkh}" = x ; then
+       AC_MSG_ERROR([tk.h not found.  Please specify its location with --with-tkinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tkh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TK_INCLUDES)
+
+    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
+       -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       # On Windows and Aqua, we need the X compat headers
+       AC_MSG_CHECKING([for X11 header files])
+       if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+           INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+           TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+           AC_SUBST(TK_XINCLUDES)
+       fi
+       AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+#      Determine the fully qualified path name of the tclsh executable
+#      in the Tcl build directory or the tclsh installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the tclsh executable even if tclsh has not yet been
+#      built in the build directory. The tclsh found is always
+#      associated with a tclConfig.sh file. This tclsh should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+    AC_MSG_CHECKING([for tclsh])
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}"
+    fi
+    AC_MSG_RESULT([${TCLSH_PROG}])
+    AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+#      Determine the fully qualified path name of the wish executable
+#      in the Tk build directory or the wish installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the wish executable even if wish has not yet been
+#      built in the build directory. The wish found is always
+#      associated with a tkConfig.sh file. This wish should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+    AC_MSG_CHECKING([for wish])
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        # tkConfig.sh is in Tk build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="${TK_BIN_DIR}/wish"
+        fi
+    else
+        # tkConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+        fi
+        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${WISH_PROG}" ; then
+                REAL_TK_BIN_DIR="`cd "$i"; pwd`"
+                break
+            fi
+        done
+        WISH_PROG="${REAL_TK_BIN_DIR}/${WISH_PROG}"
+    fi
+    AC_MSG_RESULT([${WISH_PROG}])
+    AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+#      Locate the ${1}Config.sh file and perform a sanity check on
+#      the ${1} compile flags.  These are used by packages like
+#      [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-$1=...
+#
+#      Defines the following vars:
+#              $1_BIN_DIR      Full path to the directory containing
+#                              the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+    #
+    # Ok, lets find the $1 configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-$1
+    #
+
+    if test x"${no_$1}" = x ; then
+       # we reset no_$1 in case something fails here
+       no_$1=true
+       AC_ARG_WITH($1, [  --with-$1              directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+       AC_MSG_CHECKING([for $1 configuration])
+       AC_CACHE_VAL(ac_cv_c_$1config,[
+
+           # First check to see if --with-$1 was specified.
+           if test x"${with_$1config}" != x ; then
+               case ${with_$1config} in
+                   */$1Config.sh )
+                       if test -f ${with_$1config}; then
+                           AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+                           with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+                       fi;;
+               esac
+               if test -f "${with_$1config}/$1Config.sh" ; then
+                   ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+               fi
+           fi
+
+           # then check for a private $1 installation
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in \
+                       ../$1 \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../$1 \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../$1 \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../$1 \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+                   if test -f "$i/unix/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_$1config}" = x ; then
+           $1_BIN_DIR="# no $1 configs found"
+           AC_MSG_WARN([Cannot find $1 configuration definitions])
+           exit 0
+       else
+           no_$1=
+           $1_BIN_DIR=${ac_cv_c_$1config}
+           AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+#      Load the $1Config.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              $1_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              $1_SRC_DIR
+#              $1_LIB_FILE
+#              $1_LIB_SPEC
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+        AC_MSG_RESULT([loading])
+       . ${$1_BIN_DIR}/$1Config.sh
+    else
+        AC_MSG_RESULT([file not found])
+    fi
+
+    #
+    # If the $1_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable $1_LIB_SPEC will be set to the value
+    # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+    # instead of $1_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    #
+
+    if test -f ${$1_BIN_DIR}/Makefile ; then
+       AC_MSG_WARN([Found Makefile - using build library specs for $1])
+        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+    fi
+
+    AC_SUBST($1_VERSION)
+    AC_SUBST($1_BIN_DIR)
+    AC_SUBST($1_SRC_DIR)
+
+    AC_SUBST($1_LIB_FILE)
+    AC_SUBST($1_LIB_SPEC)
+
+    AC_SUBST($1_STUB_LIB_FILE)
+    AC_SUBST($1_STUB_LIB_SPEC)
+    AC_SUBST($1_STUB_LIB_PATH)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+#      Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-celib=...
+#
+#      Defines the following vars:
+#              CELIB_DIR       Full path to the directory containing
+#                              the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+       AC_ARG_WITH(celib,[  --with-celib=DIR        use Windows/CE support library from DIR], with_celibconfig=${withval})
+       AC_MSG_CHECKING([for Windows/CE celib directory])
+       AC_CACHE_VAL(ac_cv_c_celibconfig,[
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           AC_MSG_ERROR([Cannot find celib support library directory])
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           AC_MSG_RESULT([found $CELIB_DIR])
+       fi
+    fi
+])
+
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/8.x/itcl/tests/all.tcl b/8.x/itcl/tests/all.tcl
new file mode 100755 (executable)
index 0000000..df81f64
--- /dev/null
@@ -0,0 +1,17 @@
+# all.tcl --
+#
+# This file contains a top-level script to run all of the Tcl
+# tests.  Execute it by invoking "source all.test" when running tcltest
+# in this directory.
+#
+# Copyright (c) 1998-2000 by Ajuba Solutions
+# All rights reserved.
+# 
+# RCS: @(#) $Id: all.tcl,v 1.5 2004/02/12 18:26:18 davygrvy Exp $
+
+package require tcltest 2.1
+
+tcltest::testsDirectory [file dir [info script]]
+tcltest::runAllTests
+
+return
diff --git a/8.x/itcl/tests/basic.test b/8.x/itcl/tests/basic.test
new file mode 100644 (file)
index 0000000..273cc8a
--- /dev/null
@@ -0,0 +1,407 @@
+#
+# Basic tests for class definition and method/proc access
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: basic.test,v 1.12 2007/07/03 20:46:44 hobbs Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+test basic-1.0 {empty string as class name should fail but not crash} {
+    list [catch {itcl::class "" {}} err] $err
+} {1 {invalid class name ""}}
+
+# ----------------------------------------------------------------------
+#  Simple class definition
+# ----------------------------------------------------------------------
+test basic-1.1 {define a simple class} {
+    itcl::class Counter {
+        constructor {args} {
+            incr num
+            eval configure $args
+        }
+        destructor {
+            incr num -1
+        }
+
+        method ++ {} {
+            return [incr val $by]
+        }
+        proc num {} {
+            return $num
+        }
+        public variable by 1
+        protected variable val 0
+        private common num 0
+    }
+} ""
+
+test basic-1.2 {class is now defined} {
+    itcl::find classes Counter
+} {Counter}
+
+test basic-1.3 {access command exists with class name} {
+    namespace which -command Counter
+} {::Counter}
+
+test basic-1.4 {create a simple object} {
+    Counter x
+} {x}
+
+test basic-1.5a {object names cannot be duplicated} {
+    list [catch "Counter x" msg] $msg
+} {1 {command "x" already exists in namespace "::"}}
+
+test basic-1.5b {built-in commands cannot be clobbered} {
+    list [catch "Counter info" msg] $msg
+} {1 {command "info" already exists in namespace "::"}}
+
+test basic-1.6 {objects have an access command} {
+    namespace which -command x
+} {::x}
+
+test basic-1.7a {objects are added to the master list} {
+    itcl::find objects x
+} {x}
+
+test basic-1.7b {objects are added to the master list} {
+    itcl::find objects -class Counter x
+} {x}
+
+test basic-1.8 {objects can be deleted} {
+    list [itcl::delete object x] [namespace which -command x]
+} {{} {}}
+
+test basic-1.9 {objects can be recreated with the same name} {
+    Counter x
+} {x}
+
+test basic-1.10 {objects can be destroyed by deleting their access command} {
+    rename ::x ""
+    itcl::find objects x
+} {}
+
+test basic-1.11 {find command supports object names starting with -} {
+    Counter -foo
+    itcl::find objects -class Counter -foo
+} {-foo}
+test basic-1.12 {is command with class argument} {
+    itcl::is class Counter
+} {1}
+
+test basic-1.13 {is command with class argument (global namespace)} {
+    itcl::is class ::Counter
+} {1}
+
+test basic-1.14 {is command with class argument (wrapped in code command)} {
+    itcl::is class [itcl::code Counter]
+} {1}
+
+test basic-1.15 {is command with class argument (class does not exist)} {
+    itcl::is class Count
+} {0}
+
+test basic-1.16 {is command with object argument} {
+    itcl::is object -foo
+} {1}
+
+test basic-1.17 {is command with object argument (object does not exist)} {
+    itcl::is object xxx
+} {0}
+
+test basic-1.18 {is command with object argument (with code command)} {
+    itcl::is object [itcl::code -- -foo]
+} {1}
+
+test basic-1.19 {classes can be unicode} {
+    itcl::class \u6210bcd { method foo args { return "bar" } }
+    \u6210bcd #auto
+} \u6210bcd0
+test basic-1.20 {classes can be unicode} {
+    \u6210bcd0 foo
+} bar
+
+# ----------------------------------------------------------------------
+#  #auto names
+# ----------------------------------------------------------------------
+test basic-2.1 {create an object with an automatic name} {
+    Counter #auto
+} {counter0}
+
+test basic-2.2 {bury "#auto" within object name} {
+    Counter x#autoy
+} {xcounter1y}
+
+test basic-2.3 {bury "#auto" within object name} {
+    Counter a#aut#autob
+} {a#autcounter2b}
+
+test basic-2.4 {"#auto" is smart enough to skip names that are taken} {
+    Counter counter3
+    Counter #auto
+} {counter4}
+
+test basic-2.5 {"#auto" with :: at front of name} {
+    itcl::class AutoCheck {}
+    set result [AutoCheck ::#auto]
+    rename AutoCheck {}
+    set result
+} {::autoCheck0}
+
+test basic-2.6 {"#auto" with :: at front of name inside method} {
+    itcl::class AutoCheck {
+        proc new {} {
+            return [AutoCheck ::#auto]
+        }
+    }
+    set result [AutoCheck::new]
+    rename AutoCheck {}
+    set result
+} {::autoCheck0}
+
+test basic-2.7 {"#auto" with :: at front of name inside method inside namespace} {
+    namespace eval AutoCheckNs {}
+    itcl::class AutoCheckNs::AutoCheck {
+        proc new {} {
+            return [AutoCheckNs::AutoCheck ::#auto]
+        }
+    }
+    set result [AutoCheckNs::AutoCheck::new]
+    namespace delete AutoCheckNs
+    set result
+} {::autoCheck0}
+
+# ----------------------------------------------------------------------
+#  Simple object use
+# ----------------------------------------------------------------------
+test basic-3.1 {object access command works} {
+    Counter c
+    list [c ++] [c ++] [c ++]
+} {1 2 3}
+
+test basic-3.2 {errors produce usage info} {
+    list [catch "c xyzzy" msg] $msg
+} {1 {bad option "xyzzy": should be one of...
+  c ++
+  c cget -option
+  c configure ?-option? ?value -option value...?
+  c isa className}}
+
+test basic-3.3 {built-in configure can query public variables} {
+    c configure
+} {{-by 1 1}}
+
+test basic-3.4 {built-in configure can query one public variable} {
+    c configure -by
+} {-by 1 1}
+
+test basic-3.5 {built-in configure can set public variable} {
+    list [c configure -by 2] [c cget -by]
+} {{} 2}
+
+test basic-3.6 {configure actually changes public variable} {
+    list [c ++] [c ++]
+} {5 7}
+
+test basic-3.7 {class procs can be accessed} {
+    Counter::num
+} {7}
+
+test basic-3.8 {obsolete syntax is no longer allowed} {
+    list [catch "Counter :: num" msg] $msg
+} {1 {syntax "class :: proc" is an anachronism
+[incr Tcl] no longer supports this syntax.
+Instead, remove the spaces from your procedure invocations:
+  Counter::num ?args?}}
+
+# ----------------------------------------------------------------------
+#  Classes can be destroyed and redefined
+# ----------------------------------------------------------------------
+test basic-4.1 {classes can be destroyed} {
+    list [itcl::delete class Counter] \
+         [itcl::find classes Counter] \
+         [namespace children :: Counter] \
+         [namespace which -command Counter]
+} {{} {} {} {}}
+
+test basic-4.2 {classes can be redefined} {
+    itcl::class Counter {
+        method ++ {} {
+            return [incr val $by]
+        }
+        public variable by 1
+        protected variable val 0
+    }
+} {}
+
+test basic-4.3 {the redefined class is actually different} {
+    list [catch "Counter::num" msg] $msg
+} {1 {invalid command name "Counter::num"}}
+
+test basic-4.4 {objects can be created from the new class} {
+    list [Counter #auto] [Counter #auto]
+} {counter0 counter1}
+
+test basic-4.5 {namespaces for #auto are prepended to the command name} {
+    namespace eval someNS1 {}
+    namespace eval someNS2 {}
+    list [Counter someNS1::#auto] [Counter someNS2::#auto]
+} [list someNS1::counter2 someNS2::counter3]
+
+test basic-4.6 {when a class is destroyed, its objects are deleted} {
+    list [lsort [itcl::find objects counter*]] \
+         [itcl::delete class Counter] \
+         [lsort [itcl::find objects counter*]]
+} {{counter0 counter1} {} {}}
+
+# ----------------------------------------------------------------------
+#  Namespace variables
+# ----------------------------------------------------------------------
+test basic-5.1 {define a simple class with variables in the namespace} {
+    itcl::class test_globals {
+        common g1 "global1"
+        proc getval {name} {
+            variable $name
+            return [set [namespace tail $name]]
+        }
+        proc setval {name val} {
+            variable $name
+            return [set [namespace tail $name] $val]
+        }
+        method do {args} {
+            return [eval $args]
+        }
+    }
+    namespace eval test_globals {
+        variable g2 "global2"
+    }
+} ""
+
+test basic-5.2 {create an object for the tests} {
+    test_globals #auto
+} {test_globals0}
+
+test basic-5.3 {common variables live in the namespace} {
+    lsort [info vars ::test_globals::*]
+} {::test_globals::g1 ::test_globals::g2}
+
+test basic-5.4 {common variables can be referenced transparently} {
+    list [catch {test_globals0 do set g1} msg] $msg
+} {0 global1}
+
+test basic-5.5 {namespace variables require a declaration} {
+    list [catch {test_globals0 do set g2} msg] $msg
+} {1 {can't read "g2": no such variable}}
+
+test basic-5.6a {variable accesses variables within namespace} {
+    list [catch {test_globals::getval g1} msg] $msg
+} {0 global1}
+
+test basic-5.6a {variable accesses variables within namespace} {
+    list [catch {test_globals::getval g2} msg] $msg
+} {0 global2}
+
+test basic-5.7 {variable command will not find vars in other namespaces} {
+    set ::test_global_0 "g0"
+    list [catch {test_globals::getval test_global_0} msg] $msg \
+         [catch {test_globals::getval ::test_global_0} msg] $msg \
+} {1 {can't read "test_global_0": no such variable} 0 g0}
+
+test basic-5.8 {to create globals in a namespace, use the full path} {
+    test_globals::setval ::test_global_1 g1
+    namespace eval :: {lsort [info globals test_global_*]}
+} {test_global_0 test_global_1}
+
+test basic-5.9 {variable names can have ":" in them} {
+    test_globals::setval ::test:global:2 g2
+    namespace eval :: {info globals test:global:2}
+} {test:global:2}
+
+# ----------------------------------------------------------------------
+#  Array variables
+# ----------------------------------------------------------------------
+test basic-6.1 {set up a class definition with array variables} {
+    proc test_arrays_get {name} {
+        upvar $name x
+        set rlist {}
+        foreach index [lsort [array names x]] {
+            lappend rlist [list $index $x($index)]
+        }
+        return $rlist
+    }
+    itcl::class test_arrays {
+        variable nums
+        common undefined
+
+        common colors
+        set colors(red)   #ff0000
+        set colors(green) #00ff00
+        set colors(blue)  #0000ff
+
+        constructor {} {
+            set nums(one) 1
+            set nums(two) 2
+            set nums(three) 3
+
+            set undefined(a) A
+            set undefined(b) B
+        }
+        method do {args} {
+            return [eval $args]
+        }
+    }
+    test_arrays #auto
+} {test_arrays0}
+
+test basic-6.2 {test array access for instance variables} {
+    lsort [test_arrays0 do array get nums]
+} {1 2 3 one three two}
+
+test basic-6.3 {test array access for commons} {
+    lsort [test_arrays0 do array get colors]
+} [list #0000ff #00ff00 #ff0000 blue green red]
+
+test basic-6.4 {test array access for instance variables via "upvar"} {
+    test_arrays0 do test_arrays_get nums
+} {{one 1} {three 3} {two 2}}
+
+test basic-6.5 {test array access for commons via "upvar"} {
+    test_arrays0 do test_arrays_get colors
+} {{blue #0000ff} {green #00ff00} {red #ff0000}}
+
+test basic-6.6a {test array access for commons defined in constructor} {
+    lsort [test_arrays0 do array get undefined]
+} {A B a b}
+
+test basic-6.6b {test array access for commons defined in constructor} {
+    test_arrays0 do test_arrays_get undefined
+} {{a A} {b B}}
+
+test basic-6.6c {test array access for commons defined in constructor} {
+    list [test_arrays0 do set undefined(a)] [test_arrays0 do set undefined(b)]
+} {A B}
+
+test basic-6.7 {common variables can be unset} {
+    test_arrays0 do unset undefined
+    test_arrays0 do array names undefined
+} {}
+
+test basic-6.8 {common variables can be redefined} {
+    test_arrays0 do set undefined "scalar"
+} {scalar}
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/body.test b/8.x/itcl/tests/body.test
new file mode 100644 (file)
index 0000000..794b0a2
--- /dev/null
@@ -0,0 +1,226 @@
+#
+# Tests for "body" and "configbody" commands
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: body.test,v 1.4 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Test "body" command
+# ----------------------------------------------------------------------
+test body-1.1 {define a class with missing bodies and arg lists} {
+    itcl::class test_body {
+        constructor {args} {}
+        destructor {}
+
+        method any
+        method zero {}
+        method one {x}
+        method two {x y}
+        method defvals {x {y 0} {z 1}}
+        method varargs {x args}
+
+        method override {mesg} {
+            return "override: $mesg"
+        }
+    }
+} ""
+
+test body-1.2 {cannot use methods without a body} {
+    test_body #auto
+    list [catch "test_body0 any" msg] $msg
+} {1 {member function "::test_body::any" is not defined and cannot be autoloaded}}
+
+test body-1.3 {check syntax of "body" command} {
+    list [catch "itcl::body test_body::any" msg] $msg
+} {1 {wrong # args: should be "itcl::body class::func arglist body"}}
+
+test body-1.4 {make sure members are found correctly} {
+    list [catch "itcl::body test_body::xyzzyxyzzyxyzzy {} {}" msg] $msg
+} {1 {function "xyzzyxyzzyxyzzy" is not defined in class "::test_body"}}
+
+test body-1.5a {members without an argument list can have any args} {
+    itcl::body test_body::any {} {return "any"}
+    list [catch "test_body0 any" msg] $msg
+} {0 any}
+
+test body-1.5b {members without an argument list can have any args} {
+    itcl::body test_body::any {x} {return "any: $x"}
+    list [catch "test_body0 any 1" msg] $msg
+} {0 {any: 1}}
+
+test body-1.5c {members without an argument list can have any args} {
+    itcl::body test_body::any {x {y 2}} {return "any: $x $y"}
+    list [catch "test_body0 any 1" msg] $msg
+} {0 {any: 1 2}}
+
+test body-1.6a {an empty argument list must stay empty} {
+    list [catch {itcl::body test_body::zero {x y} {return "zero: $x $y"}} msg] $msg
+} {1 {argument list changed for function "::test_body::zero": should be ""}}
+
+test body-1.6b {an empty argument list must stay empty} {
+    list [catch {itcl::body test_body::zero {} {return "zero"}} msg] $msg
+} {0 {}}
+
+test body-1.7a {preserve argument list:  fixed arguments} {
+    list [catch {itcl::body test_body::one {x y} {return "one: $x $y"}} msg] $msg
+} {1 {argument list changed for function "::test_body::one": should be "x"}}
+
+test body-1.7b {preserve argument list:  fixed arguments} {
+    list [catch {itcl::body test_body::one {a} {return "one: $a"}} msg] $msg
+} {0 {}}
+
+test body-1.7c {preserve argument list:  fixed arguments} {
+    list [catch "test_body0 one 1.0" msg] $msg
+} {0 {one: 1.0}}
+
+test body-1.8a {preserve argument list:  fixed arguments} {
+    list [catch {itcl::body test_body::two {x} {return "two: $x"}} msg] $msg
+} {1 {argument list changed for function "::test_body::two": should be "x y"}}
+
+test body-1.8b {preserve argument list:  fixed arguments} {
+    list [catch {itcl::body test_body::two {a b} {return "two: $a $b"}} msg] $msg
+} {0 {}}
+
+test body-1.8c {preserve argument list:  fixed arguments} {
+    list [catch "test_body0 two 2.0 3.0" msg] $msg
+} {0 {two: 2.0 3.0}}
+
+test body-1.9a {preserve argument list:  default arguments} {
+    list [catch {itcl::body test_body::defvals {x} {}} msg] $msg
+} {1 {argument list changed for function "::test_body::defvals": should be "x {y 0} {z 1}"}}
+
+test body-1.9b {preserve argument list:  default arguments} {
+    list [catch {itcl::body test_body::defvals {a {b 0} {c 2}} {}} msg] $msg
+} {1 {argument list changed for function "::test_body::defvals": should be "x {y 0} {z 1}"}}
+
+test body-1.9c {preserve argument list:  default arguments} {
+    list [catch {itcl::body test_body::defvals {a {b 0} {c 1}} {}} msg] $msg
+} {0 {}}
+
+test body-1.10a {preserve argument list:  variable arguments} {
+    list [catch {itcl::body test_body::varargs {} {}} msg] $msg
+} {1 {argument list changed for function "::test_body::varargs": should be "x args"}}
+
+test body-1.10b {preserve argument list:  variable arguments} {
+    list [catch {itcl::body test_body::varargs {a} {}} msg] $msg
+} {0 {}}
+
+test body-1.10c {preserve argument list:  variable arguments} {
+    list [catch {itcl::body test_body::varargs {a b c} {}} msg] $msg
+} {0 {}}
+
+test body-1.11 {redefined body really does change} {
+    list [test_body0 override "test #1"] \
+         [itcl::body test_body::override {text} {return "new: $text"}] \
+         [test_body0 override "test #2"]
+} {{override: test #1} {} {new: test #2}}
+
+# ----------------------------------------------------------------------
+#  Test "body" command with inheritance
+# ----------------------------------------------------------------------
+test body-2.1 {inherit from a class with missing bodies} {
+    itcl::class test_ibody {
+        inherit test_body
+        method zero {}
+    }
+    test_ibody #auto
+} {test_ibody0}
+
+test body-2.2 {redefine a method in a derived class} {
+    itcl::body test_ibody::zero {} {return "ibody zero"}
+    list [test_ibody0 info function zero] \
+         [test_ibody0 info function test_body::zero]
+} {{public method ::test_ibody::zero {} {return "ibody zero"}} {public method ::test_body::zero {} {return "zero"}}}
+
+test body-2.3 {try to redefine a method that was not declared} {
+    list [catch {itcl::body test_ibody::one {x} {return "new"}} msg] $msg
+} {1 {function "one" is not defined in class "::test_ibody"}}
+
+# ----------------------------------------------------------------------
+#  Test "configbody" command
+# ----------------------------------------------------------------------
+test body-3.1 {define a class with public variables} {
+    itcl::class test_cbody {
+        private variable priv
+        protected variable prot
+
+        public variable option {} {
+            lappend messages "option: $option"
+        }
+        public variable nocode {}
+        public common messages
+    }
+} ""
+
+test body-3.2 {check syntax of "configbody" command} {
+    list [catch "itcl::configbody test_cbody::option" msg] $msg
+} {1 {wrong # args: should be "itcl::configbody class::option body"}}
+
+test body-3.3 {make sure that members are found correctly} {
+    list [catch "itcl::configbody test_cbody::xyzzy {}" msg] $msg
+} {1 {option "xyzzy" is not defined in class "::test_cbody"}}
+
+test body-3.4 {private variables have no config code} {
+    list [catch "itcl::configbody test_cbody::priv {bogus}" msg] $msg
+} {1 {option "::test_cbody::priv" is not a public configuration option}}
+
+test body-3.5 {protected variables have no config code} {
+    list [catch "itcl::configbody test_cbody::prot {bogus}" msg] $msg
+} {1 {option "::test_cbody::prot" is not a public configuration option}}
+
+test body-3.6 {can use public variables without a body} {
+    test_cbody #auto
+    list [catch "test_cbody0 configure -nocode 1" msg] $msg
+} {0 {}}
+
+test body-3.7 {redefined body really does change} {
+    list [test_cbody0 configure -option "hello"] \
+         [itcl::configbody test_cbody::option {lappend messages "new: $option"}] \
+         [test_cbody0 configure -option "goodbye"] \
+         [set test_cbody::messages] \
+} {{} {} {} {{option: hello} {new: goodbye}}}
+
+# ----------------------------------------------------------------------
+#  Test "configbody" command with inheritance
+# ----------------------------------------------------------------------
+test body-4.1 {inherit from a class with missing config bodies} {
+    itcl::class test_icbody {
+        inherit test_cbody
+        public variable option "icbody"
+    }
+    test_icbody #auto
+} {test_icbody0}
+
+test body-4.2 {redefine a body in a derived class} {
+    itcl::configbody test_icbody::option {lappend messages "test_icbody: $option"}
+    list [test_icbody0 info variable option] \
+         [test_icbody0 info variable test_cbody::option]
+} {{public variable ::test_icbody::option icbody {lappend messages "test_icbody: $option"} icbody} {public variable ::test_cbody::option {} {lappend messages "new: $option"} {}}}
+
+test body-4.3 {try to redefine a body for a variable that was not declared} {
+    list [catch {itcl::configbody test_icbody::nocode {return "new"}} msg] $msg
+} {1 {option "nocode" is not defined in class "::test_icbody"}}
+
+# ----------------------------------------------------------------------
+#  Clean up
+# ----------------------------------------------------------------------
+itcl::delete class test_body test_cbody
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/chain.test b/8.x/itcl/tests/chain.test
new file mode 100644 (file)
index 0000000..fbb91dc
--- /dev/null
@@ -0,0 +1,156 @@
+#
+# Tests for chaining methods and procs
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: chain.test,v 1.4 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Chaining methods and procs
+# ----------------------------------------------------------------------
+test chain-1.1 {define simple classes with inheritance} {
+    itcl::class test_chain_a {
+        constructor {args} {
+            eval chain $args
+        } {
+            global ::test_chain_status
+            lappend test_chain_status "a::constructor $args"
+        }
+        method show {mesg} {
+            chain $mesg
+            global ::test_chain_status
+            lappend test_chain_status "a::show $mesg"
+        }
+        proc tell {mesg} {
+            global ::test_chain_status
+            lappend test_chain_status "a::tell $mesg"
+            chain $mesg
+        }
+    }
+    itcl::class test_chain_b {
+        constructor {args} {
+            eval chain $args
+        } {
+            global ::test_chain_status
+            lappend test_chain_status "b::constructor $args"
+        }
+        method show {mesg} {
+            chain $mesg
+            global ::test_chain_status
+            lappend test_chain_status "b::show $mesg"
+        }
+        proc tell {mesg} {
+            global ::test_chain_status
+            lappend test_chain_status "b::tell $mesg"
+            chain $mesg
+        }
+    }
+    itcl::class test_chain_c {
+        inherit test_chain_a test_chain_b
+        constructor {args} {
+            eval chain $args
+        } {
+            global ::test_chain_status
+            lappend test_chain_status "c::constructor $args"
+        }
+        proc tell {mesg} {
+            global ::test_chain_status
+            lappend test_chain_status "c::tell $mesg"
+            chain $mesg
+        }
+    }
+    itcl::class test_chain_d {
+        inherit test_chain_c
+        constructor {args} {
+            eval chain $args
+        } {
+            global ::test_chain_status
+            lappend test_chain_status "d::constructor $args"
+        }
+        method show {mesg} {
+            chain $mesg
+            global ::test_chain_status
+            lappend test_chain_status "d::show $mesg"
+        }
+        proc tell {mesg} {
+            global ::test_chain_status
+            lappend test_chain_status "d::tell $mesg"
+            chain $mesg
+        }
+    }
+} ""
+
+test chain-1.2 {create a test object} {
+    set test_chain_status ""
+    set testobj [test_chain_d #auto 1 2 3]
+    set test_chain_status
+} {{b::constructor 1 2 3} {a::constructor 1 2 3} {c::constructor 1 2 3} {d::constructor 1 2 3}}
+
+test chain-1.3 {invoke a chained method} {
+    set test_chain_status ""
+    $testobj show "hello there"
+    set test_chain_status
+} {{b::show hello there} {a::show hello there} {d::show hello there}}
+
+test chain-1.4 {invoke a chained method with a specific name} {
+    set test_chain_status ""
+    $testobj test_chain_d::show "hello there"
+    set test_chain_status
+} {{b::show hello there} {a::show hello there} {d::show hello there}}
+
+test chain-1.5 {chained methods can cross multiple-inheritance branches} {
+    set test_chain_status ""
+    $testobj test_chain_a::show "hello there"
+    set test_chain_status
+} {{b::show hello there} {a::show hello there}}
+
+test chain-1.6 {invoke a chained proc} {
+    set test_chain_status ""
+    test_chain_d::tell "testing 1 2 3"
+    set test_chain_status
+} {{d::tell testing 1 2 3} {c::tell testing 1 2 3} {a::tell testing 1 2 3}}
+
+test chain-1.7 {invoke a chained proc} {
+    set test_chain_status ""
+    test_chain_c::tell "testing 1 2 3"
+    set test_chain_status
+} {{c::tell testing 1 2 3} {a::tell testing 1 2 3}}
+
+test chain-2.1 {create a test object in a base class} {
+    set test_chain_status ""
+    set testobj [test_chain_c #auto 4 5 6]
+    set test_chain_status
+} {{b::constructor 4 5 6} {a::constructor 4 5 6} {c::constructor 4 5 6}}
+
+test chain-2.2 {invoke a chained method} {
+    set test_chain_status ""
+    $testobj show "hello there"
+    set test_chain_status
+} {{b::show hello there} {a::show hello there}}
+
+test chain-3.0 {invoke "chain" outside of a class} {
+    list [catch {itcl::builtin::chain 1 2 3} err] $err
+} {1 {cannot chain functions outside of a class context}}
+
+# ----------------------------------------------------------------------
+#  Clean up
+# ----------------------------------------------------------------------
+itcl::delete class test_chain_d test_chain_c test_chain_b test_chain_a
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/delete.test b/8.x/itcl/tests/delete.test
new file mode 100644 (file)
index 0000000..95939d4
--- /dev/null
@@ -0,0 +1,212 @@
+#
+# Tests for deleting classes and objects
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: delete.test,v 1.4 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Deleting classes and objects
+# ----------------------------------------------------------------------
+test delete-1.1 {define a simple classes with inheritance} {
+    itcl::class test_delete_base {
+        variable num 0
+        method show {} {
+            return $num
+        }
+    }
+} ""
+
+test delete-1.2 {create some base class objects} {
+    for {set i 0} {$i < 5} {incr i} {
+        test_delete_base #auto
+    }
+    lsort [itcl::find objects -class test_delete_base]
+} {test_delete_base0 test_delete_base1 test_delete_base2 test_delete_base3 test_delete_base4}
+
+test delete-1.3 {delete the base class--class and all objects go away} {
+    list [itcl::delete class test_delete_base] \
+         [itcl::find classes test_delete_base] \
+         [namespace children :: test_delete_base] \
+         [namespace which -command test_delete_base] \
+         [itcl::find objects test_delete_base*]
+} {{} {} {} {} {}}
+
+# ----------------------------------------------------------------------
+#  Deleting classes and objects with inheritance
+# ----------------------------------------------------------------------
+test delete-2.1 {define a simple classes with inheritance} {
+    variable ::test_delete_watch ""
+    itcl::class test_delete_base {
+        variable num 0
+        method show {} {
+            return $num
+        }
+        destructor {
+            global ::test_delete_watch
+            lappend test_delete_watch $this
+        }
+    }
+    itcl::class test_delete {
+        inherit test_delete_base
+        method show {} {
+            return ">$num<"
+        }
+    }
+} ""
+
+test delete-2.2 {create some base and derived class objects} {
+    for {set i 0} {$i < 3} {incr i} {
+        test_delete_base #auto
+    }
+    for {set i 0} {$i < 3} {incr i} {
+        test_delete #auto
+    }
+    lsort [itcl::find objects -isa test_delete_base]
+} {test_delete0 test_delete1 test_delete2 test_delete_base0 test_delete_base1 test_delete_base2}
+
+test delete-2.3 {delete the base class--class and all objects go away} {
+    list [itcl::delete class test_delete_base] \
+         [itcl::find classes test_delete*] \
+         [namespace children :: test_delete*] \
+         [namespace which -command test_delete_base] \
+         [namespace which -command test_delete] \
+         [itcl::find objects test_delete*]
+} {{} {} {} {} {} {}}
+
+test delete-2.4 {object destructors get invoked properly} {
+    lsort $test_delete_watch
+} {::test_delete0 ::test_delete1 ::test_delete2 ::test_delete_base0 ::test_delete_base1 ::test_delete_base2}
+
+# ----------------------------------------------------------------------
+#  Deleting class namespaces
+# ----------------------------------------------------------------------
+test delete-3.1 {redefine classes with inheritance} {
+    variable ::test_delete_watch ""
+    itcl::class test_delete_base {
+        variable num 0
+        method show {} {
+            return $num
+        }
+        destructor {
+            global test_delete_watch
+            lappend test_delete_watch $this
+        }
+    }
+    itcl::class test_delete {
+        inherit test_delete_base
+        method show {} {
+            return ">$num<"
+        }
+    }
+} ""
+
+test delete-3.2 {create some base and derived class objects} {
+    for {set i 0} {$i < 3} {incr i} {
+        test_delete_base #auto
+    }
+    for {set i 0} {$i < 3} {incr i} {
+        test_delete #auto
+    }
+    lsort [itcl::find objects -isa test_delete_base]
+} {test_delete0 test_delete1 test_delete2 test_delete_base0 test_delete_base1 test_delete_base2}
+
+test delete-3.3 {deleting a class namespace is like deleting a class} {
+    list [namespace delete test_delete_base] \
+         [itcl::find classes test_delete*] \
+         [namespace children :: test_delete*] \
+         [namespace which -command test_delete_base] \
+         [namespace which -command test_delete] \
+         [itcl::find objects test_delete*]
+} {{} {} {} {} {} {}}
+
+test delete-3.4 {object destructors get invoked, even during catastrophe} {
+    lsort $test_delete_watch
+} {::test_delete0 ::test_delete1 ::test_delete2 ::test_delete_base0 ::test_delete_base1 ::test_delete_base2}
+
+# ----------------------------------------------------------------------
+#  Self-destructing objects
+# ----------------------------------------------------------------------
+test basic-4.1 {define a class where objects destroy themselves} {
+    itcl::class test_delete {
+        public variable x ""
+        public variable deletecommand ""
+        constructor {args} {
+            eval configure $args
+        }
+        destructor {
+            eval $deletecommand
+        }
+        method killme {code} {
+            itcl::delete object $this
+            eval $code
+        }
+    }
+} {}
+
+test basic-4.2 {an object can delete itself} {
+    set obj [test_delete #auto -x "data stays"]
+    list [$obj killme {return $x}] [itcl::find objects -isa test_delete]
+} {{data stays} {}}
+
+test basic-4.3 {the "this" variable becomes null after delete} {
+    set obj [test_delete #auto]
+    list [$obj killme {return $this}] [itcl::find objects -isa test_delete]
+} {{} {}}
+
+test basic-4.4 {an object being destructed can't be deleted} {
+    set obj [test_delete #auto -deletecommand {itcl::delete object $this}]
+    list [catch {itcl::delete object $obj} msg] $msg
+} {1 {can't delete an object while it is being destructed}}
+
+namespace delete test_delete
+
+# ----------------------------------------------------------------------
+#  Delete objects using path names and scoped values
+# ----------------------------------------------------------------------
+test basic-5.1 {define a simple class} {
+    itcl::class test_delete_name {
+        private variable x 0
+        method test {x} {
+            return $x
+        }
+    }
+} {}
+
+test basic-5.2 {delete using a qualified name} {
+    namespace eval test_delete2 {test_delete_name #auto}
+    set cmd {itcl::delete object test_delete2::test_delete_name0}
+    list [catch $cmd msg] $msg [itcl::find objects -isa test_delete_name]
+} {0 {} {}}
+
+test basic-5.3 {delete using a scoped value} {
+    set obj [namespace eval test_delete2 {itcl::code [test_delete_name #auto]}]
+    set cmd [list itcl::delete object $obj]
+    list [catch $cmd msg] $msg [itcl::find objects -isa test_delete_name]
+} {0 {} {}}
+
+test basic-5.4 {scoped command names are decoded properly} {
+    list [catch {itcl::delete object {namespace inscope ::xyzzy xxx}} msg] $msg \
+         [catch {itcl::delete object {namespace inscope :: xxx yyy}} msg] $msg \
+         [catch {itcl::delete object {namespace inscope :: xyzzy}} msg] $msg
+} {1 {unknown namespace "::xyzzy"} 1 {malformed command "namespace inscope :: xxx yyy": should be "namespace inscope namesp command"} 1 {object "namespace inscope :: xyzzy" not found}}
+
+namespace delete test_delete_name test_delete2
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/ensemble.test b/8.x/itcl/tests/ensemble.test
new file mode 100644 (file)
index 0000000..c21531e
--- /dev/null
@@ -0,0 +1,198 @@
+#
+# Tests for the "ensemble" compound command facility
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: ensemble.test,v 1.5 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+test ensemble-1.1 {ensemble name must be specified} {
+    list [catch {itcl::ensemble} msg] $msg
+} {1 {wrong # args: should be "itcl::ensemble name ?command arg arg...?"}}
+
+test ensemble-1.2 {creating a new ensemble} {
+    itcl::ensemble test_numbers {
+        part one {x} {
+            return "one: $x"
+        }
+        part two {x y} {
+            return "two: $x $y"
+        }
+    }
+} ""
+test ensemble-1.3 {adding to an existing ensemble} {
+    itcl::ensemble test_numbers part three {x y z} {
+        return "three: $x $y $z"
+    }
+} ""
+
+test ensemble-1.4 {invoking ensemble parts} {
+    list [test_numbers one 1] [test_numbers two 2 3] [test_numbers three 3 4 5]
+} {{one: 1} {two: 2 3} {three: 3 4 5}}
+
+test ensemble-1.5 {invoking parts with improper arguments} {
+    set res [catch "test_numbers three x" msg]
+    if {[package vsatisfies [package provide Tcl] 8.4]} {
+       lappend res [string match "wrong # args*" $msg]
+    } else {
+       lappend res [string match "no value given*" $msg]
+    }
+} {1 1}
+
+test ensemble-1.6 {errors trigger a usage summary} {
+    list [catch "test_numbers foo x y" msg] $msg
+} {1 {bad option "foo": should be one of...
+  test_numbers one x
+  test_numbers three x y z
+  test_numbers two x y}}
+
+test ensemble-1.7 {one part can't overwrite another} {
+    set cmd {
+        itcl::ensemble test_numbers part three {} {
+            return "three: new version"
+        }
+    }
+    list [catch $cmd msg] $msg
+} {1 {part "three" already exists in ensemble}}
+
+test ensemble-1.8 {an ensemble can't overwrite another part} {
+    set cmd {
+        itcl::ensemble test_numbers ensemble three part new {} {
+            return "three: new version"
+        }
+    }
+    list [catch $cmd msg] $msg
+} {1 {part "three" is not an ensemble}}
+
+test ensemble-1.9 {body errors are handled gracefully} {
+    list [catch "itcl::ensemble test_numbers {foo bar baz}" msg] $msg $errorInfo
+} {1 {invalid command name "foo"} {invalid command name "foo"
+    while executing
+"foo bar baz"
+    ("ensemble" body line 1)
+    invoked from within
+"itcl::ensemble test_numbers {foo bar baz}"}}
+
+test ensemble-1.10 {part errors are handled gracefully} {
+    list [catch "itcl::ensemble test_numbers {part foo}" msg] $msg $errorInfo
+} {1 {wrong # args: should be "part name args body"} {wrong # args: should be "part name args body"
+    while executing
+"part foo"
+    ("ensemble" body line 1)
+    invoked from within
+"itcl::ensemble test_numbers {part foo}"}}
+
+test ensemble-1.11 {part argument errors are handled gracefully} {
+    list [catch "itcl::ensemble test_numbers {part foo {{}} {}}" msg] $msg $errorInfo
+} {1 {procedure "foo" has argument with no name} {procedure "foo" has argument with no name
+    while executing
+"part foo {{}} {}"
+    ("ensemble" body line 1)
+    invoked from within
+"itcl::ensemble test_numbers {part foo {{}} {}}"}}
+
+test ensemble-2.0 {defining subensembles} {
+    itcl::ensemble test_numbers {
+        ensemble hex {
+            part base {} {
+                return 16
+            }
+            part digits {args} {
+                foreach num $args {
+                    lappend result "0x$num"
+                }
+                return $result
+            }
+        }
+        ensemble octal {
+            part base {} {
+                return 8
+            }
+            part digits {{prefix 0} args} {
+                foreach num $args {
+                    lappend result "$prefix$num"
+                }
+                return $result
+            }
+        }
+    }
+    list [catch "test_numbers foo" msg] $msg
+} {1 {bad option "foo": should be one of...
+  test_numbers hex option ?arg arg ...?
+  test_numbers octal option ?arg arg ...?
+  test_numbers one x
+  test_numbers three x y z
+  test_numbers two x y}}
+
+test ensemble-2.1 {invoking sub-ensemble parts} {
+    list [catch "test_numbers hex base" msg] $msg
+} {0 16}
+
+test ensemble-2.2 {invoking sub-ensemble parts} {
+    list [catch "test_numbers hex digits 3 a f" msg] $msg
+} {0 {0x3 0xa 0xf}}
+
+test ensemble-2.3 {errors from sub-ensembles} {
+    list [catch "test_numbers hex" msg] $msg
+} {1 {wrong # args: should be one of...
+  test_numbers hex base
+  test_numbers hex digits ?arg arg ...?}}
+
+test ensemble-2.4 {invoking sub-ensemble parts} {
+    list [catch "test_numbers octal base" msg] $msg
+} {0 8}
+
+test ensemble-2.5 {invoking sub-ensemble parts} {
+    list [catch "test_numbers octal digits 0o 3 5 10" msg] $msg
+} {0 {0o3 0o5 0o10}}
+
+test ensemble-2.6 {errors from sub-ensembles} {
+    list [catch "test_numbers octal" msg] $msg
+} {1 {wrong # args: should be one of...
+  test_numbers octal base
+  test_numbers octal digits ?prefix? ?arg arg ...?}}
+
+test ensemble-2.7 {sub-ensembles can't be accidentally redefined} {
+    set cmd {
+        itcl::ensemble test_numbers part octal {args} {
+            return "octal: $args"
+        }
+    }
+    list [catch $cmd msg] $msg
+} {1 {part "octal" already exists in ensemble}}
+
+test ensemble-3.0 {an error handler part can be used to handle errors} {
+    itcl::ensemble test_numbers {
+        part @error {args} {
+            return "error: $args"
+        }
+    }
+    list [catch {test_numbers foo 1 2 3} msg] $msg
+} {0 {error: foo 1 2 3}}
+
+test ensemble-3.1 {the error handler part shows up as generic "...and"} {
+    list [catch {test_numbers} msg] $msg
+} {1 {wrong # args: should be one of...
+  test_numbers hex option ?arg arg ...?
+  test_numbers octal option ?arg arg ...?
+  test_numbers one x
+  test_numbers three x y z
+  test_numbers two x y
+...and others described on the man page}}
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/import.test b/8.x/itcl/tests/import.test
new file mode 100644 (file)
index 0000000..30340a3
--- /dev/null
@@ -0,0 +1,158 @@
+#
+# Tests for "auto_import" and autoloading facility
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: import.test,v 1.6 2004/04/29 05:57:42 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Test "itcl::import::stub" command
+# ----------------------------------------------------------------------
+test import-1.1 {basic syntax for "stub" command} {
+    list [catch {itcl::import::stub} result] $result
+} {1 {wrong # args: should be one of...
+  stub create name
+  stub exists name}}
+
+test import-1.2 {"stub create" requires one argument} {
+    list [catch {itcl::import::stub create} result] $result \
+         [catch {itcl::import::stub create x y} result] $result
+} {1 {wrong # args: should be "itcl::import::stub create name"} 1 {wrong # args: should be "itcl::import::stub create name"}}
+
+test import-1.3 {"stub exists" requires one argument} {
+    list [catch {itcl::import::stub exists} result] $result \
+         [catch {itcl::import::stub exists x y} result] $result
+} {1 {wrong # args: should be "itcl::import::stub exists name"} 1 {wrong # args: should be "itcl::import::stub exists name"}}
+
+set interp [interp create]
+$interp eval [subst -novariables {
+    [::tcltest::configure -load]
+    proc auto_load {cmd {namespace {}}} {
+        global debug
+        proc $cmd {args} \[format {return "%s: $args"} $cmd\]
+        append debug "(auto_load: $cmd)"
+        return 1
+    }
+}]
+
+test import-1.4 {"stub create" creates a stub that triggers autoloading} {
+    $interp eval {
+        set debug ""
+        list [itcl::import::stub create foo::bar::test] \
+             [info commands ::foo::bar::test] \
+             [::foo::bar::test 1 2 3] \
+             $debug
+    }
+} {{} ::foo::bar::test {::foo::bar::test: 1 2 3} {(auto_load: ::foo::bar::test)}}
+
+test import-1.5 {"stub exists" recognizes stubs created by "stub create"} {
+    $interp eval {
+        set debug ""
+        itcl::import::stub create foo::bar::stub1
+        proc foo::bar::proc1 {{args {}}} {return "proc1: $args"}
+        list [itcl::import::stub exists foo::bar::stub1] \
+             [itcl::import::stub exists foo::bar::proc1]
+    }
+} {1 0}
+
+test import-1.6 {stubs can be autoloaded and replaced} {
+    $interp eval {
+        set debug ""
+        itcl::import::stub create foo::bar::stub2
+        list [itcl::import::stub exists foo::bar::stub2] \
+             [::foo::bar::stub2 a b c] \
+             [itcl::import::stub exists foo::bar::stub2] \
+             [::foo::bar::stub2 a b c] \
+             $debug
+    }
+} {1 {::foo::bar::stub2: a b c} 0 {::foo::bar::stub2: a b c} {(auto_load: ::foo::bar::stub2)}}
+
+catch {interp delete $interp}
+
+# ----------------------------------------------------------------------
+#  Test "itcl::import::stub" command
+# ----------------------------------------------------------------------
+set interp [interp create]
+$interp eval [subst -novariables {
+    [::tcltest::configure -load]
+    proc auto_load {cmd {namespace {}}} {
+        proc $cmd {args} \[format {return "%s: $args"} $cmd\]
+        return 1
+    }
+}]
+
+test import-2.1 {initialize some commands for autoloading} {
+    $interp eval {
+        namespace eval test {
+            namespace export foo*
+        }
+        itcl::import::stub create ::test::foo1
+        itcl::import::stub create ::test::foo2
+        lsort [info commands ::test::*]
+    }
+} {::test::foo1 ::test::foo2}
+
+test import-2.2 {stubs can be imported into other namespaces} {
+    $interp eval {
+        namespace eval user1 { namespace import ::test::* }
+        namespace eval user2 { namespace import ::test::* }
+        namespace eval user3 { namespace import ::test::* }
+        list [lsort [info commands ::user1::*]] \
+             [namespace origin ::user1::foo1] \
+             [namespace origin ::user1::foo2]
+    }
+} {{::user1::foo1 ::user1::foo2} ::test::foo1 ::test::foo2}
+
+test import-2.3 {stubs can be autoloaded and imported links remain} {
+    $interp eval {
+        list [::user1::foo1 1 2 3 4] \
+             [namespace origin ::user1::foo1] \
+             [namespace origin ::user2::foo1] \
+             [namespace origin ::user3::foo1] \
+             [itcl::import::stub exists ::test::foo1]
+    }
+} {{::test::foo1: 1 2 3 4} ::test::foo1 ::test::foo1 ::test::foo1 0}
+
+test import-2.3 {itcl::class handles stubs correctly} {
+    $interp eval {
+        proc auto_load {cmd {namespace {}}} {
+            itcl::class $cmd { }
+            return 1
+        }
+        list [::user2::foo2 x] \
+             [x info class] \
+             [namespace origin ::user1::foo2] \
+             [namespace origin ::user2::foo2] \
+             [namespace origin ::user3::foo2] \
+             [itcl::import::stub exists ::test::foo2]
+    }
+} {x ::test::foo2 ::test::foo2 ::test::foo2 ::test::foo2 0}
+
+test import-2.3 {itcl::class will overwrite stubs in an existing namespace} {
+    $interp eval {
+        namespace eval test::buried { }
+        itcl::import::stub create ::test::buried
+        itcl::import::stub create ::test::buried::stub
+        list [catch {::test::buried xx} result] $result [xx info class]
+    }
+} {0 xx ::test::buried}
+
+catch {interp delete $interp}
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/info.test b/8.x/itcl/tests/info.test
new file mode 100644 (file)
index 0000000..14c8a9f
--- /dev/null
@@ -0,0 +1,396 @@
+#
+# Tests for information accessed by the "info" command
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: info.test,v 1.6 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Class definition with one of everything
+# ----------------------------------------------------------------------
+test info-1.1 {define a simple class} {
+    itcl::class test_info_base {
+        method base {} {return "default"}
+        variable base {}
+
+        method do {args} {eval $args}
+    }
+    itcl::class test_info {
+        inherit test_info_base
+
+        constructor {args} {
+            foreach v [info variable] {
+                catch {set $v "new-[set $v]"}
+            }
+        }
+        destructor {}
+
+        method defm {} {return "default method"}
+        public method pubm {x} {return "public method"}
+        protected method prom {x y} {return "protected method"}
+        private method prim {x y z} {return "private method"}
+
+        proc defp {} {return "default proc"}
+        public proc pubp {x} {return "public proc"}
+        protected proc prop {x y} {return "protected proc"}
+        private proc prip {x y z} {return "private proc"}
+
+        variable defv "default"
+        public variable pubv "public" {set pubv "public: $pubv"}
+        protected variable prov "protected"
+        private variable priv "private"
+
+        common defc "default"
+        public common pubc "public"
+        protected common proc "protected"
+        private common pric "private"
+
+        method uninitm
+        proc uninitp {x y}
+        variable uninitv
+        common uninitc
+        set uninitc(0) zero
+        set uninitc(1) one
+    }
+} ""
+
+test info-1.2 {info: errors trigger usage info} {
+    list [catch {namespace eval test_info {info}} msg] $msg
+} {1 {wrong # args: should be one of...
+  info args procname
+  info body procname
+  info class
+  info function ?name? ?-protection? ?-type? ?-name? ?-args? ?-body?
+  info heritage
+  info inherit
+  info variable ?name? ?-protection? ?-type? ?-name? ?-init? ?-value? ?-config?
+...and others described on the man page}}
+
+test basic-1.3 {info: errors trigger usage info} {
+    test_info ti
+    list [catch {ti info} msg] $msg
+} {1 {wrong # args: should be one of...
+  info args procname
+  info body procname
+  info class
+  info function ?name? ?-protection? ?-type? ?-name? ?-args? ?-body?
+  info heritage
+  info inherit
+  info variable ?name? ?-protection? ?-type? ?-name? ?-init? ?-value? ?-config?
+...and others described on the man page}}
+
+test info-1.4 {info: info class works on class itself} {
+    namespace eval test_info { info class }
+} {::test_info}
+
+# ----------------------------------------------------------------------
+#  Data members
+# ----------------------------------------------------------------------
+test info-2.1 {info: all variables} {
+    lsort [ti info variable]
+} {::test_info::defc ::test_info::defv ::test_info::pric ::test_info::priv ::test_info::proc ::test_info::prov ::test_info::pubc ::test_info::pubv ::test_info::this ::test_info::uninitc ::test_info::uninitv ::test_info_base::base}
+
+test info-2.2a {info: public variables} {
+    ti info variable pubv
+} {public variable ::test_info::pubv public {set pubv "public: $pubv"} new-public}
+
+test info-2.2b {info: public variables} {
+    list [ti info variable pubv -protection] \
+         [ti info variable pubv -type] \
+         [ti info variable pubv -name] \
+         [ti info variable pubv -init] \
+         [ti info variable pubv -config] \
+         [ti info variable pubv -value] \
+} {public variable ::test_info::pubv public {set pubv "public: $pubv"} new-public}
+
+test info-2.3a {info: protected variables} {
+    ti info variable prov
+} {protected variable ::test_info::prov protected new-protected}
+
+test info-2.3b {info: protected variables} {
+    list [ti info variable prov -protection] \
+         [ti info variable prov -type] \
+         [ti info variable prov -name] \
+         [ti info variable prov -init] \
+         [ti info variable prov -value] \
+} {protected variable ::test_info::prov protected new-protected}
+
+test info-2.4a {info: private variables} {
+    ti info variable priv
+} {private variable ::test_info::priv private new-private}
+
+test info-2.4b {info: private variables} {
+    list [ti info variable priv -protection] \
+         [ti info variable priv -type] \
+         [ti info variable priv -name] \
+         [ti info variable priv -init] \
+         [ti info variable priv -value] \
+} {private variable ::test_info::priv private new-private}
+
+test info-2.5 {"this" variable is built in} {
+    ti info variable this
+} {protected variable ::test_info::this ::ti ::ti}
+
+test info-2.6 {info: protected/private variables have no "config" code} {
+    list [ti info variable prov -config] [ti info variable priv -config]
+} {{} {}}
+
+test info-2.7 {by default, variables are "protected"} {
+    ti info variable defv
+} {protected variable ::test_info::defv default new-default}
+
+test info-2.8 {data members may be uninitialized} {
+    ti info variable uninitv
+} {protected variable ::test_info::uninitv <undefined> <undefined>}
+
+test info-2.9a {info: public common variables} {
+    ti info variable pubc
+} {public common ::test_info::pubc public new-public}
+
+test info-2.9b {info: public common variables} {
+    list [ti info variable pubc -protection] \
+         [ti info variable pubc -type] \
+         [ti info variable pubc -name] \
+         [ti info variable pubc -init] \
+         [ti info variable pubc -value] \
+} {public common ::test_info::pubc public new-public}
+
+test info-2.10a {info: protected common variables} {
+    ti info variable proc
+} {protected common ::test_info::proc protected new-protected}
+
+test info-2.10b {info: protected common variables} {
+    list [ti info variable proc -protection] \
+         [ti info variable proc -type] \
+         [ti info variable proc -name] \
+         [ti info variable proc -init] \
+         [ti info variable proc -value] \
+} {protected common ::test_info::proc protected new-protected}
+
+test info-2.11a {info: private common variables} {
+    ti info variable pric
+} {private common ::test_info::pric private new-private}
+
+test info-2.11b {info: private common variables} {
+    list [ti info variable pric -protection] \
+         [ti info variable pric -type] \
+         [ti info variable pric -name] \
+         [ti info variable pric -init] \
+         [ti info variable pric -value] \
+} {private common ::test_info::pric private new-private}
+
+test info-2.12 {info: public/protected/private vars have no "config" code} {
+    list [ti info variable pubc -config] \
+         [ti info variable proc -config] \
+         [ti info variable pric -config]
+} {{} {} {}}
+
+test info-2.13 {by default, variables are "protected"} {
+    ti info variable defc
+} {protected common ::test_info::defc default new-default}
+
+test info-2.14 {data members may be uninitialized} {
+    ti info variable uninitc
+} {protected common ::test_info::uninitc <undefined> <undefined>}
+
+test info-2.15 {common vars can be initialized within class definition} {
+    list [namespace eval test_info {lsort [array names uninitc]}] \
+         [namespace eval test_info {set uninitc(0)}] \
+         [namespace eval test_info {set uninitc(1)}]
+} {{0 1} zero one}
+
+test info-2.16 {flag syntax errors} {
+    list [catch {ti info variable defv -xyzzy} msg] $msg
+} {1 {bad option "-xyzzy": must be -config, -init, -name, -protection, -type, or -value}}
+
+# ----------------------------------------------------------------------
+#  Member functions
+# ----------------------------------------------------------------------
+test basic-3.1 {info: all functions} {
+    lsort [ti info function]
+} {::test_info::constructor ::test_info::defm ::test_info::defp ::test_info::destructor ::test_info::prim ::test_info::prip ::test_info::prom ::test_info::prop ::test_info::pubm ::test_info::pubp ::test_info::uninitm ::test_info::uninitp ::test_info_base::base ::test_info_base::cget ::test_info_base::configure ::test_info_base::do ::test_info_base::isa}
+
+test info-3.2a {info: public methods} {
+    ti info function pubm
+} {public method ::test_info::pubm x {return "public method"}}
+
+test info-3.2b {info: public methods} {
+    list [ti info function pubm -protection] \
+         [ti info function pubm -type] \
+         [ti info function pubm -name] \
+         [ti info function pubm -args] \
+         [ti info function pubm -body]
+} {public method ::test_info::pubm x {return "public method"}}
+
+test info-3.3a {info: protected methods} {
+    ti info function prom
+} {protected method ::test_info::prom {x y} {return "protected method"}}
+
+test info-3.3b {info: protected methods} {
+    list [ti info function prom -protection] \
+         [ti info function prom -type] \
+         [ti info function prom -name] \
+         [ti info function prom -args] \
+         [ti info function prom -body]
+} {protected method ::test_info::prom {x y} {return "protected method"}}
+
+test info-3.4a {info: private methods} {
+    ti info function prim
+} {private method ::test_info::prim {x y z} {return "private method"}}
+
+test info-3.4b {info: private methods} {
+    list [ti info function prim -protection] \
+         [ti info function prim -type] \
+         [ti info function prim -name] \
+         [ti info function prim -args] \
+         [ti info function prim -body]
+} {private method ::test_info::prim {x y z} {return "private method"}}
+
+test info-3.5 {"configure" function is built in} {
+    ti info function configure
+} {public method ::test_info_base::configure {?-option? ?value -option value...?} @itcl-builtin-configure}
+
+test info-3.6 {by default, methods are "public"} {
+    ti info function defm
+} {public method ::test_info::defm {} {return "default method"}}
+
+test info-3.7 {methods may not have arg lists or bodies defined} {
+    ti info function uninitm
+} {public method ::test_info::uninitm <undefined> <undefined>}
+
+test info-3.8a {info: public procs} {
+    ti info function pubp
+} {public proc ::test_info::pubp x {return "public proc"}}
+
+test info-3.8b {info: public procs} {
+    list [ti info function pubp -protection] \
+         [ti info function pubp -type] \
+         [ti info function pubp -name] \
+         [ti info function pubp -args] \
+         [ti info function pubp -body]
+} {public proc ::test_info::pubp x {return "public proc"}}
+
+test info-3.9a {info: protected procs} {
+    ti info function prop
+} {protected proc ::test_info::prop {x y} {return "protected proc"}}
+
+test info-3.9b {info: protected procs} {
+    list [ti info function prop -protection] \
+         [ti info function prop -type] \
+         [ti info function prop -name] \
+         [ti info function prop -args] \
+         [ti info function prop -body]
+} {protected proc ::test_info::prop {x y} {return "protected proc"}}
+
+test info-3.10a {info: private procs} {
+    ti info function prip
+} {private proc ::test_info::prip {x y z} {return "private proc"}}
+
+test info-3.10b {info: private procs} {
+    list [ti info function prip -protection] \
+         [ti info function prip -type] \
+         [ti info function prip -name] \
+         [ti info function prip -args] \
+         [ti info function prip -body]
+} {private proc ::test_info::prip {x y z} {return "private proc"}}
+
+test info-3.11 {by default, procs are "public"} {
+    ti info function defp
+} {public proc ::test_info::defp {} {return "default proc"}}
+
+test info-3.12 {procs may not have arg lists or bodies defined} {
+    ti info function uninitp
+} {public proc ::test_info::uninitp {x y} <undefined>}
+
+test info-3.13 {flag syntax errors} {
+    list [catch {ti info function defm -xyzzy} msg] $msg
+} {1 {bad option "-xyzzy": must be -args, -body, -name, -protection, or -type}}
+
+# ----------------------------------------------------------------------
+#  Other object-related queries
+# ----------------------------------------------------------------------
+
+test info-4.1a {query class (wrong # args)} {
+    list [catch {ti info class x} result] $result
+} {1 {wrong # args: should be "info class"}}
+
+test info-4.1b {query most-specific class} {
+    list [ti info class] [ti do info class]
+} {::test_info ::test_info}
+
+test info-4.2a {query inheritance info (wrong # args)} {
+    list [catch {ti info inherit x} result] $result
+} {1 {wrong # args: should be "info inherit"}}
+
+test info-4.2b {query inheritance info} {
+    list [ti info inherit] [ti do info inherit]
+} {::test_info_base {}}
+
+test info-4.3a {query heritage info (wrong # args)} {
+    list [catch {ti info heritage x} result] $result
+} {1 {wrong # args: should be "info heritage"}}
+
+test info-4.3b {query heritage info} {
+    list [ti info heritage] [ti do info heritage]
+} {{::test_info ::test_info_base} ::test_info_base}
+
+test info-4.4a {query argument list (wrong # args)} {
+    list [catch {ti info args} result] $result \
+         [catch {ti info args x y} result] $result
+} {1 {wrong # args: should be "info args function"} 1 {wrong # args: should be "info args function"}}
+
+test info-4.4b {query argument list} {
+    ti info args prim
+} {x y z}
+
+test info-4.4c {query argument list (undefined)} {
+    ti info args uninitm
+} {<undefined>}
+
+test info-4.5a {query body (wrong # args)} {
+    list [catch {ti info body} result] $result \
+         [catch {ti info body x y} result] $result
+} {1 {wrong # args: should be "info body function"} 1 {wrong # args: should be "info body function"}}
+
+test info-4.5b {query body} {
+    ti info body prim
+} {return "private method"}
+
+test info-4.5c {query body (undefined)} {
+    ti info body uninitm
+} {<undefined>}
+
+# ----------------------------------------------------------------------
+#  Other parts of the usual "info" command
+# ----------------------------------------------------------------------
+
+test info-5.1 {info vars} {
+    ti do info vars
+} {args}
+
+test info-5.2 {info exists} {
+    list [ti do info exists args] [ti do info exists xyzzy]
+} {1 0}
+
+# ----------------------------------------------------------------------
+#  Clean up
+# ----------------------------------------------------------------------
+itcl::delete class test_info test_info_base
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/inherit.test b/8.x/itcl/tests/inherit.test
new file mode 100644 (file)
index 0000000..55055ae
--- /dev/null
@@ -0,0 +1,588 @@
+#
+# Tests for inheritance and scope handling
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: inherit.test,v 1.5 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Test construction/destruction with inheritance
+# ----------------------------------------------------------------------
+test inherit-1.1 {define classes with constructors/destructors} {
+    variable ::test_cd_watch ""
+    itcl::class test_cd_foo {
+        constructor {x y} {
+            global ::test_cd_watch
+            lappend test_cd_watch "foo: $x $y"
+        }
+        destructor {
+            global ::test_cd_watch
+            lappend test_cd_watch "foo destruct"
+        }
+    }
+    itcl::class test_cd_bar {
+        constructor {args} {
+            global ::test_cd_watch
+            lappend test_cd_watch "bar: $args"
+        }
+        destructor {
+            global ::test_cd_watch
+            lappend test_cd_watch "bar destruct"
+        }
+    }
+    itcl::class test_cd_foobar {
+        inherit test_cd_foo test_cd_bar
+        constructor {x y args} {
+            test_cd_foo::constructor $x $y
+        } {
+            global ::test_cd_watch
+            lappend test_cd_watch "foobar: $x $y ($args)"
+        }
+        destructor {
+            global ::test_cd_watch
+            lappend test_cd_watch "foobar destruct"
+        }
+    }
+    itcl::class test_cd_geek {
+        constructor {} {
+            global ::test_cd_watch
+            lappend test_cd_watch "geek"
+        }
+        destructor {
+            global ::test_cd_watch
+            lappend test_cd_watch "geek destruct"
+        }
+    }
+    itcl::class test_cd_mongrel {
+        inherit test_cd_foobar test_cd_geek
+        constructor {x} {
+            eval test_cd_foobar::constructor 1 2 fred $x
+        } {
+            global ::test_cd_watch
+            lappend test_cd_watch "mongrel: $x"
+        }
+        destructor {
+            global ::test_cd_watch
+            lappend test_cd_watch "mongrel destruct"
+        }
+    }
+    itcl::class test_cd_none {
+        inherit test_cd_bar test_cd_geek
+    }
+    itcl::class test_cd_skip {
+        inherit test_cd_none
+        constructor {} {
+            global ::test_cd_watch
+            lappend test_cd_watch "skip"
+        }
+        destructor {
+            global ::test_cd_watch
+            lappend test_cd_watch "skip destruct"
+        }
+    }
+} {}
+
+test inherit-1.2 {constructors should be invoked in the proper order} {
+    set ::test_cd_watch ""
+    list [test_cd_mongrel #auto bob] [set ::test_cd_watch]
+} {test_cd_mongrel0 {{foo: 1 2} {bar: } {foobar: 1 2 (fred bob)} geek {mongrel: bob}}}
+
+test inherit-1.3 {destructors should be invoked in the proper order} {
+    set ::test_cd_watch ""
+    list [itcl::delete object test_cd_mongrel0] [set ::test_cd_watch]
+} {{} {{mongrel destruct} {foobar destruct} {foo destruct} {bar destruct} {geek destruct}}}
+
+test inherit-1.4 {constructors are optional} {
+    set ::test_cd_watch ""
+    list [test_cd_none #auto] [set ::test_cd_watch]
+} {test_cd_none0 {geek {bar: }}}
+
+test inherit-1.5 {destructors are optional} {
+    set ::test_cd_watch ""
+    list [itcl::delete object test_cd_none0] [set ::test_cd_watch]
+} {{} {{bar destruct} {geek destruct}}}
+
+test inherit-1.6 {construction ok if constructors are missing} {
+    set ::test_cd_watch ""
+    list [test_cd_skip #auto] [set ::test_cd_watch]
+} {test_cd_skip0 {geek {bar: } skip}}
+
+test inherit-1.7 {destruction ok if destructors are missing} {
+    set ::test_cd_watch ""
+    list [itcl::delete object test_cd_skip0] [set ::test_cd_watch]
+} {{} {{skip destruct} {bar destruct} {geek destruct}}}
+
+test inherit-1.8 {errors during construction are cleaned up and reported} {
+    global errorInfo test_cd_watch
+    set test_cd_watch ""
+    itcl::body test_cd_bar::constructor {args} {error "bar: failed"}
+    list [catch {test_cd_mongrel #auto bob} msg] $msg \
+        $errorInfo $test_cd_watch
+} {1 {bar: failed} {bar: failed
+    while executing
+"error "bar: failed""
+    while constructing object "::test_cd_mongrel1" in ::test_cd_bar::constructor (body line 1)
+    while constructing object "::test_cd_mongrel1" in ::test_cd_foobar::constructor (body line 1)
+    invoked from within
+"test_cd_foobar::constructor 1 2 fred bob"
+    ("eval" body line 1)
+    invoked from within
+"eval test_cd_foobar::constructor 1 2 fred $x"
+    while constructing object "::test_cd_mongrel1" in ::test_cd_mongrel::constructor (body line 2)
+    invoked from within
+"test_cd_mongrel #auto bob"} {{foo: 1 2} {mongrel destruct} {foobar destruct} {foo destruct} {bar destruct} {geek destruct}}}
+
+test inherit-1.9 {errors during destruction prevent object delete} {
+    global errorInfo test_cd_watch
+    itcl::body test_cd_bar::constructor {args} {return "bar: $args"}
+    itcl::body test_cd_bar::destructor {} {error "bar: failed"}
+    test_cd_mongrel mongrel1 ted
+    set test_cd_watch ""
+    list [catch {itcl::delete object mongrel1} msg] $msg \
+        $errorInfo $test_cd_watch [itcl::find objects mongrel*]
+} {1 {bar: failed} {bar: failed
+    while executing
+"error "bar: failed""
+    while deleting object "::mongrel1" in ::test_cd_bar::destructor (body line 1)
+    invoked from within
+"itcl::delete object mongrel1"} {{mongrel destruct} {foobar destruct} {foo destruct}} mongrel1}
+
+test inherit-1.10 {errors during destruction prevent class delete} {
+    list [catch {itcl::delete class test_cd_foo} msg] $msg
+} {1 {bar: failed}}
+
+eval namespace delete [itcl::find classes test_cd_*]
+
+# ----------------------------------------------------------------------
+#  Test data member access and scoping
+# ----------------------------------------------------------------------
+test inherit-2.1 {define classes with data members} {
+    itcl::class test_cd_foo {
+        protected variable x "foo-x"
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_bar {
+        protected variable x "bar-x"
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_foobar {
+        inherit test_cd_foo test_cd_bar
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_geek {
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_mongrel {
+        inherit test_cd_foobar test_cd_geek
+        protected variable x "mongrel-x"
+        method do {args} {eval $args}
+    }
+} {}
+
+test inherit-2.2 {"info" provides access to shadowed data members} {
+    test_cd_mongrel #auto
+    list [lsort [test_cd_mongrel0 info variable]] \
+         [test_cd_mongrel0 info variable test_cd_foo::x] \
+         [test_cd_mongrel0 info variable test_cd_bar::x] \
+         [test_cd_mongrel0 info variable test_cd_mongrel::x] \
+         [test_cd_mongrel0 info variable x]
+} {{::test_cd_bar::x ::test_cd_foo::x ::test_cd_mongrel::this ::test_cd_mongrel::x} {protected variable ::test_cd_foo::x foo-x foo-x} {protected variable ::test_cd_bar::x bar-x bar-x} {protected variable ::test_cd_mongrel::x mongrel-x mongrel-x} {protected variable ::test_cd_mongrel::x mongrel-x mongrel-x}}
+
+test inherit-2.3 {variable resolution works properly in methods} {
+    list [test_cd_mongrel0 test_cd_foo::do set x] \
+         [test_cd_mongrel0 test_cd_bar::do set x] \
+         [test_cd_mongrel0 test_cd_foobar::do set x] \
+         [test_cd_mongrel0 test_cd_mongrel::do set x]
+} {foo-x bar-x foo-x mongrel-x}
+
+test inherit-2.4 {methods have access to shadowed data members} {
+    list [test_cd_mongrel0 test_cd_foobar::do set x] \
+         [test_cd_mongrel0 test_cd_foobar::do set test_cd_foo::x] \
+         [test_cd_mongrel0 test_cd_foobar::do set test_cd_bar::x] \
+         [test_cd_mongrel0 test_cd_mongrel::do set test_cd_foo::x] \
+         [test_cd_mongrel0 test_cd_mongrel::do set test_cd_bar::x]
+} {foo-x foo-x bar-x foo-x bar-x}
+
+eval namespace delete [itcl::find classes test_cd_*]
+
+# ----------------------------------------------------------------------
+#  Test public variables and "configure" method
+# ----------------------------------------------------------------------
+test inherit-3.1 {define classes with public variables} {
+    variable ::test_cd_watch ""
+    itcl::class test_cd_foo {
+        public variable x "foo-x" {
+            global test_cd_watch
+            lappend test_cd_watch "foo: $x in scope [namespace current]"
+        }
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_bar {
+        public variable x "bar-x" {
+            global test_cd_watch
+            lappend test_cd_watch "bar: $x in scope [namespace current]"
+        }
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_foobar {
+        inherit test_cd_foo test_cd_bar
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_geek {
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_mongrel {
+        inherit test_cd_foobar test_cd_geek
+        public variable x "mongrel-x" {
+            global test_cd_watch
+            lappend test_cd_watch "mongrel: $x in scope [namespace current]"
+        }
+        method do {args} {eval $args}
+    }
+} {}
+
+test inherit-3.2 {create an object with public variables} {
+    test_cd_mongrel #auto
+} {test_cd_mongrel0}
+
+test inherit-3.3 {"configure" lists all public variables} {
+    lsort [test_cd_mongrel0 configure]
+} {{-test_cd_bar::x bar-x bar-x} {-test_cd_foo::x foo-x foo-x} {-x mongrel-x mongrel-x}}
+
+test inherit-3.4 {"configure" treats simple names as "most specific"} {
+    lsort [test_cd_mongrel0 configure -x]
+} {-x mongrel-x mongrel-x}
+
+test inherit-3.5 {"configure" treats simple names as "most specific"} {
+    set ::test_cd_watch ""
+    list [test_cd_mongrel0 configure -x hello] \
+         [set ::test_cd_watch]
+} {{} {{mongrel: hello in scope ::test_cd_mongrel}}}
+
+test inherit-3.6 {"configure" allows access to shadowed options} {
+    set ::test_cd_watch ""
+    list [test_cd_mongrel0 configure -test_cd_foo::x hello] \
+         [test_cd_mongrel0 configure -test_cd_bar::x there] \
+         [set ::test_cd_watch]
+} {{} {} {{foo: hello in scope ::test_cd_foo} {bar: there in scope ::test_cd_bar}}}
+
+test inherit-3.7 {"configure" will change several variables at once} {
+    set ::test_cd_watch ""
+    list [test_cd_mongrel0 configure -x one \
+                                     -test_cd_foo::x two \
+                                     -test_cd_bar::x three] \
+         [set ::test_cd_watch]
+} {{} {{mongrel: one in scope ::test_cd_mongrel} {foo: two in scope ::test_cd_foo} {bar: three in scope ::test_cd_bar}}}
+
+test inherit-3.8 {"cget" does proper name resolution} {
+    list [test_cd_mongrel0 cget -x] \
+         [test_cd_mongrel0 cget -test_cd_foo::x] \
+         [test_cd_mongrel0 cget -test_cd_bar::x] \
+         [test_cd_mongrel0 cget -test_cd_mongrel::x]
+} {one two three one}
+
+eval namespace delete [itcl::find classes test_cd_*]
+
+# ----------------------------------------------------------------------
+#  Test inheritance info
+# ----------------------------------------------------------------------
+test inherit-4.1 {define classes for inheritance info} {
+    itcl::class test_cd_foo {
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_bar {
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_foobar {
+        inherit test_cd_foo test_cd_bar
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_geek {
+        method do {args} {eval $args}
+    }
+    itcl::class test_cd_mongrel {
+        inherit test_cd_foobar test_cd_geek
+        method do {args} {eval $args}
+    }
+} {}
+
+test inherit-4.2 {create an object for inheritance tests} {
+    test_cd_mongrel #auto
+} {test_cd_mongrel0}
+
+test inherit-4.3 {"info class" should be virtual} {
+    list [test_cd_mongrel0 info class] \
+         [test_cd_mongrel0 test_cd_foo::do info class] \
+         [test_cd_mongrel0 test_cd_geek::do info class]
+} {::test_cd_mongrel ::test_cd_mongrel ::test_cd_mongrel}
+
+test inherit-4.4 {"info inherit" depends on class scope} {
+    list [test_cd_mongrel0 info inherit] \
+         [test_cd_mongrel0 test_cd_foo::do info inherit] \
+         [test_cd_mongrel0 test_cd_foobar::do info inherit]
+} {{::test_cd_foobar ::test_cd_geek} {} {::test_cd_foo ::test_cd_bar}}
+
+test inherit-4.5 {"info heritage" depends on class scope} {
+    list [test_cd_mongrel0 info heritage] \
+         [test_cd_mongrel0 test_cd_foo::do info heritage] \
+         [test_cd_mongrel0 test_cd_foobar::do info heritage]
+} {{::test_cd_mongrel ::test_cd_foobar ::test_cd_foo ::test_cd_bar ::test_cd_geek} ::test_cd_foo {::test_cd_foobar ::test_cd_foo ::test_cd_bar}}
+
+test inherit-4.6 {built-in "isa" method works} {
+    set status ""
+    foreach c [test_cd_mongrel0 info heritage] {
+        lappend status [test_cd_mongrel0 isa $c]
+    }
+    set status
+} {1 1 1 1 1}
+
+test inherit-4.7 {built-in "isa" method works within methods} {
+    set status ""
+    foreach c [test_cd_mongrel0 info heritage] {
+        lappend status [test_cd_mongrel0 test_cd_foo::do isa $c]
+    }
+    set status
+} {1 1 1 1 1}
+
+test inherit-4.8 {built-in "isa" method recognizes bad classes} {
+    itcl::class test_cd_other {}
+    test_cd_mongrel0 isa test_cd_other
+} {0}
+
+test inherit-4.9 {built-in "isa" method recognizes bad classes} {
+    list [catch {test_cd_mongrel0 isa test_cd_bogus} msg] $msg
+} {1 {class "test_cd_bogus" not found in context "::test_cd_foo"}}
+
+eval namespace delete [itcl::find classes test_cd_*]
+
+# ----------------------------------------------------------------------
+#  Test "find objects"
+# ----------------------------------------------------------------------
+test inherit-5.1 {define classes for inheritance info} {
+    itcl::class test_cd_foo {
+    }
+    itcl::class test_cd_bar {
+    }
+    itcl::class test_cd_foobar {
+        inherit test_cd_foo test_cd_bar
+    }
+    itcl::class test_cd_geek {
+    }
+    itcl::class test_cd_mongrel {
+        inherit test_cd_foobar test_cd_geek
+    }
+} {}
+
+test inherit-5.2 {create objects for info tests} {
+    list [test_cd_foo #auto] [test_cd_foo #auto] \
+         [test_cd_foobar #auto] \
+         [test_cd_geek #auto] \
+         [test_cd_mongrel #auto]
+} {test_cd_foo0 test_cd_foo1 test_cd_foobar0 test_cd_geek0 test_cd_mongrel0}
+
+test inherit-5.3 {find objects: -class qualifier} {
+    lsort [itcl::find objects -class test_cd_foo]
+} {test_cd_foo0 test_cd_foo1}
+
+test inherit-5.4 {find objects: -class qualifier} {
+    lsort [itcl::find objects -class test_cd_mongrel]
+} {test_cd_mongrel0}
+
+test inherit-5.5 {find objects: -isa qualifier} {
+    lsort [itcl::find objects -isa test_cd_foo]
+} {test_cd_foo0 test_cd_foo1 test_cd_foobar0 test_cd_mongrel0}
+
+test inherit-5.6 {find objects: -isa qualifier} {
+    lsort [itcl::find objects -isa test_cd_mongrel]
+} {test_cd_mongrel0}
+
+test inherit-5.7 {find objects: name qualifier} {
+    lsort [itcl::find objects test_cd_foo*]
+} {test_cd_foo0 test_cd_foo1 test_cd_foobar0}
+
+test inherit-5.8 {find objects: -class and -isa qualifiers} {
+    lsort [itcl::find objects -isa test_cd_foo -class test_cd_foobar]
+} {test_cd_foobar0}
+
+test inherit-5.9 {find objects: -isa and name qualifiers} {
+    lsort [itcl::find objects -isa test_cd_foo *0]
+} {test_cd_foo0 test_cd_foobar0 test_cd_mongrel0}
+
+test inherit-5.10 {find objects: usage errors} {
+    list [catch {itcl::find objects -xyzzy value} msg] $msg
+} {1 {wrong # args: should be "itcl::find objects ?-class className? ?-isa className? ?pattern?"}}
+
+eval namespace delete [itcl::find classes test_cd_*]
+
+# ----------------------------------------------------------------------
+#  Test method scoping and execution
+# ----------------------------------------------------------------------
+test inherit-6.1 {define classes for scope tests} {
+    itcl::class test_cd_foo {
+        method check {} {return "foo"}
+        method do {args} {return "foo says: [eval $args]"}
+    }
+    itcl::class test_cd_bar {
+        method check {} {return "bar"}
+        method do {args} {return "bar says: [eval $args]"}
+    }
+    itcl::class test_cd_foobar {
+        inherit test_cd_foo test_cd_bar
+        method check {} {return "foobar"}
+        method do {args} {return "foobar says: [eval $args]"}
+    }
+    itcl::class test_cd_geek {
+        method check {} {return "geek"}
+        method do {args} {return "geek says: [eval $args]"}
+    }
+    itcl::class test_cd_mongrel {
+        inherit test_cd_foobar test_cd_geek
+        method check {} {return "mongrel"}
+        method do {args} {return "mongrel says: [eval $args]"}
+    }
+} {}
+
+test inherit-6.2 {create objects for scoping tests} {
+    list [test_cd_mongrel #auto] [test_cd_foobar #auto]
+} {test_cd_mongrel0 test_cd_foobar0}
+
+test inherit-6.3 {methods are "virtual" outside of the class} {
+    test_cd_mongrel0 check
+} {mongrel}
+
+test inherit-6.4 {specific methods can be accessed by name} {
+    test_cd_mongrel0 test_cd_foo::check
+} {foo}
+
+test inherit-6.5 {methods are "virtual" within a class too} {
+    test_cd_mongrel0 test_cd_foobar::do check
+} {foobar says: mongrel}
+
+test inherit-6.6 {methods are executed where they were defined} {
+    list [test_cd_mongrel0 test_cd_foo::do namespace current] \
+         [test_cd_mongrel0 test_cd_foobar::do namespace current] \
+         [test_cd_mongrel0 do namespace current] \
+} {{foo says: ::test_cd_foo} {foobar says: ::test_cd_foobar} {mongrel says: ::test_cd_mongrel}}
+
+test inherit-6.7 {"virtual" command no longer exists} {
+    list [catch {
+        test_cd_mongrel0 test_cd_foobar::do virtual namespace current
+    } msg] $msg
+} {1 {invalid command name "virtual"}}
+
+test inherit-6.8 {"previous" command no longer exists} {
+    list [catch {
+        test_cd_mongrel0 test_cd_foobar::do previous check
+    } msg] $msg
+} {1 {invalid command name "previous"}}
+
+test inherit-6.9 {errors are detected and reported across class boundaries} {
+    #
+    # NOTE: For tcl8.2.3 and earlier the stack trace will have
+    #       'invoked from within "eval $args"' for the first eval
+    #       statement.  For later versions, it does not.  Use
+    #       string match to reduce the sensitivity to that.
+    #
+    list [catch {
+        test_cd_mongrel0 do test_cd_foobar0 do error "test" "some error"
+    } msg] $msg [string match {some error
+    ("eval" body line 1)*
+    (object "::test_cd_foobar0" method "::test_cd_foobar::do" body line 1)
+    invoked from within
+"test_cd_foobar0 do error test {some error}"
+    ("eval" body line 1)
+    invoked from within
+"eval $args"
+    (object "::test_cd_mongrel0" method "::test_cd_mongrel::do" body line 1)
+    invoked from within
+"test_cd_mongrel0 do test_cd_foobar0 do error "test" "some error""} [set ::errorInfo]]
+} {1 test 1}
+
+test inherit-6.10 {errors codes are preserved across class boundaries} {
+    list [catch {
+        test_cd_mongrel0 do test_cd_foobar0 do error "test" "problem" CODE-BLUE
+    } msg] $msg [set ::errorCode]
+} {1 test CODE-BLUE}
+
+test inherit-6.11 {multi-value error codes are preserved across class boundaries} {
+    list [catch {
+        test_cd_mongrel0 do test_cd_foobar0 do error "test" "problem" "CODE BLUE 123"
+    } msg] $msg [set ::errorCode]
+} {1 test {CODE BLUE 123}}
+
+eval namespace delete [itcl::find classes test_cd_*]
+
+# ----------------------------------------------------------------------
+#  Test inheritance errors
+# ----------------------------------------------------------------------
+test inherit-7.1 {cannot inherit from non-existant class} {
+    list [catch {
+        itcl::class bogus {
+            inherit non_existant_class_xyzzy
+        }
+    } msg] $msg
+} {1 {cannot inherit from "non_existant_class_xyzzy" (class "non_existant_class_xyzzy" not found in context "::")}}
+
+test inherit-7.2 {cannot inherit from procs} {
+    proc inherit_test_proc {x y} {
+        error "never call this"
+    }
+    list [catch {
+        itcl::class bogus {
+            inherit inherit_test_proc
+        }
+    } msg] $msg
+} {1 {cannot inherit from "inherit_test_proc" (class "inherit_test_proc" not found in context "::")}}
+
+test inherit-7.3 {cannot inherit from yourself} {
+    list [catch {
+        itcl::class bogus {
+            inherit bogus
+        }
+    } msg] $msg
+} {1 {class "bogus" cannot inherit from itself}}
+
+test inherit-7.4 {cannot have more than one inherit statement} {
+    list [catch {
+        itcl::class test_inherit_base1 { }
+        itcl::class test_inherit_base2 { }
+        itcl::class bogus {
+            inherit test_inherit_base1
+            inherit test_inherit_base2
+        }
+    } msg] $msg
+} {1 {inheritance "test_inherit_base1 " already defined for class "::bogus"}}
+
+# ----------------------------------------------------------------------
+#  Multiple base class error detection
+# ----------------------------------------------------------------------
+test inherit-8.1 {cannot inherit from the same base class more than once} {
+    itcl::class test_mi_base {}
+    itcl::class test_mi_foo {inherit test_mi_base}
+    itcl::class test_mi_bar {inherit test_mi_base}
+    list [catch {
+        itcl::class test_mi_foobar {inherit test_mi_foo test_mi_bar}
+    } msg] $msg
+} {1 {class "::test_mi_foobar" inherits base class "::test_mi_base" more than once:
+  test_mi_foobar->test_mi_foo->test_mi_base
+  test_mi_foobar->test_mi_bar->test_mi_base}}
+
+itcl::delete class test_mi_base
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/interp.test b/8.x/itcl/tests/interp.test
new file mode 100644 (file)
index 0000000..8ff30c8
--- /dev/null
@@ -0,0 +1,91 @@
+#
+# Tests for using [incr Tcl] in slave interpreters
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: interp.test,v 1.4 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Make sure that slave interpreters can be created and loaded
+#  with [incr Tcl]...
+# ----------------------------------------------------------------------
+test interp-1.1 {create a slave interp with [incr Tcl]} {
+    interp create slave
+    load "" Itcl slave
+    list [slave eval "namespace children :: itcl"] [interp delete slave]
+} {::itcl {}}
+
+test interp-1.2 {create a safe slave interp with [incr Tcl]} {
+    interp create -safe slave
+    load "" Itcl slave
+    list [slave eval "namespace children :: itcl"] [interp delete slave]
+} {::itcl {}}
+
+test interp-1.3 {errors are okay when slave interp is deleted} {
+    interp create slave
+    load "" Itcl slave
+    slave eval {
+        itcl::class Troublemaker {
+            destructor { error "cannot delete this object" }
+        }
+        itcl::class Foo {
+            variable obj ""
+            constructor {} {
+                set obj [Troublemaker #auto]
+            }
+            destructor {
+                delete object $obj
+            }
+        }
+        Foo f
+    }
+    interp delete slave
+} {}
+
+test interp-1.4 {one namespace can cause another to be destroyed} {
+    interp create slave
+    load "" Itcl slave
+    slave eval {
+        namespace eval group {
+            itcl::class base1 {}
+            itcl::class base2 {}
+        }
+        itcl::class TroubleMaker {
+            inherit group::base1 group::base2
+        }
+    }
+    interp delete slave
+} {}
+
+test interp-1.5 {cleanup interp object list, this should not
+        include an object that deletes itself in ctor} {
+    interp create slave
+    load "" Itcl slave
+    slave eval {
+        itcl::class DeleteSelf {
+            constructor {} {
+                itcl::delete object $this
+            }
+        }
+        DeleteSelf ds
+    }
+    interp delete slave
+} {}
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/local.test b/8.x/itcl/tests/local.test
new file mode 100644 (file)
index 0000000..aa138d8
--- /dev/null
@@ -0,0 +1,74 @@
+#
+# Tests for "local" command for creating objects local to a proc
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: local.test,v 1.4 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Test "local" to create objects that only exist within a proc
+# ----------------------------------------------------------------------
+test local-1.1 {define a class to use for testing} {
+    itcl::class test_local {
+        common status ""
+        constructor {} {
+            lappend status "created $this"
+        }
+        destructor {
+            lappend status "deleted $this"
+        }
+        proc clear {} {
+            set status ""
+        }
+        proc check {} {
+            return $status
+        }
+        proc test {} {
+            itcl::local test_local #auto
+            lappend status "processing"
+        }
+        proc test2 {} {
+            itcl::local test_local #auto
+            lappend status "call test..."
+            test
+            lappend status "...back"
+        }
+    }
+    test_local #auto
+} {test_local0}
+
+test local-1.2 {} {
+    test_local::clear
+    test_local::test
+    test_local::check
+} {{created ::test_local::test_local1} processing {deleted ::test_local::test_local1}}
+
+test local-1.3 {} {
+    test_local::clear
+    test_local::test2
+    test_local::check
+} {{created ::test_local::test_local2} {call test...} {created ::test_local::test_local3} processing {deleted ::test_local::test_local3} ...back {deleted ::test_local::test_local2}}
+
+test local-1.4 {} {
+    itcl::find objects -isa test_local
+} {test_local0}
+
+itcl::delete class test_local
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/methods.test b/8.x/itcl/tests/methods.test
new file mode 100644 (file)
index 0000000..2d5dc86
--- /dev/null
@@ -0,0 +1,167 @@
+#
+# Tests for argument lists and method execution
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: methods.test,v 1.6 2006/06/02 19:50:59 hobbs Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Methods with various argument lists
+# ----------------------------------------------------------------------
+test methods-1.1 {define a class with lots of methods and arg lists} {
+    itcl::class test_args {
+        method none {} {
+            return "none"
+        }
+        method two {x y} {
+            return "two: $x $y"
+        }
+        method defvals {x {y def1} {z def2}} {
+            return "defvals: $x $y $z"
+        }
+        method varargs {x {y def1} args} {
+            return "varargs: $x $y ($args)"
+        }
+        method nomagic {args x} {
+            return "nomagic: $args $x"
+        }
+        method clash {x bang boom} {
+            return "clash: $x $bang $boom"
+        }
+        method clash_time {x bang boom} {
+            time {set result "clash_time: $x $bang $boom"} 1
+            return $result
+        }
+        proc crash {x bang boom} {
+            return "crash: $x $bang $boom"
+        }
+        proc crash_time {x bang boom} {
+            time {set result "crash_time: $x $bang $boom"} 1
+            return $result
+        }
+        variable bang "ok"
+        common boom "no-problem"
+    }
+} ""
+
+test methods-1.2 {create an object to execute tests} {
+    test_args ta
+} {ta}
+
+test methods-1.3 {argument checking: not enough args} {
+    list [catch {ta two 1} msg] $msg
+} {1 {wrong # args: should be "ta two x y"}}
+
+test methods-1.4a {argument checking: too many args} {
+    list [catch {ta two 1 2 3} msg] $msg
+} {1 {wrong # args: should be "ta two x y"}}
+
+test methods-1.4b {argument checking: too many args} {
+    list [catch {ta none 1 2 3} msg] $msg
+} {1 {wrong # args: should be "ta none"}}
+
+test methods-1.5a {argument checking: just right} {
+    list [catch {ta two 1 2} msg] $msg
+} {0 {two: 1 2}}
+
+test methods-1.5b {argument checking: just right} {
+    list [catch {ta none} msg] $msg
+} {0 none}
+
+test methods-1.6a {default arguments: not enough args} {
+    list [catch {ta defvals} msg] $msg
+} {1 {wrong # args: should be "ta defvals x ?y? ?z?"}}
+
+test methods-1.6b {default arguments: missing arguments supplied} {
+    list [catch {ta defvals 1} msg] $msg
+} {0 {defvals: 1 def1 def2}}
+
+test methods-1.6c {default arguments: missing arguments supplied} {
+    list [catch {ta defvals 1 2} msg] $msg
+} {0 {defvals: 1 2 def2}}
+
+test methods-1.6d {default arguments: all arguments assigned} {
+    list [catch {ta defvals 1 2 3} msg] $msg
+} {0 {defvals: 1 2 3}}
+
+test methods-1.6e {default arguments: too many args} {
+    list [catch {ta defvals 1 2 3 4} msg] $msg
+} {1 {wrong # args: should be "ta defvals x ?y? ?z?"}}
+
+test methods-1.7a {variable arguments: not enough args} {
+    list [catch {ta varargs} msg] $msg
+} {1 {wrong # args: should be "ta varargs x ?y? ?arg arg ...?"}}
+
+test methods-1.7b {variable arguments: empty} {
+    list [catch {ta varargs 1 2} msg] $msg
+} {0 {varargs: 1 2 ()}}
+
+test methods-1.7c {variable arguments: one} {
+    list [catch {ta varargs 1 2 one} msg] $msg
+} {0 {varargs: 1 2 (one)}}
+
+test methods-1.7d {variable arguments: two} {
+    list [catch {ta varargs 1 2 one two} msg] $msg
+} {0 {varargs: 1 2 (one two)}}
+
+test methods-1.8 {magic "args" argument has no magic unless at end of list} {
+    list [catch {ta nomagic 1 2 3 4} msg] $msg
+} {1 {wrong # args: should be "ta nomagic args x"}}
+
+test methods-1.9 {formal args don't clobber class members} {
+    list [catch {ta clash 1 2 3} msg] $msg \
+         [ta info variable bang -value] \
+         [ta info variable boom -value]
+} {0 {clash: 1 2 3} ok no-problem}
+
+test methods-1.10 {formal args don't clobber class members} {
+    list [catch {test_args::crash 4 5 6} msg] $msg \
+         [ta info variable bang -value] \
+         [ta info variable boom -value]
+} {0 {crash: 4 5 6} ok no-problem}
+
+test methods-1.11 {formal args don't clobber class members, even in "time"} {
+    list [catch {ta clash_time 7 8 9} msg] $msg \
+         [ta info variable bang -value] \
+         [ta info variable boom -value]
+} {0 {clash_time: 7 8 9} ok no-problem}
+
+test methods-1.12 {formal args don't clobber class members, even in "time"} {
+    list [catch {test_args::crash_time a b c} msg] $msg \
+         [ta info variable bang -value] \
+         [ta info variable boom -value]
+} {0 {crash_time: a b c} ok no-problem}
+
+test methods-2.1 {covers leak condition test for compiled locals, no args} {
+    for {set i 0} {$i < 100} {incr i} {
+       ::itcl::class LeakClass {
+            proc leakProc {} { set n 1 }
+       }
+       LeakClass::leakProc
+       ::itcl::delete class LeakClass
+    }
+    list 0
+} 0
+
+# ----------------------------------------------------------------------
+#  Clean up
+# ----------------------------------------------------------------------
+itcl::delete class test_args
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/mkindex.itcl b/8.x/itcl/tests/mkindex.itcl
new file mode 100644 (file)
index 0000000..5480c67
--- /dev/null
@@ -0,0 +1,83 @@
+# Test file for:
+#   auto_mkindex
+#
+# This file provides example cases for testing the Tcl autoloading
+# facility.  Things are much more complicated with namespaces and classes.
+# The "auto_mkindex" facility can no longer be built on top of a simple
+# regular expression parser.  It must recognize constructs like this:
+#
+#   namespace eval foo {
+#       class Internal { ... }
+#       body Internal::func {x y} { ... }
+#       namespace eval bar {
+#           class Another { ... }
+#       }
+#   }
+#
+# Note that class definitions can be nested inside of namespaces.
+#
+# Copyright (c) 1993-1998  Lucent Technologies, Inc.
+
+#
+# Should be able to handle simple class definitions, even if
+# they are prefaced with white space.
+#
+namespace import itcl::*
+
+class Simple1 {
+    variable x 0
+    public method bump {} {incr x}
+}
+  itcl::class Simple2 {
+    variable x 0
+    public variable by 1
+    public method bump {}
+  }
+
+itcl::ensemble ens {
+    part one {x} {}
+    part two {x y} {}
+    part three {x y z} {}
+}
+
+#
+# Should be able to handle "body" and "configbody" declarations.
+#
+body Simple2::bump {} {incr x $by}
+configbody Simple2::by {if {$by <= 0} {error "bad increment"}}
+
+#
+# Should be able to handle class declarations within namespaces,
+# even if they have explicit namespace paths.
+#
+namespace eval buried {
+    class inside {
+        variable x 0
+        public variable by 1
+        public method bump {}
+        method skip {x y z} {}
+        proc find {args} {}
+    }
+    body inside::bump {} {incr x $by}
+    configbody inside::by {if {$by <= 0} {error "bad increment"}}
+
+    class ::top {
+        method skip {x y z} {}
+        method ignore {} {}
+        public proc find {args} {}
+        protected proc notice {args} {}
+    }
+
+    ensemble ens {
+        part one {x} {}
+        part two {x y} {}
+        part three {x y z} {}
+    }
+
+    namespace eval under {
+        itcl::class neath { }
+    }
+    namespace eval deep {
+        ::itcl::class within { }
+    }
+}
diff --git a/8.x/itcl/tests/mkindex.test b/8.x/itcl/tests/mkindex.test
new file mode 100644 (file)
index 0000000..0fe09f8
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Tests for "auto_mkindex" and autoloading facility
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: mkindex.test,v 1.6 2004/02/13 06:37:24 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Test "auto_mkindex" in the presence of class definitions
+# ----------------------------------------------------------------------
+test mkindex-1.1 {remove any existing tclIndex file} {
+    file delete tclIndex
+    file exists tclIndex
+} {0}
+
+test mkindex-1.2 {build tclIndex based on a test file} {
+    if {[pwd] != $::tcltest::testsDirectory} {
+       file copy -force [file join $::tcltest::testsDirectory mkindex.itcl] \
+               ./mkindex.itcl
+    }
+    auto_mkindex . mkindex.itcl
+    if {[pwd] != $::tcltest::testsDirectory} {
+       file delete -force ./mkindex.itcl
+    }
+    file exists tclIndex
+} {1}
+
+set element "{source [file join . mkindex.itcl]}"
+
+test mkindex-1.3 {examine tclIndex} {
+    namespace eval itcl_mkindex_tmp {
+        set dir "."
+        variable auto_index
+        source tclIndex
+        set result ""
+        foreach elem [lsort [array names auto_index]] {
+            lappend result [list $elem $auto_index($elem)]
+        }
+        set result
+    }
+} "{::Simple2::bump $element} {::Simple2::by $element} {::buried::deep::within $element} {::buried::ens $element} {::buried::inside $element} {::buried::inside::bump $element} {::buried::inside::by $element} {::buried::inside::find $element} {::buried::under::neath $element} {::top::find $element} {::top::notice $element} {Simple1 $element} {Simple2 $element} {ens $element} {top $element}"
+
+::tcltest::removeFile tclIndex
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/namespace.test b/8.x/itcl/tests/namespace.test
new file mode 100644 (file)
index 0000000..258318d
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# Tests for classes within namespaces
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: namespace.test,v 1.5 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Classes within namespaces
+# ----------------------------------------------------------------------
+test namespace-1.1 {same class name can be used in different namespaces} {
+    namespace eval test_ns_1 {
+        itcl::class Counter {
+            variable num 0
+            method ++ {{by 1}} {
+                incr num $by
+            }
+            method do {args} {
+                return [eval $args]
+            }
+            common tag 1
+        }
+        proc exists {} { return "don't clobber me!" }
+    }
+    namespace eval test_ns_2 {
+        itcl::class Counter {
+            variable num 0
+            method ++ {{by 2}} {
+                if {$num == 0} {
+                    set num 1
+                } else {
+                    set num [expr $num*$by]
+                }
+            }
+            method do {args} {
+                return [eval $args]
+            }
+            common tag 2
+        }
+    }
+} ""
+
+test namespace-1.2 {classes in different namespaces are different} {
+    list [namespace eval test_ns_1::Counter {info variable tag}] \
+         [namespace eval test_ns_2::Counter {info variable tag}] \
+} {{protected common ::test_ns_1::Counter::tag 1 1} {protected common ::test_ns_2::Counter::tag 2 2}}
+
+test namespace-1.3 {create an object in one namespace} {
+    namespace eval test_ns_1 {
+        list [Counter c] [c ++] [c ++] [c ++] [c ++]
+    }
+} {c 1 2 3 4}
+
+test namespace-1.4 {create an object in another namespace} {
+    namespace eval test_ns_2 {
+        list [Counter c] [c ++] [c ++] [c ++] [c ++]
+    }
+} {c 1 2 4 8}
+
+test namespace-1.5 {can find classes wrapped in a namespace} {
+    list [catch {test_ns_1::c do itcl::find objects -isa Counter} msg] $msg \
+         [catch {test_ns_1::c do itcl::find objects -class Counter} msg] $msg
+} {0 ::test_ns_1::c 0 ::test_ns_1::c}
+
+test namespace-1.6 {can't create an object that clobbers a command in this namespace} {
+    list [catch {namespace eval test_ns_1 {Counter exists}} msg] $msg
+} {1 {command "exists" already exists in namespace "::test_ns_1"}}
+
+test namespace-1.7 {can create an object that shadows a command in the global namespace} {
+    list [catch {namespace eval test_ns_1 {Counter lreplace}} msg] $msg \
+         [catch {itcl::find objects *lreplace} msg] $msg \
+         [namespace eval test_ns_1 {namespace which lreplace}]
+} {0 lreplace 0 ::test_ns_1::lreplace ::test_ns_1::lreplace}
+
+namespace delete test_ns_1 test_ns_2
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/old/AAA.test b/8.x/itcl/tests/old/AAA.test
new file mode 100644 (file)
index 0000000..c686866
--- /dev/null
@@ -0,0 +1,82 @@
+#
+# AAA - first test executed in test suite
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: AAA.test,v 1.1 1998/07/27 18:41:20 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ----------------------------------------------------------------------
+#  SHOULD HAVE A CLEAN SLATE
+# ----------------------------------------------------------------------
+test {No object info (no classes)} {
+       itcl_info classes
+} {
+       $result == ""
+}
+
+test {No object info (no objects)} {
+       itcl_info objects
+} {
+       $result == ""
+}
+
+# ----------------------------------------------------------------------
+#  TEST CLASS AUTO-LOADING
+# ----------------------------------------------------------------------
+test {Force auto-loading through inheritance} {
+       FooBar x
+} {
+       $result == "x"
+}
+
+test {Info: all classes} {
+       itcl_info classes
+} {
+       [test_cmp_lists $result {Foo Bar FooBar}]
+}
+
+test {Info: all classes matching a pattern} {
+       itcl_info classes *oo*
+} {
+       [test_cmp_lists $result {Foo FooBar}]
+}
+
+# ----------------------------------------------------------------------
+#  OBJECT AUTO-NUMBERING
+# ----------------------------------------------------------------------
+test {Create object with auto-naming} {
+       FooBar #auto -blit x
+} {
+       $result == "fooBar0" && [fooBar0 info public blit -value] == "x"
+}
+
+test {Create object with auto-naming} {
+       FooBar #auto -blit y
+} {
+       $result == "fooBar1" && [fooBar1 info public blit -value] == "y"
+}
+
+test {Auto-naming should avoid names already in use} {
+       FooBar fooBar2
+       FooBar fooBar3
+       FooBar fooBar4
+       FooBar #auto
+} {
+       $result == "fooBar5"
+}
+
+test {Destroy all outstanding objects} {
+       foreach obj [itcl_info objects] {
+               $obj delete
+       }
+} {
+       $result == ""
+}
diff --git a/8.x/itcl/tests/old/Bar.tcl b/8.x/itcl/tests/old/Bar.tcl
new file mode 100644 (file)
index 0000000..d4681ec
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: Bar.tcl,v 1.1 1998/07/27 18:41:21 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+itcl_class Bar {
+       #
+       #  Constructor/destructor add their name to a global var for
+       #  tracking implicit constructors/destructors
+       #
+       constructor {config} {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+       destructor {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+
+       method config {config} {
+               return $config
+       }
+
+       #
+       #  Define variables that will be shadowed by another class.
+       #
+       public blit
+       protected _blit
+}
diff --git a/8.x/itcl/tests/old/BarFoo.tcl b/8.x/itcl/tests/old/BarFoo.tcl
new file mode 100644 (file)
index 0000000..973fdbb
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: BarFoo.tcl,v 1.1 1998/07/27 18:41:21 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+itcl_class BarFoo {
+       inherit Bar Foo
+
+       #
+       #  Constructor/destructor add their name to a global var for
+       #  tracking implicit constructors/destructors
+       #
+       constructor {config} {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+       destructor {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+}
diff --git a/8.x/itcl/tests/old/Baz.tcl b/8.x/itcl/tests/old/Baz.tcl
new file mode 100644 (file)
index 0000000..efd6172
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: Baz.tcl,v 1.1 1998/07/27 18:41:21 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+itcl_class Baz {
+       #
+       #  Avoid defining constructor/destructor
+       #
+
+       #
+       #  Generic method for doing something in "Baz" interp
+       #
+       method do {cmds} {
+               return "Baz says '[eval $cmds]'"
+       }
+}
diff --git a/8.x/itcl/tests/old/Foo.tcl b/8.x/itcl/tests/old/Foo.tcl
new file mode 100644 (file)
index 0000000..2986dac
--- /dev/null
@@ -0,0 +1,99 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: Foo.tcl,v 1.1 1998/07/27 18:41:22 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+itcl_class Foo {
+       #
+       #  Constructor/destructor add their name to a global var for
+       #  tracking implicit constructors/destructors
+       #
+       constructor {config} {
+               global WATCH
+               lappend WATCH [namespace current]
+               set foos([namespace tail $this]) $this
+               incr nfoo
+       }
+       destructor {
+               global WATCH
+               lappend WATCH [namespace current]
+               unset foos([namespace tail $this])
+       }
+
+       method nothing {} {}
+
+       method do {cmds} {
+               return "Foo says '[eval $cmds]'"
+       }
+
+       #
+       #  Test formal arguments for methods/procs
+       #  (formal args should not clobber data members)
+       #
+       method testMethodArgs {blit _blit args} {
+               return "$blit, $_blit, and [llength $args] other args"
+       }
+       proc testProcArgs {nfoo args} {
+               return "$nfoo, and [llength $args] other args"
+       }
+
+       #
+       #  Test methods using the "config" argument
+       #
+       method config {{config "-blit auto -blat matic"}} {
+               return $config
+       }
+       method xconfig {x config} {
+               return "$x|$config"
+       }
+       method configx {config x} {
+               return "$config|$x"
+       }
+       method xecho {x args} {
+               return "$x | [llength $args]: $args"
+       }
+
+       #
+       #  Test procs and access to common vars
+       #
+       proc echo {x args} {
+               return "$x | [llength $args]: $args"
+       }
+       proc foos {{pattern *}} {
+               set retn {}
+               foreach i [array names foos] {
+                       if {$i != "_ignore_" && [string match $pattern $i]} {
+                               lappend retn $i
+                       }
+               }
+               return $retn
+       }
+       proc nfoos {} {
+               return $nfoo
+       }
+
+       #
+       #  Test public/protected/common variable definitions
+       #
+       public blit
+       public blat 0
+       public blot 1 {global WATCH; set WATCH "blot=$blot"}
+
+       protected _blit
+       protected _blat 0
+
+       common foos
+       set foos(_ignore_) "foos-is-now-an-array"
+
+       common nfoo 0
+}
diff --git a/8.x/itcl/tests/old/FooBar.tcl b/8.x/itcl/tests/old/FooBar.tcl
new file mode 100644 (file)
index 0000000..d148c74
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: FooBar.tcl,v 1.1 1998/07/27 18:41:22 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+itcl_class FooBar {
+       inherit Foo Bar
+
+       #
+       #  Constructor/destructor add their name to a global var for
+       #  tracking implicit constructors/destructors
+       #
+       constructor {config} {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+       destructor {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+}
diff --git a/8.x/itcl/tests/old/Geek.tcl b/8.x/itcl/tests/old/Geek.tcl
new file mode 100644 (file)
index 0000000..d3037a8
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: Geek.tcl,v 1.1 1998/07/27 18:41:23 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+itcl_class Geek {
+
+       #
+       #  Constructor/destructor add their name to a global var for
+       #  tracking implicit constructors/destructors
+       #
+       constructor {config} {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+       destructor {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+
+       method do {cmds} {
+               return "Geek says '[eval $cmds]'"
+       }
+
+       method config {config} {
+               return $config
+       }
+
+       #
+       #  Define variables that will be shadowed by another class.
+       #
+       public blat
+       protected _blat
+}
diff --git a/8.x/itcl/tests/old/Mongrel.tcl b/8.x/itcl/tests/old/Mongrel.tcl
new file mode 100644 (file)
index 0000000..03f0b72
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: Mongrel.tcl,v 1.1 1998/07/27 18:41:23 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+itcl_class Mongrel {
+       inherit FooBar Geek
+
+       #
+       #  Constructor/destructor add their name to a global var for
+       #  tracking implicit constructors/destructors
+       #
+       constructor {config} {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+       destructor {
+               global WATCH
+               lappend WATCH [namespace current]
+       }
+
+       public blit nonnull
+       public tag
+}
diff --git a/8.x/itcl/tests/old/VirtualErr.tcl b/8.x/itcl/tests/old/VirtualErr.tcl
new file mode 100644 (file)
index 0000000..61baf0d
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: VirtualErr.tcl,v 1.1 1998/07/27 18:41:23 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+itcl_class VirtualErr {
+       #
+       #  The following inherit statement will cause an error,
+       #  since it will find the same base class "Foo" inherited
+       #  from several places.
+       #
+       inherit Mongrel Foo BarFoo
+}
diff --git a/8.x/itcl/tests/old/all b/8.x/itcl/tests/old/all
new file mode 100644 (file)
index 0000000..95c5e82
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: all,v 1.1 1998/07/27 18:41:24 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+variable WATCH
+
+global TEST_ABS_TOL TEST_REL_TOL
+set TEST_ABS_TOL 1.0e-6
+set TEST_REL_TOL 1.0e-5
+
+if {![file readable "testlib.tcl"]} {
+       error "ERROR: execute test suite in \"tests\" directory"
+}
+
+lappend auto_path .
+
+foreach i [lsort [glob ./*.test]] {
+       source $i
+}
+puts stdout "== ALL TESTS SUCCESSFUL =="
+exit
diff --git a/8.x/itcl/tests/old/basic.test b/8.x/itcl/tests/old/basic.test
new file mode 100644 (file)
index 0000000..240394f
--- /dev/null
@@ -0,0 +1,408 @@
+#
+# Basic tests for class definition and method/proc access
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: basic.test,v 1.1 1998/07/27 18:41:24 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ----------------------------------------------------------------------
+#  CLEAN THE SLATE
+# ----------------------------------------------------------------------
+foreach obj [itcl_info objects -class Foo] {
+       $obj delete
+}
+
+# ----------------------------------------------------------------------
+#  CREATING OBJECTS
+# ----------------------------------------------------------------------
+test {Create a simple object} {
+       Foo x
+} {
+       $result == "x"
+}
+
+test {Make sure that object names cannot be duplicated} {
+       catch "Foo x" errmsg
+} {
+       $result == 1
+}
+
+test {Create another object} {
+       Foo xx
+} {
+       $result == "xx"
+}
+
+test {Create an object with an automatic name} {
+       Foo #auto
+} {
+       [string match foo* $result]
+}
+
+test {Get list of objects in a class} {
+       itcl_info objects -class Foo
+} {
+       [llength $result] == 3
+}
+
+# ----------------------------------------------------------------------
+#  PUBLIC VARIABLES
+# ----------------------------------------------------------------------
+test {Info: all public variables} {
+       x info public
+} {
+       [test_cmp_lists $result {Foo::blit Foo::blat Foo::blot}]
+}
+
+test {Info: public variable initial value} {
+       x info public blit -init
+} {
+       $result == ""
+}
+
+test {Info: public variable initial value (undefined)} {
+       x info public blit -value
+} {
+       $result == "<undefined>"
+}
+
+test {Info: public variable initial value} {
+       x info public blat -init
+} {
+       $result == 0
+}
+
+test {Info: public variable current value} {
+       x info public blot -value
+} {
+       $result == 1
+}
+
+test {Info: public variable config statement} {
+       x info public blit -config
+} {
+       $result == ""
+}
+
+test {Info: public variable config statement} {
+       x info public blot -config
+} {
+       $result == {global WATCH; set WATCH "blot=$blot"}
+}
+
+# ----------------------------------------------------------------------
+#  CONFIG-ING PUBLIC VARIABLES
+# ----------------------------------------------------------------------
+test {Setting public variables via "config"} {
+       x config -blit 27 -blat xyz
+} {
+       $result == "Foo::blit Foo::blat"
+}
+
+test {Info: public variable init/current value} {
+       x info public blit -init -value
+} {
+       $result == {{} 27}
+}
+
+test {Info: public variable init/current value} {
+       x info public blat -init -value
+} {
+       $result == {0 xyz}
+}
+
+test {"config" is ordinary arg if it is not last arg} {
+       x configx -blit pdq
+} {
+       $result == {-blit|pdq}
+}
+
+test {Public variables with "config" code} {
+       set WATCH ""
+       concat [x config -blot abc] / $WATCH
+} {
+       $result == "Foo::blot / blot=abc"
+}
+
+test {Make sure object data is local to objects} {
+       x config -blit abc
+       xx config -blit xyz
+       concat [x info public blit -value] / [xx info public blit -value]
+} {
+       $result == "abc / xyz"
+}
+
+# ----------------------------------------------------------------------
+#  PROTECTED VARIABLES
+# ----------------------------------------------------------------------
+test {Info: all protected variables} {
+       x info protected
+} {
+       [test_cmp_lists $result {Foo::_blit Foo::_blat Foo::this}]
+}
+
+test {Info: protected "this" variable} {
+       x info protected this -value
+} {
+       $result == "::x"
+}
+
+test {Info: protected "this" variable} {
+       xx info protected this -value
+} {
+       $result == "::xx"
+}
+
+test {Info: protected variable initial value} {
+       x info protected _blit -init
+} {
+       $result == ""
+}
+
+test {Info: protected variable access/value} {
+       x do {set _blit rst}
+} {
+       $result == "Foo says 'rst'" &&
+       [x info protected _blit -value] == "rst"
+}
+
+# ----------------------------------------------------------------------
+#  COMMON VARIABLES
+# ----------------------------------------------------------------------
+test {Info: all protected variables} {
+       x info common
+} {
+       [test_cmp_lists $result {Foo::foos Foo::nfoo}]
+}
+
+test {Info: common variable initial value} {
+       x info common foos -init
+} {
+       $result == ""
+}
+
+test {Info: common variable initial value} {
+       x info common nfoo -init
+} {
+       $result == 0
+}
+
+test {Info: common variable access/value} {
+       x do {set nfoo 999}
+       x info common nfoo -value
+} {
+       $result == 999
+}
+
+test {Make sure common data is really common} {
+       x do {set nfoo 0}
+       x info common nfoo -value
+} {
+       $result == [xx info common nfoo -value]
+}
+
+test {Access common data in proc} {
+       x do {set nfoo 10}
+       Foo :: nfoos
+} {
+       $result == 10
+}
+
+test {Common variables can be initialized within class definition} {
+       x do {if {[info exists foos(_ignore_)]} {set foos(_ignore_)}}
+} {
+       $result == "Foo says 'foos-is-now-an-array'"
+}
+
+test {Arrays as common data} {
+       Foo :: foos
+} {
+       [test_cmp_lists $result [itcl_info objects -class Foo]]
+}
+
+# ----------------------------------------------------------------------
+#  METHODS
+# ----------------------------------------------------------------------
+test {Info: all methods} {
+       x info method
+} {
+       [test_cmp_lists $result {
+               Foo::constructor Foo::destructor
+               Foo::nothing Foo::do Foo::xecho
+               Foo::config Foo::xconfig Foo::configx
+               Foo::testMethodArgs
+               Foo::configure Foo::delete Foo::cget Foo::isa
+       }]
+}
+
+test {Info: method args} {
+       x info method nothing -args
+} {
+       $result == ""
+}
+
+test {Info: method args} {
+       x info method xconfig -args
+} {
+       $result == "x config"
+}
+
+test {Info: method body} {
+       x info method nothing -body
+} {
+       $result == ""
+}
+
+test {Info: method body} {
+       x info method xconfig -body
+} {
+       $result == {
+               return "$x|$config"
+       }
+}
+
+# ----------------------------------------------------------------------
+#  PROCS
+# ----------------------------------------------------------------------
+test {Info: all procs} {
+       x info proc
+} {
+       [test_cmp_lists $result {
+               Foo::echo Foo::foos Foo::nfoos Foo::testProcArgs
+       }]
+}
+
+test {Info: proc args} {
+       x info proc nfoos -args
+} {
+       $result == ""
+}
+
+test {Info: proc args} {
+       x info proc foos -args
+} {
+       $result == "{pattern *}"
+}
+
+test {Info: proc body} {
+       x info proc nfoos -body
+} {
+       $result == {
+               return $nfoo
+       }
+}
+
+test {Info: proc body} {
+       x info body nfoos
+} {
+       $result == {
+               return $nfoo
+       }
+}
+
+# ----------------------------------------------------------------------
+#  ARGUMENT LISTS
+# ----------------------------------------------------------------------
+test {Default arguments can get assigned a proper value} {
+       Foo :: foos x*
+} {
+       [test_cmp_lists $result {x xx}]
+}
+
+test {Default value for "config" argument} {
+       x config
+} {
+       $result == "Foo::blit Foo::blat" &&
+       [x info public blit -value] == "auto" &&
+       [x info public blat -value] == "matic"
+}
+
+test {"args" formal argument absorbs extra arguments} {
+       Foo :: echo abc 1 2 3
+} {
+       $result == "abc | 3: 1 2 3"
+}
+
+test {"args" formal argument absorbs extra arguments} {
+       Foo :: echo def
+} {
+       $result == "def | 0: "
+}
+
+test {"args" formal argument absorbs extra arguments} {
+       x xecho abc 1 2 3
+} {
+       $result == "abc | 3: 1 2 3"
+}
+
+test {"args" formal argument absorbs extra arguments} {
+       x xecho def
+} {
+       $result == "def | 0: "
+}
+
+test {Extra args cause an error} {
+       catch "x configx arg arg error"
+} {
+       $result != 0
+}
+
+test {Extra args cause an error} {
+       catch "x nothing error"
+} {
+       $result != 0
+}
+
+test {Formal arguments don't clobber public/protected variables} {
+       x do {
+               set blit okay
+               set _blit no-problem
+       }
+       x testMethodArgs yuck puke etc.
+} {
+       $result == "yuck, puke, and 1 other args" &&
+       [x info public blit -value] == "okay" &&
+       [x info protected _blit -value] == "no-problem"
+}
+
+test {Formal arguments don't clobber common variables} {
+       Foo :: testProcArgs yuck etc.
+} {
+       $result == "yuck, and 1 other args" &&
+       [x info common nfoo -value] != "yuck"
+}
+
+# ----------------------------------------------------------------------
+#  DELETING OBJECTS
+# ----------------------------------------------------------------------
+test {Delete an object} {
+       x delete
+} {
+       $result == ""
+}
+
+test {Delete an object} {
+       xx delete
+} {
+       $result == ""
+}
+
+test {Destructor is properly invoked} {
+       Foo :: foos
+} {
+       [test_cmp_lists $result [itcl_info objects -class Foo]]
+}
+
+test {Object names are removed as commands} {
+       expr {[info commands x] == "" && [info commands xx] == ""}
+} {
+       $result == 1
+}
diff --git a/8.x/itcl/tests/old/inherit.test b/8.x/itcl/tests/old/inherit.test
new file mode 100644 (file)
index 0000000..7921cdc
--- /dev/null
@@ -0,0 +1,272 @@
+#
+# Tests for inheritance and scope handling
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: inherit.test,v 1.1 1998/07/27 18:41:25 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ----------------------------------------------------------------------
+#  MULTIPLE BASE-CLASS ERROR DETECTION
+# ----------------------------------------------------------------------
+test {Cannot inherit from the same base class more than once} {
+       catch "VirtualErr" errmsg
+       set errmsg
+} {
+       [string match {*class "::VirtualErr" inherits base class "::Foo" more than once:
+  VirtualErr->Mongrel->FooBar->Foo
+  VirtualErr->Foo
+  VirtualErr->BarFoo->Foo} $result]
+}
+
+# ----------------------------------------------------------------------
+#  CONSTRUCTION
+# ----------------------------------------------------------------------
+test {Constructors should be invoked implicitly} {
+       set WATCH ""
+       concat [Mongrel m] / $WATCH
+} {
+       $result == "m / ::Geek ::Bar ::Foo ::FooBar ::Mongrel"
+}
+
+test {Initialization of shadowed variables works properly} {
+       concat [m info public blit -value] / [m info public Foo::blit -value]
+} {
+       $result == "nonnull / <undefined>"
+}
+
+# ----------------------------------------------------------------------
+#  PUBLIC VARIABLES
+# ----------------------------------------------------------------------
+test {Inherited "config" method works on derived classes} {
+       m config -blit xyz -Foo::blit pdq
+} {
+       $result == "Mongrel::blit Foo::blit"
+}
+
+test {Inherited "config" method works on derived classes} {
+       m config -blit xyz -Foo::blit pdq
+       concat [m info public blit -value] / [m info public Foo::blit -value]
+} {
+       $result == "xyz / pdq"
+}
+
+test {Inherited "config" method works on derived classes} {
+       m config -tag #0000
+} {
+       $result == "Mongrel::tag"
+}
+
+# ----------------------------------------------------------------------
+#  INHERITANCE INFO
+# ----------------------------------------------------------------------
+test {Info: class} {
+       m info class
+} {
+       $result == "::Mongrel"
+}
+
+test {Info: inherit} {
+       m info inherit
+} {
+       $result == "::FooBar ::Geek"
+}
+
+test {Info: heritage} {
+       m info heritage
+} {
+       $result == "::Mongrel ::FooBar ::Foo ::Bar ::Geek"
+}
+
+test {Built-in "isa" method} {
+       set status 1
+       foreach c [m info heritage] {
+               set status [expr {$status && [m isa $c]}]
+       }
+       set status
+} {
+       $result == 1
+}
+
+test {Built-in "isa" method} {
+    itcl_class Watermelon {}
+       m isa Watermelon
+} {
+       $result == 0
+}
+
+# ----------------------------------------------------------------------
+#  SCOPE MANIPULATION
+# ----------------------------------------------------------------------
+test {commands normally execute in the scope of their class} {
+       m Foo::do {namespace current}
+} {
+       $result == "Foo says '::Foo'"
+}
+
+test {"virtual" command moves scope to most specific class} {
+       m Foo::do {virtual namespace current}
+} {
+       $result == "Foo says '::Mongrel'"
+}
+
+test {"previous" command moves scope upward in hierarchy} {
+       m do {virtual previous namespace current}
+} {
+       $result == "Foo says '::FooBar'"
+}
+
+test {"previous" command can be chained} {
+       m do {virtual previous previous namespace current}
+} {
+       $result == "Foo says '::Foo'"
+}
+
+# ----------------------------------------------------------------------
+#  METHOD INVOCATION
+# ----------------------------------------------------------------------
+test {Simple method names are assigned based on heritage} {
+       m do {concat "$this ([virtual info class]) at scope [namespace current]"}
+} {
+       $result == "Foo says '::m (Mongrel) at scope ::Foo'"
+}
+
+test {Explicit scoping can be used to reach shadowed members} {
+       m Geek::do {concat "$this ([virtual info class]) at scope [namespace current]"}
+} {
+       $result == "Geek says '::m (Mongrel) at scope ::Geek'"
+}
+
+test {Methods execute in local scope of class, e.g., Foo::do} {
+       m config -blit abc -Foo::blit def
+       m Foo::do {set blit xyz}
+       concat [m info public blit -value] / [m info public Foo::blit -value]
+} {
+       $result == "abc / xyz"
+}
+
+# ----------------------------------------------------------------------
+#  DESTRUCTION
+# ----------------------------------------------------------------------
+test {Destructors should be invoked implicitly} {
+       set WATCH ""
+       concat [m delete] / $WATCH
+} {
+       $result == "/ ::Mongrel ::FooBar ::Foo ::Bar ::Geek"
+}
+
+# ----------------------------------------------------------------------
+#  OBJECT INFO
+# ----------------------------------------------------------------------
+foreach obj [itcl_info objects] {
+       $obj delete
+}
+Mongrel m
+FooBar fb
+Foo f
+Geek g
+
+test {Object queries can be restricted by object name} {
+       itcl_info objects f*
+} {
+       [test_cmp_lists $result {f fb}]
+}
+
+test {Object queries can be restricted to specific classes} {
+       itcl_info objects -class Foo
+} {
+       $result == "f"
+}
+
+test {Object queries can be restricted by object heritage} {
+       itcl_info objects -isa Foo
+} {
+       [test_cmp_lists $result {m f fb}]
+}
+
+test {Object queries can be restricted by object name / specific classes} {
+       itcl_info objects f* -class Foo
+} {
+       $result == "f"
+}
+
+test {Object queries can be restricted by object name / object heritage} {
+       itcl_info objects f* -isa Foo
+} {
+       [test_cmp_lists $result {f fb}]
+}
+
+# ----------------------------------------------------------------------
+#  ERROR HANDLING ACROSS CLASS BOUNDARIES
+# ----------------------------------------------------------------------
+Mongrel m1
+FooBar fb2
+
+test {Errors and detected and reported across class boundaries} {
+       set status [catch {m1 do {fb2 do {error "test"}}} mesg]
+       format "$mesg $status"
+} {
+       $result == "test 1"
+}
+
+test {Stack trace unwinds properly across class boundaries} {
+       catch {m1 do {fb2 do {error "test"}}} mesg
+       format "$errorInfo"
+} {
+       $result == {test
+    while executing
+"error "test""
+    ("eval" body line 1)
+    invoked from within
+"eval $cmds"
+    invoked from within
+"return "Foo says '[eval $cmds]..."
+    (object "::fb2" method "::Foo::do" body line 2)
+    invoked from within
+"fb2 do {error "test"}"
+    ("eval" body line 1)
+    invoked from within
+"eval $cmds"
+    invoked from within
+"return "Foo says '[eval $cmds]..."
+    (object "::m1" method "::Foo::do" body line 2)
+    invoked from within
+"m1 do {fb2 do {error "test"}}"}
+}
+
+test {Stack trace unwinds properly across class boundaries} {
+       catch {m1 do {fb2 do {error "test" "some error"}}} mesg
+       format "$errorInfo"
+} {
+       $result == {some error
+    ("eval" body line 1)
+    invoked from within
+"eval $cmds"
+    invoked from within
+"return "Foo says '[eval $cmds]..."
+    (object "::fb2" method "::Foo::do" body line 2)
+    invoked from within
+"fb2 do {error "test" "some error"}"
+    ("eval" body line 1)
+    invoked from within
+"eval $cmds"
+    invoked from within
+"return "Foo says '[eval $cmds]..."
+    (object "::m1" method "::Foo::do" body line 2)
+    invoked from within
+"m1 do {fb2 do {error "test" "some error"}}"}
+}
+
+test {Error codes are preserved across class boundaries} {
+       catch {m1 do {fb2 do {error "test" "some error" CODE-BLUE}}} mesg
+       format "$errorCode"
+} {
+       $result == "CODE-BLUE"
+}
diff --git a/8.x/itcl/tests/old/tclIndex b/8.x/itcl/tests/old/tclIndex
new file mode 100644 (file)
index 0000000..85918fe
--- /dev/null
@@ -0,0 +1,24 @@
+# Tcl autoload index file, version 2.0
+# This file is generated by the "auto_mkindex" command
+# and sourced to set up indexing information for one or
+# more commands.  Typically each line is a command that
+# sets an element in the auto_index array, where the
+# element name is the name of a command and the value is
+# a script that loads the command.
+
+set auto_index(Bar) "source $dir/Bar.tcl"
+set auto_index(Foo) "source $dir/Foo.tcl"
+set auto_index(BarFoo) "source $dir/BarFoo.tcl"
+set auto_index(FooBar) "source $dir/FooBar.tcl"
+set auto_index(Geek) "source $dir/Geek.tcl"
+set auto_index(Mongrel) "source $dir/Mongrel.tcl"
+set auto_index(VirtualErr) "source $dir/VirtualErr.tcl"
+set auto_index(test) "source $dir/testlib.tcl"
+set auto_index(test_cmp_nums) "source $dir/testlib.tcl"
+set auto_index(test_cmp_vectors) "source $dir/testlib.tcl"
+set auto_index(test_cmp_lists) "source $dir/testlib.tcl"
+set auto_index(upvarTest_show_var) "source $dir/upvar.test"
+set auto_index(upvarTest_upvar_in_procs) "source $dir/upvar.test"
+set auto_index(uplevelTest_show_var) "source $dir/uplevel.test"
+set auto_index(uplevelTest_do) "source $dir/uplevel.test"
+set auto_index(Baz) "source $dir/Baz.tcl"
diff --git a/8.x/itcl/tests/old/testlib.tcl b/8.x/itcl/tests/old/testlib.tcl
new file mode 100644 (file)
index 0000000..070a547
--- /dev/null
@@ -0,0 +1,131 @@
+#
+# Old test suite for [incr Tcl] v1.5
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: testlib.tcl,v 1.1 1998/07/27 18:41:26 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ----------------------------------------------------------------------
+#  USAGE:  test <test-desc> <test-cmd> <check>
+#
+#  Executes the given test, the evaluates the <check> condition to
+#  see if the test passed.  The result from the <test-cmd> is kept
+#  in the variable $result.  If this condition evaluates non-zero,
+#  the test has passed.  Otherwise, the test has failed.  A variety
+#  if checking routines (test_cmp_*) are provided below to make
+#  the check condition easier to write.
+# ----------------------------------------------------------------------
+proc test {desc cmd check} {
+    set result [uplevel $cmd]
+
+    if {![expr $check]} {
+               puts stdout "-------------------------------------------------------"
+               puts stdout ">>>> FAILED TEST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
+               puts stdout "-------------------------------------------------------"
+               set lines [split $desc "\n"]
+               foreach i $lines {
+               puts stdout $i
+               }
+               puts stdout "======================================================="
+               set lines [split $cmd "\n"]
+               set label TEST
+               foreach i $lines {
+               puts stdout "   $label | $i"
+                       set label "    "
+               }
+               puts stdout "-------------------------------------------------------"
+               set lines [split $check "\n"]
+               set label CHECK
+               foreach i $lines {
+                       if {$i != ""} {
+                       puts stdout "  $label | $i"
+                               set label "     "
+                       }
+               }
+               puts stdout "-------------------------------------------------------"
+               set lines [split $result "\n"]
+               set label RESULT
+               foreach i $lines {
+                       if {$i != ""} {
+                       puts stdout " $label | \$result => $i"
+                               set label "      "
+                       }
+               }
+               puts stdout "======================================================="
+               error "tests aborted"
+    }
+}
+
+# ----------------------------------------------------------------------
+#  USAGE:  test_cmp_nums <num1> <num2>
+#
+#  Compares two numbers to see if they are "equal."  Numbers are
+#  "equal" if they have an absolute value greater than 1.0e-6 and they
+#  have at least 5 significant figures.  Returns 1/0 for true/false.
+# ----------------------------------------------------------------------
+proc test_cmp_nums {num1 num2} {
+       global TEST_ABS_TOL TEST_REL_TOL
+
+       if {[expr abs($num1)] > $TEST_ABS_TOL &&
+           [expr abs($num2)] > $TEST_ABS_TOL} {
+               set avg [expr 0.5*($num1+$num2)]
+               set diff [expr abs(($num1-$num2)/$avg)]
+
+               if {$diff > $TEST_REL_TOL} {
+                       return 0
+               }
+       }
+       return 1
+}
+
+# ----------------------------------------------------------------------
+#  USAGE:  test_cmp_vectors <list1> <list2>
+#
+#  Compares two lists of numbers to see if they are "equal."  Vectors
+#  are "equal" if elements are "equal" in the numeric sense.
+#  Returns 1/0 for true/false.
+# ----------------------------------------------------------------------
+proc test_cmp_vectors {list1 list2} {
+       if {[llength $list1] != [llength $list2]} {
+               return 0
+       }
+       for {set i 0} {$i < [llength $list1]} {incr i} {
+               set n1 [lindex $list1 $i]
+               set n2 [lindex $list2 $i]
+
+               if {![test_cmp_nums $n1 $n2]} {
+                       return 0
+               }
+       }
+       return 1
+}
+
+# ----------------------------------------------------------------------
+#  USAGE:  test_cmp_lists <list1> <list2>
+#
+#  Compares two lists to see if they are "equal."  Lists are "equal"
+#  if they contain exactly the same elements, but perhaps in a
+#  different order.  Returns 1/0 for true/false.
+# ----------------------------------------------------------------------
+proc test_cmp_lists {list1 list2} {
+       if {[llength $list1] != [llength $list2]} {
+               return 0
+       }
+       foreach elem $list1 {
+               set i [lsearch $list2 $elem]
+               if {$i >= 0} {
+                       set list2 [lreplace $list2 $i $i]
+               } else {
+                       return 0
+               }
+       }
+       return 1
+}
diff --git a/8.x/itcl/tests/old/toaster.test b/8.x/itcl/tests/old/toaster.test
new file mode 100644 (file)
index 0000000..b172263
--- /dev/null
@@ -0,0 +1,165 @@
+#
+# Tests for "toaster" example
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: toaster.test,v 1.1 1998/07/27 18:41:26 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ----------------------------------------------------------------------
+#  Get toaster classes from "demos" directory.
+# ----------------------------------------------------------------------
+lappend auto_path toasters
+
+# ----------------------------------------------------------------------
+#  Outlets send bills to an e-mail address.  Determine this address.
+# ----------------------------------------------------------------------
+if {[info exists env(USER)]} {
+       set Owner $env(USER)
+} elseif {[info exists env(LOGNAME)]} {
+       set Owner $env(LOGNAME)
+} else {
+       set Owner [exec logname]
+}
+
+# ----------------------------------------------------------------------
+#  TOASTERS
+# ----------------------------------------------------------------------
+test {Create a toaster and plug it in} {
+       global Owner
+       Toaster original -heat 1 -outlet [Outlet #auto -owner $Owner]
+} {
+       $result == "original"
+}
+
+test {Turn up the heat setting on the toaster} {
+       original config -heat 5
+} {
+       $result == ""
+}
+
+test {Toast a few slices of bread} {
+       original toast 2
+} {
+       $result == "crumb tray: 25% full"
+}
+
+test {Clean the toaster} {
+       original clean
+} {
+       $result == "crumb tray: 0% full"
+}
+
+test {Toast a few slices of bread a few different times} {
+       original clean
+       original toast 2
+       original toast 1
+} {
+       $result == "crumb tray: 38% full"
+}
+
+test {Toast too many slices of bread and cause a fire} {
+       puts stdout ">>> should say \"== FIRE! FIRE! ==\""
+       original clean
+       original toast 2
+       original toast 2
+       original toast 2
+       original toast 2
+} {
+       $result == "crumb tray: 100% full"
+}
+
+test {Destroy the toaster} {
+       original clean
+       original toast 2
+       original toast 1
+       puts stdout ">>> should say \"15 crumbs ... what a mess!\""
+       original delete
+} {
+       $result == ""
+}
+
+# ----------------------------------------------------------------------
+#  SMART TOASTERS
+# ----------------------------------------------------------------------
+test {Create a toaster and plug it in} {
+       global Owner
+       SmartToaster deluxe -heat 4 -outlet [Outlet #auto -owner $Owner]
+} {
+       $result == "deluxe"
+}
+
+test {Toast a few slices of bread} {
+       deluxe toast 2
+} {
+       $result == "crumb tray: 20% full"
+}
+
+test {Toast a few slices of bread and look for auto-clean} {
+       deluxe clean
+       deluxe toast 2
+       deluxe toast 2
+       deluxe toast 2
+       deluxe toast 2
+       deluxe toast 2
+} {
+       $result == "crumb tray: 20% full"
+}
+
+# ----------------------------------------------------------------------
+#  PRODUCT STATISTICS
+# ----------------------------------------------------------------------
+test {Check statistics gathered by Hazard base class} {
+       set tmp [Toaster #auto]
+       set stats [Hazard :: report ::Toaster]
+       $tmp delete
+       set stats
+} {
+       $result == "::Toaster: 2 produced, 1 active, 1 accidents"
+}
+
+test {Check statistics gathered by Hazard base class} {
+       Hazard :: report ::SmartToaster
+} {
+       $result == "::SmartToaster: 1 produced, 1 active, 0 accidents"
+}
+
+test {Destroy all Toasters} {
+       foreach toaster [itcl_info objects -isa Toaster] {
+               $toaster clean
+               $toaster delete
+       }
+} {
+       $result == ""
+}
+
+test {SmartToasters should have been destroyed along with Toasters} {
+       itcl_info objects -class SmartToaster
+} {
+       $result == ""
+}
+
+# ----------------------------------------------------------------------
+#  OUTLETS
+# ----------------------------------------------------------------------
+test {Bill all customers for outlet charges} {
+       Outlet :: bill
+       puts stdout ">>> should send two bills for outlets via e-mail"
+} {
+       $result == ""
+}
+
+test {Destroy all outlets} {
+       foreach outlet [itcl_info objects -class Outlet] {
+               $outlet delete
+       }
+} {
+       $result == ""
+}
diff --git a/8.x/itcl/tests/old/toasters/Appliance.tcl b/8.x/itcl/tests/old/toasters/Appliance.tcl
new file mode 100644 (file)
index 0000000..3e882cf
--- /dev/null
@@ -0,0 +1,43 @@
+# ----------------------------------------------------------------------
+#  PURPOSE:  Base class for all electrical appliances that interact
+#            with Outlets.
+#
+#   AUTHOR:  Michael J. McLennan       Phone: (610)712-2842
+#            AT&T Bell Laboratories   E-mail: michael.mclennan@att.com
+#
+#      RCS:  $Id: Appliance.tcl,v 1.1 1998/07/27 18:41:29 stanton Exp $
+# ----------------------------------------------------------------------
+#               Copyright (c) 1993  AT&T Bell Laboratories
+# ======================================================================
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that the copyright notice and warranty disclaimer appear in
+# supporting documentation, and that the names of AT&T Bell Laboratories
+# any of their entities not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# AT&T disclaims all warranties with regard to this software, including
+# all implied warranties of merchantability and fitness.  In no event
+# shall AT&T be liable for any special, indirect or consequential
+# damages or any damages whatsoever resulting from loss of use, data or
+# profits, whether in an action of contract, negligence or other
+# tortuous action, arising out of or in connection with the use or
+# performance of this software.
+# ======================================================================
+
+itcl_class Appliance {
+
+       method power {power} {
+               if {[itcl_info objects [info which $outlet]] == ""} {
+                       set outlet {}
+               }
+               if {$outlet == ""} {
+                       error "cannot use $this: not plugged in"
+               }
+               $outlet use $power
+       }
+
+       public outlet {}
+}
diff --git a/8.x/itcl/tests/old/toasters/Hazard.tcl b/8.x/itcl/tests/old/toasters/Hazard.tcl
new file mode 100644 (file)
index 0000000..805e66c
--- /dev/null
@@ -0,0 +1,78 @@
+# ----------------------------------------------------------------------
+#  PURPOSE:  Tracking for hazardous products manufactured by the
+#            "toaster" company.
+#
+#   AUTHOR:  Michael J. McLennan       Phone: (610)712-2842
+#            AT&T Bell Laboratories   E-mail: michael.mclennan@att.com
+#
+#      RCS:  $Id: Hazard.tcl,v 1.1 1998/07/27 18:41:30 stanton Exp $
+# ----------------------------------------------------------------------
+#               Copyright (c) 1993  AT&T Bell Laboratories
+# ======================================================================
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that the copyright notice and warranty disclaimer appear in
+# supporting documentation, and that the names of AT&T Bell Laboratories
+# any of their entities not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# AT&T disclaims all warranties with regard to this software, including
+# all implied warranties of merchantability and fitness.  In no event
+# shall AT&T be liable for any special, indirect or consequential
+# damages or any damages whatsoever resulting from loss of use, data or
+# profits, whether in an action of contract, negligence or other
+# tortuous action, arising out of or in connection with the use or
+# performance of this software.
+# ======================================================================
+
+itcl_class HazardRec {
+       constructor {cname} {
+               set class $cname
+       }
+       method change {var inc} {
+               if {![info exists $var]} {
+                       error "bad field \"$var\""
+               }
+               incr $var $inc
+       }
+       method report {} {
+               return "$class: $total produced, $actives active, $accidents accidents"
+       }
+       protected class {}
+       protected total 0
+       protected actives 0
+       protected accidents 0
+}
+
+itcl_class Hazard {
+
+       constructor {} {
+               set class [virtual info class]
+               if {![info exists recs($class)]} {
+                       set recs($class) [HazardRec #auto $class]
+               }
+               $recs($class) change total +1
+               $recs($class) change actives +1
+       }
+       destructor {
+               set class [virtual info class]
+               $recs($class) change actives -1
+       }
+
+       method accident {mesg} {
+               set class [virtual info class]
+               $recs($class) change accidents +1
+               puts stderr $mesg
+       }
+
+       proc report {class} {
+               if {[info exists recs($class)]} {
+                       return [$recs($class) report]
+               } else {
+                       error "no information for class \"$class\""
+               }
+       }
+    common recs
+}
diff --git a/8.x/itcl/tests/old/toasters/Outlet.tcl b/8.x/itcl/tests/old/toasters/Outlet.tcl
new file mode 100644 (file)
index 0000000..6b151a4
--- /dev/null
@@ -0,0 +1,81 @@
+# ----------------------------------------------------------------------
+#  PURPOSE:  Electrical outlet supplying power for Appliances.
+#
+#   AUTHOR:  Michael J. McLennan       Phone: (610)712-2842
+#            AT&T Bell Laboratories   E-mail: michael.mclennan@att.com
+#
+#      RCS:  $Id: Outlet.tcl,v 1.1 1998/07/27 18:41:30 stanton Exp $
+# ----------------------------------------------------------------------
+#               Copyright (c) 1993  AT&T Bell Laboratories
+# ======================================================================
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that the copyright notice and warranty disclaimer appear in
+# supporting documentation, and that the names of AT&T Bell Laboratories
+# any of their entities not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# AT&T disclaims all warranties with regard to this software, including
+# all implied warranties of merchantability and fitness.  In no event
+# shall AT&T be liable for any special, indirect or consequential
+# damages or any damages whatsoever resulting from loss of use, data or
+# profits, whether in an action of contract, negligence or other
+# tortuous action, arising out of or in connection with the use or
+# performance of this software.
+# ======================================================================
+
+itcl_class Outlet {
+       constructor {config} {}
+       method config {config} {}
+
+       destructor {
+               if {$usage > 0} bill
+       }
+
+       method use {power} {
+               set usage [expr $usage+$power]
+       }
+
+       method sendBill {} {
+               if {[catch "open /tmp/bill w" fout] != 0} {
+                       error "cannot create bill in /tmp"
+               } else {
+                       set amount [format "$%.2f" [expr $usage*$rate]]
+                       puts $fout "----------------------------------------"
+                       puts $fout "/////////// MEGA-POWER, INC. ///////////"
+                       puts $fout "----------------------------------------"
+                       puts $fout "   Customer: $owner"
+                       puts $fout "     Outlet: $this"
+                       puts $fout "      Usage: $usage kilowatt-hours"
+                       puts $fout "                                        "
+                       puts $fout " Amount Due: $amount"
+                       puts $fout "----------------------------------------"
+                       close $fout
+                       exec mail $owner < /tmp/bill
+                       set usage 0
+               }
+       }
+
+       proc bill {{customer *}} {
+               foreach outlet [itcl_info objects -class Outlet] {
+                       set owner [$outlet info public owner -value]
+                       if {[string match $customer $owner]} {
+                               $outlet sendBill
+                       }
+               }
+       }
+
+       proc rate {{newval ""}} {
+               if {$newval == ""} {
+                       return $rate
+               }
+               set rate $newval
+       }
+
+       public owner {}
+       protected usage 0
+
+       common rate 0.05
+}
diff --git a/8.x/itcl/tests/old/toasters/SmartToaster.tcl b/8.x/itcl/tests/old/toasters/SmartToaster.tcl
new file mode 100644 (file)
index 0000000..9e663d0
--- /dev/null
@@ -0,0 +1,40 @@
+# ----------------------------------------------------------------------
+#  PURPOSE:  Class definition for handling "smart" toasters via
+#            [incr Tcl].  A "smart" toaster is a toaster that
+#            automatically cleans itself when the crumb tray is full.
+#
+#   AUTHOR:  Michael J. McLennan       Phone: (610)712-2842
+#            AT&T Bell Laboratories   E-mail: michael.mclennan@att.com
+#
+#      RCS:  $Id: SmartToaster.tcl,v 1.1 1998/07/27 18:41:31 stanton Exp $
+# ----------------------------------------------------------------------
+#               Copyright (c) 1993  AT&T Bell Laboratories
+# ======================================================================
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that the copyright notice and warranty disclaimer appear in
+# supporting documentation, and that the names of AT&T Bell Laboratories
+# any of their entities not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# AT&T disclaims all warranties with regard to this software, including
+# all implied warranties of merchantability and fitness.  In no event
+# shall AT&T be liable for any special, indirect or consequential
+# damages or any damages whatsoever resulting from loss of use, data or
+# profits, whether in an action of contract, negligence or other
+# tortuous action, arising out of or in connection with the use or
+# performance of this software.
+# ======================================================================
+
+itcl_class SmartToaster {
+       inherit Toaster
+
+       method toast {nslices} {
+               if {$crumbs >= [expr $maxcrumbs-10]} {
+                       clean
+               }
+               return [Toaster::toast $nslices]
+       }
+}
diff --git a/8.x/itcl/tests/old/toasters/Toaster.tcl b/8.x/itcl/tests/old/toasters/Toaster.tcl
new file mode 100644 (file)
index 0000000..2cfd461
--- /dev/null
@@ -0,0 +1,75 @@
+# ----------------------------------------------------------------------
+#  PURPOSE:  Class definition for handling toasters via [incr Tcl].
+#
+#   AUTHOR:  Michael J. McLennan       Phone: (610)712-2842
+#            AT&T Bell Laboratories   E-mail: michael.mclennan@att.com
+#
+#      RCS:  $Id: Toaster.tcl,v 1.1 1998/07/27 18:41:31 stanton Exp $
+# ----------------------------------------------------------------------
+#               Copyright (c) 1993  AT&T Bell Laboratories
+# ======================================================================
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that the copyright notice and warranty disclaimer appear in
+# supporting documentation, and that the names of AT&T Bell Laboratories
+# any of their entities not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# AT&T disclaims all warranties with regard to this software, including
+# all implied warranties of merchantability and fitness.  In no event
+# shall AT&T be liable for any special, indirect or consequential
+# damages or any damages whatsoever resulting from loss of use, data or
+# profits, whether in an action of contract, negligence or other
+# tortuous action, arising out of or in connection with the use or
+# performance of this software.
+# ======================================================================
+
+itcl_class Toaster {
+       inherit Appliance Hazard
+
+       constructor {config} {}
+       destructor {
+               if {$crumbs > 0} {
+                       puts stdout "$crumbs crumbs ... what a mess!"
+               }
+       }
+       method config {config} {}
+
+       method toast {nslices} {
+               power [expr 0.03*$heat]
+               if {$nslices < 1 || $nslices > 2} {
+                       error "bad number of slices: should be 1 or 2"
+               }
+               set crumbs [expr $crumbs+$heat*$nslices]
+               if {$crumbs >= $maxcrumbs} {
+                       accident "== FIRE! FIRE! =="
+                       set crumbs $maxcrumbs
+               }
+               return [check]
+       }
+
+       method clean {} {
+               power 0.5
+               set crumbs 0
+               return [check]
+       }
+
+       method check {} {
+               set level [expr $crumbs*100.0/$maxcrumbs]
+               return [format "crumb tray: %.0f%% full" $level]
+       }
+
+       proc resize {newsize} {
+               set maxcrumbs $newsize
+       }
+
+       public heat 3 {
+               if {$heat < 1 || $heat > 5} {
+                       error "invalid setting $heat: should be 1-5"
+               }
+       }
+       protected crumbs 0
+       common maxcrumbs 40
+}
diff --git a/8.x/itcl/tests/old/toasters/tclIndex b/8.x/itcl/tests/old/toasters/tclIndex
new file mode 100644 (file)
index 0000000..01017bc
--- /dev/null
@@ -0,0 +1,18 @@
+# Tcl autoload index file, version 2.0
+# This file is generated by the "auto_mkindex" command
+# and sourced to set up indexing information for one or
+# more commands.  Typically each line is a command that
+# sets an element in the auto_index array, where the
+# element name is the name of a command and the value is
+# a script that loads the command.
+
+set auto_index(Appliance) "source $dir/Appliance.tcl"
+set auto_index(HazardRec) "source $dir/Hazard.tcl"
+set auto_index(Hazard) "source $dir/Hazard.tcl"
+set auto_index(Outlet) "source $dir/Outlet.tcl"
+set auto_index(SmartToaster) "source $dir/SmartToaster.tcl"
+set auto_index(Toaster) "source $dir/Toaster.tcl"
+set auto_index(make_toaster) "source $dir/usualway.tcl"
+set auto_index(toast_bread) "source $dir/usualway.tcl"
+set auto_index(clean_toaster) "source $dir/usualway.tcl"
+set auto_index(destroy_toaster) "source $dir/usualway.tcl"
diff --git a/8.x/itcl/tests/old/toasters/usualway.tcl b/8.x/itcl/tests/old/toasters/usualway.tcl
new file mode 100644 (file)
index 0000000..267e3d0
--- /dev/null
@@ -0,0 +1,122 @@
+# ----------------------------------------------------------------------
+#  PURPOSE:  Procedures for managing toasters in the usual
+#            procedure-oriented Tcl programming style.  These
+#            routines illustrate data sharing through global
+#            variables and naming conventions to logically group
+#            related procedures.  The same programming task can
+#            be accomplished much more cleanly with [incr Tcl].
+#            Inheritance also allows new behavior to be "mixed-in"
+#            more cleanly (see Appliance and Product base classes).
+#
+#   AUTHOR:  Michael J. McLennan       Phone: (610)712-2842
+#            AT&T Bell Laboratories   E-mail: michael.mclennan@att.com
+#
+#      RCS:  $Id: usualway.tcl,v 1.1 1998/07/27 18:41:32 stanton Exp $
+# ----------------------------------------------------------------------
+#               Copyright (c) 1993  AT&T Bell Laboratories
+# ======================================================================
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that the copyright notice and warranty disclaimer appear in
+# supporting documentation, and that the names of AT&T Bell Laboratories
+# any of their entities not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# AT&T disclaims all warranties with regard to this software, including
+# all implied warranties of merchantability and fitness.  In no event
+# shall AT&T be liable for any special, indirect or consequential
+# damages or any damages whatsoever resulting from loss of use, data or
+# profits, whether in an action of contract, negligence or other
+# tortuous action, arising out of or in connection with the use or
+# performance of this software.
+# ======================================================================
+
+# ----------------------------------------------------------------------
+# COMMAND: make_toaster <name> <heat>
+#
+#   INPUTS
+#     <name> = name of new toaster
+#     <heat> = heat setting (1-5)
+#
+#   RETURNS
+#     name of new toaster
+#
+#   SIDE-EFFECTS
+#     Creates a record of a new toaster with the given heat setting
+#     and an empty crumb tray.
+# ----------------------------------------------------------------------
+proc make_toaster {name heat} {
+       global allToasters
+
+       if {$heat < 1 || $heat > 5} {
+               error "invalid heat setting: should be 1-5"
+       }
+       set allToasters($name-heat) $heat
+       set allToasters($name-crumbs) 0
+}
+
+# ----------------------------------------------------------------------
+# COMMAND: toast_bread <name> <slices>
+#
+#   INPUTS
+#       <name> = name of toaster used to toast bread
+#     <slices> = number of bread slices (1 or 2)
+#
+#   RETURNS
+#     current crumb count
+#
+#   SIDE-EFFECTS
+#     Toasts bread and adds crumbs to crumb tray.
+# ----------------------------------------------------------------------
+proc toast_bread {name slices} {
+       global allToasters
+
+       if {[info exists allToasters($name-crumbs)]} {
+               set c $allToasters($name-crumbs)
+               set c [expr $c+$allToasters($name-heat)*$slices]
+               set allToasters($name-crumbs) $c
+       } else {
+               error "not a toaster: $name"
+       }
+}
+
+# ----------------------------------------------------------------------
+# COMMAND: clean_toaster <name>
+#
+#   INPUTS
+#       <name> = name of toaster to be cleaned
+#
+#   RETURNS
+#     current crumb count
+#
+#   SIDE-EFFECTS
+#     Cleans toaster by emptying crumb tray.
+# ----------------------------------------------------------------------
+proc clean_toaster {name} {
+       global allToasters
+       set allToasters($name-crumbs) 0
+}
+
+# ----------------------------------------------------------------------
+# COMMAND: destroy_toaster <name>
+#
+#   INPUTS
+#       <name> = name of toaster to be destroyed
+#
+#   RETURNS
+#     nothing
+#
+#   SIDE-EFFECTS
+#     Spills all crumbs in the toaster and then destroys it.
+# ----------------------------------------------------------------------
+proc destroy_toaster {name} {
+       global allToasters
+
+       if {[info exists allToasters($name-crumbs)]} {
+               puts stdout "$allToasters($name-crumbs) crumbs ... what a mess!"
+               unset allToasters($name-heat)
+               unset allToasters($name-crumbs)
+       }
+}
diff --git a/8.x/itcl/tests/old/uplevel.test b/8.x/itcl/tests/old/uplevel.test
new file mode 100644 (file)
index 0000000..c3a4ba1
--- /dev/null
@@ -0,0 +1,155 @@
+#
+# Tests for "uplevel" across interpreter boundaries
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: uplevel.test,v 1.1 1998/07/27 18:41:27 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ----------------------------------------------------------------------
+#  DEFINE SOME USEFUL ROUTINES
+# ----------------------------------------------------------------------
+proc uplevelTest_show_var {level var} {
+       return "$var>>[uplevel $level set $var]"
+}
+
+proc uplevelTest_do {cmd} {
+       eval $cmd
+}
+
+# ----------------------------------------------------------------------
+#  CREATE SOME OBJECTS
+# ----------------------------------------------------------------------
+Foo foo
+Baz baz
+
+# ----------------------------------------------------------------------
+#  UPLEVEL TESTS (main interp)
+# ----------------------------------------------------------------------
+test {"uplevel" can access global variables (via relative level)} {
+       set globalvar "global value"
+       uplevelTest_show_var 1 globalvar
+} {
+       $result == "globalvar>>global value"
+}
+
+test {"uplevel" can access global variables (via "#0")} {
+       set globalvar "global value"
+       uplevelTest_show_var #0 globalvar
+} {
+       $result == "globalvar>>global value"
+}
+
+test {"uplevel" can access local variables (via relative level)} {
+       uplevelTest_do {
+               set localvar "local value"
+               uplevelTest_show_var 1 localvar
+       }
+} {
+       $result == "localvar>>local value"
+}
+
+test {"uplevel" can access local variables (via relative level)} {
+       uplevelTest_do {
+               set localvar "proper value"
+               uplevelTest_do {
+                       set localvar "not this one"
+                       uplevelTest_show_var 2 localvar
+               }
+       }
+} {
+       $result == "localvar>>proper value"
+}
+
+test {"uplevel" can access local variables (via explicit level)} {
+       uplevelTest_do {
+               set localvar "local value"
+               uplevelTest_show_var #1 localvar
+       }
+} {
+       $result == "localvar>>local value"
+}
+
+# ----------------------------------------------------------------------
+#  UPLEVEL TESTS (across class interps)
+# ----------------------------------------------------------------------
+test {"uplevel" can cross class interps to access global variables} {
+       set globalvar "global value"
+       foo do {
+               uplevel #0 uplevelTest_show_var 1 globalvar
+       }
+} {
+       $result == "Foo says 'globalvar>>global value'"
+}
+
+test {"uplevel" can cross several class interps to access global variables} {
+       set globalvar "global value"
+       baz do {
+               foo do {
+                       uplevel 2 uplevelTest_show_var #0 globalvar
+               }
+       }
+} {
+       $result == "Baz says 'Foo says 'globalvar>>global value''"
+}
+
+test {"uplevel" finds proper scope for execution} {
+       baz do {
+               foo do {
+                       uplevel do {{info class}}
+               }
+       }
+} {
+       $result == "Baz says 'Foo says 'Baz says '::Baz'''"
+}
+
+test {"uplevel" finds proper scope for execution,
+and works in conjunction with "unknown" to access
+commands at the global scope with local call frames} {
+       baz do {
+               set bazvar "value in Baz"
+               foo do {
+                       uplevel ::info locals
+               }
+       }
+} {
+       $result == "Baz says 'Foo says 'bazvar cmds''"
+}
+
+# ----------------------------------------------------------------------
+#  LEVEL TESTS (across class scopes)
+# ----------------------------------------------------------------------
+test {"info level" works across scope boundaries} {
+       baz do {
+               foo do {
+                       info level
+               }
+       }
+} {
+       $result == "Baz says 'Foo says '2''"
+}
+
+test {"info level" works across scope boundaries} {
+       baz do {
+               foo do {
+                       info level 0
+               }
+       }
+} {
+       $result == "Baz says 'Foo says 'do {
+                       info level 0
+               }''"
+}
+
+# ----------------------------------------------------------------------
+#  CLEAN UP
+# ----------------------------------------------------------------------
+foo delete
+baz delete
diff --git a/8.x/itcl/tests/old/upvar.test b/8.x/itcl/tests/old/upvar.test
new file mode 100644 (file)
index 0000000..61491a7
--- /dev/null
@@ -0,0 +1,110 @@
+#
+# Tests for "upvar" across interpreter boundaries
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: upvar.test,v 1.1 1998/07/27 18:41:27 stanton Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ----------------------------------------------------------------------
+#  DEFINE SOME USEFUL ROUTINES
+# ----------------------------------------------------------------------
+proc upvarTest_show_var {var val} {
+       return "$var>>$val"
+}
+
+proc upvarTest_upvar_in_procs {} {
+       set upvarTest_var_local "value in main interp"
+       foo do {
+               upvar upvarTest_var_local var
+               set var
+       }
+}
+
+# ----------------------------------------------------------------------
+#  CREATE SOME OBJECTS
+# ----------------------------------------------------------------------
+Foo foo
+Baz baz
+
+# ----------------------------------------------------------------------
+#  UPVAR TESTS
+# ----------------------------------------------------------------------
+test {"::" sends command to global interp but preserves
+local variables.  This ensures that when control
+shifts to the global scope for Extended Tcl commands,
+Expect commands, etc., local variables will be
+recognized.} {
+       foo do {
+               set localvar "special"
+               ::eval {upvarTest_show_var localvar $localvar}
+       }
+} {
+       $result == "Foo says 'localvar>>special'"
+}
+
+
+test {"upvar" can cross interp boundaries to access local variables} {
+       upvarTest_upvar_in_procs
+} {
+       $result == "Foo says 'value in main interp'"
+}
+
+test {"upvar" can cross interp boundaries to access global variables} {
+       set upvarTest_var_global "value in main interp"
+       foo do {
+               upvar upvarTest_var_global var
+               set var
+       }
+} {
+       $result == "Foo says 'value in main interp'"
+}
+
+test {"upvar" can handle multiple call frames on the stack} {
+       set upvarTest_var_global "new value"
+       foo do {
+               foo do {
+                       upvar #0 upvarTest_var_global var
+                       set var
+               }
+       }
+} {
+       $result == "Foo says 'Foo says 'new value''"
+}
+
+test {"upvar" can cross class interp boundaries} {
+       baz do {
+               set localvar "value in Baz"
+               foo do {
+                       upvar localvar var
+                       set var
+               }
+       }
+} {
+       $result == "Baz says 'Foo says 'value in Baz''"
+}
+
+test {"upvar" can cross class interp boundaries back to main interp} {
+       set upvarTest_var_global "global value"
+       baz do {
+               foo do {
+                       upvar 2 upvarTest_var_global var
+                       set var
+               }
+       }
+} {
+       $result == "Baz says 'Foo says 'global value''"
+}
+
+# ----------------------------------------------------------------------
+#  CLEAN UP
+# ----------------------------------------------------------------------
+foo delete
+baz delete
diff --git a/8.x/itcl/tests/protection.test b/8.x/itcl/tests/protection.test
new file mode 100644 (file)
index 0000000..1b40461
--- /dev/null
@@ -0,0 +1,378 @@
+#
+# Tests for method/variable protection and access
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: protection.test,v 1.4 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Class members are protected by access restrictions
+# ----------------------------------------------------------------------
+test protect-1.1 {define a class with various protection levels} {
+    itcl::class test_pr {
+        public {
+            variable pubv "public var"
+            common pubc "public com"
+            method pubm {} {return "public method"}
+            method ovpubm {} {return "overloaded public method"}
+            proc pubp {} {return "public proc"}
+        }
+        protected {
+            variable prov "protected var"
+            common proc "protected com"
+            method prom {} {return "protected method"}
+            method ovprom {} {return "overloaded protected method"}
+            proc prop {} {return "protected proc"}
+        }
+        private {
+            variable priv "private var"
+            common pric "private com"
+            method prim {} {return "private method"}
+            method ovprim {} {return "overloaded private method"}
+            proc prip {} {return "private proc"}
+        }
+        method do {args} {eval $args}
+    }
+} ""
+
+test protect-1.2 {create an object to execute tests} {
+    test_pr #auto
+} {test_pr0}
+
+test protect-1.3a {public methods can be accessed from outside} {
+    list [catch {test_pr0 pubm} msg] $msg
+} {0 {public method}}
+
+test protect-1.3b {public methods can be accessed from inside} {
+    list [catch {test_pr0 do pubm} msg] $msg
+} {0 {public method}}
+
+test protect-1.4a {protected methods are blocked from outside} {
+    list [catch {test_pr0 prom} msg] $msg
+} {1 {bad option "prom": should be one of...
+  test_pr0 cget -option
+  test_pr0 configure ?-option? ?value -option value...?
+  test_pr0 do ?arg arg ...?
+  test_pr0 isa className
+  test_pr0 ovpubm
+  test_pr0 pubm}}
+
+test protect-1.4b {protected methods can be accessed from inside} {
+    list [catch {test_pr0 do prom} msg] $msg
+} {0 {protected method}}
+
+test protect-1.5a {private methods are blocked from outside} {
+    list [catch {test_pr0 prim} msg] $msg
+} {1 {bad option "prim": should be one of...
+  test_pr0 cget -option
+  test_pr0 configure ?-option? ?value -option value...?
+  test_pr0 do ?arg arg ...?
+  test_pr0 isa className
+  test_pr0 ovpubm
+  test_pr0 pubm}}
+
+test protect-1.5b {private methods can be accessed from inside} {
+    list [catch {test_pr0 do prim} msg] $msg
+} {0 {private method}}
+
+test protect-1.6a {public procs can be accessed from outside} {
+    list [catch {test_pr::pubp} msg] $msg
+} {0 {public proc}}
+
+test protect-1.6b {public procs can be accessed from inside} {
+    list [catch {test_pr0 do pubp} msg] $msg
+} {0 {public proc}}
+
+test protect-1.7a {protected procs are blocked from outside} {
+    list [catch {test_pr::prop} msg] $msg
+} {1 {can't access "::test_pr::prop": protected function}}
+
+test protect-1.7b {protected procs can be accessed from inside} {
+    list [catch {test_pr0 do prop} msg] $msg
+} {0 {protected proc}}
+
+test protect-1.8a {private procs are blocked from outside} {
+    list [catch {test_pr::prip} msg] $msg
+} {1 {can't access "::test_pr::prip": private function}}
+
+test protect-1.8b {private procs can be accessed from inside} {
+    list [catch {test_pr0 do prip} msg] $msg
+} {0 {private proc}}
+
+test protect-1.9a {public commons can be accessed from outside} {
+    list [catch {set test_pr::pubc} msg] $msg
+} {0 {public com}}
+
+test protect-1.9b {public commons can be accessed from inside} {
+    list [catch {test_pr0 do set pubc} msg] $msg
+} {0 {public com}}
+
+test protect-1.10 {protected commons can be accessed from inside} {
+    list [catch {test_pr0 do set proc} msg] $msg
+} {0 {protected com}}
+
+test protect-1.11 {private commons can be accessed from inside} {
+    list [catch {test_pr0 do set pric} msg] $msg
+} {0 {private com}}
+
+test protect-1.12a {object-specific variables require an access command} {
+    list [catch {set test_pr::pubv} msg] $msg
+} {1 {can't read "test_pr::pubv": no such variable}}
+
+test protect-1.12b {public variables can be accessed from inside} {
+    list [catch {test_pr0 do set pubv} msg] $msg
+} {0 {public var}}
+
+test protect-1.13a {object-specific variables require an access command} {
+    list [catch {set test_pr::prov} msg] $msg
+} {1 {can't read "test_pr::prov": no such variable}}
+
+test protect-1.13b {protected variables can be accessed from inside} {
+    list [catch {test_pr0 do set prov} msg] $msg
+} {0 {protected var}}
+
+test protect-1.14a {object-specific variables require an access command} {
+    list [catch {set test_pr::priv} msg] $msg
+} {1 {can't read "test_pr::priv": no such variable}}
+
+test protect-1.14b {private variables can be accessed from inside} {
+    list [catch {test_pr0 do set priv} msg] $msg
+} {0 {private var}}
+
+# ----------------------------------------------------------------------
+#  Access restrictions work properly with inheritance
+# ----------------------------------------------------------------------
+test protect-2.1 {define a derived class} {
+    itcl::class test_pr_derived {
+        inherit test_pr
+        method do {args} {eval $args}
+
+        public method ovpubm {} {return "specific public method"}
+        protected method ovprom {} {return "specific protected method"}
+        private method ovprim {} {return "specific private method"}
+
+        public method dpubm {} {return "pub (only in derived)"}
+        protected method dprom {} {return "pro (only in derived)"}
+        private method dprim {} {return "pri (only in derived)"}
+    }
+} ""
+
+test protect-2.2 {create an object to execute tests} {
+    test_pr_derived #auto
+} {test_pr_derived0}
+
+test protect-2.3 {public methods can be accessed from inside} {
+    list [catch {test_pr_derived0 do pubm} msg] $msg
+} {0 {public method}}
+
+test protect-2.4 {protected methods can be accessed from inside} {
+    list [catch {test_pr_derived0 do prom} msg] $msg
+} {0 {protected method}}
+
+test protect-2.5 {private methods are blocked} {
+    list [catch {test_pr_derived0 do prim} msg] $msg
+} {1 {invalid command name "prim"}}
+
+test protect-2.6 {public procs can be accessed from inside} {
+    list [catch {test_pr_derived0 do pubp} msg] $msg
+} {0 {public proc}}
+
+test protect-2.7 {protected procs can be accessed from inside} {
+    list [catch {test_pr_derived0 do prop} msg] $msg
+} {0 {protected proc}}
+
+test protect-2.8 {private procs are blocked} {
+    list [catch {test_pr_derived0 do prip} msg] $msg
+} {1 {invalid command name "prip"}}
+
+test protect-2.9 {public commons can be accessed from inside} {
+    list [catch {test_pr_derived0 do set pubc} msg] $msg
+} {0 {public com}}
+
+test protect-2.10 {protected commons can be accessed from inside} {
+    list [catch {test_pr_derived0 do set proc} msg] $msg
+} {0 {protected com}}
+
+test protect-2.11 {private commons are blocked} {
+    list [catch {test_pr_derived0 do set pric} msg] $msg
+} {1 {can't read "pric": no such variable}}
+
+test protect-2.12 {public variables can be accessed from inside} {
+    list [catch {test_pr_derived0 do set pubv} msg] $msg
+} {0 {public var}}
+
+test protect-2.13 {protected variables can be accessed from inside} {
+    list [catch {test_pr_derived0 do set prov} msg] $msg
+} {0 {protected var}}
+
+test protect-2.14 {private variables are blocked} {
+    list [catch {test_pr_derived0 do set priv} msg] $msg
+} {1 {can't read "priv": no such variable}}
+
+test protect-2.15 {can access overloaded public method} {
+    set cmd {namespace eval test_pr_derived {test_pr_derived0 ovpubm}}
+    list [catch $cmd msg] $msg
+} {0 {specific public method}}
+
+test protect-2.16 {can access overloaded public method} {
+    set cmd {namespace eval test_pr_derived {test_pr_derived0 ovprom}}
+    list [catch $cmd msg] $msg
+} {0 {specific protected method}}
+
+test protect-2.17 {can access overloaded private method} {
+    set cmd {namespace eval test_pr_derived {test_pr_derived0 ovprim}}
+    list [catch $cmd msg] $msg
+} {0 {specific private method}}
+
+test protect-2.18 {can access overloaded public method from base class} {
+    set cmd {namespace eval test_pr {test_pr_derived0 ovpubm}}
+    list [catch $cmd msg] $msg
+} {0 {specific public method}}
+
+test protect-2.19 {can access overloaded protected method from base class} {
+    set cmd {namespace eval test_pr {test_pr_derived0 ovprom}}
+    list [catch $cmd msg] $msg
+} {0 {specific protected method}}
+
+test protect-2.20 {*cannot* access overloaded private method from base class} {
+    set cmd {namespace eval test_pr {test_pr_derived0 ovprim}}
+    list [catch $cmd msg] $msg
+} {1 {bad option "ovprim": should be one of...
+  test_pr_derived0 cget -option
+  test_pr_derived0 configure ?-option? ?value -option value...?
+  test_pr_derived0 do ?arg arg ...?
+  test_pr_derived0 dpubm
+  test_pr_derived0 isa className
+  test_pr_derived0 ovprom
+  test_pr_derived0 ovpubm
+  test_pr_derived0 prim
+  test_pr_derived0 prom
+  test_pr_derived0 pubm}}
+
+test protect-2.21 {can access non-overloaded public method from base class} {
+    set cmd {namespace eval test_pr {test_pr_derived0 dpubm}}
+    list [catch $cmd msg] $msg
+} {0 {pub (only in derived)}}
+
+test protect-2.22 {*cannot* access non-overloaded protected method from base class} {
+    set cmd {namespace eval test_pr {test_pr_derived0 dprom}}
+    list [catch $cmd msg] $msg
+} {1 {bad option "dprom": should be one of...
+  test_pr_derived0 cget -option
+  test_pr_derived0 configure ?-option? ?value -option value...?
+  test_pr_derived0 do ?arg arg ...?
+  test_pr_derived0 dpubm
+  test_pr_derived0 isa className
+  test_pr_derived0 ovprom
+  test_pr_derived0 ovpubm
+  test_pr_derived0 prim
+  test_pr_derived0 prom
+  test_pr_derived0 pubm}}
+
+test protect-2.23 {*cannot* access non-overloaded private method from base class} {
+    set cmd {namespace eval test_pr {test_pr_derived0 dprim}}
+    list [catch $cmd msg] $msg
+} {1 {bad option "dprim": should be one of...
+  test_pr_derived0 cget -option
+  test_pr_derived0 configure ?-option? ?value -option value...?
+  test_pr_derived0 do ?arg arg ...?
+  test_pr_derived0 dpubm
+  test_pr_derived0 isa className
+  test_pr_derived0 ovprom
+  test_pr_derived0 ovpubm
+  test_pr_derived0 prim
+  test_pr_derived0 prom
+  test_pr_derived0 pubm}}
+
+eval namespace delete [itcl::find classes test_pr*]
+
+# ----------------------------------------------------------------------
+#  Access restrictions don't mess up "info"
+# ----------------------------------------------------------------------
+test protect-3.1 {define a base class with private variables} {
+    itcl::class test_info_base {
+        private variable pribv "pribv-value"
+        private common pribc "pribc-value"
+        protected variable probv "probv-value"
+        protected common probc "probc-value"
+        public variable pubbv "pubbv-value"
+        public common pubbc "pubbc-value"
+    }
+    itcl::class test_info_derived {
+        inherit test_info_base
+        private variable pridv "pridv-value"
+        private common pridc "pridc-value"
+    }
+} ""
+
+test protect-3.2 {create an object to execute tests} {
+    test_info_derived #auto
+} {test_info_derived0}
+
+test protect-3.3 {all variables are reported} {
+    list [catch {test_info_derived0 info variable} msg] [lsort $msg]
+} {0 {::test_info_base::pribc ::test_info_base::pribv ::test_info_base::probc ::test_info_base::probv ::test_info_base::pubbc ::test_info_base::pubbv ::test_info_derived::pridc ::test_info_derived::pridv ::test_info_derived::this}}
+
+test protect-3.4 {private base class variables can be accessed} {
+    list [catch {test_info_derived0 info variable pribv} msg] $msg
+} {0 {private variable ::test_info_base::pribv pribv-value pribv-value}}
+
+test protect-3.5 {private base class commons can be accessed} {
+    list [catch {test_info_derived0 info variable pribc} msg] $msg
+} {0 {private common ::test_info_base::pribc pribc-value pribc-value}}
+
+test protect-3.6 {protected base class variables can be accessed} {
+    list [catch {test_info_derived0 info variable probv} msg] $msg
+} {0 {protected variable ::test_info_base::probv probv-value probv-value}}
+
+test protect-3.7 {protected base class commons can be accessed} {
+    list [catch {test_info_derived0 info variable probc} msg] $msg
+} {0 {protected common ::test_info_base::probc probc-value probc-value}}
+
+test protect-3.8 {public base class variables can be accessed} {
+    list [catch {test_info_derived0 info variable pubbv} msg] $msg
+} {0 {public variable ::test_info_base::pubbv pubbv-value {} pubbv-value}}
+
+test protect-3.9 {public base class commons can be accessed} {
+    list [catch {test_info_derived0 info variable pubbc} msg] $msg
+} {0 {public common ::test_info_base::pubbc pubbc-value pubbc-value}}
+
+test protect-3.10 {private derived class variables can be accessed} {
+    list [catch {test_info_derived0 info variable pridv} msg] $msg
+} {0 {private variable ::test_info_derived::pridv pridv-value pridv-value}}
+
+test protect-3.11 {private derived class commons can be accessed} {
+    list [catch {test_info_derived0 info variable pridc} msg] $msg
+} {0 {private common ::test_info_derived::pridc pridc-value pridc-value}}
+
+test protect-3.12 {private base class variables can't be accessed from class} {
+    list [catch {
+        namespace eval test_info_derived {info variable pribv}
+    } msg] $msg
+} {1 {cannot access object-specific info without an object context}}
+
+test protect-3.13 {private base class commons can be accessed from class} {
+    list [catch {
+        namespace eval test_info_derived {info variable pribc}
+    } msg] $msg
+} {0 {private common ::test_info_base::pribc pribc-value pribc-value}}
+
+eval namespace delete [itcl::find classes test_info*]
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/scope.test b/8.x/itcl/tests/scope.test
new file mode 100644 (file)
index 0000000..2d89adf
--- /dev/null
@@ -0,0 +1,215 @@
+#
+# Tests for code/scope commands
+# ----------------------------------------------------------------------
+#   AUTHOR:  Michael J. McLennan
+#            Bell Labs Innovations for Lucent Technologies
+#            mmclennan@lucent.com
+#            http://www.tcltk.com/itcl
+#
+#      RCS:  $Id: scope.test,v 1.4 2004/02/12 18:09:50 davygrvy Exp $
+# ----------------------------------------------------------------------
+#            Copyright (c) 1993-1998  Lucent Technologies, Inc.
+# ======================================================================
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::test
+}
+
+::tcltest::loadTestedCommands
+
+# ----------------------------------------------------------------------
+#  Syntax of the "scope" command
+# ----------------------------------------------------------------------
+test scope-1.1 {scope command takes one argument} {
+    list [catch {itcl::scope} msg] $msg [catch {itcl::scope x y} msg] $msg
+} {1 {wrong # args: should be "itcl::scope varname"} 1 {wrong # args: should be "itcl::scope varname"}}
+
+test scope-1.2 {argument to scope command must be a variable} {
+    variable test_scope_var 0
+    list [catch {itcl::scope xyzzy} msg] $msg \
+         [catch {itcl::scope test_scope_var} msg] $msg
+} {1 {variable "xyzzy" not found in namespace "::"} 0 ::test_scope_var}
+
+test scope-1.3 {if variable is already fully qualified, scope does nothing} {
+    list [itcl::scope ::xyzzy] [itcl::scope ::test_scope_var]
+} {::xyzzy ::test_scope_var}
+
+test scope-1.4 {scope command returns fully qualified name} {
+    namespace eval test_scope_ns {
+        namespace eval child {
+            variable v1 0
+            itcl::scope v1
+        }
+    }
+} {::test_scope_ns::child::v1}
+
+namespace delete test_scope_ns
+unset test_scope_var
+
+# ----------------------------------------------------------------------
+#  Syntax of the "code" command
+# ----------------------------------------------------------------------
+test scope-2.1 {code command takes at least one argument} {
+    list [catch {itcl::code} msg] $msg
+} {1 {wrong # args: should be "itcl::code ?-namespace name? command ?arg arg...?"}}
+
+test scope-2.2 {code command with one argument} {
+    itcl::code arg1
+} {namespace inscope :: arg1}
+
+test scope-2.3 {code command with many arguments} {
+    list [itcl::code arg1 arg2] [itcl::code arg1 arg2 arg3 arg4]
+} {{namespace inscope :: {arg1 arg2}} {namespace inscope :: {arg1 arg2 arg3 arg4}}}
+
+test scope-2.4 {code command appends arguments as list elements} {
+    list [itcl::code "foo bar"] \
+         [itcl::code "foo bar" "hello, world!" "one, two, three"]
+} {{namespace inscope :: {foo bar}} {namespace inscope :: {{foo bar} {hello, world!} {one, two, three}}}}
+
+test scope-2.5 {code command inside code command} {
+    itcl::code [itcl::code arg1 arg2] arg3
+} {namespace inscope :: {{namespace inscope :: {arg1 arg2}} arg3}}
+
+test scope-2.6 {code command returns fully qualified names} {
+    namespace eval test_scope_ns {
+        namespace eval child {
+            itcl::code foo bar baz
+        }
+    }
+} {namespace inscope ::test_scope_ns::child {foo bar baz}}
+
+test scope-2.7 {code command lets you specify a namespace} {
+    list [catch {itcl::code -namespace xyzzy arg1 arg2} msg] $msg \
+         [catch {itcl::code -namespace test_scope_ns::child arg1 arg2} msg] $msg
+} {1 {unknown namespace "xyzzy"} 0 {namespace inscope ::test_scope_ns::child {arg1 arg2}}}
+
+test scope-2.8 {last namespace wins} {
+    itcl::code -namespace test_scope_ns::child -namespace test_scope_ns arg1
+} {namespace inscope ::test_scope_ns arg1}
+
+test scope-2.9 {"--" terminates switches} {
+    list [catch {itcl::code -namespace test_scope_ns -foo -bar} msg] $msg \
+         [catch {itcl::code -namespace test_scope_ns -- -foo -bar} msg] $msg
+    
+} {1 {bad option "-foo": should be -namespace or --} 0 {namespace inscope ::test_scope_ns {-foo -bar}}}
+
+namespace delete test_scope_ns
+
+# ----------------------------------------------------------------------
+#  Test code/scope commands in a class
+# ----------------------------------------------------------------------
+test scope-3.1 {define simple classes with things to export} {
+    itcl::class test_scope {
+        private variable priv "private-value"
+        protected variable prov "protected-value"
+        public variable pubv "public-value"
+
+        private common pric "private-common-value"
+        protected common proc "protected-common-value"
+        public common pubc "public-common-value"
+
+        variable varray
+        common carray
+
+        method mcontext {args} {
+            return [eval $args]
+        }
+        proc pcontext {args} {
+            return [eval $args]
+        }
+
+        private method prim {args} {
+            return "prim: $args"
+        }
+        protected method prom {args} {
+            return "prom: $args"
+        }
+        public method pubm {args} {
+            return "pubm: $args"
+        }
+    }
+    test_scope #auto
+} {test_scope0}
+
+test scope-3.2 {code command captures only class context} {
+    list [test_scope0 mcontext itcl::code arg1 arg2] \
+         [test_scope::pcontext itcl::code arg1 arg2]
+} {{namespace inscope ::test_scope {arg1 arg2}} {namespace inscope ::test_scope {arg1 arg2}}}
+
+test scope-3.3 {scope command captures class and object context} {
+    list [test_scope0 mcontext itcl::scope priv] \
+         [test_scope::pcontext itcl::scope pric]
+} {{@itcl ::test_scope0 ::test_scope::priv} ::test_scope::pric}
+
+test scope-3.4 {scope command must recognize variable} {
+    list [catch {test_scope0 mcontext itcl::scope xyzzy} msg] $msg
+} {1 {variable "xyzzy" not found in class "::test_scope"}}
+
+test scope-3.5 {scope command provides access to instance variables} {
+    set result ""
+    foreach vname {priv prov pubv} {
+        lappend result [test_scope0 info variable $vname]
+        set var [test_scope0 mcontext itcl::scope $vname]
+        set $var "$vname-new"
+        lappend result [test_scope0 info variable $vname]
+    }
+    set result
+} {{private variable ::test_scope::priv private-value private-value} {private variable ::test_scope::priv private-value priv-new} {protected variable ::test_scope::prov protected-value protected-value} {protected variable ::test_scope::prov protected-value prov-new} {public variable ::test_scope::pubv public-value {} public-value} {public variable ::test_scope::pubv public-value {} pubv-new}}
+
+test scope-3.6 {scope command provides access to common variables} {
+    set result ""
+    foreach vname {pric proc pubc} {
+        lappend result [test_scope0 info variable $vname]
+        set var [test_scope0 mcontext itcl::scope $vname]
+        set $var "$vname-new"
+        lappend result [test_scope0 info variable $vname]
+    }
+    set result
+} {{private common ::test_scope::pric private-common-value private-common-value} {private common ::test_scope::pric private-common-value pric-new} {protected common ::test_scope::proc protected-common-value protected-common-value} {protected common ::test_scope::proc protected-common-value proc-new} {public common ::test_scope::pubc public-common-value public-common-value} {public common ::test_scope::pubc public-common-value pubc-new}}
+
+test scope-3.7 {code command provides access to methods} {
+    set result ""
+    foreach mname {prim prom pubm} {
+        set cmd [test_scope0 mcontext eval itcl::code \$this $mname]
+        lappend result $cmd [$cmd 1 2 3]
+    }
+    set result
+} {{namespace inscope ::test_scope {::test_scope0 prim}} {prim: 1 2 3} {namespace inscope ::test_scope {::test_scope0 prom}} {prom: 1 2 3} {namespace inscope ::test_scope {::test_scope0 pubm}} {pubm: 1 2 3}}
+
+test scope-3.8 {scope command allows access to slots in an array} {
+    test_scope0 mcontext set varray(0) "defined"
+    test_scope::pcontext set carray(0) "defined"
+    list [catch {test_scope0 mcontext itcl::scope varray(0)} msg] $msg \
+         [catch {test_scope0 mcontext itcl::scope varray(1)} msg] $msg \
+         [catch {test_scope::pcontext itcl::scope carray(0)} msg] $msg \
+         [catch {test_scope::pcontext itcl::scope carray(1)} msg] $msg
+} {0 {@itcl ::test_scope0 ::test_scope::varray(0)} 0 {@itcl ::test_scope0 ::test_scope::varray(1)} 0 ::test_scope::carray(0) 0 ::test_scope::carray(1)}
+
+itcl::delete class test_scope
+
+# ----------------------------------------------------------------------
+#  Test code/scope commands in a namespace
+# ----------------------------------------------------------------------
+test scope-4.1 {define simple namespace with things to export} {
+    namespace eval test_scope_ns {
+        variable array
+        proc pcontext {args} {
+            return [eval $args]
+        }
+    }
+    namespace children :: ::test_scope_ns
+} {::test_scope_ns}
+
+test scope-4.2 {scope command allows access to slots in an array} {
+    test_scope_ns::pcontext set array(0) "defined"
+    list [catch {test_scope_ns::pcontext itcl::scope array(0)} msg] $msg \
+         [catch {test_scope_ns::pcontext itcl::scope array(1)} msg] $msg
+} {0 ::test_scope_ns::array(0) 0 ::test_scope_ns::array(1)}
+
+namespace delete test_scope_ns
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/itcl/tests/tclIndex b/8.x/itcl/tests/tclIndex
new file mode 100644 (file)
index 0000000..4f6bdae
--- /dev/null
@@ -0,0 +1,23 @@
+# Tcl autoload index file, version 2.0
+# This file is generated by the "auto_mkindex" command
+# and sourced to set up indexing information for one or
+# more commands.  Typically each line is a command that
+# sets an element in the auto_index array, where the
+# element name is the name of a command and the value is
+# a script that loads the command.
+
+set auto_index(Simple1) [list source [file join $dir mkindex.itcl]]
+set auto_index(Simple2) [list source [file join $dir mkindex.itcl]]
+set auto_index(ens) [list source [file join $dir mkindex.itcl]]
+set auto_index(::Simple2::bump) [list source [file join $dir mkindex.itcl]]
+set auto_index(::Simple2::by) [list source [file join $dir mkindex.itcl]]
+set auto_index(::buried::inside) [list source [file join $dir mkindex.itcl]]
+set auto_index(::buried::inside::find) [list source [file join $dir mkindex.itcl]]
+set auto_index(::buried::inside::bump) [list source [file join $dir mkindex.itcl]]
+set auto_index(::buried::inside::by) [list source [file join $dir mkindex.itcl]]
+set auto_index(top) [list source [file join $dir mkindex.itcl]]
+set auto_index(::top::find) [list source [file join $dir mkindex.itcl]]
+set auto_index(::top::notice) [list source [file join $dir mkindex.itcl]]
+set auto_index(::buried::ens) [list source [file join $dir mkindex.itcl]]
+set auto_index(::buried::under::neath) [list source [file join $dir mkindex.itcl]]
+set auto_index(::buried::deep::within) [list source [file join $dir mkindex.itcl]]
diff --git a/8.x/itcl/win/.cvsignore b/8.x/itcl/win/.cvsignore
new file mode 100644 (file)
index 0000000..47e2d93
--- /dev/null
@@ -0,0 +1,4 @@
+Debug
+Release
+nmakehlp.obj
+nmakehlp.exe
diff --git a/8.x/itcl/win/dllEntryPoint.c b/8.x/itcl/win/dllEntryPoint.c
new file mode 100644 (file)
index 0000000..c9842b5
--- /dev/null
@@ -0,0 +1,52 @@
+/* 
+ * dllEntryPoint.c --
+ *
+ *     This file implements the Dll entry point as needed by Windows.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#ifdef _MSC_VER
+    /* Only do this when MSVC++ is compiling us. */
+#   define DllEntryPoint DllMain
+#   if defined(USE_TCL_STUBS) && (!defined(_MT) || !defined(_DLL) || defined(_DEBUG))
+       /*
+        * This fixes a bug with how the Stubs library was compiled.
+        * The requirement for msvcrt.lib from tclstubXX.lib should
+        * be removed.
+        */
+#      pragma comment(linker, "-nodefaultlib:msvcrt.lib")
+#   endif
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DllEntryPoint --
+ *
+ *     This wrapper function is used by Windows to invoke the
+ *     initialization code for the DLL.  If we are compiling
+ *     with Visual C++, this routine will be renamed to DllMain.
+ *
+ * Results:
+ *     Returns TRUE;
+ *
+ * Side effects:
+ *     None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifndef STATIC_BUILD
+
+BOOL APIENTRY
+DllEntryPoint(hInst, reason, reserved)
+    HINSTANCE hInst;           /* Library instance handle. */
+    DWORD reason;              /* Reason this function is being called. */
+    LPVOID reserved;           /* Not used. */
+{
+    return TRUE;
+}
+
+#endif
\ No newline at end of file
diff --git a/8.x/itcl/win/makefile.vc b/8.x/itcl/win/makefile.vc
new file mode 100644 (file)
index 0000000..512855d
--- /dev/null
@@ -0,0 +1,532 @@
+# makefile.vc --                                               -*- Makefile -*-
+#
+# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
+#
+# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
+# make it suitable as a general package makefile. Look for the word EDIT
+# which marks sections that may need modification. As a minumum you will
+# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
+# relevant to your package.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+# Copyright (c) 2001 ActiveState Corporation.
+# Copyright (c) 2001-2002 David Gravereaux.
+# Copyright (c) 2003-2006 Pat Thoyts
+#
+#-------------------------------------------------------------------------
+# RCS: @(#)$Id: makefile.vc,v 1.9 2007/09/06 21:12:38 patthoyts Exp $
+#-------------------------------------------------------------------------
+
+# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
+# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
+# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
+MSG = ^
+You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
+Platform SDK first to setup the environment.  Jump to this line to read^
+the build instructions.
+!error $(MSG)
+!endif
+
+#------------------------------------------------------------------------------
+# HOW TO USE this makefile:
+#
+# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
+#     used  as a check to see if vcvars32.bat had been run prior to running
+#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
+#     been set globally and the PATH adjusted.  Either way is valid.
+#
+#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
+#     directory to setup the proper environment, if needed, for your current
+#     setup.  This is a needed bootstrap requirement and allows the swapping of
+#     different environments to be easier.
+#
+# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
+#     vcvars32.bat according to the instructions for it.  This can also turn on
+#     the 64-bit compiler, if your SDK has it.
+#
+# 3)  Targets are:
+#      all       -- Builds everything.
+#       <project> -- Builds the project (eg: nmake sample)
+#      test      -- Builds and runs the test suite.
+#      install   -- Installs the built binaries and libraries to $(INSTALLDIR)
+#                   in an appropriate subdirectory.
+#      clean/realclean/distclean -- varying levels of cleaning.
+#
+# 4)  Macros usable on the commandline:
+#      INSTALLDIR=<path>
+#              Sets where to install Tcl from the built binaries.
+#              C:\Progra~1\Tcl is assumed when not specified.
+#
+#      OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
+#              Sets special options for the core.  The default is for none.
+#              Any combination of the above may be used (comma separated).
+#              'none' will over-ride everything to nothing.
+#
+#              static  =  Builds a static library of the core instead of a
+#                         dll.  The shell will be static (and large), as well.
+#              msvcrt  =  Effects the static option only to switch it from
+#                         using libcmt(d) as the C runtime [by default] to
+#                         msvcrt(d). This is useful for static embedding
+#                         support.
+#              staticpkg = Effects the static option only to switch
+#                         tclshXX.exe to have the dde and reg extension linked
+#                         inside it.
+#              nothreads = Turns off multithreading support (not recommended)
+#              thrdalloc = Use the thread allocator (shared global free pool).
+#              symbols =  Adds symbols for step debugging.
+#              profile =  Adds profiling hooks.  Map file is assumed.
+#              loimpact =  Adds a flag for how NT treats the heap to keep memory
+#                         in use, low.  This is said to impact alloc performance.
+#
+#      STATS=memdbg,compdbg,none
+#              Sets optional memory and bytecode compiler debugging code added
+#              to the core.  The default is for none.  Any combination of the
+#              above may be used (comma separated).  'none' will over-ride
+#              everything to nothing.
+#
+#              memdbg   = Enables the debugging memory allocator.
+#              compdbg  = Enables byte compilation logging.
+#
+#      MACHINE=(IX86|IA64|ALPHA|AMD64)
+#              Set the machine type used for the compiler, linker, and
+#              resource compiler.  This hook is needed to tell the tools
+#              when alternate platforms are requested.  IX86 is the default
+#              when not specified. If the CPU environment variable has been
+#              set (ie: recent Platform SDK) then MACHINE is set from CPU.
+#
+#      TMP_DIR=<path>
+#      OUT_DIR=<path>
+#              Hooks to allow the intermediate and output directories to be
+#              changed.  $(OUT_DIR) is assumed to be 
+#              $(BINROOT)\(Release|Debug) based on if symbols are requested.
+#              $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
+#
+#      TESTPAT=<file>
+#              Reads the tests requested to be run from this file.
+#
+#      CFG_ENCODING=encoding
+#              name of encoding for configuration information. Defaults
+#              to cp1252
+#
+# 5)  Examples:
+#
+#      Basic syntax of calling nmake looks like this:
+#      nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
+#
+#                        Standard (no frills)
+#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+#       Setting environment for using Microsoft Visual C++ tools.
+#       c:\tcl_src\win\>nmake -f makefile.vc all
+#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
+#
+#                         Building for Win64
+#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+#       Setting environment for using Microsoft Visual C++ tools.
+#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
+#       Targeting Windows pre64 RETAIL
+#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
+#
+#------------------------------------------------------------------------------
+#==============================================================================
+###############################################################################
+#------------------------------------------------------------------------------
+
+!if !exist("makefile.vc")
+MSG = ^
+You must run this makefile only from the directory it is in.^
+Please `cd` to its location first.
+!error $(MSG) 
+!endif
+
+#-------------------------------------------------------------------------
+# Project specific information (EDIT)
+#
+# You should edit this with the name and version of your project. This
+# information is used to generate the name of the package library and
+# it's install location.
+#
+# For example, the sample extension is  going to build sample04.dll and
+# would install it into $(INSTALLDIR)\lib\sample04
+#
+# You need to specify the object files that need to be linked into your
+# binary here.
+#
+#-------------------------------------------------------------------------
+
+PROJECT        = itcl
+
+# Uncomment the following line if this is a Tk extension.
+#PROJECT_REQUIRES_TK=1
+!include "rules.vc"
+
+!if $(TCLINSTALL)
+!message *** Warning: [Incr Tcl] requires the source distribution of Tcl to build from,
+!message ***    at this time. Please set the TCLDIR macro to point to the sources.
+!endif
+
+!if [echo ITCL_DOTVERSION = \>> versions.vc] \
+    && [nmakehlp -V ..\generic\itcl.h ITCL_VERSION >> versions.vc]
+!endif
+!include "versions.vc"
+
+DOTVERSION      = $(ITCL_DOTVERSION)
+VERSION         = $(DOTVERSION:.=)
+STUBPREFIX     = $(PROJECT)stub
+
+DLLOBJS = \
+       $(TMP_DIR)\itcl_bicmds.obj \
+       $(TMP_DIR)\itcl_class.obj \
+       $(TMP_DIR)\itcl_cmds.obj \
+       $(TMP_DIR)\itcl_ensemble.obj \
+       $(TMP_DIR)\itcl_linkage.obj \
+       $(TMP_DIR)\itcl_migrate.obj \
+       $(TMP_DIR)\itcl_methods.obj \
+       $(TMP_DIR)\itcl_objects.obj \
+       $(TMP_DIR)\itcl_parse.obj \
+       $(TMP_DIR)\itcl_util.obj \
+!if $(TCL_DOES_STUBS)
+       $(TMP_DIR)\itclStubInit.obj \
+!endif
+!if !$(STATIC_BUILD)
+       $(TMP_DIR)\dllEntryPoint.obj \
+       $(TMP_DIR)\itcl.res
+!endif
+
+PRJSTUBOBJS = \
+!if $(TCL_DOES_STUBS)
+       $(TMP_DIR)\itclStubLib.obj
+!endif
+
+#-------------------------------------------------------------------------
+# Target names and paths ( shouldn't need changing )
+#-------------------------------------------------------------------------
+
+BINROOT                = .
+ROOT            = ..
+
+PRJIMPLIB      = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME     = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+PRJLIB         = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB     = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+### Make sure we use backslash only.
+PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR     = $(PRJ_INSTALL_DIR)
+INCLUDE_INSTALL_DIR    = $(_TCLDIR)\include
+
+### The following paths CANNOT have spaces in them.
+GENERICDIR     = $(ROOT)\generic
+WINDIR         = $(ROOT)\win
+LIBDIR          = $(ROOT)\library
+DOCDIR         = $(ROOT)\doc
+TOOLSDIR       = $(ROOT)\tools
+COMPATDIR      = $(ROOT)\compat
+RCDIR          = $(ROOT)\win\rc
+
+#---------------------------------------------------------------------
+# Compile flags
+#---------------------------------------------------------------------
+
+!if !$(DEBUG)
+!if $(OPTIMIZING)
+### This cranks the optimization level to maximize speed
+cdebug = $(OPTIMIZATIONS)
+!else
+cdebug =
+!endif
+!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+### Warnings are too many, can't support warnings into errors.
+cdebug = -Zi -Od $(DEBUGFLAGS)
+!else
+cdebug = -Zi -WX $(DEBUGFLAGS)
+!endif
+
+### Declarations common to all compiler options
+cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
+cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
+
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+!if !$(STATIC_BUILD)
+cflags = $(cflags) -DUSE_TCL_STUBS
+!if defined(TKSTUBLIB)
+cflags = $(cflags) -DUSE_TK_STUBS
+!endif
+!endif
+
+INCLUDES       = $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)"
+BASE_CFLAGS    = $(cflags) $(cdebug) $(crt) $(INCLUDES)
+CON_CFLAGS     = $(cflags) $(cdebug) $(crt) -DCONSOLE
+STUB_CFLAGS     = $(cflags) $(cdebug) $(crt) $(INCLUDES)
+TCL_CFLAGS     = -DPACKAGE_NAME="\"$(PROJECT)\"" \
+                 -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+                 -DBUILD_$(PROJECT) \
+                 $(BASE_CFLAGS) $(OPTDEFINES)
+
+#---------------------------------------------------------------------
+# Link flags
+#---------------------------------------------------------------------
+
+!if $(DEBUG)
+ldebug = -debug:full -debugtype:cv
+!if $(MSVCRT)
+ldebug = $(ldebug) -nodefaultlib:msvcrt
+!endif
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!endif
+
+### Declarations common to all linker options
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(PROFILE)
+lflags = $(lflags) -profile
+!endif
+
+!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
+### Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
+### Align sections for speed in loading by choosing the virtual page size.
+lflags = $(lflags) -align:4096
+!endif
+
+!if $(LOIMPACT)
+lflags = $(lflags) -ws:aggressive
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+!if !$(STATIC_BUILD)
+baselibs  = $(TCLSTUBLIB)
+!if defined(TKSTUBLIB)
+baselibs  = $(baselibs) $(TKSTUBLIB)
+!endif
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) >= 1400 && $(VCVERSION) < 1500
+baselibs   = $(baselibs) bufferoverflowU.lib
+!endif
+!endif
+
+!if exist("$(TCLDIR)\win\coffbase.txt")
+dllbase        = -base:@$(TCLDIR)\win\coffbase.txt,itcl
+!endif
+
+#---------------------------------------------------------------------
+# TclTest flags
+#---------------------------------------------------------------------
+
+!IF "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!ENDIF
+
+#---------------------------------------------------------------------
+# Project specific targets (EDIT)
+#---------------------------------------------------------------------
+
+all:       setup $(PROJECT)
+$(PROJECT): setup $(PRJLIB) $(PRJSTUBLIB) $(OUT_DIR)\pkgIndex.tcl
+install:    install-binaries install-libraries install-docs
+
+test : setup $(PROJECT)
+       @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+       @set TCLLIBPATH=
+!if $(TCLINSTALL)
+       @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+       @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+       $(TCLSH) ..\tests\all.tcl $(TESTFLAGS) -loadfile <<
+       set env(ITCL_LIBRARY) [file normalize $(LIBDIR:\=/)]
+       load [file normalize $(PRJLIB:\=/)]
+<<
+
+setup:
+       @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+       @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+$(PRJLIB): $(DLLOBJS)
+!if $(STATIC_BUILD)
+       $(lib32) -nologo -out:$@ @<<
+$**
+<<
+!else
+       $(link32) $(dlllflags) $(dllbase) -out:$@ $(baselibs) @<<
+$**
+<<
+       $(_VC_MANIFEST_EMBED_DLL)
+       -@del $*.exp
+!endif
+
+$(PRJSTUBLIB): $(PRJSTUBOBJS)
+       $(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
+
+#---------------------------------------------------------------------
+# Regenerate the stubs files.
+#---------------------------------------------------------------------
+
+genstubs:
+!if $(TCLINSTALL)
+       @echo Need the source distribution to regenerate the Stubs table.
+!else
+       $(TCLSH) $(TOOLSDIR)\genStubs.tcl $(GENERICDIR) \
+               $(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
+!endif
+
+#---------------------------------------------------------------------
+# Generate the source dependencies.
+#---------------------------------------------------------------------
+
+depend:
+!if !exist($(TCLSH))
+       @echo Build tclsh first!
+!else
+       $(TCLSH) $(TCLTOOLSDIR)\mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \
+               -passthru:"-DBUILD_itcl $(ITCL_INCLUDES) $(TCL_INCLUDES)" $(GENERICDIR),$$(GENERICDIR) \
+               $(WINDIR),$$(WINDIR) @<<
+$(ITCLOBJS)
+<<
+!endif
+
+#---------------------------------------------------------------------
+# Dependency rules
+#---------------------------------------------------------------------
+
+!if exist("$(OUT_DIR)\depend.mk")
+!include "$(OUT_DIR)\depend.mk"
+!message *** Dependency rules in use.
+!else
+!message *** Dependency rules are not being used.
+!endif
+
+### add a spacer in the output
+!message
+
+#---------------------------------------------------------------------
+# Implicit rules
+#---------------------------------------------------------------------
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+       $(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
+               -i "$(TCLDIR)\generic" -i "$(TCLDIR)\win" \
+               -DCOMMAVERSION=$(DOTVERSION:.=,),0,0 \
+               -DDOTVERSION=\"$(DOTVERSION)\" \
+               -DVERSION=\"$(VERSION)$(SUFX)\" \
+!if $(DEBUG)
+       -d DEBUG \
+!endif
+!if $(TCL_THREADS)
+       -d TCL_THREADS \
+!endif
+!if $(STATIC_BUILD)
+       -d STATIC_BUILD \
+!endif
+       $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+#-------------------------------------------------------------------------
+# Explicit dependency rules
+#
+#-------------------------------------------------------------------------
+
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+       nmakehlp -s << $** > $@
+@PACKAGE_VERSION@    $(DOTVERSION)
+@PACKAGE_NAME@       $(PROJECT)
+@PKG_LIB_FILE@       $(PRJLIBNAME)
+<<
+
+# The following object is part of the stub library and should not
+# be built as DLL objects but none of the symbols should be exported
+# and without reference to any specific C-runtime.
+
+$(TMP_DIR)\itclStubLib.obj : $(GENERICDIR)\itclStubLib.c
+       $(cc32) -DSTATIC_BUILD $(STUB_CFLAGS) -Zl -Fo$@ $?
+
+#---------------------------------------------------------------------
+# Installation. (EDIT)
+#
+# You may need to modify this section to reflect the final distribution
+# of your files and possibly to generate documentation.
+#
+#---------------------------------------------------------------------
+
+install-binaries:
+       @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+       @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+       @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+!if exist("$(PRJSTUBLIB)")
+       @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+!endif
+
+install-libraries: $(OUT_DIR)\pkgIndex.tcl
+        @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+        @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+       @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
+
+install-docs:
+       @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+       @if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"
+
+#---------------------------------------------------------------------
+# Clean up
+#---------------------------------------------------------------------
+
+clean:
+       @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+       @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+       @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+       @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+       @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+
+realclean: clean
+       @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+distclean: realclean
+       @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+       @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
diff --git a/8.x/itcl/win/nmakehlp.c b/8.x/itcl/win/nmakehlp.c
new file mode 100644 (file)
index 0000000..1752b48
--- /dev/null
@@ -0,0 +1,726 @@
+/*
+ * ----------------------------------------------------------------------------
+ * nmakehlp.c --
+ *
+ *     This is used to fix limitations within nmake and the environment.
+ *
+ * Copyright (c) 2002 by David Gravereaux.
+ * Copyright (c) 2006 by Pat Thoyts
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * ----------------------------------------------------------------------------
+ * RCS: @(#) $Id: nmakehlp.c,v 1.21 2007/12/14 02:27:11 patthoyts Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#define _CRT_SECURE_NO_DEPRECATE
+#include <windows.h>
+#pragma comment (lib, "user32.lib")
+#pragma comment (lib, "kernel32.lib")
+#include <stdio.h>
+#include <math.h>
+
+/*
+ * This library is required for x64 builds with _some_ versions
+ */
+#if defined(_M_IA64) || defined(_M_AMD64)
+#if _MSC_FULL_VER > 140000000 && _MSC_FULL_VER <= 140040310
+#pragma comment(lib, "bufferoverflowU")
+#endif
+#endif
+
+/* ISO hack for dumb VC++ */
+#ifdef _MSC_VER
+#define   snprintf     _snprintf
+#endif
+
+
+
+/* protos */
+
+int            CheckForCompilerFeature(const char *option);
+int            CheckForLinkerFeature(const char *option);
+int            IsIn(const char *string, const char *substring);
+int            GrepForDefine(const char *file, const char *string);
+int            SubstituteFile(const char *substs, const char *filename);
+const char *    GetVersionFromFile(const char *filename, const char *match);
+DWORD WINAPI   ReadFromPipe(LPVOID args);
+
+/* globals */
+
+#define CHUNK  25
+#define STATICBUFFERSIZE    1000
+typedef struct {
+    HANDLE pipe;
+    char buffer[STATICBUFFERSIZE];
+} pipeinfo;
+
+pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
+pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
+
+/*
+ * exitcodes: 0 == no, 1 == yes, 2 == error
+ */
+
+int
+main(
+    int argc,
+    char *argv[])
+{
+    char msg[300];
+    DWORD dwWritten;
+    int chars;
+
+    /*
+     * Make sure children (cl.exe and link.exe) are kept quiet.
+     */
+
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+
+    /*
+     * Make sure the compiler and linker aren't effected by the outside world.
+     */
+
+    SetEnvironmentVariable("CL", "");
+    SetEnvironmentVariable("LINK", "");
+
+    if (argc > 1 && *argv[1] == '-') {
+       switch (*(argv[1]+1)) {
+       case 'c':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -c <compiler option>\n"
+                       "Tests for whether cl.exe supports an option\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return CheckForCompilerFeature(argv[2]);
+       case 'l':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -l <linker option>\n"
+                       "Tests for whether link.exe supports an option\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return CheckForLinkerFeature(argv[2]);
+       case 'f':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -f <string> <substring>\n"
+                   "Find a substring within another\n"
+                   "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           } else if (argc == 3) {
+               /*
+                * If the string is blank, there is no match.
+                */
+
+               return 0;
+           } else {
+               return IsIn(argv[2], argv[3]);
+           }
+       case 'g':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -g <file> <string>\n"
+                   "grep for a #define\n"
+                       "exitcodes: integer of the found string (no decimals)\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return GrepForDefine(argv[2], argv[3]);
+       case 's':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -s <substitutions file> <file>\n"
+                       "Perform a set of string map type substutitions on a file\n"
+                       "exitcodes: 0\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+       }
+           return SubstituteFile(argv[2], argv[3]);
+       case 'V':
+           if (argc != 4) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                   "usage: %s -V filename matchstring\n"
+                   "Extract a version from a file:\n"
+                   "eg: pkgIndex.tcl \"package ifneeded http\"",
+                   argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                   &dwWritten, NULL);
+               return 0;
+    }
+           printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
+           return 0;
+       }
+    }
+    chars = snprintf(msg, sizeof(msg) - 1,
+           "usage: %s -c|-l|-f|-g|-V ...\n"
+           "This is a little helper app to equalize shell differences between WinNT and\n"
+           "Win9x and get nmake.exe to accomplish its job.\n",
+           argv[0]);
+    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
+    return 2;
+}
+
+int
+CheckForCompilerFeature(
+    const char *option)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    SECURITY_ATTRIBUTES sa;
+    DWORD threadID;
+    char msg[300];
+    BOOL ok;
+    HANDLE hProcess, h, pipeThreads[2];
+    char cmdline[100];
+
+    hProcess = GetCurrentProcess();
+
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO);
+    si.dwFlags   = STARTF_USESTDHANDLES;
+    si.hStdInput = INVALID_HANDLE_VALUE;
+
+    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = FALSE;
+
+    /*
+     * Create a non-inheritible pipe.
+     */
+
+    CreatePipe(&Out.pipe, &h, &sa, 0);
+
+    /*
+     * Dupe the write side, make it inheritible, and close the original.
+     */
+
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Same as above, but for the error side.
+     */
+
+    CreatePipe(&Err.pipe, &h, &sa, 0);
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Base command line.
+     */
+
+    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
+
+    /*
+     * Append our option for testing
+     */
+
+    lstrcat(cmdline, option);
+
+    /*
+     * Filename to compile, which exists, but is nothing and empty.
+     */
+
+    lstrcat(cmdline, " .\\nul");
+
+    ok = CreateProcess(
+           NULL,           /* Module name. */
+           cmdline,        /* Command line. */
+           NULL,           /* Process handle not inheritable. */
+           NULL,           /* Thread handle not inheritable. */
+           TRUE,           /* yes, inherit handles. */
+           DETACHED_PROCESS, /* No console for you. */
+           NULL,           /* Use parent's environment block. */
+           NULL,           /* Use parent's starting directory. */
+           &si,            /* Pointer to STARTUPINFO structure. */
+           &pi);           /* Pointer to PROCESS_INFORMATION structure. */
+
+    if (!ok) {
+       DWORD err = GetLastError();
+       int chars = snprintf(msg, sizeof(msg) - 1,
+               "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
+               FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
+               (300-chars), 0);
+       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+       return 2;
+    }
+
+    /*
+     * Close our references to the write handles that have now been inherited.
+     */
+
+    CloseHandle(si.hStdOutput);
+    CloseHandle(si.hStdError);
+
+    WaitForInputIdle(pi.hProcess, 5000);
+    CloseHandle(pi.hThread);
+
+    /*
+     * Start the pipe reader threads.
+     */
+
+    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
+    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
+
+    /*
+     * Block waiting for the process to end.
+     */
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    CloseHandle(pi.hProcess);
+
+    /*
+     * Wait for our pipe to get done reading, should it be a little slow.
+     */
+
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
+    CloseHandle(pipeThreads[0]);
+    CloseHandle(pipeThreads[1]);
+
+    /*
+     * Look for the commandline warning code in both streams.
+     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
+     */
+
+    return !(strstr(Out.buffer, "D4002") != NULL
+             || strstr(Err.buffer, "D4002") != NULL
+             || strstr(Out.buffer, "D9002") != NULL
+             || strstr(Err.buffer, "D9002") != NULL
+             || strstr(Out.buffer, "D2021") != NULL
+             || strstr(Err.buffer, "D2021") != NULL);
+}
+
+int
+CheckForLinkerFeature(
+    const char *option)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    SECURITY_ATTRIBUTES sa;
+    DWORD threadID;
+    char msg[300];
+    BOOL ok;
+    HANDLE hProcess, h, pipeThreads[2];
+    char cmdline[100];
+
+    hProcess = GetCurrentProcess();
+
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO);
+    si.dwFlags   = STARTF_USESTDHANDLES;
+    si.hStdInput = INVALID_HANDLE_VALUE;
+
+    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = TRUE;
+
+    /*
+     * Create a non-inheritible pipe.
+     */
+
+    CreatePipe(&Out.pipe, &h, &sa, 0);
+
+    /*
+     * Dupe the write side, make it inheritible, and close the original.
+     */
+
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Same as above, but for the error side.
+     */
+
+    CreatePipe(&Err.pipe, &h, &sa, 0);
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Base command line.
+     */
+
+    lstrcpy(cmdline, "link.exe -nologo ");
+
+    /*
+     * Append our option for testing.
+     */
+
+    lstrcat(cmdline, option);
+
+    ok = CreateProcess(
+           NULL,           /* Module name. */
+           cmdline,        /* Command line. */
+           NULL,           /* Process handle not inheritable. */
+           NULL,           /* Thread handle not inheritable. */
+           TRUE,           /* yes, inherit handles. */
+           DETACHED_PROCESS, /* No console for you. */
+           NULL,           /* Use parent's environment block. */
+           NULL,           /* Use parent's starting directory. */
+           &si,            /* Pointer to STARTUPINFO structure. */
+           &pi);           /* Pointer to PROCESS_INFORMATION structure. */
+
+    if (!ok) {
+       DWORD err = GetLastError();
+       int chars = snprintf(msg, sizeof(msg) - 1,
+               "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
+               FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
+               (300-chars), 0);
+       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+       return 2;
+    }
+
+    /*
+     * Close our references to the write handles that have now been inherited.
+     */
+
+    CloseHandle(si.hStdOutput);
+    CloseHandle(si.hStdError);
+
+    WaitForInputIdle(pi.hProcess, 5000);
+    CloseHandle(pi.hThread);
+
+    /*
+     * Start the pipe reader threads.
+     */
+
+    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
+    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
+
+    /*
+     * Block waiting for the process to end.
+     */
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    CloseHandle(pi.hProcess);
+
+    /*
+     * Wait for our pipe to get done reading, should it be a little slow.
+     */
+
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
+    CloseHandle(pipeThreads[0]);
+    CloseHandle(pipeThreads[1]);
+
+    /*
+     * Look for the commandline warning code in the stderr stream.
+     */
+
+    return !(strstr(Out.buffer, "LNK1117") != NULL ||
+           strstr(Err.buffer, "LNK1117") != NULL ||
+           strstr(Out.buffer, "LNK4044") != NULL ||
+           strstr(Err.buffer, "LNK4044") != NULL);
+}
+
+DWORD WINAPI
+ReadFromPipe(
+    LPVOID args)
+{
+    pipeinfo *pi = (pipeinfo *) args;
+    char *lastBuf = pi->buffer;
+    DWORD dwRead;
+    BOOL ok;
+
+  again:
+    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
+       CloseHandle(pi->pipe);
+       return (DWORD)-1;
+    }
+    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
+    if (!ok || dwRead == 0) {
+       CloseHandle(pi->pipe);
+       return 0;
+    }
+    lastBuf += dwRead;
+    goto again;
+
+    return 0;  /* makes the compiler happy */
+}
+
+int
+IsIn(
+    const char *string,
+    const char *substring)
+{
+    return (strstr(string, substring) != NULL);
+}
+
+/*
+ *  Find a specified #define by name.
+ *
+ * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
+ */
+
+int
+GrepForDefine(
+    const char *file,
+    const char *string)
+{
+    char s1[51], s2[51], s3[51];
+    FILE *f = fopen(file, "rt");
+
+    if (f == NULL) {
+       return 0;
+    }
+
+    do {
+       int r = fscanf(f, "%50s", s1);
+
+       if (r == 1 && !strcmp(s1, "#define")) {
+           /*
+            * Get next two words.
+            */
+
+           r = fscanf(f, "%50s %50s", s2, s3);
+           if (r != 2) {
+               continue;
+           }
+
+           /*
+            * Is the first word what we're looking for?
+            */
+
+           if (!strcmp(s2, string)) {
+               double d1;
+
+               fclose(f);
+
+               /*
+                * Add 1 past first double quote char. "8.5"
+                */
+
+               d1 = atof(s3 + 1);                /*    8.5  */
+               while (floor(d1) != d1) {
+                   d1 *= 10.0;
+               }
+               return ((int) d1);                /*    85   */
+           }
+       }
+    } while (!feof(f));
+
+    fclose(f);
+    return 0;
+}
+\f
+/*
+ * GetVersionFromFile --
+ *     Looks for a match string in a file and then returns the version
+ *     following the match where a version is anything acceptable to
+ *     package provide or package ifneeded.
+ */
+
+const char *
+GetVersionFromFile(
+    const char *filename,
+    const char *match)
+{
+    size_t cbBuffer = 100;
+    static char szBuffer[100];
+    char *szResult = NULL;
+    FILE *fp = fopen(filename, "rt");
+
+    if (fp != NULL) {
+       /*
+        * Read data until we see our match string.
+        */
+
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           LPSTR p, q;
+
+           p = strstr(szBuffer, match);
+           if (p != NULL) {
+               /*
+                * Skip to first digit.
+                */
+
+               while (*p && !isdigit(*p)) {
+                   ++p;
+               }
+
+               /*
+                * Find ending whitespace.
+                */
+
+               q = p;
+               while (*q && (isalnum(*q) || *q == '.')) {
+                   ++q;
+               }
+
+               memcpy(szBuffer, p, q - p);
+               szBuffer[q-p] = 0;
+               szResult = szBuffer;
+               break;
+           }
+       }
+       fclose(fp);
+    }
+    return szResult;
+}
+\f
+/*
+ * List helpers for the SubstituteFile function
+ */
+
+typedef struct list_item_t {
+    struct list_item_t *nextPtr;
+    char * key;
+    char * value;
+} list_item_t;
+
+/* insert a list item into the list (list may be null) */
+static list_item_t *
+list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
+{
+    list_item_t *itemPtr = malloc(sizeof(list_item_t));
+    if (itemPtr) {
+       itemPtr->key = strdup(key);
+       itemPtr->value = strdup(value);
+       itemPtr->nextPtr = NULL;
+
+       while(*listPtrPtr) {
+           listPtrPtr = &(*listPtrPtr)->nextPtr;
+       }
+       *listPtrPtr = itemPtr;
+    }
+    return itemPtr;
+}
+
+static void
+list_free(list_item_t **listPtrPtr)
+{
+    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
+    while (listPtr) {
+       tmpPtr = listPtr;
+       listPtr = listPtr->nextPtr;
+       free(tmpPtr->key);
+       free(tmpPtr->value);
+       free(tmpPtr);
+    }
+}
+\f
+/*
+ * SubstituteFile --
+ *     As windows doesn't provide anything useful like sed and it's unreliable
+ *     to use the tclsh you are building against (consider x-platform builds -
+ *     eg compiling AMD64 target from IX86) we provide a simple substitution
+ *     option here to handle autoconf style substitutions.
+ *     The substitution file is whitespace and line delimited. The file should
+ *     consist of lines matching the regular expression:
+ *       \s*\S+\s+\S*$
+ *
+ *     Usage is something like:
+ *       nmakehlp -S << $** > $@
+ *        @PACKAGE_NAME@ $(PACKAGE_NAME)
+ *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
+ *        <<
+ */
+
+int
+SubstituteFile(
+    const char *substitutions,
+    const char *filename)
+{
+    size_t cbBuffer = 1024;
+    static char szBuffer[1024], szCopy[1024];
+    char *szResult = NULL;
+    list_item_t *substPtr = NULL;
+    FILE *fp, *sp;
+
+    fp = fopen(filename, "rt");
+    if (fp != NULL) {
+
+       /*
+        * Build a list of substutitions from the first filename
+        */
+
+       sp = fopen(substitutions, "rt");
+       if (sp != NULL) {
+           while (fgets(szBuffer, cbBuffer, sp) != NULL) {
+               char *ks, *ke, *vs, *ve;
+               ks = szBuffer;
+               while (ks && *ks && isspace(*ks)) ++ks;
+               ke = ks;
+               while (ke && *ke && !isspace(*ke)) ++ke;
+               vs = ke;
+               while (vs && *vs && isspace(*vs)) ++vs;
+               ve = vs;
+               while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
+               *ke = 0, *ve = 0;
+               list_insert(&substPtr, ks, vs);
+           }
+           fclose(sp);
+       }
+
+       /* debug: dump the list */
+#ifdef _DEBUG
+       {
+           int n = 0;
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
+               fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
+           }
+       }
+#endif
+       
+       /*
+        * Run the substitutions over each line of the input
+        */
+       
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr) {
+               char *m = strstr(szBuffer, p->key);
+               if (m) {
+                   char *cp, *op, *sp;
+                   cp = szCopy;
+                   op = szBuffer;
+                   while (op != m) *cp++ = *op++;
+                   sp = p->value;
+                   while (sp && *sp) *cp++ = *sp++;
+                   op += strlen(p->key);
+                   while (*op) *cp++ = *op++;
+                   *cp = 0;
+                   memcpy(szBuffer, szCopy, sizeof(szCopy));
+               }
+           }
+           printf(szBuffer);
+       }
+       
+       list_free(&substPtr);
+    }
+    fclose(fp);
+    return 0;
+}
+
+/*
+ * Local variables:
+ *   mode: c
+ *   c-basic-offset: 4
+ *   fill-column: 78
+ *   indent-tabs-mode: t
+ *   tab-width: 8
+ * End:
+ */
diff --git a/8.x/itcl/win/rc/itcl.rc b/8.x/itcl/win/rc/itcl.rc
new file mode 100644 (file)
index 0000000..68b15ff
--- /dev/null
@@ -0,0 +1,56 @@
+// RCS: @(#) $Id: itcl.rc,v 1.6 2004/02/12 20:22:26 davygrvy Exp $
+//
+// Version resource script.
+//
+
+#include <winver.h>
+#include <itcl.h>
+
+//
+// build-up the name suffix that defines the type of build this is.
+//
+#if DEBUG && !UNCHECKED
+#define SUFFIX_DEBUG       "g"
+#else
+#define SUFFIX_DEBUG       ""
+#endif
+
+#define SUFFIX             SUFFIX_DEBUG
+
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION   ITCL_MAJOR_VERSION,ITCL_MINOR_VERSION,ITCL_RELEASE_LEVEL,ITCL_RELEASE_SERIAL
+ PRODUCTVERSION        ITCL_MAJOR_VERSION,ITCL_MINOR_VERSION,ITCL_RELEASE_LEVEL,ITCL_RELEASE_SERIAL
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS     VS_FF_DEBUG
+#else
+ FILEFLAGS     0x0L
+#endif
+ FILEOS        VOS__WINDOWS32
+ FILETYPE      VFT_DLL
+ FILESUBTYPE   0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+       BLOCK "040904b0"
+       BEGIN
+           VALUE "FileDescription", "Itcl language extension for Tcl\0"
+           VALUE "Authors", "Michael McLennan\0"
+           VALUE "OriginalFilename", "itcl" STRINGIFY(ITCL_MAJOR_VERSION) STRINGIFY(ITCL_MINOR_VERSION) SUFFIX ".dll\0"
+           VALUE "CompanyName", "Bell Labs Innovations for Lucent Technologies\0"
+           VALUE "FileVersion", ITCL_PATCH_LEVEL
+           VALUE "LegalCopyright", "Copyright \251 1993-2004\0"
+           VALUE "ProductName", "[Incr Tcl] " ITCL_VERSION " for Windows\0"
+           VALUE "ProductVersion", ITCL_PATCH_LEVEL
+       END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+       VALUE "Translation", 0x409, 1200
+    END
+END
+
+
+
+
diff --git a/8.x/itcl/win/toaster.bmp b/8.x/itcl/win/toaster.bmp
new file mode 100644 (file)
index 0000000..5ea80e6
Binary files /dev/null and b/8.x/itcl/win/toaster.bmp differ
diff --git a/8.x/mk/CHANGES b/8.x/mk/CHANGES
new file mode 100755 (executable)
index 0000000..ded36c1
--- /dev/null
@@ -0,0 +1,2076 @@
+2009-02-10    Create Python install dir if not yet present
+
+    As with C++ and Tcl, the installation directory is created if
+    it did not exist (patch provided by A. Sampson).
+
+2007-06-25    Various Tcl tweaks (recovered from SVN log)
+
+    Cleanup/overhaul, adding CONST86, stubs, and Tcl_GetErrorLine
+    compatibility to allow compiling Mk4tcl for Tcl 8.6*.
+
+2007-06-24    Tcl TEA3 overhaul
+
+    Replace configure.in/Makefile.in with new versions, adapted from
+    Tcl's sampleextension.  Now generates config.h and pkgIndex.tcl
+    from corresponding *.in files.
+    
+    Comnvert all tcl/test/ entries to new ones in tcl/tests/ to use
+    the standard tcltest framework.  Just 40 tests in all so far.
+    
+    Update to tcl.m4 3.6, with a patch to fix "make test" on macosx.
+
+2007-06-24    Cleanup obsolete code
+
+    Remove Lua binding in lua/ - it was never actually completed.
+    Remove win/{catfish,kitviewer,msevc3,msvc152} - now unsupported.
+    Remove mac/, pre-macosx builds are no longer supported.
+    Removed the MKSQL logic and tcl/mksql.tcl, since it is not used.
+
+2007-06-24    Patch for cygwin
+
+    There's a submitted patch (F152) which tries to fix a problem
+    when compilng MK on cygwin with CXXFLAGS=-mno-cygwin, but it may
+    not be the best way to fix things.  Instead, this change adds the
+    $(LDFLAGS) parameter in a few places in the Makefile.  It was not
+    used before, and $(SHLIB_FLAGS) still isn't being used - weird.
+
+2007-06-18    Fix threading problems in Mk4tcl
+
+    A change is needed to make the thread fix work with mk::loop,
+    because the _ws pointer could be null in FreeCursorInternalRep.
+    Fixed by no longer clearing _ws and changing a test for that case.
+
+2007-06-16    ############################################    MK 2.4.9.7
+
+    If you're using Tcl in threaded mode, please upgrade - see below.
+
+2007-06-16    Fix threading problems in Mk4tcl
+
+    The Mk4tcl binding had two serious bugs, causing potential crashes
+    and database corruption when used in multi-threaded mode:
+    
+    1) The Makefile did not set -DTCL_THREADS when configured with
+       the "--enable-threads" flag, only -Dq4_MULTI, which is the C++
+       level threading support of Metakit.  So all builds were still
+       running the Mk4tcl wrapper in unprotected mode (!).
+       
+    2) Tcl's type conversion callbacks did not contain mutex calls to
+       prevent calls from Tcl into Mk4tcl other than mk::* commands.
+       This happens during "Tcl_ObjType mkCursorType" type conversions.
+       
+    Added the proper -DTCL_THREADS flag to Makefile.in, and extra code
+    to implement recursive mutex protection on top of Tcl's primitives.
+    
+    This problem does not affect the C++ core (which has been in use in
+    threaded mode for some time, on many platforms including Windows),
+    nor the Mk4py binding for Python which uses a global interp lock.
+
+2007-02-12    Continue unmapped, also in debug mode
+
+    In the WIN32 version of ResetFileMapping, there were two assertions
+    which made the code fail in debug builds, even though both cases are
+    properly handled with if's.  Dropped the asserts, so that the logic
+    is the same as in release builds: when memory mapping fails, simply
+    continue without memory mapping and fall back to buffering all data.
+
+2006-11-15    ############################################    MK 2.4.9.6
+
+    Please upgrade, this consolidates a year with various fixes.
+    
+    Added some notes to the README about building the Python and
+    Tcl extensions using various approaches.
+    
+    Bumped hardwired Python version number to 2.5 in unix/configure.
+
+2006-11-11    More precise file head/tail marker checks
+
+    The tests for valid head / tail file markers have been relaxed a
+    tiny bit, to allow for future file format changes.  This has no 
+    effect on current uses of MK, the file format remains the same.
+
+2006-11-11    Reformatted all C++ source files
+
+    To get rid of some tab/indent problems accumulated over the last
+    few years, I've run all C++ sources through a pretty-print app
+    (SourceFormatX, a shareware Windows app).  These sources are all
+    being checked-in, so the list of affected files is quite large.
+
+    No semantic changes whatsoever to MK.  All tests pass, as before.
+
+2006-10-31    Fixes for the Python binding
+
+    Fix 64-bit compile with Python 2.5 by Ralf Schmitt, see
+    http://www.equi4.com/pipermail/metakit/2006-October/002236.html
+    
+    Memory leak fix in PWOMapping.h, by Brian Warner, see
+    http://www.equi4.com/pipermail/metakit/2006-October/002229.html
+    
+    Fix 64-bit ptr -> int conversions in {PyRowRef,PyView}.cpp, see
+    http://systemexit.de/repo/metakit?cs=f8f1ef2f6099
+    
+2006-10-31    Fix int overflow in mapped file check
+
+    As reported by Max Kaehn, there is a test in column.cpp which is
+    sensitive to integer overflow when two pointers are > 2 Gb apart.
+    This may have been an old problem for anyone who uses the default
+    memory-mapping files enabled.  Embarassing that this was not caught
+    or resolved before, but I was never able to reliably reproduce it.
+    
+    This is a potentially serious problem, upgrading is recommended.
+    
+2006-10-31    Bring this change log up to date from CVStrac timeline
+
+    I've decided to not adopt the CVStrac system for this change log,
+    because having this log inside the source tree is more convenient.
+    
+    (08-01) persist.cpp: maintain stable-storage space usage on re-open
+    (05-08) view.cpp: fix resource leak in view.cpp
+    (01-26) PyStorage.cpp: fix metakit.py pathnames are required to
+            be of type str & support unicode filenames in storage()
+    (01-25) mk4tcl.cpp: fix crash in mk::select with -keyword search
+    (01-24) fileio.cpp: fix compile error in fileio.cpp with mingw
+    (01-13) configure.in: tweaks to configure.in to use Tcl stubs when
+            compiling a dynamic Mk4tcl on macosx/darwin
+    
+2006-01-12    Don't call _open on WinNT, make commit fail on > 2 Gb
+
+    Fixes for the Dec 5 patch to still always support Win98, thx Matt.
+
+    Fix ticket #2, return false on commit if files would exceed 2 Gb.
+
+2006-01-12    Started using CVStrac for this project, makefile tweak
+
+    CVStrac is a CVS browser, bug tracking system, and more.  All files
+    have gone through a dummy check-in to complete the transition.  The
+    CVS repository is not affected by this change, but this does mean
+    that CVStrac only really started tracking changes from here on.
+
+    If it works out well, this CHANGES file will probably be abandoned
+    in favor of the "timeline" feature in CVStrac which offers the same
+    functionality and *much* more (lots of cross-/hyper-links for one).
+
+    Tweaked Makefile so "make test" does not complain about CVS dir.
+
+2005-12-05    Fix the broken hpux change of 2005-09-06
+
+    It turns out that the 2005-09-06 change, which was rolled back on
+    2005-10-01, was simply incomplete.  Now that it works, it has been
+    adopted on all platforms because it is more portable and equivalent.
+    Thx again Matt.
+
+2005-12-05    Better support for UTF-8 file & property names
+
+    Patch submitted by Matt Newman.  Fixes handling of property names
+    in a description string to support UTF-8 and %'s in names.  Also
+    fix file name handling (convert UTF-8 to native before open).
+
+2005-11-22    ############################################    MK 2.4.9.5
+
+    Main reason for this release is the 11-18 disk-full handling fix.
+
+2005-11-21    Optimization for access via c4_BytesRef::Access
+
+    Added a noCopy flag (default remains as before), by A. Stigsen:
+    When I first looked at c4_BytesRef::Access() I noticed that
+    FetchBytes had the forceCopy option set. So I tried removing that,
+    and that gave some improvement. But it still often happened that the
+    item was in several segments, forcing a copy. So I have added a
+    noCopy option to Access() to ensure that I do not get any uneeded
+    memcopies. It gave a huge performance boost in my application, so it
+    might be useful for others as well.
+
+2005-11-18    Fixed incorrect case of handling disk-full on commit
+
+    This is a potentially serious bug (though all data can still be
+    recovered if dealt with right away).  When an I/O error occurs
+    under specific circumstances in the commit, the resulting file
+    may be left in an improper state.  Full details are desribed in
+    http://www.equi4.com/pipermail/metakit/2005-November/002144.html
+
+2005-11-16    Ranlib called too early
+
+    Fixed call to ranlib when installing Mk4tcl.a - this was copied
+    incorrectly by my from the 11-11 patches.  Thx A. Kupries.
+
+2005-11-15    Version number fixed
+
+    Fixed version number mismatch (2.4.9.3, should now be 2.4.9.4).
+
+2005-11-11    Build fixes for Tcl (by Matt Newman)
+
+    Added logic to disable mmap calls on some HP-UX versions.
+    Plus other tweaks for the Tcl build.  Mods by Matt Newman.
+    
+2005-10-01    The HP-UX fix did not work on macosx.
+
+    Made the 2005-09-06 change below conditional on __hpux, so that
+    builds on Mac OS X don't break, i.e. revert it.  Thx D. Steffen.
+
+2005-09-26    Linking with g++ i.s.o. gcc
+
+    Fixed SHARED_LD to use G++ instead of gcc.  This caused problems
+    when using the shared library from a gcc-compiled main.
+
+2005-09-06    Tweak Tcl binding to avoid compiler problems
+
+    Made some changes to let HP-UX's aCC compile mk4tcl.{h,cpp}
+    properly (no static inits with function ptrs?).  Thx Bob T.
+    Also got rid of some warnings caused by const-ness mismatches.
+
+2005-09-05    Fix potential Tcl close problem
+
+    Bug if a Tcl channel is still open on exit in mk::channel.  Fix
+    thanks to Matt Newman.  Also cleaned up some old unused code.
+
+2005-06-10    ############################################    MK 2.4.9.4
+
+    Maintenance release, consolidates over a year of changes/tweaks.
+
+2005-06-10    Adjusted Python builds
+
+    Changed configure.in to use Python 2.4.x by default (was 2.3).
+
+2005-04-15    Fix typo in Mk4py code
+
+    The 2005-01-29 changes had a typo (InsertA i.s.o. InsertAt).
+    So no one built the CVS version since then?  (thx, Ben R.)
+
+2005-03-01    Fix for BTS#112, insert one part of a view in other
+
+    Only showed up in debug builds, due to malloc overwriting mem,
+    this was a dangling pointer.  Reported and fixed by A. Stimms.
+
+2005-02-18    Backed out of faulty change on 2004-09-23
+
+    The c4_BytesRef::Modify change was not correct.  Will need to
+    be reviewed again, thanks to P. Thoyts for reporting this.
+
+2005-02-14    Minor mods or PocketPC
+
+    Changed some #defines to build under eVC4 for PoscketPC.
+    Updated Tcl build to TEA 3.2 for same reason.
+
+2005-01-31    Updated Tcl build to use TEA 3.1
+
+    A number of changes were needed to make the configure & make
+    setup in the tcl/ area work with Tcl's TEA 3.1 build system.
+    Install target not quite there due to missing doc/tests dirs.
+
+2005-01-29    Allow inserting view in Mk4py
+
+    Fix by B. Kelley to support inserting a view into another.
+    Properties in the source view will be added to dest as needed.
+
+2005-01-07    Some Mk4py fixes
+
+    See BTS#105 for report, PyView.cpp leak fixed.
+    See BTS#106 for report, submitter unknown (change in PyHead.h).
+
+2004-11-30    Added license terms in separate file
+
+    As suggested by Daniel Steffen, see "license.terms".
+
+2004-09-23    Fix c4_BytesRef::Modify bytes insertion
+
+    There was a bug preventing bytes from being inserted past the
+    original size.  Reported by A. Stimms, disgnosed by B. Kelley.
+    The solution was to remove an incorrect minor optimization.
+
+2004-06-03    Fixed missing include
+
+    Added stdio include to mk4too.cpp, fixes Tcl 8.5 compile.
+
+2004-05-20    Mac OS X tweak
+
+    Fix gcc shared lib builds flags for Mac OS X (thx D. Steffen).
+
+2004-04-27    Optimization of blocked views
+
+    New caching of most recent subview block saves a lot of time when
+    frequently getting and storing values (also in sequential order).
+    Effects depend on usage pattern of course, expect 10..40% gain.
+
+    Many thanks to M Berk for submitting a good working patch, which
+    was then further tweaked.  No change in API / usage / storage.
+
+    With this improvement, blocked views are highly recommended for
+    larger views, i.e. millions of rows (up to address space limit).
+    This requires C++, Mk4py, or Oomk/Mk4too (not Mk4tcl).
+
+2004-04-26    Python Unicode strings and distutils test suite
+
+    Did some work to integrate Nicholas Riley's PyRowRef.cpp changes
+    into the core.  Now supports unicode and rejects strings which
+    have null bytes in them (use 'B' i.s.o. 'S' type to accept 'em).
+
+    Tweaked setup.py a bit to properly run "python setup.py tests".
+    This required a hack I don't understand, lines 135 and on, marked
+    "jcw".  Without these extra imports, the tests are not found.
+
+    Merged tweak to PyView.cpp to barf on view.append with >1 args.
+
+    Thanks to Nicholas Riley for lots of improvements.
+
+2004-04-24    Autoconf tweaks
+
+    Dropped LINK_SPECIAL_FLAGS="-rpath ${libdir}" from configure.in,
+    which was causing havoc on Linux: make & make test work again now.
+
+    Fixed configure.in + Makefile.in to support static builds again.
+    The Tcl static target is now Mk4tcl.a i.s.o. libmk4tcl.a (ouch).
+    
+    For Tcl and Python, the following now works on my Linux box:
+       ../unix/conficure --with-tcl=/usr/include --with-tcl=/usr
+    More elaborate params are also supported, see "configure --help".
+
+2004-03-30    Fix opening Win32 files with unicode/multibyte chars
+
+    The _open call used on Win32 is not Unicode/multi-byte friendly (!).
+
+    Added code to try a conversion and use the _wopen variant when the
+    _open fails.  This should work for opening existing files and for
+    creating new files as long as the file tail does not have special
+    chars (i.e. only special chars in the directories leading up to it).
+
+    Also removed UTF conversions from mk4tcl.cpp (Windows build), which
+    interfere with this new logic.
+
+    Detected and resolved by Jeff Hobbs for use in the Mk4tcl extension.
+
+2004-03-09    Added new build files for Mk4tcl
+
+    Added the TEA configure system to tcl/, so that Mk4tcl can now also
+    be built with that approach.  This supercedes the current Mk4tcl
+    code in unix/Makefile.in, which will probably be dropped soon.
+
+2004-03-08    Added DESTDIR to makefile
+
+    Added Stuart Cassoff's patches to support DESTDIR in the Makefile.
+
+2004-03-07    Removed libtool dependency
+
+    Thrown out libtool, it is more hassle than it's worth.  Adjusted
+    configure.in and Makefile.in accordingly - these changes are very
+    preliminary, all help to fix remaining platform issues appreciated!
+
+2004-03-03    Added Microsoft Visual Studio 7.0 project files
+
+    Added a new win/msvc70/ directory with all MSVC 7.0 project files.
+    With thanks to David Van Maren for sharing his work on this.
+    
+    Also added David McNab's info on how to build Mk4py with older
+    versions of Python.  See python/README-dmn for details.
+
+2004-02-29    Fix in Mk4tcl property caching
+
+    In very specific cases, Mk4tcl does not properly track properties
+    cached in a Tcl_Obj*.  This affects byte-compiled code when there
+    are properties using the same name but with different types.  Fixed
+    in the mk4tcl.h and mk4tcl.cpp sources.
+
+    Also optimized selections a bit further (pass Tcl_Obj* instead of
+    strings to force more typed matches, and avoid some c4_String's).
+
+2004-02-16    Minor tweaks
+
+    Change in std.h (for STL) to build with Borland C++ 5.0, and a typo
+    in checking code of c4_View::IsCompatibleWith, which means incorrect
+    use of MK was not detected properly (can't happen in blocked views,
+    the main call point of this routine).  Reported by M Dierolf, thx!
+
+2004-01-28    Free space query
+
+    Added a new FreeSpace() member to c4_Storage to determine how much
+    unused space is in a datafile.  The validity of the returned values
+    has not been verified yet, it's an "undocumented feature" for now.
+
+2004-01-26    ############################################    MK 2.4.9.3
+
+    Maintenance release, consolidates past 9 months of changes/tweaks.
+
+    Fixed test for "__name__" in python/metakit.py to run a quick test.
+
+2004-01-22    Fixed refcount problem with temp rows in Mk4tcl
+
+    This was a long-standing bug: "mk::row create" did not work right
+    because the tracking of temporary rows was completely messed up.
+    Added test case for Tcl (mk6.8), fixes FB14, BTS#78, and BTS#29.
+
+2004-01-21    Documentation updates
+
+    Updated copyright notices to 2004, and udated to Doxygen 1.3.5 for
+    a new set of C++ documentation.  In anticipation of next release.
+
+2004-01-20    Don't trip over duplicate property names
+
+    Added code in c4_Field constructor to avoid crashing when there is a
+    duplicate property name in the format description string.  Duplicate
+    names are now ignored (there is no good way to report errors at this
+    point).  Avoids an even bigger problem: conflicting property types.
+
+    Added test s49 to detect this case (FB20, reported by Brian Kelley).
+
+2004-01-18    Fixed rare but very serious subview resizing bug
+
+    Fixed rare but serious file damaging bug, when resizing a comitted
+    subview to empty, committing, and then resizing back to containing
+    data.  Added new s48 test to force this bug to the surface.
+
+    Fortunately this usage pattern *never* happens in blocked views!
+    Fixes are at the end of c4_FormatV::Insert and c4_FormatV::Remove.
+
+2004-01-16    Gracefully deal with bad property type specifiers
+
+    When GetAs is a called with a bad description, such as for example
+    "myview[name:A]", the release code would crash on a null pointer
+    dereference at some point.  Changed so the code now treats any type
+    it does not know about as "I" (works a bit better than using "S").
+   
+    The debug build still hits an assertion, as before.  Added s47 test.
+
+2004-01-03    Fixed typo in PyView.cpp
+
+    Forgot to fix closing brace after the 2003-12-11 mods.
+
+2003-12-21    Fixed Mk4too sorting on subview of length 1
+
+    There was a silly bug when sorting on subviews in the new Mk4too
+    interface (not in Mk4tcl), which returns a view, instead of a list
+    of integers.  In the case of 1 row, optimization was done wrongly,
+    omitting the sort as well as the remapping.  Fixed.
+    
+    Oomk needs to be patched to work around this (don't sort if n=1).
+
+2003-12-13    Tweak to avoid two unisgned/signed compiler warnings
+
+    In remap.cpp, compiled in debug mode on Win32 (DWORD vs. t4_i32).
+
+2003-12-11    Checked in numerous changes to Mk4py by Nicholas Riley
+
+    All changes are local to the python/directory - for details, see
+      http://www.equi4.com/pipermail/metakit/2003-September/001407.html
+    With a big thank you to Nicholas for contributing these improvements.
+
+2003-11-23    Bumped to Python 2.3, doc tweaks, lots of name fixes
+
+    Adjusted makefile to now look for Python 2.3 by default.
+    Regenerated config files.  Fixed obsolete links in the doc files.
+
+    Got rid of tons of Metakit "interCap" cases, should be Metakit.
+    This affects a huge number of source files and one #define (which
+    has been defined twice for compatibility: d4_MetakitLibraryVersion).
+    Use "cvs diff -i" to see real changes, other than case swapping.
+
+2003-10-28    Get rid of --enable-python, check in c22.txt
+
+    It's not valid, but some files mentioned it.  Use --with-python.
+    Forgot to check in the new c22.txt file added earlier this month.
+
+2003-10-16    Added note to Tcl docs
+
+    Added a note to doc/tcl.html on how to load a MK datafiles stored in
+    another one, as needed when using VFS for example.
+
+2003-10-10    Added c22 test
+
+    Added test to make sure groubpy/select bug is not present in the C++
+    core (bts #75 reports the bug found for Mk4tcl/Mk4too).
+
+2003-10-01    Fixed bugs in Tcl test suite
+
+    The tests in tcl/test/ were incorrectly closing non-test datafiles,
+    such as the "exe" one open while tclkit runs, and needed when a
+    slave is created which needs to re-run init.tcl etc from VFS.
+    
+2003-09-30    Python 2.3.1 & cleanup
+
+    Tweaked PWONumber.h and PyRowRef.cpp and MSVC6 project so it can
+    compile Mk4py for Python 2.3.1 again.  Windows binary uploaded.
+
+    Removed the win/msvc60/tests/ directory, it's no longer needed.
+
+2003-09-20    Autoconf and libtool rebuilds
+
+    In an attempt to stay ahead of version trouble and other nonsense,
+    the autoconf / configure and libtool files have been regenerated.
+    Autoconf is at 2.57 and libtoolize is at 1.4.3 on this dev system.
+
+2003-08-26    Documentation fix
+
+    Fixed install comments for Mk4py, as reported in bts #59.
+
+2003-07-17    Fixes to Mk4py (Gordon)
+
+    Fix crash when db.description(nm) is called for missing view "nm".
+    Fix wrap - for the special case of wrapping a list of primitives
+    (eg, ints, floats, strings) in a single property "view".
+
+2003-07-11    Fix for Linux not finding .lai file
+
+    Posted for RH 8.0 on MK mailing list by Jeff Web on July 3rd.
+
+2003-07-01    Fixed "Metakit" (preferred) vs "Metakit" (obsolete)
+
+    Get rid of InterCappedWords.  Time to grow up, d00d...
+
+2003-06-06    Fix to Mk4py for case (in)sensitivity.
+
+    When using a dict (or keyword args), makeRow now gets the
+    names from the dict's keys and gets the properties by name.
+    This allows case insensitive matching. Note that using an
+    instance still requires that the instance attributes have
+    names that match (case sensitive) with the view.
+
+2003-05-15    Add distutils setup.py script (Gordon).
+
+    Tested on Linux & Windows (MSVC).
+    You can now do a plain configure / make (without python)
+    then cd python; python setup.py build | install
+
+2003-05-08    Fixed array bound bug when not using mmap-ed files
+
+    There was an incorrect test, when dealing with a new file and
+    memory mapping is not enabled (which is uncommon, these days).
+    Thanks to V Demarco for catching and resolving this bug.
+
+2003-04-28    Sourceforge
+
+    Synced to SF's CVS, see http://sourceforge.net/projects/metakit
+
+2003-04-25    Autoconf/libtool update
+
+    Did "autoreconf -force" with autoconf 2.5.7 and libtool 1.4.3, as
+    suggested by Gerfried Fuchs/Ryan Murray.  Some Makefile.in tweaks.
+
+2003-04-22    Fixes to Mk4py (Gordon).
+
+    Make view.append(instance) work again.
+    Fix recursively adding subview data.
+    Make properties compare properly.
+    Initial (incomplete) unittest based test script.
+
+2003-03-16    ############################################    MK 2.4.9.2
+
+    Also allow passing pairs to "mk::row append" as a list (Mk4tcl).
+
+2003-03-10    Fixes for sparc64 configure and AIX strcasecmp
+
+    Both changes contributed by Andreas Kupries.
+
+2003-03-07    Fix more bugs in blocked view, add 64-bit Sparc support
+
+    The blocked viewer deletion was STILL incorrect.  Fixed bad offset
+    calculations, added several more assertion checks, and added a new
+    m07 test case which checks for numerous cases of deletion overlap,
+    i.e. cases where multi-row deletions cross subview boundaries.
+
+    Added __sparc9 #define to mk4.h (thanks again, Andreas K)
+
+2003-03-05    Fixed two potential races in C++ threaded build
+
+    There was a serious bug in view.cpp, whereby Unix (p)thread locks
+    were non-functional in release mode (#define NDEBUG).  Yikes!
+
+    In addition the logic was flawed (both Unix and Windows), failing to
+    protect from indexing while sPropNames / sPropCounts were being
+    resized (i.e. a realloc).  Added explicit locking to all affected
+    paths, and removed the now obsolete count locks (i.e. AddRef).
+
+    Thanks to Murat Berk for chasing this and explaining the problem.
+
+    This bug "only" affects C++ builds.  Tcl and Python each have an
+    extra layer on top which means there can be no races inside MK.
+
+2003-03-03    ############################################    MK 2.4.9.1
+
+    Moving to a new 4-level bugfix release number.
+
+2003-03-02    Fixes to Mk4py (gmcm)
+
+    Modify some recent patches that were Python 2.2 only so they would
+    still work with 2.1. Add a view.properties() method (returning a
+    dict of propname -> Property) for cases where a property is masked
+    by a method name.
+
+2003-03-01    Reverted changes in Mk4py/scxx, avoid Mk4tcl warning
+
+   One was in SCXX, PWONumber.h - ouch and apologies (jcw).  Changed
+   comparison logic in mk4too.cpp (64-bit ints, new code).
+
+2003-02-28    Fixed relaxed layout in Mk4tcl, several Mk4py fixes
+
+   Use list operators to convert a Tcl layout to MK format.  This used
+   to crash, Tcl test 6.7 added to verify the fix.  Changed test 3.1 to
+   use a different notation for nested defs (^).
+
+   Added to ViewerAsSeq, to allow v1+v2+v3 (thanks Michael Scharf).
+   Also fixed several mem leaks - thx again!
+
+2003-02-27    Added support for HPUX aCC "long long"
+
+   Added #ifdef's to mk4.h to match autoconf HAVE_LONG_LONG settings.
+   Tweaks to configure.in by Andreas K to better support HP/UX (thx!).
+
+2003-02-26    Added 64-bit int support to Mk4tcl, fix mingw
+
+   The "L" type was not exposed, though Tcl >= 8.4 has "wide" ints!
+   Will now support 64-bit ints, if built against a Tcl 8.4+ header, but
+   still defaults to without for use in Tcl's <= 8.3.
+
+   Fix _strdup #ifdef in univ.cpp when compiled from mingw on win32.
+
+2003-02-24    Break was missing in switch Mk4py
+
+   Fixed a serious problem, which must have come from editing too
+   wildly (Mk4py needs a test suite!).
+
+2003-02-20    Remove a stray include, remove CR's
+
+   Remove "#include <stdio.h>" from remap.cpp, leftover from debugging.
+   Also removed CR's left behind from editing under Windows (doh!).
+
+2003-02-18    ##############################################    MK 2.4.9
+
+   This is mostly a bug fix release (some features added to Mk4tcl).
+
+2003-02-18    Fixed a bug in blocked view deletion, and hash byteorder
+
+   There was an off-by-one error in the deletion of multiple rows
+   which span more than an entire subview block.  Test m06 is ok now.
+   Also added consistency checks (when compiled in debug mode).
+
+   Fixed a too-strict assertion in mk4tcl.cpp, Item destructor.
+
+   Fixed a byte-order sensitivity in hash views for numeric properties.
+
+2003-02-17    Configure tweaks for hpux/ia64
+
+   Re-instated hpux changes by A. Kupries, for ia64, also -lpthread.
+
+2003-02-14    Bug found in blocked viewer modification
+
+   Added test m06 to catch a problem first detected in the Tcl test
+   suite (test 5.7) - recoded to C++.  This is a show-stopper for the
+   upcoming 2.4.9 release - fixing it is now a top priority.
+
+2003-02-14    Some changes to OO interface in Tcl
+
+   The OO "select" cmd now returns a view, not a list of row #'s.
+   Added "product" and "rename" operators, they were not exposed.
+
+2003-02-14    Enable stdio buffering
+
+   On platforms where stdio is used, the setbuf(..., 0) calls have been
+   removed (fileio.cpp).  This improves performance, and lets caller set
+   up whatever buffering they like.
+
+2003-02-07    Tweaks to restore broken MK ports
+
+   Fixes by A. Kupries to fix MK builds I broke (Itanium/HPUX).
+
+2003-02-07    Changed code to avoid compiler warning
+
+   In remap.cpp, LookDict(), add return at end to avoid a mistaken
+   compiler warning (on AIX 5.1).  No effect on runtime behavior.
+
+2003-02-02    Work around optimizer bug in gcc 3.2.1
+
+   The sign-extension in c4_ColOfInts::Get_16r was not being done right
+   with -O2 on Linux.  This only manifests itself with files having
+   reversed bytes (e.g. PowerPC/Mac).  Changed code to use a local temp
+   buffer instead.  This bug was the reason why some starkits failed to
+   load when created on Mac and used on Linux.
+
+2003-01-24    Fixed cleanup order bug in Mk4tcl
+
+   There was a long-standing bug in Mk4tcl, in which cleanup order of
+   MkPath objects caused them to access their MkWorkspace parent even
+   though it was already deleted.  This may have caused some of the
+   crash-on-exit bugs in the past.
+
+2003-01-22    Add missing -lstdc++
+
+   For unknown reasons, the current make failed to produce shared libs
+   with libstdc++ linked in - manually added to LDFLAGS again.
+
+2003-01-19    Tweak to temp object use
+
+   Two changes in handler.cpp to avoid bug in compilers which get the
+   cleanup logic of temp objects wrong (thx, Dan Gregory).
+
+2003-01-17    Add synonym for mk4tcl "info" command
+
+   To avoid a name clash, "$view info" can now also be written as 
+   "$view properties" (or an abbreviation of that).
+
+2003-01-16    Allow access to root view in Mk4tcl
+
+   Access to root view (i.e. the storage object itself) was not
+   allowed - added a small change to allow this (MkPath::AttachView).
+
+2003-01-15    Use strdup
+
+   On Unix, use strdup i.s.o own code for _strdup, see univ.cpp.
+   Perhaps it's time to start reversing the names, and make unix std.
+
+2003-01-10    Build improvements, Mk4py long and Mac improvements
+
+   Merged changes submitted by Nicholas Riley (thanks!) into CVS:
+   - changes to build Mk4py on MacOS X (framework/dylib)
+   - support 'L' fields, handle overflow, throw exceptions
+   - the beginnings of a test suite for Mk4py (in python/test/)
+
+   Separated PPC and 68K projects (Mac classic), because PPC is now
+   built with 8.3 (Carbon support), while 68K requires 6.3.  The x86
+   cross-compile-from-mac projects have been dropped.
+
+2003-01-09    String compare tweak, Mac Carbon runtime mmap code
+
+   Use strcasecmp on unix, instead of own code (string.cpp).
+
+   Added code based on Paul Snively's contributed patch to recognize
+   running under OSX, so carbon apps can benefit from mmapped files.
+   All changes are within fileio.cpp, requires CW8 to build this way.
+   Added "PPC Carbon" target to cw.mcp, derived from "PPC DLL" one.
+
+2002-12-23    Tweak for Borland builder 5 & 6
+
+   Changed #ifdef line 22 in univ.cpp (fix by S. Cusack).
+   
+2002-12-09    Fixed bug in selection view change propagation
+
+   Fixed a bug when a row is inserted in a view on which a selection
+   depends, when the inserted position is not part of the derived one.
+   This looks like an oversight in 2.3/2.4 changes, and must have been
+   in there for quite some time.  Added new n14 test to verify this.
+
+2002-12-02    Fixed bug in MK old-file format conversion
+
+   Fixed bug in on-the-fly conversion of old 1.x/2.0.x format files.
+
+2002-11-24    Fixed Mk4tcl threaded build
+
+   Release and reclaim mutex lock while calling eval inside loops.
+   Added "--enable-threads" option to configure script.
+
+2002-11-22    Configure tweak for HPUX/Itanium
+
+   Removed ia64 check in configure.in, now that libtool has been fixed.
+
+2002-11-16    Tweaks to compile on Mac
+
+   Small changes to the source code to avoid errors from the MWCW 8.x
+   compilers.  Omit stricmp and strdup with CW version >= 8.
+   
+2002-11-04    Fixed typo in Makefile
+
+   This prevented Mk4py from getting installed (thanks F. Majid).
+
+2002-11-03    ##############################################    MK 2.4.8
+
+   Reverted non-portable change in Makefile to copy to "Mk4tcl.*".
+
+2002-10-28    Workaround for bugs on ARM/WinCE and HP/UX, Mk4tcl/WinCE
+
+   Turn off c4_ColofInts::Set_8i optimization when compiling for ARM on
+   WinCE using EVC3.  All regression tests now pass (on ARM & x86emu).
+
+   On HP/UX, enable copying in fileio.cpp, line 265, so a write is not
+   done directly from a mmap'ed file (this can hang a process, hard).
+
+   Added a "mktcl" subproject to msevc3, to build "Mk4tcl.dll".
+   
+2002-10-27    Added multi-thread support for Unix
+
+   Added changes to support same appartment-threading model on Unix as
+   on Win32 (pthreads based).  This merely adds support to allow safe
+   use of the current "each datafile in one thread" design on Unix.  All
+   changes in view.cpp (thank you, M. Berk).  Define q4_MULTI to enable.
+
+2002-10-26    Merged WinCE changes
+
+   Merged changes to build MK for WinCE using MS Embedded VC 3.0.
+   These changes are based on Joseph Tate's modifications (thanks!).
+
+2002-10-21    Updated autoconf & libtool (on teevie)
+
+   Files in unix/ regenerated with autoconf 2.53a and libtool 1.4.1.
+
+2002-10-16    Added "dup" subcommand to Mk4tcl OO
+
+   There was no way to duplicate a view in the mk4tcl OO interface.
+   Needed to properly deal with re-use / ref counts - added "dup".
+
+2002-10-11    Cast widened in Mk4tcl, support q4_TINY def for Mk4tcl
+
+   Changed cast from int to long, to avoid compiler warning on some
+   64-bit machines (mk4tcl.cpp, line 2013).
+
+   Remove float/double code when q4_TINY is defined, also in Mk4tcl.
+
+2002-10-10    Makefile tweaks
+
+   Removed duplicate flags from CXXFLAGS definition.
+
+2002-10-09    Fixed blocked/subview bug, tweak for the ARM platform
+
+   Blocked viewers were not doing the right thing when rows had subviews
+   in them - fixed the logic, and add a new m05 test to verify it all.
+
+   Fixed a signed-char bug which prevented MK from passing all tests on
+   the ARM, in this case the Compaq iPaq PDA with Linux and gcc 2.95.4.
+
+2002-10-07    Tweak to prevent gcc compiler bug
+
+   Added intermediate temp var in derived.cpp to prevent gcc -O failure.
+
+2002-10-04    Config and makefile adjustments
+
+   Adjusted configure.in to use ".sl" for HP-UX, and ".dll" for Cygwin.
+
+   Changed "install -d" to "mkdir -p" (2x) in Makefile.in, since the
+   former is not supported by all incarnations of install (A Kupries).
+
+   Added @CXXFLAGS@ to the end of "CXXFLAGS =" lines in Makefile.in,
+   as suggested by Donal K. Fellows.  Used for his IRIX(64) builds.
+
+   Added logic to build properly on HP-UX, including a small assembly
+   file (!) which allows loading C++ shared lib from C, as needed in
+   Tcl - with thanks to Andreas Kupries for solving and patching this.
+
+2002-09-25    Build tweaks for Mac OS X
+
+   Applied patches by Daniel Steffen to deal with ".dylib" (thanks!).
+
+   Use -O i.s.o. -O2, which caused test b27 to fail on OS X (gcc 3.1).
+
+2002-09-09    More 64-bit platforms recognized
+
+   Added #ifdefs for more 64-bit platforms, thanks to Reinhard Max.
+
+2002-09-08    Make tweaks for HP-UX
+
+   Tweaks to build on HP-UX / 9000 (added __hpux #ifdef in header.h).
+
+2002-09-03    Fixed Mac OSX build problem
+
+   Compile Mk4tcl lib with stubs only if building the shared lib.
+   Ignore strip errors (fails with Mk4tcl.so on OSX / dyld libs).
+
+2002-07-01    Python and Tcl installation improved
+
+   Now installs Python Mk4py.so and metakit.py in the most common dir
+   location by default, i.e. "/usr/local/lib/python2.2/site-packages".
+   Locations can be overridden through $pyincludedir and $pylibdir.
+
+   For Tcl, "make install" now constructs a standard package dir, i.e.
+   "/usr/local/lib/Mk4tcl/" with entries "Mk4tcl.so" and "pkgIndex.tcl".
+   Locations can be overridden through $tclincludedir and $tcllibdir.
+
+2002-05-30    ##############################################    MK 2.4.7
+
+   Fix CONST84 logic so source compiles under both Tcl 8.3 and 8.4.
+   Fix creation of tests/CVS/ so diff in regression tests won't fail.
+
+2002-05-14    Fixed an adaptive int insert/delete bug
+
+   Another bug in the 2.3/2.4 codebase, related to adaptive integers.
+
+   Symptom: one int entry has incorrect bytes after insert/delete.
+
+   Scenario: ints are 1..8 bits, and an odd number are added/removed,
+   leaving an odd-sized internal "gap".  Then store a 16/32 bit value,
+   forcing resizing.  Once this is done, there will be one value which
+   cannot be properly read or set because its data is split *across* the
+   gap (commit is ok and removes the problem).  Fix in column.{h,cpp},
+   with a new regression test s46 added to make sure things are ok now.
+
+   Let's hope that this is truly the *last* deeply embarrassing bug...
+
+2002-05-06    ##############################################    MK 2.4.6
+
+   Recent bug fix was critical enough to warrant a new revision.
+   It is safest to avoid using versions 2.4.2 .. 2.4.5 altogether.
+
+2002-05-05    Fixed major bug in string/bytes after multiple commits
+
+   Finally found a way to reproduce spurious bugs reported in the latest
+   revisions.  It turns out that one of the optimizations of the past 2
+   months (no exact details) caused memo's to be tracked incorrectly in
+   their free space use.  This causes trouble with strings over 10 Kb
+   (or smaller if there are over 1000 rows).
+
+   The bug is forced by new (frightfully short) test cases s44 + s45.
+   Fixed by performing a slightly less agressive optimization in the
+   c4_FormatB::Commit (which is also shared with strings, type 'S').
+
+   Removed a "--exclude" from diff, which is not portable enough.
+
+2002-05-01    Added support for Windows CE
+
+   Patches submitted by Joseph Tate (thank you!), with minor tweaks.
+
+2002-04-29    ##############################################    MK 2.4.5
+
+   Various bug fixes, fixed a number of platform issues.
+
+2002-04-28    Fix small-int re-use view bug
+
+   A nasty bug was reported by VPI which caused upper bytes to be
+   truncated from int values.  The problem appears when storing ints of
+   1..4 bits in a view, then clearing the view (so a gap is placed past
+   the end of the column), then adding a row with an int of 2 or more
+   bytes.  This uncovered a bug in forgetting to truncate columns with
+   sub-byte int storage.  Now fixed, added regression test s43.
+
+   This bug could also have affected string and byte storage, since
+   these use int columns to store item sizes.  Under very specific
+   conditions, it may have lead to truncated or even mixed-up values.
+
+2002-04-27    Fix nested mk4tcl loop bug
+
+   Loops would exit prematurely when nested - due to objc/objv being
+   overwritten in the inner loop.  Affects mk4tcl.cpp and mk4too.cpp.
+
+2002-04-10    Fix bug introduced in recent blocked viewer optimization
+
+   Murphy was at it again.  The bug affected the way row inserts and
+   deletes were done, and can cause incorrect data to be copied.  It is
+   relatively hard to reproduce (the test dataset was 12 Mb), but the
+   change explains things fully and is in fact very small.
+   
+2002-04-02    Fix bug in debug code
+
+   In remap.cpp line 531, a debug assertion was moved in the wrong way.
+
+2002-04-01    Backed out to libtool 1.4d, fix test diff and Tcl const
+
+   Backed out to the more official 1.4d release of libtool (instead of
+   the CVS version, which is adding "tags" we will not need anyway).
+   The unix/Makefile.in has been simplified, back to how it used to be.
+
+   Fixed the "diff" call at the end of "make test" so that it no longer
+   generates extra output if things match and now fails if they do not.
+
+   Added fix to allow compiling mk4tcl.cpp with "pre-constified" Tcl
+   code, thanks to a tip by Don Porter (see "grep CONST84 mk4tcl.*").
+
+2002-03-31    ##############################################    MK 2.4.4
+
+   Various bug fixes and (blocked view) performance enhacements.
+
+2002-03-28    More blocked optimizations, IRIX tweaks
+
+   Switched Slot() to binary search.  This seems to slow down a few
+   percentage point for smaller views, but with 5 millions rows this is
+   reported to make a huge difference (from code by Zhang Dehua).
+
+   Added header "bool" fix by Erik Hofman so MK compiles on IRIX (SGI).
+
+2002-03-27    Added definitions for AIX
+
+   Added six operators defs before c4_Cursor class, to avoid compile
+   errors on AIX.  With apologies to Murat Berk for taking so long...
+
+2002-03-26    Re-instated the c4_View::RelocateRows operation
+
+   Re-enabled code which supports efficient moves of rows from one view
+   to another - avoiding copying of subviews.  Strings/memos are still
+   being copied for now.  Also moved a slow test out into a new call
+   "c4_View::IsCompatibleWith", this must be checked to make sure that
+   RelocateRows can work.  Passing incompatible views will still cause
+   an assertion in debug mode, but must be avoided in release builds.
+
+   This change ought to have a dramatic effect on inserts/deletes for
+   blocked views with large subviews.  Added examples/blockdels.tcl to
+   thoroughly exercise this new code and all boundary conditions.
+
+2002-03-22    Fixed a serious bug in serialization code
+
+   When serializing string/bytes columns with large strings using the
+   c4_Storage::SaveTo function, memo's would sometimes not be written,
+   leading to a *damaged* datafile (and incorrect free-space tracking).
+
+2002-03-15    Better configure logic, "mk::view layout" fix
+
+   Many tweaks to configures, makes, and libtool setup.  Get rid of the
+   library version numbers and the special Mk4*.so targets.  Instead of
+   Mk4tcl.so use libmk4tcl.so (likewise Mk4py.so is now libmk4py.so).
+
+   Fixed "mk::view layout", it was broken by the 10-2-2002 change.
+
+2002-03-13    Extend partial access 'B' usage
+
+   Added code to Access and Modify to simulate partial data access the
+   hard way when the underlying view does not support it (c4_Bytes
+   only), i.e. copy via full temp.  Added test s41, doing partial access
+   on a blocked view.
+
+2002-03-12    Add test for serialized input
+
+   The c4_Storage::LoadFrom() call (mk::file load) can be tricky.  After
+   a commit, the header is adjusted so that reading from the start
+   works.  This is not the case in commit-extend mode, where a load will
+   read th state as it was before extending - it cannot know there is
+   more.
+  
+   Added test s40 to verify this case.  Also reorged a few more files
+   (tbasics and tstore4 split into 2 each).
+
+   Added test in mk4tl.cpp so LoadFrom failure generates an error
+   return, instead of being ignored.
+
+2002-03-10    Tweaked March 8 fix a tad further
+
+   The workaround implemented below wasn't 100% complete.
+
+2002-03-08    Workaround for file extend on Win
+
+   There seems to be a bug when extending a file on at least NT4 with
+   NTFS (file server works fine).  When extending the file in such a way
+   that a gap is created to save new data during commit, the file
+   appears to get rounded up to the next 512-byte boundary.  At that
+   point, the datafile no longer has a valid end marker and is sort of
+   corrupt.
+
+   Wrote workaround for Win32 builds, see persist.cpp notes names "March
+   8, 2002".  One way to force this bug is to run "mkhash Dmhs 250000" -
+   after row 150000, it asserts on bad filesize when built in debug mode
+   and run on NTFS.
+
+2002-02-19    Fixed over-aggressive optimization
+
+   Change made on Feb 7 was releasing too many objects in a commit,
+   causing it to detach empty top-level views, even when in use.  Fixed,
+   added s39 to test for this case.
+
+2002-02-10    Improve Mk4tcl's "mk::view layout"
+
+   Avoid crash when asking for the layout of a non-existent view.  Now
+   returns an error instead.
+
+2002-02-07    Fast commit with many empty subviews
+
+   Avoid creating subviews when committing, if these are empty anyway.
+   Added new s38 test for this case.
+
+2002-02-02    Small optimizations
+
+   Changed a few c4_Property instances to const& references to avoid
+   copying (2 in view.cpp, 2 in custom.cpp).
+
+2002-02-01    ##############################################    MK 2.4.3
+
+   Bug-fix release, mostly.
+
+   Python include path now upgraded to python2.2 (was 2.1).
+
+2002-01-31    Cross-platform serialization, Tcl
+
+   There was a bug with serializing a datafile (SaveTo) when it was
+   created on a platform with reverse endian-ness.  Fixed so serialized
+   data also flags reversed byte order.
+
+   Tweaks to fix const changes in the latest Tcl cvs branch.  Fixed a
+   recently-introduced UTF8 path bug in mk4tcl.cpp.
+
+2001-12-21    Optimized GetAs
+
+   Now that GetAs is used so much more, optimize the common case where a
+   description does not require restructuring.  Can lead to order-of
+   magnitude speed improvement in cases where a storage contains many
+   views.
+
+2001-12-20    Fixed bug in Locate, comparison issue
+
+   Testing for the Mk4py changes uncovered a serious bug in
+   c4_View::Locate, causing it to sometimes return zero, even if there
+   are matching rows (thanks, Gordon).
+
+   But a very fundamental weakness also showed up, being that row
+   comparisons (and that includes the C++ operators) have the confusing
+   property of not being symmetric in all cases.  The problem occurs
+   when left- and right-hand sides do not contain the same (number of)
+   properties.  In that case, the *left-hand* row participating in the
+   comparison determines which properties take part in a comparison.
+
+   In the case of Locate, this caused improper comparisons.  And it is
+   very easy to get bitten by this, such as here: c4_RowRef key = ...;
+   int n = view.Search(key); bool match = n >= 0 && view[n] == key; The
+   above code is *wrong*.  The last line needs to be: bool match = n >=
+   0 && key == view[n];
+
+   This is very clearly a design mistake.  Comparisons should have been
+   *either* implemented *or* named differently.
+
+   A new "m04" test has been added to the regression suite.
+
+2001-12-19    Changes to mk4py by Gordon McMillan
+
+   Several changes and cleanups.  Mk4py now has logic to track different
+   view categories, e.g. to make sure a R/O view is not being written
+   to.  This should greatly reduce the number of silently ignored
+   incorrect calls, as well as crashes, and will produce appropriate
+   error messages instead.
+
+2001-12-18    Cleanup
+
+   Cleaned up source comments and got rid of yet more warnings.
+
+2001-12-14    Fixed yet another case of crash-on-exit
+
+   The new Unmapped() code of 2.4.2 forgot one case of cleaning up,
+   which has now been fixed (in c4_FormatB::Commit).
+
+2001-12-12    ##############################################    MK 2.4.2
+
+   Better portability, hashing improved
+
+   This release marks the consolidation of a number of changes, mostly
+   relating to better portability & hashing.  The speed of commits with
+   many strings and subviews should be notably better.  The Tcl
+   extension no longer needs a "stub" library to compile (it now has
+   that code itself), just std headers.
+
+2001-12-08    Changes to commit cleanup, Mac stuff
+
+   Changed the logic of how ReleaseAllSegments gets called at the end of
+   commits.  There was at least one case of leaving a column pointing
+   into mapped file space when it was about to be remapped.  This should
+   fix a very long-tanding bug which shows itself as freeing unallocated
+   memory during commit or cleanup of the storage object.
+
+   Changes to test coding and PyRowRef.cpp to deal with builds on
+   Macintosh (different issues for MacOS 9 and MacOS X).  The
+   mac/cw.sea.hqx project has been upgraded to MW CW 6.3.  Verified Tcl
+   8.3.2 and Python 2.1.1 builds with CW6 on Mac.
+
+2001-12-06    Tweaks to Tcl interface
+
+   More robust, added "$vw loop var ... {body}" object command.  The
+   "$vw size" command now takes an optional newsize arg.
+
+2001-12-04    Tweaks to makefile and configure
+
+   Tweaks, in preparation of an upcoming 2.4.2 release.
+
+2001-12-03    Changes in M4py, avoid gcc problem, hash
+
+   The "-fomit-frame-pointer" option for gcc has been turned off,
+   because it causes problems with exception handling in Mk4py.  All
+   failures in Mk4py now propagate properly to Python AFAIK.
+
+   Simplified Mk4py - by removing a layer of exception handler classes
+   in scxx.  Errors now set info and throw a plain int.
+
+   The mkhash.cpp sample program exposed a problem with multi-key
+   hashing: the order of properties in the search key must match exactly
+   the order in the hash view itself.  For now, this has been left as is
+   (it's easy to do, once you are aware of it).
+
+2001-11-30    Win MT fix, commit tweak, indent cleanup
+
+   Drop static buffer in fileio.cpp (DataWrite), uses stack now, so the
+   code can be used in MT context even on Win 95/98.  It does more
+   copying than would be needed for NT (2K?), alas.
+
+   More changes in c4_FormatB::Commit to properly detect memo use in
+   blocked views.  The recent changes introduced a bug which shows up
+   only with blocked views and large string/bytes items.  Reported by
+   Steve Baxter with demo, new "m02" regression test.
+
+   Changed fileio.cpp to turn off file buffering, this avoids a few
+   reads when writing and seeking a lot.  It does not have as big an
+   impact as one might expect, but every little bit helps.
+
+   Cleaned up new 2-space indentation in several source files.
+
+   Added new "mk::file space" in Mk4tcl, to inspect the current file
+   space usage.  This is only intended for internal testing.
+
+2001-11-28    Fixed memory leak in string/memo cleanup
+
+   There was a mem-leak in c4_FormatB::Commit which showed up due to
+   yesterday's more extensive testing.  Only showed up after a commit,
+   in string columns with widely varying item sizes.  This caused
+   regression test s37 to fail in MFC-debug compile.
+
+2001-11-27    Major performance bug fix, and MT strings
+
+   A serious problem has been resolved, which slowed down commits, and
+   prevented blocked views from committing efficiently.  The reason was
+   that for string props, the string size was always being saved anew,
+   even if no changes in that view took place.  This did not affect
+   proper operation, just speed, and was most noticeable with many
+   (sub-)views containing many string props.
+
+   The solution is in src/format.cpp, the examples/mkhash.cpp code was
+   further adjusted to better expose and measure the effects.  Thanks to
+   P. Baspeyras and S. Baxter for helping me resolve it.
+
+   Another change was to alter the way empty strings are allocated in
+   the src/string.cpp code, making it compatible with multi- threaded
+   use and removing the remaining memory leak.
+
+2001-11-26    Fix in assertion check (blocked view)
+
+   Corrected an off-by-one bug.  Only shows up with debugging on, since
+   it's inside an assert().  Thanks to Steve Baxter.
+
+2001-11-25    More arg checking in Mk4py, locate
+
+   Added more checks against incorrect usage, based on sample code by
+   Mitch Chapman.  The "throw" code appears to be inconsistent when
+   called at top of *some* calls, using a workaround for now.
+
+   Added "view.locate(key)" wrapper, returns (pos,count) tuple.
+
+   Various source code formatting adjustments (indents and such).
+
+2001-11-04    Added alternate calls to c4_CustomViewer
+
+   Added extra defs to "mk4.h" of Lookup and InsertRows which take a
+   "const c4_RowRef&" i.s.o. a c4_Cursor.  Inlined in "mk4.inl".  The
+   "c4_Cursor" datatype might one day become obsolete.
+
+2001-11-03    Removed tcl/kit/ and copyright notices
+
+   Removed the entire tcl/kit/ tree, Tclkit will be distributed as
+   separate package from now on (the 2.4.1 release still builds ok).
+
+   Also replaced all copyright notices by version Id's and an URL.
+
+2001-11-02    Fixed partial memo commit bug, makefile fix
+
+   Modifying a small item as memo (i.e. through Modify) properly
+   committed a change, but subsequently left an incorrect pointer after
+   the commit.  Fixed, and added test s37 to catch this case.
+
+   Don't strip symbols from installed static libs (whoops!).
+   
+2001-10-31    Fixed Mk4py error flag clear on delete
+
+   When deleting rows, a slice was constructed from a PWOSequence, which
+   generates an otherwise harmless error when its length is checked.
+   The flag was not cleared, causing errors in subsequent Python
+   statements.  Changed to a PWOTuple in PyView.cpp (2x).
+
+2001-10-26    Fixed Mk4tcl re-open test
+
+   The tcl/test/mk1basic.tcl test #6 was reporting open failure on
+   non-Linux systems.  Fixed, the code works, the message was wrong.
+
+2001-10-19    Rearranged some demo files, Lua binding
+
+   Rearranged some of the demos/samples from the python/ and tcl/ areas,
+   and placed them in examples/ instead, for consistency.
+
+   Added "selmap.tcl" to illustrate how to turn select into a view.
+
+   Added a basic Lua binding (incomplete, but it's a start) in lua/.
+
+2001-10-18    Fixed recent hash bug, and add to ordered
+
+   The recent "fix" to deal with hash misses introduced a huge bug,
+   causing the mapping to be recalculated on each insertion.
+
+   Adding to an ordered view did not always work, because the code was
+   based on SetAtGrow, which is not suitable for an ordered view in
+   which the row position is determined implicitly.  Fixed by changing
+   c4_View::Add to use c4_View::InsertAt instead.
+
+2001-10-14    ##############################################    MK 2.4.1
+
+   Custom-extended Tclkit, and threading
+
+   Minor kitInit.c change allows wrapping apps as a "custom-extended"
+   version of Tclkit.  Enable threaded Tcl build on Unix.
+
+   This release consolidates the most recent fixes and code tweaks.
+
+2001-09-27    Fix temp storage open in Mk4tcl
+
+   A recent change made it impossible to open temporary storages from
+   Tcl ("mk::file open db") - <blush> - now fixed again.
+
+2001-09-19    Bug fixes
+
+   Fixed a problem during commit, when memo's are modified, causing them
+   to be stored inline again.  This caused a late reference to mapped
+   memory - leading to intermittent crashes on commit.
+
+   Changes/fixes in mk4tcl.cpp, to prevent a problem when a datafile is
+   re-opened again under the same name later on.  Old references could
+   in some cases end up stale - leading to crashes much later.
+
+2001-09-05    Bug fixes
+
+   Hashing bug fixed: failed to terminate when looking for a missing key
+   after a hash collision.  The fill count was not being tracked
+   properly to enforce that there is always at least one unused slot.
+
+   Fixed bug when setting a string from a higher row: the data gets
+   trashed, because too little copying was done while creating a gap.
+   This bug may have led to some other cases of "damaged" datafiles.
+   Solved by copying input data in c4_FormatB::SetOne().
+
+   Fixed long-standing bug with commit-after-load, by now doing a full
+   view/subview copy.  This is inefficient, but it avoids all sorts of
+   mapping/strategy problems.  This also fixes test s33 (at last!).
+
+   Added regression tests b27, c21, m01, and s36 to check above fixes.
+
+2001-06-29    ##############################################    MK 2.4.0
+
+   More changes to the Mk4py interface
+
+    - allow setting a row to a value if the row has a single property
+    - there is an unexplained crash when setting slices with wrong type
+
+2001-06-22    Changes to the Mk4py interface
+
+    Modifications and fixes gratefully accepted from John Barnard:
+    - c4_LongProp support ('L' datatype)
+    - row.__attrs__ returns the list of all properties
+    - row.__view__ returns the container view of the row
+    - row.__index__ returns current position in view
+    - view.setsize(n) added, extends/truncates number of rows
+    - generalized makerow to allow any sequence, not just lists
+    
+    Changed PyRowRef to inc/dec the reference it has to the underlying
+    view.  Should prevent dangling pointer problems, such as deleting a
+    storage while rows are still in use.  This adds a little overhead.
+
+    Fixed a PyErr_Clear issue when accessing non-existent properties.
+
+2001-06-12    Close DB filedesc on exec
+
+    Added an fcntl call to fileio.cpp, so that on Unix database file
+    decriptors are closed on exec (relevant when doing "exec ... &").
+
+2001-05-30    Fixed mem-leak in Mk4tcl
+
+    A long-standing bug, in TclSelector::ExactKeyProps.
+
+2001-05-28    Security fix in Tclkit
+
+    See end of the tcl/kit/README file for deatils.
+
+2001-03-30    Fixed long-standing commit bug
+
+    There was an intermittent bug in c4_Persist::Commit, when properties
+    were "restructured away" (dropped).  The bug was hard to track down,
+    because it depended on what address ranges the O/S assigned to
+    mem-maps.  Might also fix other spurious commit/exit crashes.
+
+2001-03-29    ##############################################    MK 2.3.4
+
+    The "last" release candidate
+
+    Now checked into its *new* CVS home at equi4.com.  Mailings list(s)
+    have also been moved to this site.
+
+2001-03-28    Fix Win build, broken on Mar 27
+
+    Dropped kBufMax from mk4.h, it caused compiler errors in MSVC6 -
+    switched to "sizeof" in a couple of places.  This error was
+    introduced by the double-fix of 3/27.
+
+2001-03-28    Allow builds of Tclkit with Sun CC
+
+    Integrated a few changes provided by D.J. Hagberg.  Note: the
+    M-solaris.sh and M-dyn.sh scripts need to be manually edited when
+    choosing between CC and gcc.
+
+2001-03-27    Double-alignment bug on Solaris
+
+    Two changes (c4_Bytes in mk4.h and src/column.h) to fix an alignment
+    problem for 8-byte doubles on Solaris.  This caused tests b17, b23,
+    b24, s22, and s28 to fail.
+
+2001-03-26    Fixed cross-platform commit bug
+
+    There was a nasty bug in the 2.3.x code, which wrote incorrect field
+    sizes when committing to a datafile with a different byte order
+    (i.e. created on a machine using different endian-ness from the one
+    doing commit).
+
+2001-02-14    Removed file events from Tclkit
+
+    Changed kit/rechan.cpp to not generate file events.  This avoids a
+    bug in Tclkit whereby an open file can generate a continuous stream
+    of file events as long as the file is open - the console will seem
+    to be frozen, though "close $file" does work and fixes it.
+
+2000-12-13    Added missing c4_LongRef export
+
+    Added a line in mk4dll.h to resolve references to the new
+    c4_LongProp/c4_LongRef datatype on Windows.
+
+2000-12-04    Fixed conversion bug
+
+    There was a bug in c4_FormatV::OldDefine, causing MK to crash when
+    trying to convert an old-format file with empty subviews in it.  Bug
+    introduced on 14 Nov.
+
+2000-12-02    Fixes in Tclkit code
+
+    Fixed a Tcl-level bug causing memory leaks for all compressed files
+    stored with MK opened for reading.
+
+    Disabled event sources (mk4tcl.cpp and rechan.cpp) to avoid a GUI
+    freeze-up while a fake file is open.
+
+2000-11-16    Simplified c4_Storage
+
+    Made some changes so that a c4_Storage no longer has a separate
+    c4_Persist* copy.  As a result, a storage can now be reconstructed
+    from any root-level view.  This generalizes views, and prepares for
+    a merge.
+
+2000-11-14    Fixed mem leak in conversion code
+
+    The conversion code from pre 2.3 files had a memory leak in
+    c4_FormatV::OldDefine, causing f06 to leak, as well as several
+    subsequent erroneous leak reports.  Changed a few "new" to "d4_new"
+    calls along the way.
+
+    Remove FlipBytes members, they are no longer needed.
+
+2000-11-08    Tclkit now in the distribution
+
+    The "Tclkit" project has been merged into Metakit.  Details and
+    updated build info at "tcl/kit/README".  The SourceForge CVS
+    repository is up to date again.
+
+    Mk4py: improved number conversion and error handling.
+    
+2000-11-03    ##############################################    MK 2.3.3
+
+    First final release candidate
+
+    Yes, there will probably be a second one as well...
+
+2000-10-31    Improved error handling
+
+    More logic added to catch errors in flush and streams.  This affects
+    the C++ core as well as Mk4py and Mk4tcl.  API of c4_Stream::Write
+    changed to return success flag.
+
+2000-10-30    Added autocommit call to Mk4tcl
+
+    To better support VFS, Mk4tcl now has a new command "mk::file
+    autocommit <db>" to force commit on close.
+
+2000-10-26    Changes to compile with Borland C++
+
+    Minor tweaks to compile with Borland C++ Builder 4.0, which does not
+    support "long long".  A new Kitviewer has been built (new code to
+    replace c4_View::Describe).
+
+2000-10-03    Fixes for Alpha Unix
+
+    Moved _item in column.h up to fix alignment sensitivity.  Config.h
+    did not get SIZE_LONG right on Alpha Unix (0?).
+
+2000-09-27    Contributed fixes and Python 2.0b2
+
+    Adjusted makefile to build with Python 2.0b2 release.
+
+    Source code tweaks to avoid DEC CXX 5.7 compiler errors.  Add
+    no-inherit flags for Win32 to not leak file handles.
+    
+2000-08-27    Allow derived row deletes in Mk4py
+
+    Added code to PyView.cpp to handle deletes (and slice deletes) in
+    derived views, see "examples/derived.py".
+
+2000-07-30    Major auto-convert 1.8.6 file bug
+
+    Bug in on-the-fly conversion of bytes properties ('B') in pre-2.0
+    datafiles (i.e. 1.8.6 and earlier) resolved.
+
+    Unfortunately, this bug can not be 100% unambiguously fixed.  The
+    new code *will* properly detect most cases, and convert both 1.8.6
+    and 2.0 datafiles on the fly, but especially for views with only a
+    few rows and at most a few bytes of data per row - the conversion
+    *might* fail.
+
+    In this case, MK will have to be compiled with a define to force it
+    to either assume all old datafiles are 1.8.6 (-Dq4_OLD_IS_PRE_V2),
+    or to assume that they are always 2.0 (-Dq4_OLD_IS_ALWAYS_V2).  If
+    you are currently using MK 1.8.6, then you should *skip* the update
+    to 2.01, and consider updating to 2.3.x.  This way you never have
+    any 2.0 files around, and can force all your code to handle 1.8.6
+    files properly (by using "-Dq4_OLD_IS_PRE_V2").
+
+    See src/format.cpp, c4_FormatB::OldDefine for details.
+
+    This bug *only* applies to bytes properties in pre-2.0 data files.
+    Conversion of 2.0x files is unaffected.
+    
+2000-07-25    Fixed new self-referential views
+
+    The new recursive / self-referential view definition style has been
+    fixed, e.g. "view[data:S,self[^]]" will now let you store a tree of
+    arbitrary depth, with each 'self' subview having data and self
+    properties.  See the demo in "examples/selfref.py" to see how this
+    all works.
+
+2000-07-22    Fixed bug in double restructuring
+
+    Solved a very long-standing bug in restructuring, which caused
+    incorrect (non-zero, small) default values when a c4_DoubleProp was
+    added to a view which already had rows.  
+
+2000-07-18    Added remapwith and pair to Mk4py
+
+    Exposed C++'s c4_View::RemapWith as v1.remapwith(v2), and
+    c4_View::Pair as v1.pair(v2) in the Mk4py Python binding.  Added
+    pair.py, remap.py, and wrap.py in "examples/" dir.
+
+2000-07-12    Added metakit.py wrapper
+
+    Added "metakit.py" script to wrap Mk4py, including a new
+    metakit.dump() to pretty-print views.  More utility code will be
+    added over time.  The preferred way to use Metakit from Python is
+    now "import metakit".
+
+2000-07-06    Conversion fix, warning cleanup
+
+    Fixed on-the fly conversion of old datafiles.  The free space was
+    not managed properly - changed to never touch any data inside the
+    file during conversion.
+
+    Some source code change to get the compile through gcc flags
+    "-fguiding-decls -Wall -pedantic -Wno-unused".  The only remaining
+    complaint is about using "long long".
+
+2000-07-04    MkSQL subtree, "indexed" mapped viewer
+
+    Added the sql and mksql subtrees to the distribution, with Gordon
+    McMillan's MkSQL engine, written in Python.  The "isql.py" script is
+    a simple interactive shell around it.
+
+    Started work on a new viewer which maintains a persistent index (as
+    a one-int-prop permutation), see src/remap.cpp.
+
+2000-07-03    Mk4tcl fixes
+
+    Fixed view rename problem and "delete end" (Matt Newman).  Adjusted
+    the tests in tcl/test/mk5object.tcl accordingly.
+
+2000-06-30    Tequila fixes
+
+    Close fix and failure handler (Steve Landers).
+
+2000-06-29    ##############################################    MK 2.3.2
+
+    First beta release
+
+    The new release is 99% feature-complete.  What remains is to further
+    document C++/Python/Tcl use and to fix bugs.
+
+    Python sample code in "python/aside.py" and "python/find.py".  Tcl
+    samples in "tcl/test/mk5object.tcl" and "tcl/mapped.tcl".
+
+2000-06-28    Hash/blocked/ordered: changes and fixes
+
+    Changed hash insertion to insert at specified position.  This makes
+    it possible to use hashes "under" ordered views.  For best
+    performance, insert rows at end of hash views.
+
+2000-06-26    Documentation, example, Mk4tcl OO fixes
+
+    Moved C++ member documentation out of "mk4.h" header.  Added
+    examples/ directory, with a find.py timing example.  Fixed bugs in
+    new Mk4tcl: "$vw find" and "$vw delete end".  Added tests for new
+    Mk4tcl OO interface: ":mk5object.test".
+
+2000-06-16    Improved modifiable custom viewers
+
+    The Pair and Slice viewers now support set/insert/remove, while
+    RemapWith/Concat/Rename support setting values.  
+
+2000-06-15    Many changes to the Tcl code, hashing
+
+    Contributed by Matt Newman, it adds support for most custom viewers,
+    including the new hash etc.  Added a fast find.  Caveat: most old
+    custom viewers are still not modifiable.
+
+    Hash calculation improved, far less collisions than before.
+
+    Blocked viewer seems to work.  Ordered on top is sub-optimal.
+
+2000-06-12    GetUpperLimit, Blocked, Ordered, mk4too
+
+    Removed c4_View::GetUpperLimit (it's equivalent to GetSize-1 and was
+    not being used anywhere).
+
+    Start implementing c4_BlockedViewer, a simple balanced/blocked
+    nested data structure.  Also started on a c4_OrderedViewer, which
+    keeps the underlying view sorted during changes.  These two can be
+    combined to implement an efficient 2-level btree.
+
+    Adopted code by Matt Newman for oo-cmd's for Mk4tcl views.  First
+    trials work, started to extend with new custom viewers.
+
+2000-06-09    Change case of a few Mk4py members
+
+    Changed all top-level members in the Python interface to lower case:
+    storage, property, view, wrap (will break existing code).
+
+    Fix bounds check in Mk4tcl.cpp for commit/rollback (new code).
+
+    Whoops, forgot to add new src/remap.{h,cpp} to the cvs tree.
+
+2000-06-08    Implemented hash lookup
+
+    Added a new virtual c4_Sequence::RestrictSearch, which lets a view
+    take over searching (used by c4_View::Find).  The result is that the
+    new hash viewer gives a huge speedup for finds.  Find requests which
+    require linear scanning are unaffected.
+
+2000-06-07    Documentation extraction based on Doxygen
+
+    The automatically generated output from Doxygen is working out well
+    and looking pretty, added "src/doxy.h" with more comments.
+
+2000-06-05    Started hash and btree custom viewers
+
+    The hash implementation is nearly done, also usable from Python.
+    Btrees are being implemented as fixed 2-level for now.
+
+2000-06-01    Fixes
+
+    Fixed crash when opening missing file r/o new in 2.3.1 alpha.  Fixed
+    incorrect on-the-fly-conversion of 2.0 format subviews.  Added
+    "storage.aside(storage)" to the Python interface.
+
+2000-05-30    Fixed commit-aside
+
+    The new commit-aside code was botched by recent changes.  Fixed
+    SetAside to pick up new root seq, changed by implicit rollback.
+    Note that a commit-aside is not finished until you *also* commit the
+    secondary file containing all newly generated changes.
+
+    Fixed bug in c4_BytesRef::Access, introduced in 2.3.1 alpha.
+
+2000-05-29    Added new 64-bit long datatype
+
+    Added support for 64-bit longs (type 'L'), and c4_LongProp, etc.
+    This type is not autosizing, it always uses 8 bytes per entry.  Uses
+    "long long" or "__int64", else defines struct with 2 longs.  This is
+    not yet correct for platforms which have no 64b ints.  No regression
+    tests or Python/Tcl interfaces yet.
+
+2000-05-28    Better file mark scanning
+
+    Added c4_Strategy::EndOfData, to determine the logical end of a
+    Metakit datafile.  This call can be used to check whether a file
+    contains any data, and whether a commit-extend has been performed.
+    Old-style scripted documents (with preamble) can now be opened.
+    Changed strategy class, DataSeek has been merged with read/write.
+    Removed c4_LoadContext, LoadIt member moved to c4_Persist.
+
+2000-05-27    Tweaked configuration define's
+
+    Make the release build the default (no assertions, use inlines).
+    Enable booleans for gnuc by default (it's pretty standard by now).
+    Added extra include path to better find Python's includes.
+
+2000-05-26    Fixed Tcl dependency
+
+    Changed configure script to no longer look for Tcl if the
+    "--with-tcl=..." parameter is not specified.
+
+2000-05-25    ##############################################    MK 2.3.1
+
+    First alpha release
+
+    Officially, this is "Metakit 2.3.1 alpha" (ignore "2.3.0" in mk4.h).
+    All alpha's are 2.3.1 (beta's will be 2.3.2, finals start at 2.3.5).
+    Builds on Linux/Mac/Win appear ok - as do Mk4py, Mk4tcl, and Tclkit.
+
+2000-05-06    Massive changes to the core
+
+    To summarize the main issues: management info is now stored in such
+    a way that it need not be read in right away - file open is now
+    instant.  The S(tring) datatype is now stored as B, making it far
+    more scalable (API/use is unchanged).  Storage objects now derived
+    from views, both can be initialized from a stream (data will be kept
+    in a buffer, beware of potentially large memory use).
+
+    Several file format changes are "for future expansion".
+
+2000-05-05    Fixed builds without Tcl
+
+    In 2.0.1, the make would fail if there was no Tcl to build with, or
+    not an appropriate release.  Changed Makefile to report and skip Tcl
+    builds in that case.
+
+2000-04-06    Fixed a nasty restructure/mmap bug
+
+    When a property is deleted by a restructure, then committed, then
+    later committed again, a problem can cause MK to crash.  It has only
+    been detected in debug builds, but the problem turns out to be a
+    fundamental one (only happens with memory-mapped files, if the file
+    is resized).  Fix in next rel (c4_HandlerSeq::DetachFromStorage).
+
+2000-04-02    Memo properties are no longer needed
+
+    The M datatype is gone from the public API (and now illegal).
+    Everything binary should now be stored in B(ytes) properties, which
+    then adaptively decide which internal format to use, based on a
+    simple heuristic (which will be refined later).  Existing datafiles
+    will automatically convert from M to B.  The partial Access and
+    Modify calls now also work on B items.
+
+2000-03-30    Minor change in c4_Strategy
+
+    Dropped the _keepAfterCommit flag in c4_Strategy, it probably has
+    never been used and it interferes with new features.
+
+2000-03-27    Change in API for creating storages
+
+    It is no longer possible to create a storage and define its
+    structure with a single call.  Instead, open a storage in r/w mode
+    (i.e. "1") and then call the (now public) SetStructure member to
+    define the structure of all views.  This change is necessary to
+    prepare for the upcoming "commit-aside" logic.
+
+2000-03-23    File format changes (in progress)
+
+    The new file format has an incompatible header, so old code will not
+    recognize new datafiles.  Major changes are: added a file tail
+    marker, the serialized format is now a very good way to compress
+    datafiles, since it can be efficiently opened in on-demand/mmap'ed
+    mode.  The new format supports several planned features.  Code to
+    convert existing files on-the-fly will be added before this change
+    is released.
+
+2000-03-19    Added c4_Strategy::FileSize
+
+    The Strategy::FileSize call is used for a file format change.
+
+2000-03-18    Added c4_View::Locate
+
+    Locate returns the number of matching rows, and optionally the
+    position of the first one, using binary search.  Like the
+    c4_View::Search function, it requires the view to be sorted.
+
+2000-03-17    ##############################################    MK 2.01
+
+    Maintenance release, it's solid
+
+    Updated MK version number to 2.01, this maintenance release
+    represents a very stable version.
+
+    Small change to b07 test to avoid evaluation order problems.
+
+    Added unix/metakit.spec file for RPM, thanks to Sean Summers.
+
+2000-03-16    Drop Store, fix deep copy, drop segments
+
+    c4_Storage::Store never worked properly under all conditions.  It's
+    been deprecated for some time and has now been removed.  Made a
+    handful of changes to test- and demo code to drop it.
+
+    Duplicating a view with deep copy never worked, because it used the
+    buggy Store call as well.  Changed to use recursion.
+
+    Dropped support for segmented tree-walk storage, which hasn't been
+    used since 1.5 (use a commit with 2.0 to convert files).  This is
+    necessary to prepare for some file format changes.
+
+2000-03-15    Modifiable custom viewers, other tweaks
+
+    A start has been made with making custom viewers updatable.  The new
+    methods are Set, InsertAt, RemoveAt, and Move, but the number of
+    viewers which implement this is still limited.  Mk4py has been
+    adjusted to allow "set" on wrapped views.
+
+    Removed c4_Strategy::DataLoad, it was only used in one place.  Small
+    optimization of the 2 calls to c4_Streamer::NextByte.  Get rid of /
+    disallow read calls on memory mapped files.
+
+2000-03-14    Makefile tweaks, non-commits smarter
+
+    Changed from --enable-tcl to --with-tcl=DIR, because the old
+    approach only worked with Tcl installed in a standard place.
+
+    Commits of a R/O file now fail.  Also, if no changes have been made,
+    a commit will no longer write anything to file.
+
+2000-03-13    Several new commands added to Mk4py
+
+    Several changes were submitted by Gordon McMillan, which add better
+    support for his upcoming SQL engine.
+
+2000-03-12    Allow embedding MK datafile at end of EXE
+
+    Mk4tcl was changed to look for an optional trailer for quick access
+    to the start offset.  This makes it possible to append datafiles to
+    executables, even if they are larger than 4 Kb.
+
+2000-02-29    Fixed rare bug with lots of memo fields
+
+    There was a bug in free space management (persist.cpp), which can
+    only occur when exactly 7500 free space gaps are present, and a
+    commit crosses the threshold.  There was also a small mistake in
+    that same code causing a bit of free space waste.
+
+2000-02-24    Added proxy support to Tequila
+
+    Tequila can now be used as basic client/server setup for Tcl
+    scripts.  See tcl/tequila/README for details and an example.
+
+2000-02-04    Fixed mk::views (Mk4tcl)
+
+    The mk::views command failed to list the first view in the file
+    (this bug was introduced by changes in MK 1.99).
+
+2000-01-02    Adjusted y2k
+
+    Copyright and license dates adjusted.
+
+1999-12-26    More Mk4py changes
+
+    Added sortrev, and fixed "select(low,high)".  Docs updated.
+
+1999-12-23    New view operators in Mk4py
+
+    Added rename, project, groupby, and counts operators to Mk4py.
+    These were already part of the C++ core.
+
+1999-12-22    Avoid GetId inline warning
+
+    Reordered GetId in "mk4.inl" to avoid (harmless) inline warning.
+
+1999-12-21    Checked-in Catfish and Kitviewer sources
+
+    Added win/catfish and win/kitviewer areas.  Catfish was built with
+    MSVC 1.52, so the win/msvc152 area has also been added.
+
+    Kitviewer requires Borland C++ Builder 4.0 to build (using VCL), it
+    has been adjusted to now also recognize scripted documents.
+
+1999-12-20    Bug fix in set-after-get situations
+
+    A bug has surfaced when setting string/byte/memo values which span a
+    4 Kb block boundary.  The bug can only happen if data is first
+    fetched and subsequently changed.  The affected code is in
+    src/format.cpp (3x).  Added Tcl test 5.5 to catch this.
+
+1999-12-19    Mac tweaks
+
+    Changes to make the Mac versions build from the CVS repository.  The
+    Mac can also cross-compile Windows libraries using MWCW 5.
+
+1999-12-17    Add the Tequila example
+
+    Added the Tequila global Tcl array data server, see tcl/tequila/.
+
+1999-12-15  MK 2.0      Official Open Source release
+
+    Removed a bad assertion from FormatX::Compare.
+
+    Several new services set up on the excellent SourceForge.com site.
+
+1999-12-14    Documentation added
+
+    The C++ API documentation has been added to the distribution, as
+    well as a document describing the file format details of Metakit.
+
+1999-12-13    Bug fix affecting c4_View::Description
+
+    There was a problem with c4_ViewScanner::Describe, due to a change
+    from c4_String to (const char*).  Now c4_View::Store works again.
+
+1999-12-12  MK 1.99     New release, as open source software
+
+    The major change is that Metakit has been released as open source
+    software, based on the liberal X/MIT-style license.  Commercial
+    support remains unchanged for all recent commercial customers, and
+    for those who purchase the Enterprise License.  The Universal Source
+    license has been terminated, because full source code is now freely
+    downloadable by anyone from the website.
+
+    Sources and documentation files have been adjusted accordingly.
+
+1999-12-08  MK 1.9h     Bool support for gcc/egcs, minor fix
+
+    Clear _field after delete in c4_HandlerSeq::DefineRoot.  This
+    triggered an assertion on Linux, when compiled in debug mode.
+
+    Added pre-processor logic to detect whether gcc supports bools.
+
+    Removed all indentation from #define's, #ifdef's, etc.  This was
+    done after a report that some compilers can get confused by this.
+
+1999-12-06    Derived view row copy fix
+
+    There was a problem when using SetAt with derived views as source,
+    due to a remapping problem.  Fixed viewx.cpp, added new test b25.
+
+1999-11-25  MK 1.9g     Makefile changes, thread-safe Mk4tcl
+
+    Renamed options to --enable-python and --enable-tcl, both now off by
+    default, since most people probably don't want to enable both.
+
+    The new "-shared" changes to make Mk4tcl thread-safe have been
+    folded into the main source code.
+
+1999-11-22    Channel improvements Mk4tcl
+
+    There was a close conflict in mk::channel, also several changes to
+    improve mk::channel fileevent handling.
+
+1999-11-19    Bug fix in Mk4tcl
+
+    There was an array overrun when mk::get was called without fields.
+    Added code to avoid this.
+
+1999-11-11    Mk4tcl exit handling
+
+    Simplified Mk4tcl exit handling, fixes "interp delete" crash.  Added
+    new mk5fixed.4 test to catch this case.
+
+1999-11-10    Mk4tcl shared and multi-threaded access
+
+    Made a first experimental version of Mk4tcl (1.2.1, not announced)
+    which allows sharing a database between interpreters and threads.
+
+1999-11-09    STL, MkWrap, compare caching
+
+    Tweaked the makefile to support STL builds (also adjusted README).
+
+    Fixed bug in MkWrap, calling storage.description() without args.
+
+    Yet more fixes in comparisons, this is all one problem, caused by
+    changes in caching for ints, floats, and doubles.  Added B24 test.
+    These (last?) problems occured in custom / compound views.
+
+1999-11-08  MK 1.9f     Fixed sort comparisons
+
+    There was a cache problem with comparisons of int / float / double
+    sorts.  Fixed, also added new B23 regression test to check for it.
+
+1999-11-07    Little nasty details
+
+    Tweaked some make/project files.  All regress tests and Tcl tests
+    now reported to really work on Solaris, Linux, Windows, and Mac.
+    Regression tests required more memory on Mac to get past L03 case.
+
+1999-11-06  MK 1.9e     Big oops: Mk4tcl and MkWrap were broken!
+
+    Fixed a c4_Strategy / c4_FileStrategy mixup in Mk4tcl and MkWrap.
+
+1999-11-05    Simplify c4_Storage
+
+    Moved state out of c4_Storage and into c4_Persist, to prepare for
+    multi-thread wrappers.  Made a new, simpler design to achieve that.
+
+1999-11-04  MK 1.9d     Factor out stdio dependencies
+
+    Moved all stdio dependencies out of core into new "fileio.cpp" src.
+    The mk4.h header no longer includes <stdio.h>, added new "mk4io.h"
+    header with a c4_FileStrategy class, derived from c4_Strategy.
+
+    Also factored c4_Stream/c4_FileStream out of the c4_Strategy class.
+    This alters the API slightly, but makes it 100% portable/embeddable.
+
+    Added "tcl/iohan.tcl", a simple wrapper for generic storage access:
+    locally, on a FTP server, in a local MK datafile, or using a remote
+    Tequila server (see http://www.equi4.com/tclkit/tequila.html).
+
+1999-11-03    Improved detach/restructure handling
+
+    Changed detach to drop all persistent formathandlers, but leave the
+    number of rows intact.  It will be much faster to destroy columns
+    than to delete (and propagate) rows.  The result is that a pointer
+    to a view of which the underlying storage object goes away will end
+    up with the same number of rows as before, but no properties at all.
+
+    Fixed a problem which would have occured when properties are being
+    "restructured away" and then committed.  The solution is to check
+    for this and delete all such properties at commit time.
+
+    Moved Buffer() out of c4_HandlerSeq and c4_CustomSeq, and made the
+    new version in c4_Sequence allocate the c4_Bytes object lazily.
+    Faster, and decreases sequence object size (for lots of subviews).
+
+    Mk4tcl, mk::layout now returns the proper layout even if the views
+    are empty.  Solved by adding extra arg to c4_Storage::Description,
+    to return structure of a single top-level view.  Fixes "mk8basic.1",
+    and the returned string now has one bogus list layer stripped off.
+
+    MkWrap also adjusted with optional arg for storage.description().
+
+1999-11-02    New Wrap code in MkWrap
+
+    MkWrap, added new Wrap(seq,props,byPos) member, a c4_CustomViewer
+    which wraps any Python sequence as MK view (for use in joins, etc).
+
+1999-11-01  MK 1.9c     Mk4tcl changes
+
+    Mk4tcl, several changes: added "-size" option to mk::get to return
+    the size of prop value without fetching it (see new basic.9 test).
+    Added "-globnc" for case-insensitive globbing (for regexp, this is
+    available through the new (?i) metasytnax of Tcl 8.2 (see basic.10).
+
+1999-10-31  MK 1.9b     Solved shared lib unload with Tcl 8.2
+
+    Changed property symbol table setup to avoid static initializers, to
+    work around a problem with shared library cleanup from Tcl 8.2.
+    Added new c4_Property::CleanupInternalData call to clean up 100%
+    (this code need not usually be called, only if memory is tracked).
+    This fixes the crash-on-exit bug in Mk4tcl (Linux and Solaris).
+
+1999-10-29    Make support for MkWrap and Mk4tcl
+
+    Both MSVC and MWCW now also build Mk4tcl and MkWrap extensions.  The
+    MWCW project compiles for Win and Mac *on* either Win or Mac.
+    Makefile extended to build Mk4tcl and MkWrap, added dist target.
+    Updated to latest Perceps 3.5 beta, started generating docs again.
+
+1999-10-27  MK 1.9a     New build / directory structure
+
+    Completely reworked the directory structure to simplify all builds.
+    Created new "builds/" area for all intermediate and output files.
+    New MSVC 6.0 project structure created in "win/msvc60/".
+
+    Moved Mk4tcl to the "tcl/" top-level directory, and MkWrap to the
+    "python/" dir.  The MkWrap code has been removed from the project.
+
+    Removed c4_View::Match and the regular expression package, since it
+    can just as efficiently be done with a wrapper around MK, now that
+    string results no longer allocate a temporary copy.
+
+    Started writing a Tcl-based test suite for use with Mk4tcl.
+
+MAJOR CHANGE SINCE 1.8.6
+
+    Merge handler.cpp and format.cpp classes to get rid of special-cased
+    in-memory version of handlers.  This has major effects on how data
+    is kept for unattached views (they still exist, but no longer
+    special).  The code is leaner and meaner, it passes all regression
+    tests.
+
+ALSO LISTED IN THE RELEASE HISTORY
+
+    Added c4_MemoRef::Access and c4_Memoref::Modify for partial access
+    to memo fields.  Avoids copying and allows inserts/deletes anywhere.
+    MkWrap and Mk4tcl have both been extended to allow using Memo fields
+    for simulated file IO (mk::channel for Tcl, MkMemoIO.py for Python).
+
+    Added c4_Reference::GetSize to determine the size of a value without
+    accessing it.  For ints, returns negated bit width if 1/2/4 bits.
+
+    Added experimental c4_View::RelocateRows to move rows from one view
+    to another (both must be in same storage, with the same structure).
+    Moves do not involve any data copying w.r.t. subviews and memo's.
+
+The old release history is at http://www.equi4.com/metakit/history.html
+
+# vim: tw=72
diff --git a/8.x/mk/NOTES-2.3.4 b/8.x/mk/NOTES-2.3.4
new file mode 100644 (file)
index 0000000..31ede5f
--- /dev/null
@@ -0,0 +1,385 @@
+Metakit 2.3.4 - last release candidate
+March, 2001
+
+Welcome to the latest release of the Metakit embedded database library.
+This is a near-final release, it is functionally 100% done, but a few
+minor problems/bugs still remain.  Release MK 2.3.4 is essentialy ready
+for production use, with one extremely important disclaimer:
+
+   >>> Do *not* rely on new commit-aside/-extend models, these
+   >>> new features are not good enough for general use yet.
+   >>> Worse still, they will remain experimental in 2.3 final!
+
+This document describes the main changes since 2.01 in some detail:
+
+ - a new version numbering scheme (again)
+ - some essential file format changes
+ - new commit modes: commit-aside and commit-extend
+ - the memo datatype has been removed from the public API
+ - made a start with making custom viewers modifiable
+ - new "mapped views": hashed, blocked, and ordered
+ - recursive view definitions
+ - the Tcl language binding now includes a command-object API
+ - better error checking to avoid disk full errors from being missed
+ - documentation and current status
+
+Most of these changes are intended to make Metakit more scalable and to
+improve performance in various ways.  This process is not complete, as
+several new bottlenecks have been intoduced in the new code.  The main
+goal of the 2.3 release is to make sure the file format is correct and
+functioning properly.  The next minor releases will then address various
+bottlenecks to take maximum advantage of the new file format.
+
+See the last section for notes about the status and stability of MK.
+
+
+NEW VERSION NUMBERING SCHEME
+
+I am adopting a more rigid 3-level numbering scheme, as follows:
+
+ - stable release are X.0, X.2, X.4, i.e. even-numbered
+ - development releases are X.1, X.3, X.5, i.e. odd-numbered
+ - alpha releases are all called X.Y.1, they are distinguished only by
+   the date embedded in the snapshot tarball, e.g "mk2-20000629.tar.gz"
+ - beta releases are all called X.Y.2, again only dates in snapshots
+ - the "final release candidate" will be called X.Y.3, with one extra
+   chance to fix any remaining mistakes in a release called X.Y.4
+ - the first final release will be called X.Y.5, with every new update
+   and fix incrementing that third digit
+
+To avoid confusion between 2.01 and a version number of 2.1, this new
+release has been dubbed 2.3 - since it is still development version.
+
+
+NEW FILE FORMAT
+
+This release has major changes in the way data is stored on file, or to
+be more accurate: the data itself is hardly different, but administration
+of the data is now radically different (it used to be a tree-walk on each
+open and commit, the new format reads/commits far more lazily).
+
+The most immediate effect is that file opens are now O(1), and no longer
+take time proprotional to the number of subviews and columns.  There has
+been some "cutting corners" in this release, but the file format is now
+able to support several degrees of laziness, which will gradually be
+implemented to make opens instant, and frequent commits cheap.
+
+The biggest drawback of this change, is that there are now two different
+file formats.  The new 2.3 release will convert old formats on-the-fly
+during open, and will save the new format on commit.  This means that
+moving to the new release is relatively painless, but once changes are
+committed with 2.3, you can not go back to 2.01 or earlier.
+
+The "random" versus "serial" file format differences of pre-2.3 Metakit is
+now gone.  When serializing data out with "SaveTo", MK will now figure out
+how to save the file in an optimally compact form, suitable for loading on
+demand.  That means that the best way to reorganize a MK datafile to get
+rid of internal free space, is now to serialize it out to file.  As extra
+benefit, a serialized file has an accurate file size in the header, so
+that the exact size is known up front when serializing back in.  This can
+be useful when data is streamed across a communications channel.  Finally,
+storage objects are now derived from views, and both can be initialized
+from an input file/stream.
+
+One special file format change affects the top level: MK datafiles are now
+conformant with *IFF file formats (i.e. 8-byte header with type and size).
+Serialized files, and files using the ordinary ("full") commits consist of
+exactly one section.  However, files using commit-extend (described below) 
+will contain multiple sections.
+
+The new file format now uses a tail marker.  Because of that, a datafile
+can be appended to another file.  MK will always start by looking for the
+tail marker to determine where the file starts (resorting to old-style
+search-from-start to deal with pre-2.3 files).  Another effect, is that
+any existing file can now be opened by MK.  If there is no valid MK data,
+new contents will be appended.  There is a new c4_Strategy::EndOfData
+member which returns -1 if the file contained to valid MK data.  One goal
+of all this logic, was to allow adding MK data at the end of executables.
+
+Several features have been prepared for in the new file format, including
+heterogenous views, clustering, compression, encryption - as well as the
+ability to store revisions.  None of this is anywhere near implementation,
+so please don't expect much in these areas for quite some time.  The main
+reason to mention this at all, is to indicate that the new file format has
+plenty of room for future expansion.
+
+
+NEW COMMIT MODES
+
+There are two new commit modes: "commit-aside" and "commit-extend", with
+very different characteristics.  They cannot yet be combined, but this is
+one of the goals, since that will support some interesting scenario's.
+
+Commit-aside stores all changes made to one datafile in another one.  The
+primary datafile is not altered, it may be opened read-only.  The changes
+are saved in a special format and managed completely by MK.  Opening the
+original file later will of course lead to the original pre-commit state.
+By attaching that other file (using c4_Storage::SetAside), the latest
+changes become visible again.  This logic can be stacked, though the API
+for all this is not very intuitive.  Commit-aside applies to every change
+made to the file, including structure changes.  The second data file is
+in effect a "difference file", it has no use without the original file.
+
+In commit-aside mode, the c4_View::Commit call takes an extra argument,
+specifying whether to do a "fast" or a "full" commit (fast is default).
+Fast means: save the changes in the aside file, full means: apply all
+changes to the primary datafile and clear the aside file contents.  The
+rollback also comes in two versions: fast rollback rolls back to the
+state before the last commit, while full rollback forgets about commit
+aside altogether and reverts to the original datafile (without deleting
+the aside file contents - it can be re-attached later).  Note that any
+changes made to the primary datafile will invalidate the aside file.
+
+The purpose of commit-aside is two-fold: to speed up commits, and as a
+way to save changes when a key database needs to remain unchanged (this
+is useful when distributing over CD-ROM, or to manage original releases,
+for example).  Commit aside is not yet optimally efficient, but it'll get
+better - the key issue is that the amount of data saved is proportional
+to the amount of change, and *not* to the size/number of views & columns,
+
+Commit-extend is somewhat different: it is a modified version of a normal
+commit, which saves all changes at the end of the datafile, in such a way
+that current readers are not affected.  Readers will not see any changes
+until they do a rollback (which is a misnomer in this context).  At that
+point, the reader will resynchronize to the latest *committed* changes.
+
+Commit-extend supports multiple readers and a single writer, and due to
+the way it is implemented it does so without any locking or contention.
+The trade-off is that datafiles will grow on each commit, and need to be
+cleaned up periodically to avoid filling the disk.  This can often be
+scheduled to some "idle" period, at which point a normal (exclusive)
+open and commit can be performed, possible followed by serialization to
+generate an optimally-packed datafile again.  Note that commit-extend is
+not much more efficient than a normal commit, it still writes out entire
+changed columns (there is a speedup because free-space is not reclaimed).
+
+In this release, commit-aside and commit-extend cannot be combined: this
+would greatly reduce the amount of data saved on commit, while supporting
+a form of high-performance concurrency.  This "hybrid commit" is planned
+for the final 2.3 release, as is a more sophisticated degree of delta-
+storage in commit-aside.
+
+
+NO MORE MEMOS TO WORRY ABOUT
+
+The memo ("M") datatype has always been a confusing addition to MK, since
+it complements the bytes ("B") datatype yet adds very little value.  It
+has always been difficult to decide between B and M in the design phase,
+and since there were no conversion tools - that choice has to be made up
+front.  This release does away with memos.  
+
+At least, that's how it looks on the outside.  On the inside, MK has now
+been extended to dynamically switch between column-wise (B) and item-wise
+(M) storage, depending on the amount of data and the size of the view.
+The result is likely to be better than either approach before, because
+the choise is based on actual dynamics, and on an item-by-item basis.
+The heuristics which determine how data is stored internally are still
+being tweaked.  But the good news is that binary data storage is now
+always specified in a uniform manner, i.e. through c4_BytesProp.  In a
+way, this is analogous to how MK has always offered "adaptive integers",
+i.e. the fully transparent switch between 1/2/4/8/16/32-bit integers.
+
+Another change is that strings are now internally based on the same more
+adaptive style, they now scale much better than before and also no longer
+suffer from a startup delay (caused by a pre-2.3 null-byte scan on open).
+
+
+MODIFIABLE CUSTOM VIEWERS
+
+Custom viewers were introduced in version 1.8 and have turned out to be
+extremely effective and flexible.  Almost all the relational operators of
+MK are implemented as classes derived from c4_CustomViewer.  As of this
+release, custom viewers now support the ability to handle modifications.
+
+Many of the existing viewers, such as join and intersection, are still
+read-only (and some changes could never be handled properly), but a few
+others were realtively easy to extend.  View operators such as Concat,
+RemapWith, Pair, now support modifications on the resulting view.  These
+modifications are passed back to the underlying views.
+
+There are several types of modifications: setting individual properties
+in individual rows, inserting/removing rows, and changing structure.
+Propagating individual property changes is usually easiest to implement.
+Inserting/deleting rows is far more complex, and not even semantically
+obvious in many cases (where do you insert row N, if the view is the
+result of concatenating an N-row view A and an M-row view B?).  For the
+moment, row insertions/deletions are only implemented in mapped views
+(see below).
+
+The last category of changes is the most complex of all, and has not
+been addressed in this release.  The best way to stay out of trouble is
+to only restructure views on open (i.e. at app initialization time),
+and to then only deal with inserting/modifying/deleting rows.  Subviews
+are no different, and can be modified in the same way as the main views.
+
+
+MAPPED VIEWS
+
+Modifiable custom viewers which support row insertion and deletion have
+been dubbed "mapped views", because they usually represent a mapping of
+some kind over one or more underlying views.  Changes are propagated to
+the underlying views in the way that is deemed most intuitive.
+
+The 2.3 release contains three new mapped view implementations: hash,
+blocked, and ordered.
+
+The hash view takes a main "data" view as input, plus a "map" view.  The
+map view must be defined with a fixed structure ("_H:I,_R:I"), and is
+managed fully by the hash view.  The data view can be any structure, it
+is the collection of data on which hashing is to be applied.  When hash
+views are defined, they must be told how many of the first properties
+form a key (note that the key fields must always be first).  What the
+hash view does is create a new layer on top of the original data view,
+which intercepts all modification and find requests.  Modifications
+are applied to the data, but also cause the map view to be adjusted as
+needed.  Find requests which happen to specify a value for the key are
+singled out and cause a fast O(1) hash lookup to take place.
+
+There are several consequences of this approach: first of all, it is up
+to the application to set up a hash view after open (for now at least).
+Also, once you want hashing, you should *never* change the underlying
+data or map views - the only way to make sure they contain the proper
+info for hashing to work is to always change *through* the hash view.
+Note that the data view is the same as without hashing, all details
+needed for instant hash lookup are maintained in the separate map view.
+Unlike most conventional hash tables, insertion by position is still
+allowed, though insertion at the end is fastest (by far).  Also unlike
+most hash implementations, it is possible to change the key of a row,
+because MK will rehash whenever that happens.  Caveat: the details of
+changing key fields are not yet correct in this release.
+
+Find requests automatically detect hash views and optimize accordingly.
+The "python/find.py" script demonstrates find access optimizations.
+
+The blocked view is a view which stores its rows in "blocks", i.e. one
+extra level of subviews.  To make a view of the form "a:I,b:S,c:D"
+blocked, you have to define it as "_B[a:I,b:S,c:D]" instead, then call
+the Blocked member to produce the view you can work with.  The blocked
+view then takes over all insertions and deletions and rebalances both
+root and leaf blocks in such a way that none of the subviews ever
+contains either very few nor very many rows ("few" and "many" depend
+on the total number of rows, everything is adaptive).  Due to the extra
+level of indirection, blocked views are slightly slower, but the gain
+is that they can scale to an unlimited number of rows and still offer
+good performance (probably O(log N) instead of the usual O(N)).  These
+blocked views will behave like ordinary views in every respect, i.e.
+you can iterate and access rows by position, regardless of the blocking
+and occasional rebalancing that takes place underneath.
+
+The ordered view is a view which assumes the underlying view is sorted
+on its first N properties (N defaults to 1), and which maintains that
+order by ignoring isnert positions and supplying its own instead.  As
+with hash views, keys are unique.  Inserting a row which has the same
+key as another one will cause the other row to be replaced instead.
+
+Ordered views intercept changes, but also find requests.  If a find
+specifies a value for the key field(s), then binary search is used to
+find the rows far more quickly.
+
+All of the above views can be combined, e.g. by layering a hash view
+on top of a blocked data view, you get a persistent hash structure
+which scales up indefinitely, yet offers O(1) hash access performance.
+
+An ordered view on top a blocked view creates a blocked structure
+which keeps its rows sorted.  The current release will take advantage
+of binary search if possible - but real btree-like searches will be
+implemented before 2.3 final (this is far more efficient than "just"
+binary search, due to its much higher locality of reference).
+
+And finally, you can layer an ordered view on a hash view on one or
+two blocked views (for data and/or map).  This creates a structure
+which maintains sort order (and can be traversed in that order), yet
+with instant hash access on single key values.  The "tcl/mapped.tcl"
+script shows an example of various ways in which this can be done.
+
+
+RECURSIVE VIEW DEFINIONS
+
+You can now define views with recursive subviews.  The way this is
+done is to specify a subview of the form "subview[^]".  An example:
+       roots[name:S,children[^]]
+This define a "roots" view containing 0 or more rows.  Each has the
+form given above, which is also identical to:
+       name:S,children[name:S,children[^]]
+In other words, the "children" subview has the same format as its
+parent, and this continues to arbitrary depths.  The above example is
+in fact nothing but a definition of a tree containing named nodes.
+Restructuring works, it will recursively restructure the entire tree.
+
+
+COMMAND OBJECTS IN MK4TCL
+
+The Mk4tcl extension has undergone a massive face-lift.  The original
+API is still there, but there is now also an OO-style command interface
+(in the same way as Tk works).  This is based on work by Matt Newman.
+Because of this, a far more powerful binding to the MK C++ core is now
+available from Tcl (as it has been in Python for a while).  These new
+calls include relational operators, such as join, select, sort, etc.
+For now, this is "thinly" documented in the "tcl/mk4tcl.h" header.
+Another useful source to check, is the "tcl/test/mk5object.tcl" script.
+
+The Tequila server and the I/O handler package (iohan) have undergone
+some changes (extensions, really).
+
+
+BETTER ERROR CHECKING
+
+The write and commit logic have been improved to better detect whether
+anything went wrong during the commit, to prevent the final end marker
+from being updated.  This has the effect of ignoring all changes.  The
+most important change was to check and remember errors in fflush, and
+to make the c4_Stream::Write member return a success flag i.s.o. void.
+
+
+DOCUMENTATION
+
+Documentation.  Hm, what documentation?  I have converted the C++ docs
+to work with Doxygen, which extracts everything from comments in the
+source code.  The C++ documentation is available as a scripted document.
+To get it, you need to download the file:
+       http://www.equi4.com/previews/mk4api.bin
+and one of the following (sorry, only Linux and Windows for now):
+       http://www.equi4.com/previews/tclkit-linux.bin
+       http://www.equi4.com/previews/tclkit.exe
+Uncompress and make all files executable, then drop mk4api on tclkit,
+or whatever your explorer, navigator, finder, or shell wants you to do.
+If this is not workable, I will create a tarball of the html/gif files.
+
+For Python and Tcl, check the pages doc/python.html and doc/tcl.html
+in the source distribution (they are also part of the above "mk4api").
+There is a new examples/ directory with several Python and Tcl examples.
+
+The documentation is far from complete ("non-existent" or "wrong" are
+also applicable terms in some cases, I'm afraid).  I have started work
+on improving this.  Comments on what needs to be done first are most
+gratefully accepted - there is a huge amount of work left to do.
+
+
+CURRENT STATUS
+
+This 2.3.4 build passes all but one of the original regression tests
+(the one which does not pass is related to serialized data loading).
+
+There are several performance bottlenecks, despite the fact that the new
+format really should work better than the pre-2.3 file format.  For now,
+the first goal is to make sure that the file format is 100% frozen and
+useable as is - to avoid even more complex future conversion nightmares.
+I will start aiming for top speed *after* everything works properly.
+
+The commit logic can be slow for complex datasets, I am looking into it.
+
+There are some problems when changing keys in hash & ordered views, the
+best workaround is to not change key properties - delete and re-insert
+the row instead if you need this capability.
+
+This MK 2.3.4 final release candidate is very solid.  Recent versions
+of the beta preceding it have been in use in a wide range of active
+projects without substantial problems.  A byte-order conversion bug has
+recently been found and fixed, as well as double alignment on Solaris.
+
+At this point, I recommend using 2.3.4 as replacement for 2.01, except
+when tweaks for top performance have been done in 2.01 (2.3.4 is not yet
+as highly optimized, and has a slightly different performance behavior).
+
+
+-- Jean-Claude Wippler <jcw@equi4.com>
diff --git a/8.x/mk/README b/8.x/mk/README
new file mode 100755 (executable)
index 0000000..e638e74
--- /dev/null
@@ -0,0 +1,203 @@
+The Metakit Library 2.4.9.7                                           Jun 2007
+==============================================================================
+
+
+WHAT IT IS - Metakit is an embeddable database which runs on Unix, Windows,
+    Macintosh, and other platforms.  It lets you build applications which
+    store their data efficiently, in a portable way, and which will not need a
+    complex runtime installation.  In terms of the data model, Metakit takes
+    the middle ground between RDBMS, OODBMS, and flat-file databases - yet it
+    is quite different from each of them.
+
+TECHNOLOGY - Everything is stored variable-sized yet with efficient positional
+    row access.  Changing an existing datafile structure is as simple as re-
+    opening it with that new structure.  All changes are transacted, including
+    restructuring.  You can mix and match software written in C++, Python,
+    and Tcl.  Things can't get much more flexible...
+
+CORE - The Metakit core library is written in C++.  It has a code footprint of
+    just over 100 Kb on Windows.  It can be used as DLL, or linked statically.
+    Debug builds include extensive assertion checks to catch problems early.
+
+PYTHON - The binding for Python is called "Mk4py".  It uses SCXX by Gordon
+    McMillan as C++ glue interface.  The source is in directory "python/".
+
+TCL/TK - The MK extension for Tcl is called "Mk4tcl".  It is being used in a
+    number of commercial projects.  The source is in directory "tcl/".
+
+LICENSE AND SUPPORT - Metakit is distributed as open source software (see the
+    X/MIT-style license at the end of this document).  Commercial support is
+    available through an Enterprise License, see the URL mentioned below.
+
+DOCUMENTATION - All documentation uses HTML.  The main page is "Metakit.html",
+    which leads to the rest of the documentation in the "doc/" directory.
+    The C++ API Reference is extracted from the source code using Doxygen.
+
+WEBSITE URLS - The main pages on the world wide web, for news and downloads:
+    Homepage:       http://www.equi4.com/metakit.html
+    Python news:    http://www.equi4.com/metakit/python.html
+    Tcl/Tk news:    http://www.equi4.com/metakit/tcl.html
+    License info:   http://www.equi4.com/metakit/license.html
+    Contact info:   http://www.equi4.com/about/contact.html
+
+ACKNOWLEDGEMENTS - Thanks to everyone who has helped shape and extend Metakit,
+    including Kyrill Denisenko, Mark Roseman, Gordon McMillan, Matt Newman,
+    Christian Tismer, John Bushakra, Steve Landers, Jacob Levy, John Barnard,
+    Nicholas Riley, Brian Kelley, and many more people who have reported bugs
+    and helped fix them.  Last but not least, many thanks to all enterprise
+    license customers and all my clients for funding Metakit work.
+
+
+INSTALLATION
+============
+
+All platform builds and language bindings are designed to work from a single
+common "builds/" directory.  Where possible, that is - it turns out to be
+impossible to keep build side-effects limited to *just* this directory
+(CodeWarrior can't be told where to place its temp data, and Visual C++ still
+alters a few files next to the project ".dsw" file, to name two offenders).
+
+PYTHON - Nov 2006
+
+    There is a --with-python option in unix/configure, but it does not always
+    seem to work.  One problem is python version numbers being hard-wired into
+    the configure/make files (2.5 right now).  This worked for me on Mac OS X:
+        cd builds
+        ../unix/configure \
+          --with-python=/Library/Frameworks/Python.framework/Versions/2.5
+        ln -s Mk4py.dylib Mk4py.so
+    Note that the arg to --with-python is the path *upto* include/python2.5
+    
+    There is also a python/setup.py script which should simplify building for
+    Python.  Unfortunately, it does things in a somewhat tricky way in that
+    it uses MK's .o files from the builds/ directory.  This in turn means 
+    that on Mac OS X, you'll need to hack things a bit to make these .o's end
+    up as "fat" (ppc+i386) binaries since setup.py needs them that way.
+    
+    Here's how a non-macosx build should work:
+        cd builds
+        sh ../unix/configure
+        make test
+        cd ../python
+        python setup.py clean build
+    The result will be left in ../builds/lib.*/{Mk4py.so,metakit.py}
+    
+    For Mac OS X, you need to hack ../builds/Makefile after running configure:
+        * change "CXXFLAGS = $(CXX_FLAGS)" to "CXXFLAGS = $(CXX_FLAGS) \
+            -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk"
+        * change "SHLIB_LD = g++" to "SHLIB_LD = g++ -dynamiclib \
+            -flat_namespace -undefined suppress -arch ppc -arch"
+    Then do the rest, using "make" i.s.o. "make test" because the changes to
+    the flags don't seem to create proper executables.  That's ok though, the
+    .o files are fat, which is all setup.py needs.
+
+TCL - Jun 2007
+
+    The Tcl build has been converted to use the TEA3-based configure script
+    in the tcl/ directory.  The way to build Mk4tcl is now as follows:
+
+        mkdir tbuild      # can be anywhere, really...
+        cd tbuild
+        CC=g++ sh ../tcl/configure
+        make
+        make test
+        make install
+
+    This build configuration has not yet been tested with non-gcc compilers.
+    There are no dependencies on the C++ build process, nor the builds/ dir.
+    
+    Note: for Windows CE, an older version of the tcl.configure script was
+    successfully used with MS EVC3.  One trick is that in tcl/configure.in,
+    "TEA_ADD_CFLAGS([])" has to be changed to "TEA_ADD_CFLAGS([-Dq4_WINCE])".
+    
+UNIX (ALSO MAC OS X)
+
+    It is no longer advised to build the Unix code in the "unix/" directory.
+    Instead, you should perform the following steps:
+        cd builds
+        sh ../unix/configure
+        make
+        make test
+    And optionally (this only installs the core lib, not script extensions):
+        make install
+
+    By switching to the "builds/" directory, you will keep the distribution
+    directory tree 100% unaltered.  All changes are made in this subdir, and
+    all final build results are left behind in this same subdir.
+
+    To build with STL containers and strings, you can do the following:
+        make CXXFLAGS='-Dq4_STD' test   # add -O3 etc, as needed
+
+    OLD: to build the Mk4tcl extension on Unix, change the configure to:
+        ../unix/configure --with-tcl=<dir-where-tcl.h-is>
+    OLD: to build the Mk4py extension on Unix, change the configure to:
+        ../unix/configure --with-python=<dir-where-include/-is>
+    E.g.
+        ../unix/configure --with-tcl=/usr/include --with-python=/usr
+
+    Use "../unix/configure --help" to find out about other variants, when the
+    include & lib dirs are completely different, and for other build options.
+
+WINDOWS
+
+    There is a "win/" directory which contains subdirectories for a number of
+    compiler systems.  Metakit has been built with many different compilers
+    in the past (Microsoft, Borland, Watcom, Symantec, Metrowerks, Optima),
+    only a few are maintained (there are 12 configurations for MSVC6 alone!).
+
+    The MS Visual C++ 6.0 project is "win/msvc60/mksrc.dsw", with subprojects
+    for the C++ demo (mkdemo), building dll's (mkdll), static libs (mklib),
+    regression tests (mktest), as well as Tcl (mktcl) and Python (mkpython).
+    It has been set up to place all intermediate files and final results in
+    the "builds/" subdirectory, even though you'll launch it from "win/".
+
+    An MSVC 7.0 project by David Van Maren is in win/msvc70/mksrc.sln.
+
+    To build with STL containers and strings under MSVC, define "q4_STD".
+    To build with MFC containers and strings under MSVC, define "q4_MFC".
+
+    The Metrowerks Codewarrior project is in the "mac/" directory, and can be
+    used to build both Mac and Windows versions (on either Mac *or* Windows).
+    The core libraries are built with "mac/cw5.mcp", demos / tests are built
+    with "cw5apps.mcp", Tcl is "cw5tcl.mcp", and Python is "cw5python.mcp".
+
+    The Borland C++ Builder projects have not yet been incorporated in this
+    release, but the "KitViewer" application is an example of how to use BCB.
+
+    The Cygwin build (B20.1 / gcc 2.95.2) is different, because it uses the
+    unix autoconf system, and must be launched as described above for UNIX.
+    I have upgraded to the latest development of libtool to be able to build
+    DLL's with Cygwin.  You can build the "-mno-cygwin" version by editing
+    the Makefile by hand and adding that option to CXXFLAGS.
+
+    Rob Bloodgood adds that the following GCC options are for maximum code
+    efficiency on x86 hardware: "-O2 -m486 -malign-loops=2 -malign-jumps=2".
+    I have not yet tried this myself, but am passing on the tip.
+
+
+LICENSE AND COPYRIGHT STATEMENT
+===============================
+
+Copyright (c) 1996-2007 Jean-Claude Wippler
+
+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.
+
+
+==============================================================================
+-- Jean-Claude Wippler <jcw@equi4.com>
diff --git a/8.x/mk/builds/!keepme.txt b/8.x/mk/builds/!keepme.txt
new file mode 100644 (file)
index 0000000..48cdce8
--- /dev/null
@@ -0,0 +1 @@
+placeholder
diff --git a/8.x/mk/demos/demo.cpp b/8.x/mk/demos/demo.cpp
new file mode 100755 (executable)
index 0000000..a32a9f0
--- /dev/null
@@ -0,0 +1,114 @@
+//  An example using the Metakit C++ persistence library
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//  This code demonstrates:
+//
+//    - Creating a persistent view and adding two data rows to it.
+//    - Adding a third data row using Metakit's operator shorthands.
+//    - Adding an additional property without losing the existing data.
+//    - Storing an additional view in the data file later on.
+//    - Inserting a new record into one of the views in the datafile.
+//    - Real persistence, the data file will grow each time this is run.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include "mk4.h"
+#include "mk4str.h"
+
+#include <stdio.h>
+
+int
+#if _WIN32_WCE
+_cdecl
+#endif
+main()
+{
+    // These properties could just as well have been declared globally.
+  c4_StringProp pName ("name");
+  c4_StringProp pCountry ("country");
+
+    // Note: be careful with the lifetime of views vs. storage objects.
+    // When a storage object goes away, all associated views are cleared.
+  c4_Storage storage ("myfile.dat", true);
+
+// There are two ways to make views persistent, but the c4_View::Store call
+// call used in previous demos will be dropped, use "c4_View::GetAs" instead.
+  
+    // Start with an empty view of the proper structure.
+  c4_View vAddress = storage.GetAs("address[name:S,country:S]");
+
+    // Let's add two rows of data to the view.
+  c4_Row row;
+
+  pName (row) = "John Williams";
+  pCountry (row) = "UK";
+  vAddress.Add(row);
+
+  pName (row) = "Paco Pena";
+  pCountry (row) = "Spain";
+  vAddress.Add(row);
+
+    // A simple check to prove that the data is in the view.
+  c4_String s1 (pName (vAddress[1]));
+  c4_String s2 (pCountry (vAddress[1]));
+  printf("The country of %s is: %s\n", (const char*) s1, (const char*) s2);
+
+    // This saves the data to file.
+  storage.Commit(); // Data file now contains 2 addresses.
+
+    // A very compact notation to create and add a third row.
+  vAddress.Add(pName ["Julien Coco"] + pCountry ["Netherlands"]);
+
+  storage.Commit(); // Data file now contains 3 addresses.
+
+    // Add a third property to the address view ("on-the-fly").
+  vAddress = storage.GetAs("address[name:S,country:S,age:I]");
+
+    // Set the new age property in one of the existing addresses.
+  c4_IntProp pAge ("age");
+  pAge (vAddress[1]) = 44;
+
+  storage.Commit(); // Data file now contains 3 addresses with age field.
+
+    // Add a second view to the data file, leaving the first view intact.
+  c4_View vInfo = storage.GetAs("info[version:I]");
+
+    // Add some data, a single integer in this case.
+  c4_IntProp pVersion ("version");
+  vInfo.Add(pVersion [100]);
+
+  storage.Commit(); // Data file now contains 3 addresses and 1 info rec.
+
+    // Insert a row into the address view.  Note that another (duplicate)
+    // property definition is used here - just to show it can be done.
+  c4_IntProp pYears ("age");  // On file this is still the "age" field.
+
+  vAddress.InsertAt(2, pName ["Julian Bream"] + pYears [50]);
+
+    // Preceding commits were only included for demonstration purposes.
+  storage.Commit(); // Datafile now contains 4 addresses and 1 info rec.
+
+    // To inspect the data file, use the dump utility: "DUMP MYFILE.DAT".
+    // It should generate the following output:
+    //
+    //    myfile.dat: 3 properties
+    //      address[name:S,country:S,age:I],info[version:I]
+    //
+    //     VIEW   1 rows = address:V info:V
+    //      0: subview 'address'
+    //       VIEW   4 rows = name:S country:S age:I
+    //        0: 'John Williams' 'UK' 0
+    //        1: 'Paco Pena' 'Spain' 44
+    //        2: 'Julian Bream' '' 50
+    //        3: 'Julien Coco' 'Netherlands' 0
+    //      0: subview 'info'
+    //       VIEW   1 rows = version:I
+    //        0: 100
+    //
+    // Note: results will differ if this program is run more than once.
+
+  return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/demos/dump.cpp b/8.x/mk/demos/dump.cpp
new file mode 100755 (executable)
index 0000000..971eae6
--- /dev/null
@@ -0,0 +1,150 @@
+//  Datafile dump utility sample code
+
+#include "mk4.h"
+#include "mk4str.h"
+
+#include <stdio.h>
+
+#if defined (unix)
+#define try
+#define catch(x)  if (0)
+#endif     
+
+#if defined (macintosh)
+#include /**/ <console.h>
+#define d4_InitMain(c,v)  c = ccommand(&v)
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Recursively display the entire view contents. The results shown do not
+// depend on file layout (free space, file positions, flat vs. on-demand).
+
+static void ViewDisplay(const c4_View& v_, int l_ =0)
+{
+  c4_String types;
+  bool hasData = false, hasSubs = false;
+
+    // display header info and collect all data types
+  printf("%*s VIEW %5d rows =", l_, "", v_.GetSize());
+  for (int n = 0; n < v_.NumProperties(); ++n)
+  {
+    c4_Property prop = v_.NthProperty(n);
+    char t = prop.Type();
+
+    printf(" %s:%c", (const char*) prop.Name(), t);
+    
+    types += t;
+  
+    if (t == 'V')
+      hasSubs = true;
+    else
+      hasData = true;
+  }
+  printf("\n");
+
+  for (int j = 0; j < v_.GetSize(); ++j)
+  {
+    if (hasData)  // data properties are all shown on the same line
+    {
+      printf("%*s %4d:", l_, "", j);
+      c4_RowRef r = v_[j];
+      c4_Bytes data;
+
+      for (int k = 0; k < types.GetLength(); ++k)
+      {
+        c4_Property p = v_.NthProperty(k);
+
+        switch (types[k])
+        {
+        case 'I':
+          printf(" %ld", (long) ((c4_IntProp&) p) (r));
+          break;
+
+#if !q4_TINY
+        case 'F':
+          printf(" %g", (double) ((c4_FloatProp&) p) (r));
+          break;
+
+        case 'D':
+          printf(" %.12g", (double) ((c4_DoubleProp&) p) (r));
+          break;
+#endif
+
+        case 'S':
+          printf(" '%s'", (const char*) ((c4_StringProp&) p) (r));
+          break;
+
+        case 'M': // backward compatibility
+        case 'B':
+          (p (r)).GetData(data);
+          printf(" (%db)", data.Size());
+          break;
+
+        default:
+          if (types[k] != 'V')
+            printf(" (%c?)", types[k]);
+        }
+      }
+
+      printf("\n");
+    }
+
+    if (hasSubs)  // subviews are then shown, each as a separate block
+    {
+      for (int k = 0; k < types.GetLength(); ++k)
+      {
+        if (types[k] == 'V')
+        {
+          c4_Property prop = v_.NthProperty(k);
+
+          printf("%*s %4d: subview '%s'\n", l_, "", j,
+              (const char*) prop.Name());
+
+          c4_ViewProp& vp = (c4_ViewProp&) prop;
+          
+          ViewDisplay(vp (v_[j]), l_ + 2);
+        }
+      }
+    }
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main(int argc, char** argv)
+{
+#ifdef d4_InitMain
+  d4_InitMain(argc, argv);
+#endif
+
+  const char* msg = 0;
+  
+  if (argc != 2)
+    fprintf(stderr, "Usage: DUMP file\n");
+  else
+    try
+    {
+      msg = "could not open data file";
+
+      c4_Storage store (argv[1], false);
+
+      msg = "file may be damaged";
+
+      printf("%s: %d properties\n  %s\n\n",
+                  argv[1], store.NumProperties(),
+                  (const char*) store.Description());
+      ViewDisplay(store);
+
+      msg = 0;
+    }
+    catch (...)
+    {
+    }
+  
+  if (msg)
+    fprintf(stderr, "Abnormal termination, %s\n", msg);
+
+  return msg ? 1 : 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/demos/myio.cpp b/8.x/mk/demos/myio.cpp
new file mode 100755 (executable)
index 0000000..9b22470
--- /dev/null
@@ -0,0 +1,137 @@
+//  This code demonstrates:
+//
+//  - A class derived from c4_Strategy to implement encrypted storage.
+//  - Disabling the Flush calls issued during Commit() for speed.
+//  - Using c4_Strategy objects as the basis of all file I/O in Metakit.
+
+#include "mk4.h"
+#include "mk4io.h"
+
+#include <string.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// This derived strategy encrypts its data on disk and omits flushes
+
+class CEncryptStrategy : public c4_FileStrategy
+{
+public:
+  CEncryptStrategy (const char* fileName_, bool rw_);
+  virtual ~CEncryptStrategy ();
+
+  // Reading and writing of course messes around with all the data
+  virtual int  DataRead(long, void*, int);
+  virtual void DataWrite(long, const void*, int);
+
+  // For this example, we also disable all explicit file flushes
+  virtual void DataCommit(long) { }
+
+  // Cannot use memory mapped file access when decoding on the fly
+  virtual void ResetFileMapping() { }
+  
+private:
+  // This example uses a trivial encoding, incorporating offsets.
+  static char Encode(long pos, char c_)
+    { return (char) (c_ ^ pos ^ 211); }
+  static char Decode(long pos, char c_)
+    { return (char) (c_ ^ pos ^ 211); }
+};
+
+CEncryptStrategy::CEncryptStrategy (const char* fileName_, bool rw_)
+{
+  c4_FileStrategy::DataOpen(fileName_, rw_);
+}
+
+CEncryptStrategy::~CEncryptStrategy ()
+{
+}
+
+int CEncryptStrategy::DataRead(long lOff, void* lpBuf, int nCount)
+{
+  int result = 0;
+
+  if (nCount > 0)
+  {
+    char* ptr = (char*) lpBuf;
+  
+    result = c4_FileStrategy::DataRead(lOff, ptr, nCount);
+  
+    for (int i = 0; i < result; ++i)
+      ptr[i] = Decode(lOff++, ptr[i]);
+  }
+
+  return result;
+}
+
+void CEncryptStrategy::DataWrite(long lOff, const void* lpBuf, int nCount)
+{
+  if (nCount > 0)
+  {
+    c4_Bytes buf;
+    char* ptr = (char*) buf.SetBuffer(nCount);
+  
+    memcpy(ptr, lpBuf, nCount);
+  
+    for (int i = 0; i < nCount; ++i)
+      ptr[i] = Encode(lOff++, ptr[i]);
+  
+    c4_FileStrategy::DataWrite(lOff - nCount, ptr, nCount);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main()
+{
+  // This property could just as well have been declared globally.
+  c4_StringProp pLine ("line");
+
+  {
+      // This is where the magic takes place.
+    CEncryptStrategy efile ("secret.dat", true);
+    
+    c4_Storage storage (efile);
+  
+    static const char* message[] = {
+      "This is a small message which will be encrypted on file.",
+      "As a result, none of the other Metakit utilities can read it.",
+      "Furthermore, a hex dump of this file will produce gibberish.",
+      "The encryption used here is ridiculously simple, however.",
+      "Beware of naive encryption schemes, cracking them is a sport.",
+      0
+    };
+  
+      // Store the text lines as separate entries in the view.
+    c4_View vText;
+  
+    for (const char** p = message; *p; ++p)
+      vText.Add(pLine [*p]);
+  
+      // changed 2000-03-15: Store is gone
+    //storage.Store("text", vText);
+    c4_View v2 = storage.GetAs("text[line:S]");
+    v2.InsertAt(0, vText);
+
+    storage.Commit();
+  }
+
+  // The end of the preceding block will flush out all data to file.
+  {
+      // Repeat the process when accessing the encrypted file again.
+    CEncryptStrategy efile ("secret.dat", false);
+  
+    c4_Storage storage (efile);
+    c4_View vText = storage.View("text");
+  
+    for (int i = 0; i < vText.GetSize(); ++i)
+    {
+      const char* s = pLine (vText[i]);
+      puts(s);
+    }
+  }
+
+  // At this point, an encrypted data file is left behind on the disk.
+
+  return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/demos/struct.cpp b/8.x/mk/demos/struct.cpp
new file mode 100755 (executable)
index 0000000..d46743e
--- /dev/null
@@ -0,0 +1,32 @@
+//  This command-line utility displays the data structure of a datafile
+//  created with the Metakit library as a one-line description.
+
+#include "mk4.h"
+
+#include <stdio.h>
+
+#if defined (macintosh)
+#include /**/ <console.h>
+#define d4_InitMain(c,v)  c = ccommand(&v)
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+  
+int main(int argc, char** argv)
+{
+#ifdef d4_InitMain
+  d4_InitMain(argc, argv);
+#endif
+
+  if (argc != 2)
+    fputs("Usage: STRUCT datafile", stderr);
+  else
+  {
+    c4_Storage store (argv[1], false);
+    puts(store.Description());
+  }
+    
+  return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/doc/api/c4_Bytes.html b/8.x/mk/doc/api/c4_Bytes.html
new file mode 100644 (file)
index 0000000..738294f
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Bytes</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Bytes_desc.html">
+       <frame name="k-info" src="c4_Bytes_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_BytesProp.html b/8.x/mk/doc/api/c4_BytesProp.html
new file mode 100644 (file)
index 0000000..4cdf660
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_BytesProp</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_BytesProp_desc.html">
+       <frame name="k-info" src="c4_BytesProp_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_BytesProp_desc.html b/8.x/mk/doc/api/c4_BytesProp_desc.html
new file mode 100644 (file)
index 0000000..d9d59f9
--- /dev/null
@@ -0,0 +1,144 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_BytesProp</b>
+ : public <A HREF="c4_Property.html" >c4_Property</A> <br><br>
+
+<dd><font face=Times size=3>
+Binary properties.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_BytesProp</b> (const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_BytesRef.html" >c4_BytesRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set a bytes property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get a bytes property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set a bytes property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one bytes object, shorthand for AsRow</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>AsRow</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one bytes object</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Property" href="c4_Property.html">c4_Property</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_BytesProp_info.html b/8.x/mk/doc/api/c4_BytesProp_info.html
new file mode 100644 (file)
index 0000000..993a4a7
--- /dev/null
@@ -0,0 +1,208 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_BytesProp</b> - Binary properties.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_BytesProp_AsRow_const__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>AsRow</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one bytes object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_BytesProp_Get_const__const"><dt>
+         <nobr>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A> 
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get a bytes property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_BytesProp_Set_constconst__const"><dt>
+         <nobr>
+         void 
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set a bytes property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_BytesProp_c4_BytesProp_const_"><dt>
+         <nobr>
+         
+         <b>c4_BytesProp</b> (const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_BytesProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_BytesRef.html" >c4_BytesRef</A> 
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set a bytes property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_BytesProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>operator[]</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one bytes object, shorthand for AsRow</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_CleanupInternalData___"><dt>
+         <nobr>
+         static void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::CleanupInternalData</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Call this to get rid of som eonternal datastructues (on exit)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_GetId___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::GetId</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          A property object in fact merely represents an entry in a globally
+ maintained symbol table. Each property is assigned a unique id,
+ which remains valid as long as some reference to that property
+ exists. In general, property id's remain unique as long as the
+ application runs. Do not store id's on file, since they are
+ not guaranteed to remain the same across program invocations.
+ All properties with the same name are given the same id.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Name___const"><dt>
+         <nobr>
+         const char* 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Name</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the name of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Refs_int__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Refs</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is part of the implementation and shouldn't normally be called.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Type___const"><dt>
+         <nobr>
+         char 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Type</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the type of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set this untyped property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_BytesProp</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_BytesRef.html b/8.x/mk/doc/api/c4_BytesRef.html
new file mode 100644 (file)
index 0000000..266ea52
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_BytesRef</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_BytesRef_desc.html">
+       <frame name="k-info" src="c4_BytesRef_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_BytesRef_desc.html b/8.x/mk/doc/api/c4_BytesRef_desc.html
new file mode 100644 (file)
index 0000000..a7e901e
--- /dev/null
@@ -0,0 +1,102 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_BytesRef</b>
+ : public <A HREF="c4_Reference.html" >c4_Reference</A> <br><br>
+
+<dd><font face=Times size=3>
+Used to get or set binary object values.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_BytesRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         operator 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Bytes</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get the value as binary object</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_BytesRef.html" >c4_BytesRef</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set the value to the specified binary object</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Reference" href="c4_Reference.html">c4_Reference</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_BytesRef_info.html b/8.x/mk/doc/api/c4_BytesRef_info.html
new file mode 100644 (file)
index 0000000..069ec27
--- /dev/null
@@ -0,0 +1,135 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_BytesRef</b> - Used to get or set binary object values.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_BytesRef_c4_Bytes___const"><dt>
+         <nobr>
+         operator 
+         <b>c4_Bytes</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get the value as binary object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_BytesRef_c4_BytesRef_const_"><dt>
+         <nobr>
+         
+         <b>c4_BytesRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_BytesRef_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_BytesRef.html" >c4_BytesRef</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set the value to the specified binary object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetData_c4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve the value of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_SetData_const__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a value into the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__property"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_property</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of one data item</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_BytesRef</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Bytes___NONAME.html b/8.x/mk/doc/api/c4_Bytes___NONAME.html
new file mode 100644 (file)
index 0000000..4ee0c6c
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Bytes::NONAME</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Bytes::NONAME_desc.html">
+       <frame name="k-info" src="c4_Bytes::NONAME_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_Bytes___NONAME_desc.html b/8.x/mk/doc/api/c4_Bytes___NONAME_desc.html
new file mode 100644 (file)
index 0000000..0373e19
--- /dev/null
@@ -0,0 +1,75 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Bytes::NONAME</b>
+<br><br>
+
+<dd><font face=Times size=3>
+
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         t4_byte* 
+    </td>
+       <td>
+         <nobr>
+         <b>_contents</b>;
+         
+         
+               
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         double 
+    </td>
+       <td>
+         <nobr>
+         <b>_aligner</b>;
+         
+         <a href="c4_Bytes::NONAME_info.html#c4_Bytes__NONAME__aligner" target="k-info">
+               </a>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Bytes___NONAME_info.html b/8.x/mk/doc/api/c4_Bytes___NONAME_info.html
new file mode 100644 (file)
index 0000000..a0dc005
--- /dev/null
@@ -0,0 +1,45 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_Bytes::NONAME</b> - 
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Bytes__NONAME__aligner"><dt>
+         <nobr>
+         double 
+         <b>_aligner</b>;
+         </nobr>
+       <dd>
+         
+          on a Sparc, the int below wasn't enough...
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes__NONAME__contents"><dt>
+         <nobr>
+         t4_byte* 
+         <b>_contents</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Bytes::NONAME</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Bytes_desc.html b/8.x/mk/doc/api/c4_Bytes_desc.html
new file mode 100644 (file)
index 0000000..d0083ca
--- /dev/null
@@ -0,0 +1,234 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Bytes</b>
+<br><br>
+
+<dd><font face=Times size=3>
+Generic data buffer, with optional automatic clean up.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Bytes</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct an empty binary object</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Bytes</b> (const void* buffer_, int length_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct an object with contents, no copy</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Bytes</b> (const void* buffer_, int length_, bool makeCopy_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct an object with contents, optionally as a copy</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Bytes</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; bytes_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Copy constructor </font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_Bytes</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Destructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; bytes_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Assignment, this may make a private copy of contents</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Swap</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; bytes_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Swap the contents and ownership of two byte objects</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>Size</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the number of bytes of its contents</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const t4_byte* 
+    </td>
+       <td>
+         <nobr>
+         <b>Contents</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a pointer to the contents</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         t4_byte* 
+    </td>
+       <td>
+         <nobr>
+         <b>SetBuffer</b> (int length_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Define contents as a freshly allocated buffer of given size</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         t4_byte* 
+    </td>
+       <td>
+         <nobr>
+         <b>SetBufferClear</b> (int length_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Allocate a buffer and fills its contents with zero bytes</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Friends</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator==</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; a_, const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; b_);
+         <font face=Helvetica size=-1><br>Return true if the contents of both objects are equal</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator!=</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; a_, const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; b_);
+         <font face=Helvetica size=-1><br>Return true if the contents of both objects are not equal</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Bytes_info.html b/8.x/mk/doc/api/c4_Bytes_info.html
new file mode 100644 (file)
index 0000000..d272275
--- /dev/null
@@ -0,0 +1,281 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+These objects are used to pass around untyped data without concern about
+clean-up.  They know whether the bytes need to be de-allocated when these
+objects go out of scope.  Small amounts of data are stored in the object.
+<P>
+
+Objects of this class are used a lot within Metakit to manipulate its own
+data items generically.  The <A HREF="c4_BytesProp.html" >c4_BytesProp</A> class allows storing binary
+data explicitly in a file.  If such data files must be portable, then the 
+application itself must define a generic format to deal with byte order.
+<P>
+
+How to store an object in binary form in a row (this is not portable):
+<P>
+
+
+<PRE>    struct MyStruct { ... };
+    MyStruct something;</PRE>
+<P>
+
+
+<PRE>    <A HREF="c4_BytesProp.html" >c4_BytesProp</A> pData ("Data");
+    <A HREF="c4_Row.html" >c4_Row</A> row;</PRE>
+<P>
+
+
+<PRE>    pData (row) = <A HREF="c4_Bytes.html" >c4_Bytes</A> (&amp;something, sizeof something);
+</PRE>
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Bytes_Contents___const"><dt>
+         <nobr>
+         const t4_byte* 
+         <b>Contents</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a pointer to the contents</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_NONAME"><dt>
+         <nobr>
+         union 
+         <b><A HREF='c4_Bytes___NONAME.html'>NONAME</A></b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_SetBuffer_int__"><dt>
+         <nobr>
+         t4_byte* 
+         <b>SetBuffer</b> (int length_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Define contents as a freshly allocated buffer of given size</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_SetBufferClear_int__"><dt>
+         <nobr>
+         t4_byte* 
+         <b>SetBufferClear</b> (int length_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Allocate a buffer and fills its contents with zero bytes</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_Size___const"><dt>
+         <nobr>
+         int 
+         <b>Size</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the number of bytes of its contents</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_Swap_c4_Bytes___"><dt>
+         <nobr>
+         void 
+         <b>Swap</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; bytes_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Swap the contents and ownership of two byte objects</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes__LoseCopy___"><dt>
+         <nobr>
+         void 
+         <b>_LoseCopy</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes__MakeCopy___"><dt>
+         <nobr>
+         void 
+         <b>_MakeCopy</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes__buffer__kMaxBuf_"><dt>
+         <nobr>
+         t4_byte 
+         <b>_buffer [kMaxBuf]</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes__copy"><dt>
+         <nobr>
+         bool 
+         <b>_copy</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes__size"><dt>
+         <nobr>
+         int 
+         <b>_size</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_c4_Bytes__"><dt>
+         <nobr>
+         
+         <b>c4_Bytes</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct an empty binary object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_c4_Bytes_const_"><dt>
+         <nobr>
+         
+         <b>c4_Bytes</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; bytes_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Copy constructor </font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_c4_Bytes_constint_"><dt>
+         <nobr>
+         
+         <b>c4_Bytes</b> (const void* buffer_, int length_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct an object with contents, no copy</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_c4_Bytes_constintbool_"><dt>
+         <nobr>
+         
+         <b>c4_Bytes</b> (const void* buffer_, int length_, bool makeCopy_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct an object with contents, optionally as a copy</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_enum_1"><dt>
+         <nobr>
+         
+         <b>enum</b> { kMaxBuf = 16 };
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; bytes_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment, this may make a private copy of contents</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Bytes__c4_Bytes__"><dt>
+         <nobr>
+         
+         <b>~c4_Bytes</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Destructor</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Bytes</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Cursor.html b/8.x/mk/doc/api/c4_Cursor.html
new file mode 100644 (file)
index 0000000..484cd0f
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Cursor</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Cursor_desc.html">
+       <frame name="k-info" src="c4_Cursor_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_Cursor_desc.html b/8.x/mk/doc/api/c4_Cursor_desc.html
new file mode 100644 (file)
index 0000000..e7b98e2
--- /dev/null
@@ -0,0 +1,454 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Cursor</b>
+<br><br>
+
+<dd><font face=Times size=3>
+An iterator for collections of rows (views).<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Cursor</b> (<A HREF="c4_Sequence.html" >c4_Sequence</A>&#38; implementation_, int index_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator* </b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Dereference this cursor to "almost" a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (int index_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       This is the same as *(cursor + offset)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator++</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Pre-increment the cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator++</b> (int);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Post-increment the cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator--</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Pre-decrement the cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator--</b> (int);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Post-decrement the cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator+=</b> (int offset_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Advance by a given offset</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator-=</b> (int offset_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Back up by a given offset</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator- </b> (int) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Subtract a specified offset</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>operator- </b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> cursor_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the distance between two cursors</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Friends</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator+ </b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> cursor_, int offset_);
+         <font face=Helvetica size=-1><br>Add specified offset</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator+ </b> (int offset_, <A HREF="c4_Cursor.html" >c4_Cursor</A> cursor_);
+         <font face=Helvetica size=-1><br>Add specified offset to cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator==</b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> a_, <A HREF="c4_Cursor.html" >c4_Cursor</A> b_);
+         <font face=Helvetica size=-1><br>Return true if both cursors are equal</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator!=</b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> a_, <A HREF="c4_Cursor.html" >c4_Cursor</A> b_);
+         <font face=Helvetica size=-1><br>Return true if both cursors are not equal</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator< </b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> a_, <A HREF="c4_Cursor.html" >c4_Cursor</A> b_);
+         <font face=Helvetica size=-1><br>True if first cursor is less than second cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator> </b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> a_, <A HREF="c4_Cursor.html" >c4_Cursor</A> b_);
+         <font face=Helvetica size=-1><br>True if first cursor is greater than second cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator<=</b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> a_, <A HREF="c4_Cursor.html" >c4_Cursor</A> b_);
+         <font face=Helvetica size=-1><br>True if first cursor is less or equal to second cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator>=</b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> a_, <A HREF="c4_Cursor.html" >c4_Cursor</A> b_);
+         <font face=Helvetica size=-1><br>True if first cursor is greater or equal to second cursor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator==</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; a_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; b_);
+         <font face=Helvetica size=-1><br>Return true if the contents of both rows are equal</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator!=</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; a_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; b_);
+         <font face=Helvetica size=-1><br>Return true if the contents of both rows are not equal</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator< </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; a_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; b_);
+         <font face=Helvetica size=-1><br>True if first row is less than second row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator> </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; a_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; b_);
+         <font face=Helvetica size=-1><br>True if first row is greater than second row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator<=</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; a_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; b_);
+         <font face=Helvetica size=-1><br>True if first row is less or equal to second row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator>=</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; a_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; b_);
+         <font face=Helvetica size=-1><br>True if first row is greater or equal to second row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_MemoRef</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Reference</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Row</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_RowRef</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_View</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Sequence</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_FilterSeq</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_SortSeq</b>;
+         
+       </td>
+       </tr>
+  
+  </table>
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Cursor_info.html b/8.x/mk/doc/api/c4_Cursor_info.html
new file mode 100644 (file)
index 0000000..6bf6fb8
--- /dev/null
@@ -0,0 +1,206 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+Cursor objects can be used to point to specific entries in a view.
+A cursor acts very much like a pointer to a row in a view, and is 
+returned when taking the address of a <A HREF="c4_RowRef.html" >c4_RowRef</A>.  Dereferencing
+a cursor leads to the original row reference again.  You can construct a
+cursor for a <A HREF="c4_Row.html" >c4_Row</A>, but since such rows are not part of a collection,
+incrementing or decrementing these cursors is meaningless (and wrong). 
+<P>
+
+The usual range of pointer operations can be applied to these objects:
+pre/post-increment and decrement, adding or subtracting integer offsets,
+as well as the full range of comparison operators.  If two cursors
+point to entries in the same view, their difference can be calculated.
+<P>
+
+As with regular pointers, care must be taken to avoid running off of
+either end of a view (the debug build includes assertions to check this).
+
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Cursor__index"><dt>
+         <nobr>
+         int 
+         <b>_index</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor__seq"><dt>
+         <nobr>
+         <A HREF="c4_Sequence.html" >c4_Sequence</A>* 
+         <b>_seq</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_c4_Cursor_c4_Sequence_int_"><dt>
+         <nobr>
+         
+         <b>c4_Cursor</b> (<A HREF="c4_Sequence.html" >c4_Sequence</A>&#38; implementation_, int index_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new cursor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator_____const"><dt>
+         <nobr>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+         <b>operator* </b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Dereference this cursor to "almost" a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator_____"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A>&#38; 
+         <b>operator++</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Pre-increment the cursor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator___int__"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b>operator++</b> (int);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Post-increment the cursor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator___int__"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A>&#38; 
+         <b>operator+=</b> (int offset_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Advance by a given offset</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator___c4_Cursor__const"><dt>
+         <nobr>
+         int 
+         <b>operator- </b> (<A HREF="c4_Cursor.html" >c4_Cursor</A> cursor_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the distance between two cursors</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator___int__const"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b>operator- </b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Subtract a specified offset</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator_____"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A>&#38; 
+         <b>operator--</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Pre-decrement the cursor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator___int__"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b>operator--</b> (int);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Post-decrement the cursor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator___int__"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A>&#38; 
+         <b>operator-=</b> (int offset_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Back up by a given offset</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Cursor_operator___int__const"><dt>
+         <nobr>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+         <b>operator[]</b> (int index_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>This is the same as *(cursor + offset)</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Cursor</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_CustomViewer.html b/8.x/mk/doc/api/c4_CustomViewer.html
new file mode 100644 (file)
index 0000000..2855dfc
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_CustomViewer</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_CustomViewer_desc.html">
+       <frame name="k-info" src="c4_CustomViewer_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_CustomViewer_desc.html b/8.x/mk/doc/api/c4_CustomViewer_desc.html
new file mode 100644 (file)
index 0000000..092e9c9
--- /dev/null
@@ -0,0 +1,125 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_CustomViewer</b>
+<br><br>
+
+<dd><font face=Times size=3>
+Abstract base class for definition of custom views.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual 
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_CustomViewer</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Destructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>GetTemplate</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the structure of this view (initialization, called once)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>GetSize</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the number of rows in this view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual bool 
+    </td>
+       <td>
+         <nobr>
+         <b>GetItem</b> (int row_, int col_, <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; buf_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Fetch one data item, return it as a generic data value</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Protected members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_CustomViewer</b> ();
+         <font face=Helvetica size=-1><br>Constructor, must be overriden in derived class</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_CustomViewer_info.html b/8.x/mk/doc/api/c4_CustomViewer_info.html
new file mode 100644 (file)
index 0000000..1b4c6dd
--- /dev/null
@@ -0,0 +1,101 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+A custom view is a view which can be accessed like any other view, using
+row and property operations, but which is fully managed by a customized
+"viewer" class.  The viewer will eventually handle all requests for the
+view, such as defining its structure and size, as well as providing the
+actual data values when requested.
+<P>
+
+Custom views are read-only in this version, and cannot propagate changes.
+<P>
+
+To implement a custom view, you must derive your viewer from this base
+class and define each of the virtual members.  Then create a new object
+of this type on the heap and pass it to the <A HREF="c4_View.html" >c4_View</A> constructor.  Your
+viewer will automatically be destroyed when the last reference to its
+view goes away.  See the DBF2MK sample code for an example of a viewer.
+
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_CustomViewer_GetItem_intintc4_Bytes___"><dt>
+         <nobr>
+         virtual bool 
+         <b>GetItem</b> (int row_, int col_, <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; buf_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Fetch one data item, return it as a generic data value</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_CustomViewer_GetSize___"><dt>
+         <nobr>
+         virtual int 
+         <b>GetSize</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the number of rows in this view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_CustomViewer_GetTemplate___"><dt>
+         <nobr>
+         virtual <A HREF="c4_View.html" >c4_View</A> 
+         <b>GetTemplate</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the structure of this view (initialization, called once)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_CustomViewer_c4_CustomViewer__"><dt>
+         <nobr>
+         
+         <b>c4_CustomViewer</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor, must be overriden in derived class</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_CustomViewer__c4_CustomViewer___"><dt>
+         <nobr>
+         virtual 
+         <b>~c4_CustomViewer</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Destructor</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_CustomViewer</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_DoubleProp.html b/8.x/mk/doc/api/c4_DoubleProp.html
new file mode 100644 (file)
index 0000000..3aed86a
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_DoubleProp</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_DoubleProp_desc.html">
+       <frame name="k-info" src="c4_DoubleProp_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_DoubleProp_desc.html b/8.x/mk/doc/api/c4_DoubleProp_desc.html
new file mode 100644 (file)
index 0000000..ac8e70d
--- /dev/null
@@ -0,0 +1,144 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_DoubleProp</b>
+ : public <A HREF="c4_Property.html" >c4_Property</A> <br><br>
+
+<dd><font face=Times size=3>
+Double precision properties.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_DoubleProp</b> (const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property.</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_DoubleRef.html" >c4_DoubleRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set a double precision property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         double 
+    </td>
+       <td>
+         <nobr>
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get a double precision property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, double value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set a double precision property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (double value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one double precision value, shorthand for AsRow</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>AsRow</b> (double value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one double precision value</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Property" href="c4_Property.html">c4_Property</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_DoubleProp_info.html b/8.x/mk/doc/api/c4_DoubleProp_info.html
new file mode 100644 (file)
index 0000000..15c8aec
--- /dev/null
@@ -0,0 +1,208 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_DoubleProp</b> - Double precision properties.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_DoubleProp_AsRow_double__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>AsRow</b> (double value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one double precision value</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_DoubleProp_Get_const__const"><dt>
+         <nobr>
+         double 
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get a double precision property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_DoubleProp_Set_constdouble__const"><dt>
+         <nobr>
+         void 
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, double value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set a double precision property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_DoubleProp_c4_DoubleProp_const_"><dt>
+         <nobr>
+         
+         <b>c4_DoubleProp</b> (const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property.</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_DoubleProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_DoubleRef.html" >c4_DoubleRef</A> 
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set a double precision property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_DoubleProp_operator___double__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>operator[]</b> (double value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one double precision value, shorthand for AsRow</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_CleanupInternalData___"><dt>
+         <nobr>
+         static void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::CleanupInternalData</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Call this to get rid of som eonternal datastructues (on exit)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_GetId___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::GetId</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          A property object in fact merely represents an entry in a globally
+ maintained symbol table. Each property is assigned a unique id,
+ which remains valid as long as some reference to that property
+ exists. In general, property id's remain unique as long as the
+ application runs. Do not store id's on file, since they are
+ not guaranteed to remain the same across program invocations.
+ All properties with the same name are given the same id.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Name___const"><dt>
+         <nobr>
+         const char* 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Name</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the name of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Refs_int__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Refs</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is part of the implementation and shouldn't normally be called.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Type___const"><dt>
+         <nobr>
+         char 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Type</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the type of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set this untyped property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_DoubleProp</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_DoubleRef.html b/8.x/mk/doc/api/c4_DoubleRef.html
new file mode 100644 (file)
index 0000000..e14ef75
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_DoubleRef</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_DoubleRef_desc.html">
+       <frame name="k-info" src="c4_DoubleRef_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_DoubleRef_desc.html b/8.x/mk/doc/api/c4_DoubleRef_desc.html
new file mode 100644 (file)
index 0000000..6b02ded
--- /dev/null
@@ -0,0 +1,102 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_DoubleRef</b>
+ : public <A HREF="c4_Reference.html" >c4_Reference</A> <br><br>
+
+<dd><font face=Times size=3>
+Used to get or set double precision values.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_DoubleRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         operator 
+    </td>
+       <td>
+         <nobr>
+         <b>double</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get the value as floating point</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_DoubleRef.html" >c4_DoubleRef</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (double);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set the value to the specified floating point</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Reference" href="c4_Reference.html">c4_Reference</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_DoubleRef_info.html b/8.x/mk/doc/api/c4_DoubleRef_info.html
new file mode 100644 (file)
index 0000000..a093caf
--- /dev/null
@@ -0,0 +1,135 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_DoubleRef</b> - Used to get or set double precision values.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_DoubleRef_c4_DoubleRef_const_"><dt>
+         <nobr>
+         
+         <b>c4_DoubleRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_DoubleRef_double___const"><dt>
+         <nobr>
+         operator 
+         <b>double</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get the value as floating point</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_DoubleRef_operator___double__"><dt>
+         <nobr>
+         <A HREF="c4_DoubleRef.html" >c4_DoubleRef</A>&#38; 
+         <b>operator= </b> (double);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set the value to the specified floating point</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetData_c4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve the value of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_SetData_const__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a value into the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__property"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_property</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of one data item</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_DoubleRef</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_FloatProp.html b/8.x/mk/doc/api/c4_FloatProp.html
new file mode 100644 (file)
index 0000000..7a191d9
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_FloatProp</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_FloatProp_desc.html">
+       <frame name="k-info" src="c4_FloatProp_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_FloatProp_desc.html b/8.x/mk/doc/api/c4_FloatProp_desc.html
new file mode 100644 (file)
index 0000000..3a5c824
--- /dev/null
@@ -0,0 +1,144 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_FloatProp</b>
+ : public <A HREF="c4_Property.html" >c4_Property</A> <br><br>
+
+<dd><font face=Times size=3>
+Floating point properties.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_FloatProp</b> (const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_FloatRef.html" >c4_FloatRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set a floating point property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         double 
+    </td>
+       <td>
+         <nobr>
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get a floating point property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, double value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set a floating point property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (double value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one floating point value, shorthand for AsRow</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>AsRow</b> (double value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one floating point value</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Property" href="c4_Property.html">c4_Property</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_FloatProp_info.html b/8.x/mk/doc/api/c4_FloatProp_info.html
new file mode 100644 (file)
index 0000000..b7292d5
--- /dev/null
@@ -0,0 +1,208 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_FloatProp</b> - Floating point properties.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_FloatProp_AsRow_double__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>AsRow</b> (double value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one floating point value</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_FloatProp_Get_const__const"><dt>
+         <nobr>
+         double 
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get a floating point property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_FloatProp_Set_constdouble__const"><dt>
+         <nobr>
+         void 
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, double value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set a floating point property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_FloatProp_c4_FloatProp_const_"><dt>
+         <nobr>
+         
+         <b>c4_FloatProp</b> (const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_FloatProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_FloatRef.html" >c4_FloatRef</A> 
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set a floating point property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_FloatProp_operator___double__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>operator[]</b> (double value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one floating point value, shorthand for AsRow</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_CleanupInternalData___"><dt>
+         <nobr>
+         static void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::CleanupInternalData</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Call this to get rid of som eonternal datastructues (on exit)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_GetId___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::GetId</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          A property object in fact merely represents an entry in a globally
+ maintained symbol table. Each property is assigned a unique id,
+ which remains valid as long as some reference to that property
+ exists. In general, property id's remain unique as long as the
+ application runs. Do not store id's on file, since they are
+ not guaranteed to remain the same across program invocations.
+ All properties with the same name are given the same id.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Name___const"><dt>
+         <nobr>
+         const char* 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Name</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the name of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Refs_int__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Refs</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is part of the implementation and shouldn't normally be called.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Type___const"><dt>
+         <nobr>
+         char 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Type</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the type of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set this untyped property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_FloatProp</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_FloatRef.html b/8.x/mk/doc/api/c4_FloatRef.html
new file mode 100644 (file)
index 0000000..53a6e96
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_FloatRef</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_FloatRef_desc.html">
+       <frame name="k-info" src="c4_FloatRef_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_FloatRef_desc.html b/8.x/mk/doc/api/c4_FloatRef_desc.html
new file mode 100644 (file)
index 0000000..e401c17
--- /dev/null
@@ -0,0 +1,102 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_FloatRef</b>
+ : public <A HREF="c4_Reference.html" >c4_Reference</A> <br><br>
+
+<dd><font face=Times size=3>
+Used to get or set floating point values.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_FloatRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         operator 
+    </td>
+       <td>
+         <nobr>
+         <b>double</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get the value as floating point</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_FloatRef.html" >c4_FloatRef</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (double);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set the value to the specified floating point</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Reference" href="c4_Reference.html">c4_Reference</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_FloatRef_info.html b/8.x/mk/doc/api/c4_FloatRef_info.html
new file mode 100644 (file)
index 0000000..35f38f9
--- /dev/null
@@ -0,0 +1,135 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_FloatRef</b> - Used to get or set floating point values.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_FloatRef_c4_FloatRef_const_"><dt>
+         <nobr>
+         
+         <b>c4_FloatRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_FloatRef_double___const"><dt>
+         <nobr>
+         operator 
+         <b>double</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get the value as floating point</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_FloatRef_operator___double__"><dt>
+         <nobr>
+         <A HREF="c4_FloatRef.html" >c4_FloatRef</A>&#38; 
+         <b>operator= </b> (double);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set the value to the specified floating point</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetData_c4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve the value of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_SetData_const__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a value into the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__property"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_property</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of one data item</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_FloatRef</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_IntProp.html b/8.x/mk/doc/api/c4_IntProp.html
new file mode 100644 (file)
index 0000000..fe8b103
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_IntProp</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_IntProp_desc.html">
+       <frame name="k-info" src="c4_IntProp_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_IntProp_desc.html b/8.x/mk/doc/api/c4_IntProp_desc.html
new file mode 100644 (file)
index 0000000..be02b03
--- /dev/null
@@ -0,0 +1,144 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_IntProp</b>
+ : public <A HREF="c4_Property.html" >c4_Property</A> <br><br>
+
+<dd><font face=Times size=3>
+Integer properties.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_IntProp</b> (const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_IntRef.html" >c4_IntRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set an integer property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         t4_i32 
+    </td>
+       <td>
+         <nobr>
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get an integer property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, t4_i32 value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set an integer property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (t4_i32 value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Creates a row with one integer, shorthand for AsRow.</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>AsRow</b> (t4_i32 value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Creates a row with one integer.</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Property" href="c4_Property.html">c4_Property</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_IntProp_info.html b/8.x/mk/doc/api/c4_IntProp_info.html
new file mode 100644 (file)
index 0000000..fa7ee83
--- /dev/null
@@ -0,0 +1,208 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_IntProp</b> - Integer properties.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_IntProp_AsRow_t4_i32__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>AsRow</b> (t4_i32 value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Creates a row with one integer.</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_IntProp_Get_const__const"><dt>
+         <nobr>
+         t4_i32 
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get an integer property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_IntProp_Set_constt4_i32__const"><dt>
+         <nobr>
+         void 
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, t4_i32 value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set an integer property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_IntProp_c4_IntProp_const_"><dt>
+         <nobr>
+         
+         <b>c4_IntProp</b> (const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_IntProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_IntRef.html" >c4_IntRef</A> 
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set an integer property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_IntProp_operator___t4_i32__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>operator[]</b> (t4_i32 value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Creates a row with one integer, shorthand for AsRow.</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_CleanupInternalData___"><dt>
+         <nobr>
+         static void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::CleanupInternalData</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Call this to get rid of som eonternal datastructues (on exit)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_GetId___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::GetId</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          A property object in fact merely represents an entry in a globally
+ maintained symbol table. Each property is assigned a unique id,
+ which remains valid as long as some reference to that property
+ exists. In general, property id's remain unique as long as the
+ application runs. Do not store id's on file, since they are
+ not guaranteed to remain the same across program invocations.
+ All properties with the same name are given the same id.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Name___const"><dt>
+         <nobr>
+         const char* 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Name</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the name of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Refs_int__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Refs</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is part of the implementation and shouldn't normally be called.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Type___const"><dt>
+         <nobr>
+         char 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Type</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the type of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set this untyped property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_IntProp</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_IntRef.html b/8.x/mk/doc/api/c4_IntRef.html
new file mode 100644 (file)
index 0000000..dc43952
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_IntRef</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_IntRef_desc.html">
+       <frame name="k-info" src="c4_IntRef_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_IntRef_desc.html b/8.x/mk/doc/api/c4_IntRef_desc.html
new file mode 100644 (file)
index 0000000..92f9540
--- /dev/null
@@ -0,0 +1,102 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_IntRef</b>
+ : public <A HREF="c4_Reference.html" >c4_Reference</A> <br><br>
+
+<dd><font face=Times size=3>
+Used to get or set integer values.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_IntRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         operator 
+    </td>
+       <td>
+         <nobr>
+         <b>t4_i32</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get the value as long integer</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_IntRef.html" >c4_IntRef</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (t4_i32);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set the value to the specified long integer</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Reference" href="c4_Reference.html">c4_Reference</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_IntRef_info.html b/8.x/mk/doc/api/c4_IntRef_info.html
new file mode 100644 (file)
index 0000000..17adca3
--- /dev/null
@@ -0,0 +1,135 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_IntRef_c4_IntRef_const_"><dt>
+         <nobr>
+         
+         <b>c4_IntRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_IntRef_operator___t4_i32__"><dt>
+         <nobr>
+         <A HREF="c4_IntRef.html" >c4_IntRef</A>&#38; 
+         <b>operator= </b> (t4_i32);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set the value to the specified long integer</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_IntRef_t4_i32___const"><dt>
+         <nobr>
+         operator 
+         <b>t4_i32</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get the value as long integer</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetData_c4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve the value of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_SetData_const__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a value into the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__property"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_property</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of one data item</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_IntRef</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_MemoProp.html b/8.x/mk/doc/api/c4_MemoProp.html
new file mode 100644 (file)
index 0000000..44d77ad
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_MemoProp</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_MemoProp_desc.html">
+       <frame name="k-info" src="c4_MemoProp_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_MemoProp_desc.html b/8.x/mk/doc/api/c4_MemoProp_desc.html
new file mode 100644 (file)
index 0000000..1b2c582
--- /dev/null
@@ -0,0 +1,144 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_MemoProp</b>
+ : public <A HREF="c4_Property.html" >c4_Property</A> <br><br>
+
+<dd><font face=Times size=3>
+Memo properties.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_MemoProp</b> (const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_MemoRef.html" >c4_MemoRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set a memo property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get a memo property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set a memo property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one memo object, shorthand for AsRow</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>AsRow</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one memo object</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Property" href="c4_Property.html">c4_Property</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_MemoProp_info.html b/8.x/mk/doc/api/c4_MemoProp_info.html
new file mode 100644 (file)
index 0000000..fae5dbe
--- /dev/null
@@ -0,0 +1,208 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_MemoProp</b> - Memo properties.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_MemoProp_AsRow_const__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>AsRow</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one memo object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoProp_Get_const__const"><dt>
+         <nobr>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A> 
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get a memo property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoProp_Set_constconst__const"><dt>
+         <nobr>
+         void 
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set a memo property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoProp_c4_MemoProp_const_"><dt>
+         <nobr>
+         
+         <b>c4_MemoProp</b> (const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_MemoRef.html" >c4_MemoRef</A> 
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set a memo property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>operator[]</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one memo object, shorthand for AsRow</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_CleanupInternalData___"><dt>
+         <nobr>
+         static void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::CleanupInternalData</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Call this to get rid of som eonternal datastructues (on exit)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_GetId___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::GetId</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          A property object in fact merely represents an entry in a globally
+ maintained symbol table. Each property is assigned a unique id,
+ which remains valid as long as some reference to that property
+ exists. In general, property id's remain unique as long as the
+ application runs. Do not store id's on file, since they are
+ not guaranteed to remain the same across program invocations.
+ All properties with the same name are given the same id.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Name___const"><dt>
+         <nobr>
+         const char* 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Name</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the name of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Refs_int__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Refs</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is part of the implementation and shouldn't normally be called.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Type___const"><dt>
+         <nobr>
+         char 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Type</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the type of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set this untyped property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_MemoProp</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_MemoRef.html b/8.x/mk/doc/api/c4_MemoRef.html
new file mode 100644 (file)
index 0000000..3b61ea6
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_MemoRef</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_MemoRef_desc.html">
+       <frame name="k-info" src="c4_MemoRef_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_MemoRef_desc.html b/8.x/mk/doc/api/c4_MemoRef_desc.html
new file mode 100644 (file)
index 0000000..c4fc48b
--- /dev/null
@@ -0,0 +1,130 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_MemoRef</b>
+ : public <A HREF="c4_Reference.html" >c4_Reference</A> <br><br>
+
+<dd><font face=Times size=3>
+Used to get or set memo values (growable large binary objects).<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_MemoRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         operator 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Bytes</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get the value as binary object</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_MemoRef.html" >c4_MemoRef</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set the value to the specified binary object</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Access</b> (t4_u32 off_, int len_ =0) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Fetch data from the memo field, up to end if length is zero</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         bool 
+    </td>
+       <td>
+         <nobr>
+         <b>Modify</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; buf_, t4_u32 off_, int diff_ =0) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Store data, resize by diff_ bytes, return true if successful</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Reference" href="c4_Reference.html">c4_Reference</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_MemoRef_info.html b/8.x/mk/doc/api/c4_MemoRef_info.html
new file mode 100644 (file)
index 0000000..8984bb0
--- /dev/null
@@ -0,0 +1,161 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_MemoRef</b> - Used to get or set memo values (growable large binary objects).
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_MemoRef_Access_t4_u32int__const"><dt>
+         <nobr>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A> 
+         <b>Access</b> (t4_u32 off_, int len_ =0) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Fetch data from the memo field, up to end if length is zero</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoRef_Modify_constt4_u32int__const"><dt>
+         <nobr>
+         bool 
+         <b>Modify</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; buf_, t4_u32 off_, int diff_ =0) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store data, resize by diff_ bytes, return true if successful</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoRef_c4_Bytes___const"><dt>
+         <nobr>
+         operator 
+         <b>c4_Bytes</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get the value as binary object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoRef_c4_MemoRef_const_"><dt>
+         <nobr>
+         
+         <b>c4_MemoRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_MemoRef_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_MemoRef.html" >c4_MemoRef</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set the value to the specified binary object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetData_c4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve the value of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_SetData_const__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a value into the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__property"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_property</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of one data item</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_MemoRef</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Property.html b/8.x/mk/doc/api/c4_Property.html
new file mode 100644 (file)
index 0000000..3543bef
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Property</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Property_desc.html">
+       <frame name="k-info" src="c4_Property_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_Property_desc.html b/8.x/mk/doc/api/c4_Property_desc.html
new file mode 100644 (file)
index 0000000..30d44d6
--- /dev/null
@@ -0,0 +1,240 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Property</b>
+<br><br>
+
+<dd><font face=Times size=3>
+Base class for the basic data types.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Property</b> (char type_, int id_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property with the give type and id</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Property</b> (char type_, const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property with the give type and name</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_Property</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Destructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Property</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Copy constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Assignment</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const char* 
+    </td>
+       <td>
+         <nobr>
+         <b>Name</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the name of this property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         char 
+    </td>
+       <td>
+         <nobr>
+         <b>Type</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the type of this property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>GetId</b> () <i>const</i>;
+         
+         <a href="c4_Property_info.html#c4_Property_GetId___const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Return a unique id for this property</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set this untyped property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Refs</b> (int) <i>const</i>;
+         
+         <a href="c4_Property_info.html#c4_Property_Refs_int__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Adjust the reference count</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a view like the first, with a property appended to it</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         static void 
+    </td>
+       <td>
+         <nobr>
+         <b>CleanupInternalData</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Call this to get rid of som eonternal datastructues (on exit)</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+    <tr>
+    <td valign=top>
+         <font face=Helvetica size=-1><b>See also</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_BytesProp" href="c4_BytesProp.html">c4_BytesProp</a>,
+         
+               <a name="c4_DoubleProp" href="c4_DoubleProp.html">c4_DoubleProp</a>,
+         
+               <a name="c4_FloatProp" href="c4_FloatProp.html">c4_FloatProp</a>,
+         
+               <a name="c4_IntProp" href="c4_IntProp.html">c4_IntProp</a>,
+         
+               <a name="c4_MemoProp" href="c4_MemoProp.html">c4_MemoProp</a>,
+         
+               <a name="c4_StringProp" href="c4_StringProp.html">c4_StringProp</a>,
+         
+               <a name="c4_ViewProp" href="c4_ViewProp.html">c4_ViewProp</a>
+         
+    </td>
+       </tr>
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Property_info.html b/8.x/mk/doc/api/c4_Property_info.html
new file mode 100644 (file)
index 0000000..c5fe70e
--- /dev/null
@@ -0,0 +1,214 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+Property objects exist independently of view, row, and storage objects.
+They have a name and type, and can appear in any number of views.
+You will normally only use derived classes, to maintain strong typing.
+
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Property_CleanupInternalData___"><dt>
+         <nobr>
+         static void 
+         <b>CleanupInternalData</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Call this to get rid of som eonternal datastructues (on exit)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_GetId___const"><dt>
+         <nobr>
+         int 
+         <b>GetId</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          A property object in fact merely represents an entry in a globally
+ maintained symbol table. Each property is assigned a unique id,
+ which remains valid as long as some reference to that property
+ exists. In general, property id's remain unique as long as the
+ application runs. Do not store id's on file, since they are
+ not guaranteed to remain the same across program invocations.
+ All properties with the same name are given the same id.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Name___const"><dt>
+         <nobr>
+         const char* 
+         <b>Name</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the name of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Refs_int__const"><dt>
+         <nobr>
+         void 
+         <b>Refs</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is part of the implementation and shouldn't normally be called.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Type___const"><dt>
+         <nobr>
+         char 
+         <b>Type</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the type of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property__id"><dt>
+         <nobr>
+         short 
+         <b>_id</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property__type"><dt>
+         <nobr>
+         char 
+         <b>_type</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_c4_Property_charconst_"><dt>
+         <nobr>
+         
+         <b>c4_Property</b> (char type_, const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property with the give type and name</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_c4_Property_charint_"><dt>
+         <nobr>
+         
+         <b>c4_Property</b> (char type_, int id_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property with the give type and id</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_c4_Property_const_"><dt>
+         <nobr>
+         
+         <b>c4_Property</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Copy constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set this untyped property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__"><dt>
+         <nobr>
+         void 
+         <b>operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property__c4_Property__"><dt>
+         <nobr>
+         
+         <b>~c4_Property</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Destructor</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Property</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Reference.html b/8.x/mk/doc/api/c4_Reference.html
new file mode 100644 (file)
index 0000000..ad853bd
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Reference</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Reference_desc.html">
+       <frame name="k-info" src="c4_Reference_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_Reference_desc.html b/8.x/mk/doc/api/c4_Reference_desc.html
new file mode 100644 (file)
index 0000000..98daf2b
--- /dev/null
@@ -0,0 +1,204 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Reference</b>
+<br><br>
+
+<dd><font face=Times size=3>
+A reference is used to get or set typed data, using derived classes.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Reference</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38;, const <A HREF="c4_Property.html" >c4_Property</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Assignment of one data item</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>GetSize</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return width of the referenced data item</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         bool 
+    </td>
+       <td>
+         <nobr>
+         <b>GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Retrieve the value of the referenced data item</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Store a value into the referenced data item</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Protected members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>_cursor</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>_property</b>;
+         
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Friends</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator==</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;, const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         <font face=Helvetica size=-1><br>Return true if the contents of both references is equal</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator!=</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;, const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         <font face=Helvetica size=-1><br>Return true if the contents of both references is not equal</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+    <tr>
+    <td valign=top>
+         <font face=Helvetica size=-1><b>See also</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_BytesRef" href="c4_BytesRef.html">c4_BytesRef</a>,
+         
+               <a name="c4_DoubleRef" href="c4_DoubleRef.html">c4_DoubleRef</a>,
+         
+               <a name="c4_FloatRef" href="c4_FloatRef.html">c4_FloatRef</a>,
+         
+               <a name="c4_IntRef" href="c4_IntRef.html">c4_IntRef</a>,
+         
+               <a name="c4_MemoRef" href="c4_MemoRef.html">c4_MemoRef</a>,
+         
+               <a name="c4_StringRef" href="c4_StringRef.html">c4_StringRef</a>,
+         
+               <a name="c4_ViewRef" href="c4_ViewRef.html">c4_ViewRef</a>
+         
+    </td>
+       </tr>
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Reference_info.html b/8.x/mk/doc/api/c4_Reference_info.html
new file mode 100644 (file)
index 0000000..95c3479
--- /dev/null
@@ -0,0 +1,129 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+Objects of this class are only intended to be used as a temporary handle
+while getting and setting properties in a row.  They are normally only
+constructed as result of function overload operators: "property (row)".
+
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Reference_GetData_c4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b>GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve the value of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b>GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_SetData_const__const"><dt>
+         <nobr>
+         void 
+         <b>SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a value into the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b>_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__property"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b>_property</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_c4_Reference_constconst_"><dt>
+         <nobr>
+         
+         <b>c4_Reference</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38;, const <A HREF="c4_Property.html" >c4_Property</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator_____const"><dt>
+         <nobr>
+         void 
+         <b>operator& </b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          not implemented
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of one data item</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Reference</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Row.html b/8.x/mk/doc/api/c4_Row.html
new file mode 100644 (file)
index 0000000..594f51e
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Row</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Row_desc.html">
+       <frame name="k-info" src="c4_Row_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_RowRef.html b/8.x/mk/doc/api/c4_RowRef.html
new file mode 100644 (file)
index 0000000..18a8325
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_RowRef</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_RowRef_desc.html">
+       <frame name="k-info" src="c4_RowRef_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_RowRef_desc.html b/8.x/mk/doc/api/c4_RowRef_desc.html
new file mode 100644 (file)
index 0000000..24b8958
--- /dev/null
@@ -0,0 +1,153 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_RowRef</b>
+<br><br>
+
+<dd><font face=Times size=3>
+Reference to a data row, can be used on either side of an assignment.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Assign the value of another row to this one</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator& </b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the cursor associated to this row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Container</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the underlying container view</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Protected members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_RowRef</b> (<A HREF="c4_Cursor.html" >c4_Cursor</A>);
+         <font face=Helvetica size=-1><br>Constructor, not for general use</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Friends</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Cursor</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Row</b>;
+         
+       </td>
+       </tr>
+  
+  </table>
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+    <tr>
+    <td valign=top>
+         <font face=Helvetica size=-1><b>See also</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Row" href="c4_Row.html">c4_Row</a>
+         
+    </td>
+       </tr>
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_RowRef_info.html b/8.x/mk/doc/api/c4_RowRef_info.html
new file mode 100644 (file)
index 0000000..a81ccef
--- /dev/null
@@ -0,0 +1,97 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+Row references are created when dereferencing a <A HREF="c4_Cursor.html" >c4_Cursor</A> or when
+indexing an element of a <A HREF="c4_View.html" >c4_View</A>.  Assignment will change the
+corresponding item.  Rows (objects of type <A HREF="c4_Row.html" >c4_Row</A>) are a special
+case of row references, consisting of a view with exactly one item.
+<P>
+
+Internally, row references are very similar to cursors, in fact they are
+little more than a wrapper around them.  The essential difference is one
+of semantics: comparing row references compares contents, copying row
+references copies the contents, whereas cursor comparison and copying
+deals with the pointer to the row, not its contents.
+
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_RowRef_Container___const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Container</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the underlying container view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_RowRef__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b>_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_RowRef_c4_RowRef_c4_Cursor_"><dt>
+         <nobr>
+         
+         <b>c4_RowRef</b> (<A HREF="c4_Cursor.html" >c4_Cursor</A>);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor, not for general use</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_RowRef_operator_____const"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b>operator& </b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the cursor associated to this row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_RowRef_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+         <b>operator= </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assign the value of another row to this one</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_RowRef</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Row_desc.html b/8.x/mk/doc/api/c4_Row_desc.html
new file mode 100644 (file)
index 0000000..55e0261
--- /dev/null
@@ -0,0 +1,189 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Row</b>
+ : public <A HREF="c4_RowRef.html" >c4_RowRef</A> <br><br>
+
+<dd><font face=Times size=3>
+An entry in a collection with copy semantics.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Row</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a row with no properties</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Row</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a row from another oneConstruct a row copy from a row reference</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Row</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a row from another oneConstruct a row copy from a row reference</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_Row</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Destructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Assign a copy of another row to this oneCopy another row to this one</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Assign a copy of another row to this oneCopy another row to this one</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>ConcatRow</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Add all properties and values into this row</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Friends</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator+ </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; a_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; b_);
+         <font face=Helvetica size=-1><br>Return a new row which is the concatenation of two others</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+    <tr>
+    <td valign=top>
+         <font face=Helvetica size=-1><b>See also</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Row" href="c4_Row.html">c4_Row</a>
+         
+    </td>
+       </tr>
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_RowRef" href="c4_RowRef.html">c4_RowRef</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Row_info.html b/8.x/mk/doc/api/c4_Row_info.html
new file mode 100644 (file)
index 0000000..b5c2e92
--- /dev/null
@@ -0,0 +1,182 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+Rows can exist by themselves and as contents of views.  Row assignment
+implies that a copy of the contents of the originating row is made.
+<P>
+
+A row is implemented as an unattached view with exactly one element.
+
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Row_Allocate___"><dt>
+         <nobr>
+         static <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b>Allocate</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Row_ConcatRow_const__"><dt>
+         <nobr>
+         void 
+         <b>ConcatRow</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Add all properties and values into this row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Row_Release_c4_Cursor__"><dt>
+         <nobr>
+         static void 
+         <b>Release</b> (<A HREF="c4_Cursor.html" >c4_Cursor</A>);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Row_c4_Row__"><dt>
+         <nobr>
+         
+         <b>c4_Row</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a row with no properties</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Row_c4_Row_const_"><dt>
+         <nobr>
+         
+         <b>c4_Row</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a row from another oneConstruct a row copy from a row reference</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Row_c4_Row_const_"><dt>
+         <nobr>
+         
+         <b>c4_Row</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a row from another oneConstruct a row copy from a row reference</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Row_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assign a copy of another row to this oneCopy another row to this one</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Row_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assign a copy of another row to this oneCopy another row to this one</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Row__c4_Row__"><dt>
+         <nobr>
+         
+         <b>~c4_Row</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Destructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_RowRef_Container___const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b><A HREF='c4_RowRef.html'>c4_RowRef</A>::Container</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the underlying container view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_RowRef_operator_____const"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b><A HREF='c4_RowRef.html'>c4_RowRef</A>::operator& </b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the cursor associated to this row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_RowRef_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+         <b><A HREF='c4_RowRef.html'>c4_RowRef</A>::operator= </b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assign the value of another row to this one</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Row</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Sequence.html b/8.x/mk/doc/api/c4_Sequence.html
new file mode 100644 (file)
index 0000000..ac9945f
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Sequence</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Sequence_desc.html">
+       <frame name="k-info" src="c4_Sequence_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_Sequence_desc.html b/8.x/mk/doc/api/c4_Sequence_desc.html
new file mode 100644 (file)
index 0000000..f87e86a
--- /dev/null
@@ -0,0 +1,559 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Sequence</b>
+<br><br>
+
+<dd><font face=Times size=3>
+A sequence is an abstract base class for views on ranges of records.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Sequence</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Abstract constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>Compare</b> (int, <A HREF="c4_Cursor.html" >c4_Cursor</A>) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Compare the specified row with another one</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>SetAt</b> (int, <A HREF="c4_Cursor.html" >c4_Cursor</A>);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Replace the contents of a specified row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>RemapIndex</b> (int, const <A HREF="c4_Sequence.html" >c4_Sequence</A>*) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Remap the index to an underlying view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const char* 
+    </td>
+       <td>
+         <nobr>
+         <b>Describe</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a descriptions of the current data structure</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>IncRef</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Increment the reference count of this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>DecRef</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Decrement the reference count, delete objects when last</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>NumRefs</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the current number of references to this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>Size</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the current number of rows</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Resize</b> (int, int =-1);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Change number of rows, either by inserting or removing them</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>InsertAt</b> (int, <A HREF="c4_Cursor.html" >c4_Cursor</A>, int =1);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Insert one or more rows into this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>RemoveAt</b> (int, int =1);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Remove one or more rows from this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>Move</b> (int, int);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Move a row to another position</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>NthPropId</b> (int) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the id of the N-th property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>PropIndex</b> (int);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Find the index of a property by its id</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>PropIndex</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Find the index of a property, or create a new entry</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>NumHandlers</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the number of data handlers in this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual c4_Handler&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>NthHandler</b> (int) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a reference to the N-th handler in this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual const <A HREF="c4_Sequence.html" >c4_Sequence</A>* 
+    </td>
+       <td>
+         <nobr>
+         <b>HandlerContext</b> (int) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the context of the N-th handler in this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>AddHandler</b> (c4_Handler*);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Add the specified data handler to this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual c4_Handler* 
+    </td>
+       <td>
+         <nobr>
+         <b>CreateHandler</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a handler of the appropriate type</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>ItemSize</b> (int index_, int propId_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return width of specified data item</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual bool 
+    </td>
+       <td>
+         <nobr>
+         <b>Get</b> (int, int, <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Retrieve one data item from this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>Set</b> (int, const <A HREF="c4_Property.html" >c4_Property</A>&#38;, const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Store a data item into this sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Attach</b> (<A HREF="c4_Sequence.html" >c4_Sequence</A>* child_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Register a sequence to receive change notifications</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Detach</b> (<A HREF="c4_Sequence.html" >c4_Sequence</A>* child_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Unregister a sequence which received change notifications</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         c4_Dependencies* 
+    </td>
+       <td>
+         <nobr>
+         <b>GetDependencies</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a pointer to the dependencies, or null</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual c4_Notifier* 
+    </td>
+       <td>
+         <nobr>
+         <b>PreChange</b> (c4_Notifier&#38; nf_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Called just before a change is made to the sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>PostChange</b> (c4_Notifier&#38; nf_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Called after changes have been made to the sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const char* 
+    </td>
+       <td>
+         <nobr>
+         <b>UseTempBuffer</b> (const char*);
+         
+         
+               
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>SetSize</b> (int size_);
+         
+         
+               
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>Buffer</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Gives access to a general purpose temporary buffer</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Protected members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>_propertyLimit</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         short* 
+    </td>
+       <td>
+         <nobr>
+         <b>_propertyMap</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A>* 
+    </td>
+       <td>
+         <nobr>
+         <b>_tempBuf</b>;
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual 
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_Sequence</b> ();
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>ClearCache</b> ();
+         
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Sequence_info.html b/8.x/mk/doc/api/c4_Sequence_info.html
new file mode 100644 (file)
index 0000000..a26ca02
--- /dev/null
@@ -0,0 +1,561 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+Sequences represent arrays of rows (or indexed collections / tables).
+Insertion and removal of entries is allowed, but could take linear time.
+A reference count is maintained to decide when the object should go away.
+
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Sequence_AddHandler_c4_Handler___"><dt>
+         <nobr>
+         virtual int 
+         <b>AddHandler</b> (c4_Handler*);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Add the specified data handler to this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Attach_c4_Sequence___"><dt>
+         <nobr>
+         void 
+         <b>Attach</b> (<A HREF="c4_Sequence.html" >c4_Sequence</A>* child_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Register a sequence to receive change notifications</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Buffer___"><dt>
+         <nobr>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; 
+         <b>Buffer</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Gives access to a general purpose temporary buffer</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_ClearCache___"><dt>
+         <nobr>
+         void 
+         <b>ClearCache</b> ();
+         </nobr>
+       <dd>
+         
+         ! for c4_Table::Sequence setup
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Compare_intc4_Cursor__const"><dt>
+         <nobr>
+         virtual int 
+         <b>Compare</b> (int, <A HREF="c4_Cursor.html" >c4_Cursor</A>) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Compare the specified row with another one</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_CreateHandler_const__"><dt>
+         <nobr>
+         virtual c4_Handler* 
+         <b>CreateHandler</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a handler of the appropriate type</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_DecRef___"><dt>
+         <nobr>
+         void 
+         <b>DecRef</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Decrement the reference count, delete objects when last</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Describe___"><dt>
+         <nobr>
+         const char* 
+         <b>Describe</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a descriptions of the current data structure</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Detach_c4_Sequence___"><dt>
+         <nobr>
+         void 
+         <b>Detach</b> (<A HREF="c4_Sequence.html" >c4_Sequence</A>* child_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Unregister a sequence which received change notifications</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Get_intintc4_Bytes___"><dt>
+         <nobr>
+         virtual bool 
+         <b>Get</b> (int, int, <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve one data item from this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_GetDependencies___const"><dt>
+         <nobr>
+         c4_Dependencies* 
+         <b>GetDependencies</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a pointer to the dependencies, or null</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_HandlerContext_int__const"><dt>
+         <nobr>
+         virtual const <A HREF="c4_Sequence.html" >c4_Sequence</A>* 
+         <b>HandlerContext</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the context of the N-th handler in this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_IncRef___"><dt>
+         <nobr>
+         void 
+         <b>IncRef</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Increment the reference count of this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_InsertAt_intc4_Cursorint__"><dt>
+         <nobr>
+         virtual void 
+         <b>InsertAt</b> (int, <A HREF="c4_Cursor.html" >c4_Cursor</A>, int =1);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Insert one or more rows into this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_ItemSize_intint__"><dt>
+         <nobr>
+         virtual int 
+         <b>ItemSize</b> (int index_, int propId_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of specified data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Move_intint__"><dt>
+         <nobr>
+         virtual void 
+         <b>Move</b> (int, int);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Move a row to another position</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_NthHandler_int__const"><dt>
+         <nobr>
+         virtual c4_Handler&#38; 
+         <b>NthHandler</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a reference to the N-th handler in this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_NthPropId_int__const"><dt>
+         <nobr>
+         int 
+         <b>NthPropId</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the id of the N-th property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_NumHandlers___const"><dt>
+         <nobr>
+         virtual int 
+         <b>NumHandlers</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the number of data handlers in this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_NumRefs___const"><dt>
+         <nobr>
+         int 
+         <b>NumRefs</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the current number of references to this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_PostChange_c4_Notifier___"><dt>
+         <nobr>
+         virtual void 
+         <b>PostChange</b> (c4_Notifier&#38; nf_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Called after changes have been made to the sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_PreChange_c4_Notifier___"><dt>
+         <nobr>
+         virtual c4_Notifier* 
+         <b>PreChange</b> (c4_Notifier&#38; nf_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Called just before a change is made to the sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_PropIndex_const__"><dt>
+         <nobr>
+         int 
+         <b>PropIndex</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Find the index of a property, or create a new entry</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_PropIndex_int__"><dt>
+         <nobr>
+         int 
+         <b>PropIndex</b> (int);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Find the index of a property by its id</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_RemapIndex_intconst__const"><dt>
+         <nobr>
+         virtual int 
+         <b>RemapIndex</b> (int, const <A HREF="c4_Sequence.html" >c4_Sequence</A>*) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Remap the index to an underlying view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_RemoveAt_intint__"><dt>
+         <nobr>
+         virtual void 
+         <b>RemoveAt</b> (int, int =1);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Remove one or more rows from this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Resize_intint__"><dt>
+         <nobr>
+         void 
+         <b>Resize</b> (int, int =-1);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Change number of rows, either by inserting or removing them</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Set_intconstconst__"><dt>
+         <nobr>
+         virtual void 
+         <b>Set</b> (int, const <A HREF="c4_Property.html" >c4_Property</A>&#38;, const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a data item into this sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_SetAt_intc4_Cursor__"><dt>
+         <nobr>
+         void 
+         <b>SetAt</b> (int, <A HREF="c4_Cursor.html" >c4_Cursor</A>);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Replace the contents of a specified row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_SetSize_int__"><dt>
+         <nobr>
+         virtual void 
+         <b>SetSize</b> (int size_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_Size___const"><dt>
+         <nobr>
+         virtual int 
+         <b>Size</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the current number of rows</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_UseTempBuffer_const__"><dt>
+         <nobr>
+         const char* 
+         <b>UseTempBuffer</b> (const char*);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence__dependencies"><dt>
+         <nobr>
+         c4_Dependencies* 
+         <b>_dependencies</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence__propertyLimit"><dt>
+         <nobr>
+         int 
+         <b>_propertyLimit</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence__propertyMap"><dt>
+         <nobr>
+         short* 
+         <b>_propertyMap</b>;
+         </nobr>
+       <dd>
+         
+          see c4_HandlerSeq::Reset()
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence__refCount"><dt>
+         <nobr>
+         int 
+         <b>_refCount</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence__tempBuf"><dt>
+         <nobr>
+         <A HREF="c4_Bytes.html" >c4_Bytes</A>* 
+         <b>_tempBuf</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_c4_Sequence__"><dt>
+         <nobr>
+         
+         <b>c4_Sequence</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Abstract constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_c4_Sequence_const_"><dt>
+         <nobr>
+         
+         <b>c4_Sequence</b> (const <A HREF="c4_Sequence.html" >c4_Sequence</A>&#38;);
+         </nobr>
+       <dd>
+         
+          not implemented
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence_operator___const__"><dt>
+         <nobr>
+         void 
+         <b>operator= </b> (const <A HREF="c4_Sequence.html" >c4_Sequence</A>&#38;);
+         </nobr>
+       <dd>
+         
+          not implemented
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Sequence__c4_Sequence___"><dt>
+         <nobr>
+         virtual 
+         <b>~c4_Sequence</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Sequence</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Storage.html b/8.x/mk/doc/api/c4_Storage.html
new file mode 100644 (file)
index 0000000..b5d10b6
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Storage</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Storage_desc.html">
+       <frame name="k-info" src="c4_Storage_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_Storage_desc.html b/8.x/mk/doc/api/c4_Storage_desc.html
new file mode 100644 (file)
index 0000000..baf0b12
--- /dev/null
@@ -0,0 +1,315 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Storage</b>
+<br><br>
+
+<dd><font face=Times size=3>
+Manager for persistent storage of view structures.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Storage</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct streaming-only storage object</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Storage</b> (<A HREF="c4_Strategy.html" >c4_Strategy</A>&#38; strategy_, bool owned_ =false);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a storage using the specified strategy handler</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Storage</b> (const char* filename_, const char* description_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a storage object for given file and format</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Storage</b> (const char* filename_, bool canModify_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a storage object, keeping the current structure</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Storage</b> (const <A HREF="c4_Storage.html" >c4_Storage</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Copy constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_Storage</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Destructor, usually closes file, but does not commit by default</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Storage.html" >c4_Storage</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_Storage.html" >c4_Storage</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Assignment of storage implements reference semantics</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>AutoCommit</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set storage up to always call Commit in the destructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Contents</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Give access to the stored data as a single row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Strategy.html" >c4_Strategy</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>Strategy</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the strategy object associated with this storage</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         c4_HandlerSeq&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>RootTable</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the root table entry</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const char* 
+    </td>
+       <td>
+         <nobr>
+         <b>Description</b> (const char* name_ =0);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a description of the view structure (default is all)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         bool 
+    </td>
+       <td>
+         <nobr>
+         <b>Commit</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Flush pending changes to file right now</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         bool 
+    </td>
+       <td>
+         <nobr>
+         <b>Rollback</b> ();
+         
+         <a href="c4_Storage_info.html#c4_Storage_Rollback___" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       (Re)initialize for on-demand loading</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_ViewRef.html" >c4_ViewRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>View</b> (const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set a named view in this storage object</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>GetAs</b> (const char* description_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get a named view, redefining it to match the given structure</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Store</b> (const char* name_, const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Attach a view using specified name in this storage object</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>LoadFrom</b> (<A HREF="c4_Stream.html" >c4_Stream</A>&#38; stream_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Load contents from the specified input stream</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>SaveTo</b> (<A HREF="c4_Stream.html" >c4_Stream</A>&#38; stream_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Save contents to the specified output stream</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Storage_info.html b/8.x/mk/doc/api/c4_Storage_info.html
new file mode 100644 (file)
index 0000000..8810915
--- /dev/null
@@ -0,0 +1,353 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+The storage class uses a view, with additional functionality to be able 
+to store and reload the data it contains (including nested subviews).
+<P>
+
+By default, data is loaded on demand, i.e. whenever data which has
+not yet been referenced is used for the first time.  Loading is limited
+to the lifetime of this storage object, since the storage object carries
+the file descriptor with it that is needed to access the data file.
+<P>
+
+To save changes, call the Commit member.  This is the only time
+that data is written to file - when using a read-only file simply avoid
+calling Commit.
+<P>
+
+The LoadFromStream and SaveToStream members can be used to
+serialize the contents of this storage row using only sequential I/O
+(no seeking, only read or write calls).
+<P>
+
+The data storage mechanism implementation provides fail-safe operation:
+if anything prevents Commit from completing its task, the last
+succesfully committed version of the saved data will be recovered on
+the next open. This also includes changes made to the table structure. 
+<P>
+
+The following code creates a view with 1 row and stores it on file:
+<P>
+
+
+<PRE>    <A HREF="c4_StringProp.html" >c4_StringProp</A> pName ("Name");
+    <A HREF="c4_IntProp.html" >c4_IntProp</A> pAge ("Age");</PRE>
+<P>
+
+
+<PRE>    <A HREF="c4_Storage.html" >c4_Storage</A> storage ("myfile.dat", true);
+    <A HREF="c4_View.html" >c4_View</A> myView = storage.GetAs("Musicians[Name:S,Age:I]");</PRE>
+<P>
+
+
+<PRE>    myView.Add(pName ["John Williams"] + pAge [43]);</PRE>
+<P>
+
+
+<PRE>    storage.Commit();
+</PRE>
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Storage_AutoCommit___"><dt>
+         <nobr>
+         void 
+         <b>AutoCommit</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set storage up to always call Commit in the destructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_Commit___"><dt>
+         <nobr>
+         bool 
+         <b>Commit</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Flush pending changes to file right now</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_Contents___const"><dt>
+         <nobr>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+         <b>Contents</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Give access to the stored data as a single row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_Description_const__"><dt>
+         <nobr>
+         const char* 
+         <b>Description</b> (const char* name_ =0);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a description of the view structure (default is all)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_GetAs_const__"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>GetAs</b> (const char* description_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get a named view, redefining it to match the given structure</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_Initialize_constbool__"><dt>
+         <nobr>
+         void 
+         <b>Initialize</b> (const char*, bool);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_LoadFrom_c4_Stream___"><dt>
+         <nobr>
+         void 
+         <b>LoadFrom</b> (<A HREF="c4_Stream.html" >c4_Stream</A>&#38; stream_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Load contents from the specified input stream</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_Rollback___"><dt>
+         <nobr>
+         bool 
+         <b>Rollback</b> ();
+         </nobr>
+       <dd>
+         
+          Calling Rollback will cancel all uncommitted changes.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_RootTable___const"><dt>
+         <nobr>
+         c4_HandlerSeq&#38; 
+         <b>RootTable</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the root table entry</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_SaveTo_c4_Stream___"><dt>
+         <nobr>
+         void 
+         <b>SaveTo</b> (<A HREF="c4_Stream.html" >c4_Stream</A>&#38; stream_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Save contents to the specified output stream</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_SetStructure_const__"><dt>
+         <nobr>
+         void 
+         <b>SetStructure</b> (const char*);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_Store_constconst__"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Store</b> (const char* name_, const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Attach a view using specified name in this storage object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_Strategy___const"><dt>
+         <nobr>
+         <A HREF="c4_Strategy.html" >c4_Strategy</A>&#38; 
+         <b>Strategy</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the strategy object associated with this storage</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_View_const__"><dt>
+         <nobr>
+         <A HREF="c4_ViewRef.html" >c4_ViewRef</A> 
+         <b>View</b> (const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set a named view in this storage object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage__persist"><dt>
+         <nobr>
+         c4_Persist* 
+         <b>_persist</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_c4_Storage__"><dt>
+         <nobr>
+         
+         <b>c4_Storage</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct streaming-only storage object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_c4_Storage_c4_Strategy_bool_"><dt>
+         <nobr>
+         
+         <b>c4_Storage</b> (<A HREF="c4_Strategy.html" >c4_Strategy</A>&#38; strategy_, bool owned_ =false);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a storage using the specified strategy handler</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_c4_Storage_const_"><dt>
+         <nobr>
+         
+         <b>c4_Storage</b> (const <A HREF="c4_Storage.html" >c4_Storage</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Copy constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_c4_Storage_constbool_"><dt>
+         <nobr>
+         
+         <b>c4_Storage</b> (const char* filename_, bool canModify_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a storage object, keeping the current structure</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_c4_Storage_constconst_"><dt>
+         <nobr>
+         
+         <b>c4_Storage</b> (const char* filename_, const char* description_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a storage object for given file and format</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Storage.html" >c4_Storage</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_Storage.html" >c4_Storage</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of storage implements reference semantics</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Storage__c4_Storage__"><dt>
+         <nobr>
+         
+         <b>~c4_Storage</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Destructor, usually closes file, but does not commit by default</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Storage</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Strategy.html b/8.x/mk/doc/api/c4_Strategy.html
new file mode 100644 (file)
index 0000000..0750868
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Strategy</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Strategy_desc.html">
+       <frame name="k-info" src="c4_Strategy_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_Strategy_desc.html b/8.x/mk/doc/api/c4_Strategy_desc.html
new file mode 100644 (file)
index 0000000..311c503
--- /dev/null
@@ -0,0 +1,243 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Strategy</b>
+<br><br>
+
+<dd><font face=Times size=3>
+A strategy encapsulates code dealing with the I/O system interface.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_Strategy</b> ();
+         
+         
+               
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual 
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_Strategy</b> ();
+         
+         
+               
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual bool 
+    </td>
+       <td>
+         <nobr>
+         <b>IsValid</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       True if we can do I/O with this object</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>DataSeek</b> (t4_i32 position_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set file position</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>DataRead</b> (void* buffer_, int length_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Read a number of bytes</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>DataLoad</b> (void* buffer_, int length_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Read an exact number of bytes</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual bool 
+    </td>
+       <td>
+         <nobr>
+         <b>DataWrite</b> (const void* buffer_, int length_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Write a number of bytes, return true if successful</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>DataCommit</b> (t4_i32 newSize_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Flush and truncate file</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>ResetFileMapping</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Override to support memory-mapped files</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         bool 
+    </td>
+       <td>
+         <nobr>
+         <b>_keepAfterCommit</b>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Keep data in memory after each commit (default is false)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         bool 
+    </td>
+       <td>
+         <nobr>
+         <b>_bytesFlipped</b>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       True if the storage format is not native (default is false)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>_failure</b>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Error code of last failed I/O operation, zero if I/O was ok</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const t4_byte* 
+    </td>
+       <td>
+         <nobr>
+         <b>_mapStart</b>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       First byte in file mapping, zero if not active</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const t4_byte* 
+    </td>
+       <td>
+         <nobr>
+         <b>_mapLimit</b>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Past last byte in file mapping, zero if not active</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Strategy_info.html b/8.x/mk/doc/api/c4_Strategy_info.html
new file mode 100644 (file)
index 0000000..f1c39f8
--- /dev/null
@@ -0,0 +1,200 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Strategy_DataCommit_t4_i32__"><dt>
+         <nobr>
+         virtual void 
+         <b>DataCommit</b> (t4_i32 newSize_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Flush and truncate file</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy_DataLoad_void_int__"><dt>
+         <nobr>
+         void 
+         <b>DataLoad</b> (void* buffer_, int length_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Read an exact number of bytes</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy_DataRead_void_int__"><dt>
+         <nobr>
+         virtual int 
+         <b>DataRead</b> (void* buffer_, int length_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Read a number of bytes</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy_DataSeek_t4_i32__"><dt>
+         <nobr>
+         virtual void 
+         <b>DataSeek</b> (t4_i32 position_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set file position</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy_DataWrite_constint__"><dt>
+         <nobr>
+         virtual bool 
+         <b>DataWrite</b> (const void* buffer_, int length_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Write a number of bytes, return true if successful</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy_IsValid___const"><dt>
+         <nobr>
+         virtual bool 
+         <b>IsValid</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>True if we can do I/O with this object</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy_ResetFileMapping___"><dt>
+         <nobr>
+         virtual void 
+         <b>ResetFileMapping</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Override to support memory-mapped files</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy__bytesFlipped"><dt>
+         <nobr>
+         bool 
+         <b>_bytesFlipped</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>True if the storage format is not native (default is false)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy__failure"><dt>
+         <nobr>
+         int 
+         <b>_failure</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Error code of last failed I/O operation, zero if I/O was ok</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy__keepAfterCommit"><dt>
+         <nobr>
+         bool 
+         <b>_keepAfterCommit</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Keep data in memory after each commit (default is false)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy__mapLimit"><dt>
+         <nobr>
+         const t4_byte* 
+         <b>_mapLimit</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Past last byte in file mapping, zero if not active</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy__mapStart"><dt>
+         <nobr>
+         const t4_byte* 
+         <b>_mapStart</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>First byte in file mapping, zero if not active</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy_c4_Strategy__"><dt>
+         <nobr>
+         
+         <b>c4_Strategy</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Strategy__c4_Strategy___"><dt>
+         <nobr>
+         virtual 
+         <b>~c4_Strategy</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Strategy</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_Stream.html b/8.x/mk/doc/api/c4_Stream.html
new file mode 100644 (file)
index 0000000..cea243c
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_Stream</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_Stream_desc.html">
+       <frame name="k-info" src="c4_Stream_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_Stream_desc.html b/8.x/mk/doc/api/c4_Stream_desc.html
new file mode 100644 (file)
index 0000000..edf8458
--- /dev/null
@@ -0,0 +1,90 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_Stream</b>
+<br><br>
+
+<dd><font face=Times size=3>
+A stream is a virtual helper class to serialize in binary form.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual 
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_Stream</b> ();
+         
+         
+               
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual int 
+    </td>
+       <td>
+         <nobr>
+         <b>Read</b> (void* buffer_, int length_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Fetch some bytes sequentially</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         virtual void 
+    </td>
+       <td>
+         <nobr>
+         <b>Write</b> (const void* buffer_, int length_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Store some bytes sequentially</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_Stream_info.html b/8.x/mk/doc/api/c4_Stream_info.html
new file mode 100644 (file)
index 0000000..22dc976
--- /dev/null
@@ -0,0 +1,57 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Stream_Read_void_int__"><dt>
+         <nobr>
+         virtual int 
+         <b>Read</b> (void* buffer_, int length_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Fetch some bytes sequentially</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Stream_Write_constint__"><dt>
+         <nobr>
+         virtual void 
+         <b>Write</b> (const void* buffer_, int length_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store some bytes sequentially</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Stream__c4_Stream___"><dt>
+         <nobr>
+         virtual 
+         <b>~c4_Stream</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_Stream</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_StringProp.html b/8.x/mk/doc/api/c4_StringProp.html
new file mode 100644 (file)
index 0000000..a052004
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_StringProp</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_StringProp_desc.html">
+       <frame name="k-info" src="c4_StringProp_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_StringProp_desc.html b/8.x/mk/doc/api/c4_StringProp_desc.html
new file mode 100644 (file)
index 0000000..8ac5d2f
--- /dev/null
@@ -0,0 +1,144 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_StringProp</b>
+ : public <A HREF="c4_Property.html" >c4_Property</A> <br><br>
+
+<dd><font face=Times size=3>
+String properties.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_StringProp</b> (const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_StringRef.html" >c4_StringRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set a string property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const char* 
+    </td>
+       <td>
+         <nobr>
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get a string property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, const char* value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set a string property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (const char* value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one string, shorthand for AsRow</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>AsRow</b> (const char* value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one string</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Property" href="c4_Property.html">c4_Property</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_StringProp_info.html b/8.x/mk/doc/api/c4_StringProp_info.html
new file mode 100644 (file)
index 0000000..4474641
--- /dev/null
@@ -0,0 +1,208 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_StringProp</b> - String properties.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Property_CleanupInternalData___"><dt>
+         <nobr>
+         static void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::CleanupInternalData</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Call this to get rid of som eonternal datastructues (on exit)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_GetId___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::GetId</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          A property object in fact merely represents an entry in a globally
+ maintained symbol table. Each property is assigned a unique id,
+ which remains valid as long as some reference to that property
+ exists. In general, property id's remain unique as long as the
+ application runs. Do not store id's on file, since they are
+ not guaranteed to remain the same across program invocations.
+ All properties with the same name are given the same id.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Name___const"><dt>
+         <nobr>
+         const char* 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Name</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the name of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Refs_int__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Refs</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is part of the implementation and shouldn't normally be called.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Type___const"><dt>
+         <nobr>
+         char 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Type</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the type of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set this untyped property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringProp_AsRow_const__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>AsRow</b> (const char* value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one string</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringProp_Get_const__const"><dt>
+         <nobr>
+         const char* 
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get a string property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringProp_Set_constconst__const"><dt>
+         <nobr>
+         void 
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, const char* value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set a string property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringProp_c4_StringProp_const_"><dt>
+         <nobr>
+         
+         <b>c4_StringProp</b> (const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_StringRef.html" >c4_StringRef</A> 
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set a string property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>operator[]</b> (const char* value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one string, shorthand for AsRow</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_StringProp</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_StringRef.html b/8.x/mk/doc/api/c4_StringRef.html
new file mode 100644 (file)
index 0000000..6c8794f
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_StringRef</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_StringRef_desc.html">
+       <frame name="k-info" src="c4_StringRef_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_StringRef_desc.html b/8.x/mk/doc/api/c4_StringRef_desc.html
new file mode 100644 (file)
index 0000000..dff861d
--- /dev/null
@@ -0,0 +1,102 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_StringRef</b>
+ : public <A HREF="c4_Reference.html" >c4_Reference</A> <br><br>
+
+<dd><font face=Times size=3>
+Used to get or set string values.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_StringRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         operator const 
+    </td>
+       <td>
+         <nobr>
+         <b>char*</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get the value as string</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_StringRef.html" >c4_StringRef</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const char*);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set the value to the specified string</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Reference" href="c4_Reference.html">c4_Reference</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_StringRef_info.html b/8.x/mk/doc/api/c4_StringRef_info.html
new file mode 100644 (file)
index 0000000..b474e66
--- /dev/null
@@ -0,0 +1,135 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_StringRef</b> - Used to get or set string values.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Reference_GetData_c4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve the value of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_SetData_const__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a value into the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__property"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_property</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of one data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringRef_c4_StringRef_const_"><dt>
+         <nobr>
+         
+         <b>c4_StringRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringRef_char____const"><dt>
+         <nobr>
+         operator const 
+         <b>char*</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get the value as string</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_StringRef_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_StringRef.html" >c4_StringRef</A>&#38; 
+         <b>operator= </b> (const char*);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set the value to the specified string</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_StringRef</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_View.html b/8.x/mk/doc/api/c4_View.html
new file mode 100644 (file)
index 0000000..f7e4d15
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_View</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_View_desc.html">
+       <frame name="k-info" src="c4_View_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_ViewProp.html b/8.x/mk/doc/api/c4_ViewProp.html
new file mode 100644 (file)
index 0000000..f50d7db
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_ViewProp</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_ViewProp_desc.html">
+       <frame name="k-info" src="c4_ViewProp_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_ViewProp_desc.html b/8.x/mk/doc/api/c4_ViewProp_desc.html
new file mode 100644 (file)
index 0000000..9d1a0db
--- /dev/null
@@ -0,0 +1,144 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_ViewProp</b>
+ : public <A HREF="c4_Property.html" >c4_Property</A> <br><br>
+
+<dd><font face=Times size=3>
+View properties.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_ViewProp</b> (const char* name_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_ViewRef.html" >c4_ViewRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get or set a view property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get a view property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, const <A HREF="c4_View.html" >c4_View</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set a view property in a row</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one view, shorthand for AsRow</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>AsRow</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; value_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create a row with one view</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Property" href="c4_Property.html">c4_Property</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_ViewProp_info.html b/8.x/mk/doc/api/c4_ViewProp_info.html
new file mode 100644 (file)
index 0000000..ce3bf1f
--- /dev/null
@@ -0,0 +1,208 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_ViewProp</b> - View properties.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Property_CleanupInternalData___"><dt>
+         <nobr>
+         static void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::CleanupInternalData</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Call this to get rid of som eonternal datastructues (on exit)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_GetId___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::GetId</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          A property object in fact merely represents an entry in a globally
+ maintained symbol table. Each property is assigned a unique id,
+ which remains valid as long as some reference to that property
+ exists. In general, property id's remain unique as long as the
+ application runs. Do not store id's on file, since they are
+ not guaranteed to remain the same across program invocations.
+ All properties with the same name are given the same id.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Name___const"><dt>
+         <nobr>
+         const char* 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Name</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the name of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Refs_int__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Refs</b> (int) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is part of the implementation and shouldn't normally be called.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_Type___const"><dt>
+         <nobr>
+         char 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::Type</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the type of this property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set this untyped property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; prop_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Property_operator___const__"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Property.html'>c4_Property</A>::operator= </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewProp_AsRow_const__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>AsRow</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewProp_Get_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Get</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get a view property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewProp_Set_constconst__const"><dt>
+         <nobr>
+         void 
+         <b>Set</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, const <A HREF="c4_View.html" >c4_View</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set a view property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewProp_c4_ViewProp_const_"><dt>
+         <nobr>
+         
+         <b>c4_ViewProp</b> (const char* name_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_ViewRef.html" >c4_ViewRef</A> 
+         <b>operator()</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get or set a view property in a row</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewProp_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_Row.html" >c4_Row</A> 
+         <b>operator[]</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; value_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create a row with one view, shorthand for AsRow</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_ViewProp</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_ViewRef.html b/8.x/mk/doc/api/c4_ViewRef.html
new file mode 100644 (file)
index 0000000..750f154
--- /dev/null
@@ -0,0 +1,6 @@
+<html><head><title>class c4_ViewRef</title></head>
+
+<frameset  rows="*,200">
+       <frame name="k-desc" src="c4_ViewRef_desc.html">
+       <frame name="k-info" src="c4_ViewRef_info.html">
+</frameset>
diff --git a/8.x/mk/doc/api/c4_ViewRef_desc.html b/8.x/mk/doc/api/c4_ViewRef_desc.html
new file mode 100644 (file)
index 0000000..feb354d
--- /dev/null
@@ -0,0 +1,102 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_ViewRef</b>
+ : public <A HREF="c4_Reference.html" >c4_Reference</A> <br><br>
+
+<dd><font face=Times size=3>
+Used to get or set view values.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_ViewRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Constructor</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         operator 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_View</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Get the value as view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_ViewRef.html" >c4_ViewRef</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_View.html" >c4_View</A>&#38;);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set the value to the specified view</font>
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+    <tr>
+    <td>
+         <font face=Helvetica size=-1><b>Derived from</b></font>
+    </td>
+    <td>
+         
+               <a name="c4_Reference" href="c4_Reference.html">c4_Reference</a>
+         
+    </td>
+       </tr>
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_ViewRef_info.html b/8.x/mk/doc/api/c4_ViewRef_info.html
new file mode 100644 (file)
index 0000000..a78a852
--- /dev/null
@@ -0,0 +1,135 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+<b>class c4_ViewRef</b> - Used to get or set view values.
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_Reference_GetData_c4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetData</b> (<A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Retrieve the value of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return width of the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_SetData_const__const"><dt>
+         <nobr>
+         void 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::SetData</b> (const <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38;) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Store a value into the referenced data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__cursor"><dt>
+         <nobr>
+         <A HREF="c4_Cursor.html" >c4_Cursor</A> 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_cursor</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference__property"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::_property</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_Reference_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_Reference.html" >c4_Reference</A>&#38; 
+         <b><A HREF='c4_Reference.html'>c4_Reference</A>::operator= </b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Assignment of one data item</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewRef_c4_View___const"><dt>
+         <nobr>
+         operator 
+         <b>c4_View</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Get the value as view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewRef_c4_ViewRef_const_"><dt>
+         <nobr>
+         
+         <b>c4_ViewRef</b> (const <A HREF="c4_Reference.html" >c4_Reference</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Constructor</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_ViewRef_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_ViewRef.html" >c4_ViewRef</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_View.html" >c4_View</A>&#38;);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set the value to the specified view</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_ViewRef</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/c4_View_desc.html b/8.x/mk/doc/api/c4_View_desc.html
new file mode 100644 (file)
index 0000000..4e4fa54
--- /dev/null
@@ -0,0 +1,977 @@
+<html><head><base target=k-main></head><body bgcolor=white><nobr>
+
+<font face=Helvetica size=3>
+<dl><dt>
+
+  <b>class c4_View</b>
+<br><br>
+
+<dd><font face=Times size=3>
+A collection of data rows.<br><br>
+
+
+</font></dl>
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Public members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_View</b> (<A HREF="c4_Sequence.html" >c4_Sequence</A>* implementation_ =0);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a view based on a sequence</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_View</b> (<A HREF="c4_CustomViewer.html" >c4_CustomViewer</A>* viewer_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a view based on a custom viewer</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_View</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct an empty view with one propertyConstruct a view from another one</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>c4_View</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct an empty view with one propertyConstruct a view from another one</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         
+    </td>
+       <td>
+         <nobr>
+         <b>~c4_View</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Destructor, decrements reference count</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>operator= </b> (const <A HREF="c4_View.html" >c4_View</A>&#38; source_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Make this view the same as another one</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>GetSize</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the number of entries</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>GetUpperBound</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return highest index (size - 1)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>SetSize</b> (int newSize_, int growBy_ =-1);
+         
+         <a href="c4_View_info.html#c4_View_SetSize_intint__" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Change the size of this view</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>RemoveAll</b> ();
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Remove all entries (sets size to zero)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>GetAt</b> (int index_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a reference to specified entry</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator[]</b> (int index_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Shorthand for <A HREF="c4_View.html" >c4_View</A>::GetAt</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>SetAt</b> (int index_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         <a href="c4_View_info.html#c4_View_SetAt_intconst__" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Change the value of the specified entry</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>ElementAt</b> (int index_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Element access, for use as RHS or LHS</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         bool 
+    </td>
+       <td>
+         <nobr>
+         <b>GetItem</b> (int row_, int col_, <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; buf_) <i>const</i>;
+         <a href="c4_View_info.html#c4_View_GetItem_intintc4_Bytes___const" target="k-info">
+         
+               <font face=Helvetica size=-1><br>
+                       Get a single data item in a generic way</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>SetAtGrow</b> (int index_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Set an entry, growing the view if needed</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>Add</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Add a new entry, same as "SetAtGrow(GetSize(), ...)".</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>InsertAt</b> (int index_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, int count_ =1);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Insert one or more copies of an entry</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>RemoveAt</b> (int index_, int count_ =1);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Remove entries starting at the given index</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>InsertAt</b> (int index_, const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Insert a copy of the contents of another view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         bool 
+    </td>
+       <td>
+         <nobr>
+         <b>RelocateRows</b> (int from_, int count_, <A HREF="c4_View.html" >c4_View</A>&#38; dest_, int pos_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Move attached rows to somewhere else in same storage</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>NumProperties</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the number of properties</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+    </td>
+       <td>
+         <nobr>
+         <b>NthProperty</b> (int column_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the id of the N-th property</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>FindProperty</b> (int id_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Find the index of a property, given its id</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>FindPropIndexByName</b> (const char* name_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Find the index of a property, given its name</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Structure</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a view which describes the structure of this view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         const char* 
+    </td>
+       <td>
+         <nobr>
+         <b>Describe</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a description of the structure</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         static const char* 
+    </td>
+       <td>
+         <nobr>
+         <b>Description</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a homogenized description of this view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Duplicate</b> (bool deepCopy_ =false) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new view with a copy of the data</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Clone</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Construct a new view with the same structure but no data</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>AddProperty</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Adds a property column to a view if not already present</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return a view like the first, with a property appended to it</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Sort</b> () <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create view with all rows in natural (property-wise) order</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>SortOn</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create view sorted according to the specified properties</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>SortOnReverse</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_, const <A HREF="c4_View.html" >c4_View</A>&#38; orderDown_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create sorted view, with some properties sorted in reverse</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Select</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; criterium_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create view with rows matching the specified value</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>SelectRange</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; rowLow_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; rowHigh_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create view with row values within the specified range</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Project</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create view with the specified property arrangement</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>ProjectWithout</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create derived view with some properties omitted</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Slice</b> (int start_, int limit_ =-1, int step_ =1) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Slice_intintint__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view which is a segment/slice (default is up to end)</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Product</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Product_const__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view which is the cartesian product with given view</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>RemapWith</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_RemapWith_const__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view which remaps another given view</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Pair</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Pair_const__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view which pairs each row with corresponding row</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Concat</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Concat_const__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view with rows from another view appended</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Rename</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; old_, const <A HREF="c4_Property.html" >c4_Property</A>&#38; new_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Create view with one property renamed (must be of same type)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>GroupBy</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; keys_, const <A HREF="c4_ViewProp.html" >c4_ViewProp</A>&#38; name_) <i>const</i>;
+         <a href="c4_View_info.html#c4_View_GroupBy_constconst__const" target="k-info">
+         
+               <font face=Helvetica size=-1><br>
+                       Create view with a subview, grouped by the specified properties</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Counts</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; keys_, const <A HREF="c4_IntProp.html" >c4_IntProp</A>&#38; name_) <i>const</i>;
+         <a href="c4_View_info.html#c4_View_Counts_constconst__const" target="k-info">
+         
+               <font face=Helvetica size=-1><br>
+                       Create view with count of duplicates, when grouped by key</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Unique</b> () <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Unique___const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view with all duplicate rows omitted</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Union</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Union_const__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view which is the set union (assumes no duplicate rows)</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Intersect</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Intersect_const__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view with all rows also in the given view (no dups)</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Different</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Different_const__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view with all rows not in both views (no dups)</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Minus</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         
+         <a href="c4_View_info.html#c4_View_Minus_const__const" target="k-info">
+               <font face=Helvetica size=-1><br>
+                       Create view with all rows not in the given view (no dups)</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>JoinProp</b> (const <A HREF="c4_ViewProp.html" >c4_ViewProp</A>&#38; sub_, bool outer_ =false) <i>const</i>;
+         <a href="c4_View_info.html#c4_View_JoinProp_constbool__const" target="k-info">
+         
+               <font face=Helvetica size=-1><br>
+                       Create view with a specific subview expanded, like a join</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         <A HREF="c4_View.html" >c4_View</A> 
+    </td>
+       <td>
+         <nobr>
+         <b>Join</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; keys_, const <A HREF="c4_View.html" >c4_View</A>&#38; view_, bool outer_ =false) <i>const</i>;
+         <a href="c4_View_info.html#c4_View_Join_constconstbool__const" target="k-info">
+         
+               <font face=Helvetica size=-1><br>
+                       Create view which is the relational join on the given keys</font></a>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>GetIndexOf</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Return the index of the specified row in this view (or -1)</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>Find</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; key_, int start_ =0) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Find index of the the next entry matching the specified key</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>Search</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; key_) <i>const</i>;
+         
+         
+               <font face=Helvetica size=-1><br>
+                       Search for a key, using the native sort order of the view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         int 
+    </td>
+       <td>
+         <nobr>
+         <b>Compare</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         
+         
+               
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Protected members</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>_IncSeqRef</b> ();
+         
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         void 
+    </td>
+       <td>
+         <nobr>
+         <b>_DecSeqRef</b> ();
+         
+       </td>
+       </tr>
+  
+  </table>
+
+
+
+  <table cellborder=0>
+    <tr>
+    <td colspan=2>
+         <font face=Helvetica size=-1><b>Friends</b></font>
+    </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator==</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; a_, const <A HREF="c4_View.html" >c4_View</A>&#38; b_);
+         <font face=Helvetica size=-1><br>Return true if the contents of both views are equal</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator!=</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; a_, const <A HREF="c4_View.html" >c4_View</A>&#38; b_);
+         <font face=Helvetica size=-1><br>Return true if the contents of both views are not equal</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator< </b> (const <A HREF="c4_View.html" >c4_View</A>&#38; a_, const <A HREF="c4_View.html" >c4_View</A>&#38; b_);
+         <font face=Helvetica size=-1><br>True if first view is less than second view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator> </b> (const <A HREF="c4_View.html" >c4_View</A>&#38; a_, const <A HREF="c4_View.html" >c4_View</A>&#38; b_);
+         <font face=Helvetica size=-1><br>True if first view is greater than second view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator<=</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; a_, const <A HREF="c4_View.html" >c4_View</A>&#38; b_);
+         <font face=Helvetica size=-1><br>True if first view is less or equal to second view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend bool 
+    </td>
+       <td>
+         <nobr>
+         <b>operator>=</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; a_, const <A HREF="c4_View.html" >c4_View</A>&#38; b_);
+         <font face=Helvetica size=-1><br>True if first view is greater or equal to second view</font>
+       </td>
+       </tr>
+  
+    <tr>
+    <td valign=top align=right width=150>
+         friend class 
+    </td>
+       <td>
+         <nobr>
+         <b>c4_ViewRef</b>;
+         
+       </td>
+       </tr>
+  
+  </table>
+
+
+<br><hr size=1 width=50 align=left>
+
+<table cellborder=0>
+    <tr>
+    <td width=150>
+         <font face=Helvetica size=-1><b>Header file</b></font>
+    </td>
+    <td>
+         "mk4.h" &nbsp; -- &nbsp; Dec 9, 1999
+    </td>
+       </tr>
+
+  
+
+  
+</table>
+
+</font></font>
+
+</nobr></body></html>
diff --git a/8.x/mk/doc/api/c4_View_info.html b/8.x/mk/doc/api/c4_View_info.html
new file mode 100644 (file)
index 0000000..aa97c01
--- /dev/null
@@ -0,0 +1,924 @@
+<html><head><base target=k-main></head><body bgcolor=white>
+
+<font face=Times size=3>
+
+Views act like pointers to the actual collections, setting a view to a new
+value does not alter the collection to which this view pointed previously.
+<P>
+
+The protocol used for this class mimics the way many other collection
+classes are defined. For example, when used with MFC, you will see member
+definitions such as <A HREF="c4_View.html" >c4_View</A>::GetSize, <A HREF="c4_View.html" >c4_View</A>::GetAt, <A HREF="c4_View.html" >c4_View</A>::InsertAt.
+<P>
+
+The elements of views can be referred to by their 0-based index, which
+produces a row-reference of type <A HREF="c4_RowRef.html" >c4_RowRef</A>.  These row references can
+be copied, used to get or set properties, or dereferenced (in which case
+an object of class <A HREF="c4_Row.html" >c4_Row</A> is returned).  Taking the address of a row
+reference produces a <A HREF="c4_Cursor.html" >c4_Cursor</A>, which acts very much like a pointer.
+<P>
+
+The following code creates a view with 1 row and 2 properties:
+<P>
+
+
+<PRE>    <A HREF="c4_StringProp.html" >c4_StringProp</A> pName ("Name");
+    <A HREF="c4_IntProp.html" >c4_IntProp</A> pAge ("Age");</PRE>
+<P>
+
+
+<PRE>    <A HREF="c4_Row.html" >c4_Row</A> data;
+    pName (data) = "John Williams";
+    pAge (data) = 43;</PRE>
+<P>
+
+
+<PRE>    <A HREF="c4_View.html" >c4_View</A> myView;
+    myView.Add(row);
+</PRE>
+<P>
+
+
+
+<hr size=1>
+
+<dl>
+  
+  <if !private>
+       <a name="c4_View_Add_const__"><dt>
+         <nobr>
+         int 
+         <b>Add</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Add a new entry, same as "SetAtGrow(GetSize(), ...)".</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_AddProperty_const__"><dt>
+         <nobr>
+         int 
+         <b>AddProperty</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Adds a property column to a view if not already present</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Clone___const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Clone</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new view with the same structure but no data</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Compare_const__const"><dt>
+         <nobr>
+         int 
+         <b>Compare</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Concat_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Concat</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          Constructs a view which has all rows of this view, and all rows
+ of the second view appended. The structure of the second view
+ is assumed to be identical to this one. This operation is a bit
+ similar to appending all rows from the second view, but it does
+ not actually store the result anywhere, it just looks like it.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Counts_constconst__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Counts</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; keys_, const <A HREF="c4_IntProp.html" >c4_IntProp</A>&#38; name_) <i>const</i>;
+         </nobr>
+       <dd>
+         <ul><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>keys_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>the properties in this view determine the grouping</FONT></I></TD></TR>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>name_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>name of the new count property defined in result</FONT></I></TD></TR>
+</TABLE>
+</ul>
+          This is similar to <A HREF="c4_View.html" >c4_View</A>::GroupBy, but it determines only the
+ number of rows in each group and does not create a nested view.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Describe___const"><dt>
+         <nobr>
+         const char* 
+         <b>Describe</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a description of the structure</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Description_const__"><dt>
+         <nobr>
+         static const char* 
+         <b>Description</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a homogenized description of this view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Different_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Different</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          Calculates the "XOR" of two sets. This will only work if both
+ input views are sets, i.e. they have no duplicate rows in them.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Duplicate_bool__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Duplicate</b> (bool deepCopy_ =false) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a new view with a copy of the data</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_ElementAt_int__"><dt>
+         <nobr>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+         <b>ElementAt</b> (int index_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Element access, for use as RHS or LHS</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Find_constint__const"><dt>
+         <nobr>
+         int 
+         <b>Find</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; key_, int start_ =0) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Find index of the the next entry matching the specified key</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_FindPropIndexByName_const__const"><dt>
+         <nobr>
+         int 
+         <b>FindPropIndexByName</b> (const char* name_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Find the index of a property, given its name</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_FindProperty_int__"><dt>
+         <nobr>
+         int 
+         <b>FindProperty</b> (int id_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Find the index of a property, given its id</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_GetAt_int__const"><dt>
+         <nobr>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+         <b>GetAt</b> (int index_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a reference to specified entry</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_GetIndexOf_const__const"><dt>
+         <nobr>
+         int 
+         <b>GetIndexOf</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the index of the specified row in this view (or -1)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_GetItem_intintc4_Bytes___const"><dt>
+         <nobr>
+         bool 
+         <b>GetItem</b> (int row_, int col_, <A HREF="c4_Bytes.html" >c4_Bytes</A>&#38; buf_) <i>const</i>;
+         </nobr>
+       <dd>
+         <ul><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>row_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>row index, range [0 .. GetSize())</FONT></I></TD></TR>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>col_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>property index, range [0 .. NumProperties())</FONT></I></TD></TR>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>buf_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>buffer for the result</FONT></I></TD></TR>
+</TABLE>
+</ul>
+          This can be used to access view data in a generalized way.
+ Useful for c4_CustomViewers which are based on other views.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_GetSize___const"><dt>
+         <nobr>
+         int 
+         <b>GetSize</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the number of entries</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_GetUpperBound___const"><dt>
+         <nobr>
+         int 
+         <b>GetUpperBound</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return highest index (size - 1)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_GroupBy_constconst__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>GroupBy</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; keys_, const <A HREF="c4_ViewProp.html" >c4_ViewProp</A>&#38; name_) <i>const</i>;
+         </nobr>
+       <dd>
+         <ul><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>keys_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>the properties in this view determine the grouping</FONT></I></TD></TR>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>name_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>name of the new subview defined in result</FONT></I></TD></TR>
+</TABLE>
+</ul>
+          This operation is similar to the SQL 'GROUP BY', but it takes
+ advantage of the fact that Metakit supports nested views. The
+ view returned from this member has one row per distinct group,
+ with an extra view property holding the remaining properties.
+ If there are N rows in the original view matching key X, then
+ the result is a row for key X, with a subview of N rows. The
+ properties of the subview are all the properties not in the key.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_InsertAt_intconst__"><dt>
+         <nobr>
+         void 
+         <b>InsertAt</b> (int index_, const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Insert a copy of the contents of another view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_InsertAt_intconstint__"><dt>
+         <nobr>
+         void 
+         <b>InsertAt</b> (int index_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_, int count_ =1);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Insert one or more copies of an entry</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Intersect_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Intersect</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          Calculates the set intersection. This will only work if both
+ input views are sets, i.e. they have no duplicate rows in them.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Join_constconstbool__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Join</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; keys_, const <A HREF="c4_View.html" >c4_View</A>&#38; view_, bool outer_ =false) <i>const</i>;
+         </nobr>
+       <dd>
+         <ul><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>keys_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>the properties in this view determine the join</FONT></I></TD></TR>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>view_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>second view participating in the join</FONT></I></TD></TR>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>outer_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>true: keep rows with no match in second view</FONT></I></TD></TR>
+</TABLE>
+</ul>
+         
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_JoinProp_constbool__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>JoinProp</b> (const <A HREF="c4_ViewProp.html" >c4_ViewProp</A>&#38; sub_, bool outer_ =false) <i>const</i>;
+         </nobr>
+       <dd>
+         <ul><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>sub_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>name of the subview to expand</FONT></I></TD></TR>
+<TR><TD><B><FONT FACE=Helvetica SIZE=2>outer_</FONT></B></TD><TD width=20></TD><TD><I><FONT FACE=Helvetica SIZE=2>true: keep rows with empty subviews</FONT></I></TD></TR>
+</TABLE>
+</ul>
+          This operation is the inverse of <A HREF="c4_View.html" >c4_View</A>::GroupBy, expanding
+ all rows in specified subview and returning a view which looks
+ as if the rows in each subview were "expanded in place".
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Minus_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Minus</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          Calculates set-difference of this view minus arg view. Result
+ is a subset, unlike <A HREF="c4_View.html" >c4_View</A>::Different. Will only work if both
+ input views are sets, i.e. they have no duplicate rows in them.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_NthProperty_int__const"><dt>
+         <nobr>
+         const <A HREF="c4_Property.html" >c4_Property</A>&#38; 
+         <b>NthProperty</b> (int column_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the id of the N-th property</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_NumProperties___const"><dt>
+         <nobr>
+         int 
+         <b>NumProperties</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return the number of properties</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Pair_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Pair</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          This is like a row-by-row concatenation. Both views must have
+ the same number of rows, the result has all properties from
+ this view plus any other properties from the other view.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Product_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Product</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          The cartesian product is defined as every combination of rows
+ in both views. The number of entries is the product of the
+ number of entries in the two views, properties which are present
+ in both views will use the values defined in this view.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Project_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Project</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create view with the specified property arrangement</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_ProjectWithout_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>ProjectWithout</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create derived view with some properties omitted</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_RelocateRows_intintc4_View_int__"><dt>
+         <nobr>
+         bool 
+         <b>RelocateRows</b> (int from_, int count_, <A HREF="c4_View.html" >c4_View</A>&#38; dest_, int pos_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Move attached rows to somewhere else in same storage</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_RemapWith_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>RemapWith</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          Remapping constructs a view with the rows indicated by another
+ view. The first property in the order_ view must be an int
+ property with index values referring to this one. The size of
+ the resulting view is determined by the order_ view and can
+ differ, for example to act as a subset selection (if smaller).
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_RemoveAll___"><dt>
+         <nobr>
+         void 
+         <b>RemoveAll</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Remove all entries (sets size to zero)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_RemoveAt_intint__"><dt>
+         <nobr>
+         void 
+         <b>RemoveAt</b> (int index_, int count_ =1);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Remove entries starting at the given index</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Rename_constconst__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Rename</b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; old_, const <A HREF="c4_Property.html" >c4_Property</A>&#38; new_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create view with one property renamed (must be of same type)</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Search_const__const"><dt>
+         <nobr>
+         int 
+         <b>Search</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; key_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Search for a key, using the native sort order of the view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Select_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Select</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; criterium_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create view with rows matching the specified value</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_SelectRange_constconst__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>SelectRange</b> (const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; rowLow_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; rowHigh_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create view with row values within the specified range</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_SetAt_intconst__"><dt>
+         <nobr>
+         void 
+         <b>SetAt</b> (int index_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+          Replace an entry with the contents of another row. If the
+ row contains subviews, they will be replaced as well, but
+ there are two cases: if this is an attached view, all the
+ subview rows will be copied (deep copy), whereas for an
+ unattached view the new subviews will be shared with the 
+ original (shallow copy).
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_SetAtGrow_intconst__"><dt>
+         <nobr>
+         void 
+         <b>SetAtGrow</b> (int index_, const <A HREF="c4_RowRef.html" >c4_RowRef</A>&#38; row_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Set an entry, growing the view if needed</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_SetSize_intint__"><dt>
+         <nobr>
+         void 
+         <b>SetSize</b> (int newSize_, int growBy_ =-1);
+         </nobr>
+       <dd>
+         
+          Since views act like dynamic arrays, you can quickly
+ change their size. Increasing the size will append rows
+ with zero/empty values, while decreasing it will delete
+ the last rows. The growBy_ parameter is currently unused.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Slice_intintint__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Slice</b> (int start_, int limit_ =-1, int step_ =1) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          Returns a view which is a subset, either a contiguous range, or
+ a "slice" with element taken from every step_ entries. If the
+ step is negative, the same entries are returned, but in reverse
+ order (start_ is still lower index, it'll then be returned last).
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Sort___const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Sort</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create view with all rows in natural (property-wise) order</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_SortOn_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>SortOn</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create view sorted according to the specified properties</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_SortOnReverse_constconst__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>SortOnReverse</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; order_, const <A HREF="c4_View.html" >c4_View</A>&#38; orderDown_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Create sorted view, with some properties sorted in reverse</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Structure___const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Structure</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view which describes the structure of this view</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Union_const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Union</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+          Calculates the set union. This will only work if both input
+ views are sets, i.e. they have no duplicate rows in them.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_Unique___const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>Unique</b> () <i>const</i>;
+         </nobr>
+       <dd>
+         
+          Returns a subset which does not contain any duplicate rows.
+<br>
+         
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View__DecSeqRef___"><dt>
+         <nobr>
+         void 
+         <b>_DecSeqRef</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View__IncSeqRef___"><dt>
+         <nobr>
+         void 
+         <b>_IncSeqRef</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View__seq"><dt>
+         <nobr>
+         <A HREF="c4_Sequence.html" >c4_Sequence</A>* 
+         <b>_seq</b>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1></font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_c4_View_c4_CustomViewer__"><dt>
+         <nobr>
+         
+         <b>c4_View</b> (<A HREF="c4_CustomViewer.html" >c4_CustomViewer</A>* viewer_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a view based on a custom viewer</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_c4_View_c4_Sequence__"><dt>
+         <nobr>
+         
+         <b>c4_View</b> (<A HREF="c4_Sequence.html" >c4_Sequence</A>* implementation_ =0);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct a view based on a sequence</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_c4_View_const_"><dt>
+         <nobr>
+         
+         <b>c4_View</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct an empty view with one propertyConstruct a view from another one</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_c4_View_const_"><dt>
+         <nobr>
+         
+         <b>c4_View</b> (const <A HREF="c4_View.html" >c4_View</A>&#38; view_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Construct an empty view with one propertyConstruct a view from another one</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_operator___const__const"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A> 
+         <b>operator, </b> (const <A HREF="c4_Property.html" >c4_Property</A>&#38; property_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Return a view like the first, with a property appended to it</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_operator___const__"><dt>
+         <nobr>
+         <A HREF="c4_View.html" >c4_View</A>&#38; 
+         <b>operator= </b> (const <A HREF="c4_View.html" >c4_View</A>&#38; source_);
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Make this view the same as another one</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View_operator___int__const"><dt>
+         <nobr>
+         <A HREF="c4_RowRef.html" >c4_RowRef</A> 
+         <b>operator[]</b> (int index_) <i>const</i>;
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Shorthand for <A HREF="c4_View.html" >c4_View</A>::GetAt</font>
+       <p>
+  
+  
+  <if !private>
+       <a name="c4_View__c4_View__"><dt>
+         <nobr>
+         
+         <b>~c4_View</b> ();
+         </nobr>
+       <dd>
+         
+         
+         <font face=Helvetica size=-1>Destructor, decrements reference count</font>
+       <p>
+  
+  
+</dl>
+
+<hr size=1 width=50 align=left>
+class 
+<b>c4_View</b>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/classes.html b/8.x/mk/doc/api/classes.html
new file mode 100644 (file)
index 0000000..5eacbd7
--- /dev/null
@@ -0,0 +1,182 @@
+<html>
+<head>
+<title>Metakit Class Index</title></head>
+<body  bgcolor="#FFFFFF" alink="#008000" vlink="#800080" link="#0000FF" text="#000000">
+
+<table cellspacing=0 cellpadding=0 border=0 width="100%"><tr valign=top>
+       <td width=100><a href="http://www.equi4.com/">
+               <img src=e4w.gif alt="E q u i 4" align=left width=97 height=35 hspace=0 border=0></a>
+       </td><td align=center>
+       <font size=+2>Metakit Class Index</font><br>
+       <i>December 1999</i>
+       </td><td width=100></td></tr></table>
+<p>
+
+
+<center>
+<!--begin-->
+<table border=0>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Bytes.html"><b>c4_Bytes</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Generic data buffer, with optional automatic clean up.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_BytesProp.html"><b>c4_BytesProp</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Binary properties.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_BytesRef.html"><b>c4_BytesRef</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Used to get or set binary object values.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Cursor.html"><b>c4_Cursor</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>An iterator for collections of rows (views).</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_CustomViewer.html"><b>c4_CustomViewer</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Abstract base class for definition of custom views.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_DoubleProp.html"><b>c4_DoubleProp</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Double precision properties.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_DoubleRef.html"><b>c4_DoubleRef</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Used to get or set double precision values.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_FloatProp.html"><b>c4_FloatProp</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Floating point properties.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_FloatRef.html"><b>c4_FloatRef</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Used to get or set floating point values.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_IntProp.html"><b>c4_IntProp</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Integer properties.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_IntRef.html"><b>c4_IntRef</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Used to get or set integer values.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_MemoProp.html"><b>c4_MemoProp</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Memo properties.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_MemoRef.html"><b>c4_MemoRef</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Used to get or set memo values (growable large binary objects).</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Property.html"><b>c4_Property</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Base class for the basic data types.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Reference.html"><b>c4_Reference</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>A reference is used to get or set typed data, using derived classes.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Row.html"><b>c4_Row</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>An entry in a collection with copy semantics.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_RowRef.html"><b>c4_RowRef</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Reference to a data row, can be used on either side of an assignment.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Sequence.html"><b>c4_Sequence</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>A sequence is an abstract base class for views on ranges of records.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Storage.html"><b>c4_Storage</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Manager for persistent storage of view structures.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Strategy.html"><b>c4_Strategy</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>A strategy encapsulates code dealing with the I/O system interface.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_Stream.html"><b>c4_Stream</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>A stream is a virtual helper class to serialize in binary form.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_StringProp.html"><b>c4_StringProp</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>String properties.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_StringRef.html"><b>c4_StringRef</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Used to get or set string values.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_View.html"><b>c4_View</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>A collection of data rows.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_ViewProp.html"><b>c4_ViewProp</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>View properties.</td>
+       </tr>
+  
+       <tr>
+         <td align=right valign=top><a href="c4_ViewRef.html"><b>c4_ViewRef</b></a></td>
+         <td width=10></td>
+         <td><font face=Times>Used to get or set view values.</td>
+       </tr>
+  
+</table>
+<p>
+<hr size=1>
+<font color="#000099" size=-1>&copy; 1999 Equi4 Software. All rights reserved.</font>
+
+</body>
+</html>
diff --git a/8.x/mk/doc/api/doc_catfish.html b/8.x/mk/doc/api/doc_catfish.html
new file mode 100644 (file)
index 0000000..c407868
--- /dev/null
@@ -0,0 +1,105 @@
+<html><head>
+       <title>Metakit CatFish Sample</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - CatFish</h2><br clear=left>
+
+<p>CatFish is the flagship of these sample applications. It is a very fast
+disk catalog browser which can easily deal with the huge file collections
+often found on current hard disks and CD-ROM software collections. </p>
+
+<p><b>What it does</b>: CatFish allows you to create disk catalogs by scanning
+disks, either entirely or from a specified directory, and to browse through
+the directories in each catalog to list the files, their sizes, and their
+modification dates. In addition, CatFish displays statistics about each
+directory, such as the total number of sub-directories, files, and kilobytes
+in each (including all nested entries). It also tells you the date of the
+most recent file in each directory (even if that file is inside a sub-directory).
+There is a flexible search facility to find files by (partial) name, size,
+and/or date. Finally, CatFish can be used as an application/document launcher
+- a bit like the File Manager (or the Explorer in Windows 95). </p>
+
+<p>The data files used by CatFish use the same format as those created
+by DisCat and FtpCat. You can use FtpCat to create FTP server catalogs
+- and then use CatFish to browse through them. </p>
+
+<p><b>What it illustrates</b>: CatFish is a 16-bit Windows application
+(it runs on Windows 95, and probably Windows NT, as well). The freeware
+version has been built with the static library version of Metakit and is
+fully self-contained. The size of the executable file illustrates how small
+complete applications can be when using Metakit for persistent storage.
+The makefile included with the sources are configured for dynamic linkage,
+which will produce an even smaller executable. </p>
+
+<p>CatFish uses a carefully chosen data structure with a high &quot;locality
+of reference&quot;, which generates very compact catalog files and which
+makes browsing extremely fast - even for full CD-ROM catalogs and large
+FTP archive server catalogs (created with FtpCat). </p>
+
+<p>There are several goodies in this sample application. Among other things,
+CatFish demonstrates: </p>
+
+<ul>
+       <li>How to use a sorted view subset (selection) of Metakit in a CListBox (MFC) </li>
+       <li>How to implement customizable sort order for a listbox, with clickable headers</li>
+       <li>How to scan directories recursively - in Win16 / Win32 / Win95 (long filenames) </li>
+       <li>How to quickly display huge lists - using the owner-draw listbox control </li>
+       <li>How to simplify columnar list formatting - using the MS Sans Serif font </li>
+       <li>How to implement the ellipsis (...) for text strings which are too long to show </li>
+       <li>How to deal with international dates, times, and numbers - but only a little bit </li>
+       <li>How to launch applications and/or documents - using ShellExecute()</li> 
+       <li>How to make a modal dialog main window deal with menus and accelerators</li>
+</ul>
+
+<p><b>How to use it</b>: This sample application is also separately distributed
+as freeware, and includes more of the standard features you would expect
+than the other sample applications in this library. Using CatFish is simple:
+set up one or more catalog files (which will be stored in the same directory
+as the executable) and start browsing by clicking on the various lists
+in the main window. To descend into a subdirectory, double-click on its
+name. To go back, double-click on one of the parent directory names. </p>
+
+<p>To search for a file, you can use the Edit / Find menu entry or use
+keyboard shortcuts, such as CTRL+F (find), F3 (find next), SHIFT+F3 (find
+previous).</p>
+
+<p>If you want to use FtpCat in combination with CatFish, make sure that
+you give all catalog files the extension &quot;.cf4&quot; and that you
+place them in the same directory as the CatFish utility itself. That's
+all. </p>
+
+<p><b>Known problems</b>: None.</p>
+
+<p><b>Files in EXAMPLES\CATFISH</b>: </p>
+
+<p>CATFISH.H, CATFISH.CPP - Main MFC application code 
+<br>CATFISH.MAK - MSVC 1.52 project makefile for Win16 
+<br>CATFISH.DEF, CATFISH.RC - Linker definitions, Application resources
+
+<br>PICKDIR.H, PICKDIR.CPP - Directory picker 
+<br>RESOURCE.H - Resource symbol definitions 
+<br>SCANDISK.H, SCANDISK.CPP - Creates a disk catalog object using Metakit
+
+<br>SETUPDLG.H, SETUPDLG.CPP - Setup dialog 
+<br>STDAFX.H, STDAFX.CPP - Used for precompiled headers 
+<br>RES\*.* - Application resources </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_catrecv.html b/8.x/mk/doc/api/doc_catrecv.html
new file mode 100644 (file)
index 0000000..da129fe
--- /dev/null
@@ -0,0 +1,81 @@
+<html><head>
+       <title>Metakit sample code - CatRecv</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - CatRecv</h2><br clear=left>
+
+<p>This application is a simple TCP/IP server based on Winsock. </p>
+
+<p><b>What it does</b>: When CatRecv is started, is enters a loop waiting
+for the CatSend client application to connect. Each new connection sets
+up its own window to displays the contents of a catalog tree sent by CatSend.
+You can examine the catalog tree and verify that it actually contains what
+the DisCat sample program previously saved on file. </p>
+
+<p><b>What it illustrates</b>: CatRecv is pretty neat. Apart from illustrating
+how to transfer a complex Metakit data structure over a network connection,
+it shows off the new tree and list controls now available in Windows 95
+with MFC 4.2, and it demonstrates how to design a little TCP/IP network
+server. The catalog window uses an Explorer-like tree interface to allow
+you to easily examine a catalog tree structure, and it didn't even take
+a lot of work to create it in C++. Since this is mainly intended as a demonstration
+of the use of Metakit, some more fancy user-interface features, such as
+sortable file lists and splitter views were not included, although this
+is probably quite easy to add. </p>
+
+<p><b>How to use it</b>: As it is, CatRecv only makes sense in combination
+with CatSend and DisCat. To try it out, you should first create a catalog
+file with DisCat which you can then pick up with CatSend. Note that like
+any typical client-server application, the CatRecv server application must
+be running before using CatSend to open a connection. Whenever a new connection
+is opened and a catalog object is received, CatRecv will open a new window
+with the contents of that catalog. </p>
+
+<p>This sample application uses a fixed TCP/IP port for its communication,
+but you can change the default port number to any value you like in the
+opening dialog. Just make sure to use the same port number in CatRecv,
+or you won't be able to connect. </p>
+
+<p><b>Known problems</b>: None, but since CatRecv uses both the new Windows
+common controls and Winsock, you can only run this application on Windows
+95, and you need to have a correctly installed version of the TCP/IP protocol
+stack (such as the one that comes with Windows 95 itself). </p>
+
+<p>You do not need an active network connection or any network hardware,
+since every TCP/IP installation can select local communication by using
+&quot;localhost&quot; as a host name (i.e. IP address 127.0.0.1). If you
+obtained this package from Internet via FTP, then you should be all set,
+since FTP access implies that you have a properly working TCP/IP configuration.
+</p>
+
+<p><b>Files in EXAMPLES\CATRECV</b>: </p>
+
+<p>CATRECV.H, CATRECV.CPP - Main MFC application code 
+<br>CATRECV.MAK, CATRECV.MDP - MSVC 4.2 project makefiles for Win32 
+<br>CATRECV.RC - Application resources 
+<br>MYDLG.H, MYDLG.CPP - Opening dialog 
+<br>RESOURCE.H - Resource symbol definitions 
+<br>STDAFX.H, STDAFX.CPP - Used for precompiled headers 
+<br>TREEDLG.H, TREEDLG.CPP - Contains the interesting pieces of this application
+
+<br>RES\*.* - Application resources </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_catsend.html b/8.x/mk/doc/api/doc_catsend.html
new file mode 100644 (file)
index 0000000..c66e9cc
--- /dev/null
@@ -0,0 +1,70 @@
+<html><head>
+       <title>Metakit sample code - CatSend</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - CatSend</h2><br clear=left>
+
+<p>This application is a simple TCP/IP client based on Winsock. </p>
+
+<p><b>What it does</b>: CatSend allows you to select a datafile and to
+transmit its contents over a TCP/IP connection. Although CatSend can handle
+any Metakit datafile, only the catalog files created by DisCat will make
+sense to the receiving program called &quot;CatRecv&quot; (see below).
+By altering the address shown on the screen, you can transfer the data
+across the network to any other machine on Internet running CatRecv...
+this is only a demonstration of what can be done, this serves no useful
+purpose whatsoever. </p>
+
+<p><b>What it illustrates</b>: CatSend illustrates how to work with Metakit
+datafiles of which the structure is unknown or only partially known. Since
+CatSend doesn't care, this program will continue to work even if DisCat
+and CatRecv are modified to use a different data structure on file. </p>
+
+<p><b>How to use it</b>: CatSend only makes sense in combination with Catrecv
+and DisCat. To try it out, you should first create a catalog file with
+DisCat which you can then pick up with CatSend. Note that like any typical
+client-server application, the CatRecv server application must be running
+before using CatSend to open a connection. Apart from selecting a datafile
+and transmitting it to CatRecv, the CatSend application is pretty boring.
+The &quot;interesting&quot; source code is less than 10 lines long... </p>
+
+<p><b>Known problems</b>: None, but since CatSend uses Winsock, you need
+to have a correctly installed version of the TCP/IP protocol stack (such
+as the one that comes with Windows 95). </p>
+
+<p>You do not need an active network connection or any network hardware,
+since every TCP/IP installation can select local communication by using
+&quot;localhost&quot; as a host name (i.e. IP address 127.0.0.1). If you
+obtained this package from Internet via FTP, then you should be all set,
+since FTP access implies that you have a properly working TCP/IP configuration.
+</p>
+
+<p><b>Files in EXAMPLES\CATSEND</b>: </p>
+
+<p>CATSEND.H, CATSEND.CPP - Main MFC application code 
+<br>CATSEND.MAK, CATSEND.MDP - MSVC 4.2 project makefiles for Win32 
+<br>CATSEND.RC - Application resources 
+<br>MYDLG.H, MYDLG.CPP - Main dialog 
+<br>RESOURCE.H - Resource symbol definitions 
+<br>STDAFX.H, STDAFX.CPP - Used for precompiled headers 
+<br>RES\*.* - Application resources </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_dbf2mk.html b/8.x/mk/doc/api/doc_dbf2mk.html
new file mode 100644 (file)
index 0000000..778329f
--- /dev/null
@@ -0,0 +1,44 @@
+<html><head>
+       <title>Metakit sample code - Dump</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - Dbf2mk</h2><br clear=left>
+
+<p>This is a generic utility for the Metakit library. </p>
+
+<p><b>What it does</b>: Dbf2mk is a utility program which reads data from one
+or more industry-standard DBF files and saves the data in a Metakit datafile. </p>
+
+<p><b>What it illustrates</b>: ***TBD*** </p>
+
+<p><b>How to use it</b>: ***TBD***.
+</p>
+
+<p><b>Known problems</b>: None.  This utility has not yet been extensively
+tested. This version can handle files of any size, but it does not load
+DBase "memo" fields and ignores all index files and calculated fields.</p>
+
+<p><b>Files in EXAMPLES\DBF2MK</b>: </p>
+
+<p>DBF2MK.CPP - Dbf2mk main program 
+<br>DBF2MK.MAK, DBF2MK.DSP - MSVC 5.0 project makefiles for Win32 </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_demo.html b/8.x/mk/doc/api/doc_demo.html
new file mode 100644 (file)
index 0000000..4d78dc5
--- /dev/null
@@ -0,0 +1,56 @@
+<html><head>
+       <title>Metakit sample code - Demo</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - Demo</h2><br clear=left>
+
+<p>This example is more a "proof of concept" than anything else... </p>
+
+<p><b>What it does</b>: Demo creates a simple view on disk, makes a few
+changes to the data as well as the structure, and then saves these too.
+</p>
+
+<p><b>What it illustrates</b>: This sample program shows how to set up
+a simple program which uses Metakit. The source code of this
+application can be compiled for 32-bit Windows (as console application)
+as well as for 16-bit small-model DOS targets. When run more than once, i.e. with an existing
+datafile, this program will cause some changes to the data which illustrate
+the effects of "on-the-fly data restrcuturing".
+Demo has little practical use, other than to show you
+how to get started with Metakit. </p>
+
+<p><b>How to use it</b>: When you launch the 16-bit DOS version called DEMO16.EXE, 
+it creates a datafile called "myfile.dat", saves some
+data to it, and then reopens it and displays the line:
+<pre>     The country of Paco Pena is: Spain </pre>
+
+By following the code, you can see where this came from.  You can use the Metakit
+dump utility (see below) to examine the contents of the data file.
+
+<p><b>Known problems</b>: None.</p>
+
+<p><b>Files in EXAMPLES\DEMO</b>: </p>
+
+<p>DEMO.CPP - Demo main program 
+<br>DEMO.MAK, DEMO.MDP - MSVC 4.2 project makefiles for Win32 
+<br>DEMO16.MAK - MSVC 1.52 project makefile
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_discat.html b/8.x/mk/doc/api/doc_discat.html
new file mode 100644 (file)
index 0000000..6ed2ccb
--- /dev/null
@@ -0,0 +1,78 @@
+<html><head>
+       <title>Metakit sample code - DisCat</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - DisCat</h2><br clear=left>
+
+<p>This application is a good starting point to learn about Metakit. </p>
+
+<p><b>What it does</b>: DisCat is a very simple disk catalog application.
+It recursively scans a directory tree on your hard disk and creates a data
+file with information about all files and subdirectories it finds during
+that scan. The total number of directories scanned is reported on the screen.
+</p>
+
+<p><b>What it illustrates</b>: This sample program shows how to set up
+a simple MFC-based application which uses Metakit. The source code of this
+application can be compiled for 32-bit Windows as well as for 16-bit Windows
+targets. DisCat has no practical use, other than to generate a not-quite-trivial
+datafile using the Metakit library. </p>
+
+<p><b>How to use it</b>: When you launch DISCAT.EXE (or the 16-bit version,
+which is called DISCAT16.EXE), you will see a dialog box with an edit box
+where you can enter a path name. After pressing the &quot;Scan&quot; button,
+the selected directory and all of its subdirectories will be traversed.
+Then you are asked to choose a name for the datafile which is to be used
+for storing the results. Apart from seeing confirmation in the form of
+a directory count, this application is rather boring... </p>
+
+<p><b>Known problems</b>: None, but you need to make sure that your system
+meets the requirements of either DISCAT.EXE or DISCAT16.EXE. </p>
+
+<p>The DISCAT.EXE application is a 32-bit application which requires Windows
+95 (or Windows NT, or Win32s, but neither of those two has been tried).
+In addition, you need to have two of the DLLs which come with Microsoft
+Visual C++ version 4.2: MFC42.DLL and MSVCRT.DLL (these contain the MFC
+library, and the runtime library, respectively). </p>
+
+<p>Alternately, you can use DISCAT16.EXE, which runs on either Windows
+95 or Windows 3.1(1). This application requires the file MFC250.DLL in
+the system directory (usually C:\WINDOWS\SYSTEM) to start properly. </p>
+
+<p>These DLL requirements are caused by the fact that the sample programs
+and the Metakit libraries are distributed in the smallest possible format,
+which happens to be as MFC extension DLLs. As a result, you need to supply
+the MFC libraries yourself. Considering the fact that Metakit is currently
+only useful in combination with MFC, this should not be a problem. </p>
+
+<p><b>Files in EXAMPLES\DISCAT</b>: </p>
+
+<p>CATALOG.H, CATALOG.CPP - Creates a disk catalog object using Metakit
+
+<br>DISCAT.H, DISCAT.CPP - Main MFC application code 
+<br>DISCAT.MAK, DISCAT.MDP - MSVC 4.2 project makefiles for Win32 
+<br>DISCAT.DEF, DISCAT.RC - Linker definitions, Application resources 
+<br>DISCAT16.MAK - MSVC 1.52 project makefile for Win16 
+<br>RESOURCE.H - Resource symbol definitions 
+<br>STDAFX.H, STDAFX.CPP - Used for precompiled headers 
+<br>RES\*.* - Application resources </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_dump.html b/8.x/mk/doc/api/doc_dump.html
new file mode 100644 (file)
index 0000000..e0be691
--- /dev/null
@@ -0,0 +1,71 @@
+<html><head>
+       <title>Metakit sample code - Dump</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - Dump</h2><br clear=left>
+
+<p>This application is a generic utility for the Metakit library. </p>
+
+<p><b>What it does</b>: Dump is a utility program which displays the contents
+of a Metakit datafile on standard output. The output shows all the information
+which is stored in the datafile, which can be quite useful while developing
+and debugging applications based on Metakit. </p>
+
+<p><b>What it illustrates</b>: Dump is a so-called &quot;32-bit console
+application&quot;, this is the modern version of the classical MS-DOS command-line
+executables. It shows how you can extract structural information from a
+Metakit datafile without knowing anything about it. The basic trick is
+to simply open the file, and then to step through each of the properties
+(using the members NumProperties and NthProperty). The executable file
+is tiny, because both Metakit and MFC have been linked as DLLs. </p>
+
+<p><b>How to use it</b>: To dump a datafile, you can start DUMP.EXE from
+the MS-DOS prompt with the filename as argument (or drop a file on it in
+the Explorer). Since datafiles can store arbitrarily nested data structures,
+you may need to examine the output to understand how the information is
+presented on standard output. Dump adds quite a bit of detail to guide
+you (including all the property names). Basically, the data structure is
+traversed recursively, with indentation added to reflect the current nesting
+level. There are a number of command-line options to modify the default
+output style: </p>
+
+<ul>
+<dl>
+       <dt><b>-s</b> </dt> <dd>List all tables and subtable, but omit the actual data values. </dd>
+       <dt><b>-d</b> </dt> <dd>List all tables and subtables, including a low-level data dump. </dd>
+       <dt><b>-f </b></dt> <dd>Only list all the fields (properties) and their structure. </dd>
+       <dt><b>-w</b> </dt> <dd>Wait for the RETURN key just before exiting. </dd>
+</dl>
+</ul>
+
+<p>You can redirect the output to file, just like any other console application.
+</p>
+
+<p><b>Known problems</b>: None. Note that this is a 32-bit application
+which requires Windows 95 (or perhaps Windows NT or Win32s), and that the
+Metakit DLLs are used. </p>
+
+<p><b>Files in EXAMPLES\DUMP</b>: </p>
+
+<p>DUMP.CPP - Dump main program 
+<br>DUMP.MAK, DUMP.MDP - MSVC 4.2 project makefiles for Win32 </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_ftpcat.html b/8.x/mk/doc/api/doc_ftpcat.html
new file mode 100644 (file)
index 0000000..0c0f7fe
--- /dev/null
@@ -0,0 +1,77 @@
+<html><head>
+       <title>Metakit sample code - FtpCat</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - FtpCat</h2><br clear=left>
+
+<p>This tiny application does not illustrate any new aspects fo Metakit,
+but it may be useful in its own right, especially with the CatFish application
+described hereafter. </p>
+
+<p><b>What it does</b>: FtpCat creates a catalog file of a directory tree,
+just like DisCat. In this case, however the directory listings are obtained
+from an FTP server anywhere on the network. Since FtpCat has no browse
+facility, you will have to use CatSend &amp; CatrRecv (or Dump) to examine
+the contents of the resulting catalog. </p>
+
+<p><b>What it illustrates</b>: FtpCat is a 32-bit console application,
+which is dynamically linked to both Metakit and MFC. FtpCat is a bit peculiar,
+in that it uses the FTP.EXE application which is part of Windows 95 to
+take care of all networking (after all, Metakit is not an introduction
+on how to build ftp clients). There are no ftp-related routines, nor even
+any Winsock calls, in FtpCat. There is a fair amount of tricky code in
+here to juggle two pipes which are used to control the child process (ftp.exe).
+</p>
+
+<p><b>How to use it</b>: FtpCat is very simple to use: simply call it with
+an URL as argument, and it will open an ftp connection and retrieve the
+listings of the specified directory and all its subdirectories. If you
+do not supply a second parameter, the catalog will be stored in a file
+called &quot;ftpcat.dat&quot;. As with DisCat, you can then use CatSend
+&amp; CatRecv to examine the catalog contents. </p>
+
+<p>If you're connected to Internet, you could try &quot;ftpcat ftp://ftp.winsite.com/pub/pc/win3/programr&quot;
+(this is one the areas where new distributions of the Metakit library are
+posted). The &quot;ftp://&quot; prefix is optional, and you may add a &quot;user:password@&quot;
+prefix to the site to login under a specific name. This allows you to produce
+a catalog of protected areas, for example with &quot;ftpcat user:passwd@mysite.org/mydir&quot;.
+Please be aware of the fact that some sites on internet are huge, and that
+a command such as &quot;ftpcat ftp.winsite.com&quot; which uses &quot;/&quot;
+as default path may take some time to complete, depending on the speed
+of your connection. </p>
+
+<p><b>Known problems</b>: None, but there are some limitations in this
+sample application: </p>
+
+<ol>
+<li>The &quot;site:port&quot; notation is not implemented, you can only
+connect to standard ftp servers. </li>
+
+<li>This version does not commit intermediate results to file. If you cancel
+it, nothing is saved. </li>
+</ol>
+
+<p><b>Files in EXAMPLES\FTPCAT</b>: </p>
+
+<p>FTPCAT.CPP - FtpCat main program 
+<br>FTPCAT.MAK, FTPCAT.MDP - MSVC 4.2 project makefiles for Win32 </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_kbind.html b/8.x/mk/doc/api/doc_kbind.html
new file mode 100644 (file)
index 0000000..03f8356
--- /dev/null
@@ -0,0 +1,86 @@
+<html><head>
+       <title>Metakit sample code - KitBinder</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - KitBinder</h2><br clear=left>
+<p>
+This application is a generic utility for the Metakit library.
+<p>
+<b>What it does</b>: KitBinder is a utility program which converts any
+Metakit datafile into a format suitable for embedding as resources inside
+an excutable program.  The current version supports Win16 and Win32.
+<p>
+<b>What it illustrates</b>: KitBinder further enhances the stand-alone
+nature of Metakit by allowing you to package read-only data as part of
+your application, to simplify deployment and installation.
+Compression is used to further reduce the size of this read-only data,
+the resources can optionally be encoded to protect sensitive data.
+<p>
+<b>How to use it</b>: To use these resources, you must make some very
+simple changes to your code, using the "c4_BoundStorage" class
+which is part of the KitBinder sample code.
+<p>
+Here is some more information from the "kbound.h" file:
+<blockquote><table width=550 cellpadding=10 cellspacing=0 border=1><tr><td>
+    The process of switching to bound data is quite simple:
+<p>
+<ol>
+       <li> Presumably, you have a Metakit datafile with some data in it.
+            Let's assume it is now stored in a file called "try.dat".
+       <li> Create source files for the resource editor (Win32):
+                <u>kbinder try.dat kbtry</u>,
+            or for Win16, use a text format instead:
+                <u>kbinder -t try.dat kbtry</u>.
+       <li> This produces a file called "kbtry.rc", as well as one or more
+            files called "kbtryXXX.res" (or "kbtryXXX.rc" if text format).
+       <li> Add the following line to your application resource file:
+                <u>#include "kbtry.rc"</u>
+       <li> Include the file "kbound.h" to define the c4_BoundStorage class,
+            and include the code which is in "kbound.cpp" in your project.
+       <li> Create your storage object from the class "c4_BoundStorage",
+         ie. change:
+                <u>c4_Storage myStorage ("try.dat", false)</u>;
+            to
+                <u>c4_BoundStorage myStorage</u>;
+       <li> That's it, you now have a read-only copy of "try.dat" bound to
+            your application and no longer need that data file at run time.
+            Everything will continue to work, but you cannot commit changes.
+            You can however call DumpAsRes, or c4_Storage::SaveToStream.
+</ol>
+<p>
+    For the original comments about the compression code, see "kboundw.cpp".
+<p>
+    To use encoding, you need to point c4_BoundStorage::_Encoder to an
+    appropriate function before creating any instances of c4_BoundStorage.
+</td></tr></table></blockquote>
+<p>
+The "kbdump" program is a example based on some code taken from the
+"Dump" utility.  When you run it, it will dump a sample datafile
+(the catalog of the Metakit 1.5 release).  That data was bound using the
+procedure described above, and is embedded in the "kbdump" executable.
+<p>
+<b>Known problems</b>: None.
+<p>
+<b>Files in EXAMPLES\KN\BIND</b>:
+<p>DUMP.CPP - Dump main program 
+<br>DUMP.MAK, DUMP.MDP - MSVC 4.2 project makefiles for Win32
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_mkoptim.html b/8.x/mk/doc/api/doc_mkoptim.html
new file mode 100644 (file)
index 0000000..3c69e01
--- /dev/null
@@ -0,0 +1,44 @@
+<html><head>
+       <title>Metakit sample code - Dump</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - MkOptim</h2><br clear=left>
+
+<p>This a generic utility for the Metakit library. </p>
+
+<p><b>What it does</b>: MkOptim is a utility program which copies data from
+one Metakit file to another.  This has the effect of optimizing the datafile
+(automatic integer sizing and compaction to remove all unused space) and of
+converting old datafile formats to the current one. </p>
+
+<p><b>What it illustrates</b>: ***TBD*** </p>
+
+<p><b>How to use it</b>: ***TBD***.
+</p>
+
+<p><b>Known problems</b>: None.</p>
+
+<p><b>Files in EXAMPLES\MKOPTIM</b>: </p>
+
+<p>MKOPTIM.CPP - MkOptim main program 
+<br>MKOPTIM.MAK, MKOPTIM.DSP - MSVC 5.0 project makefiles for Win32 </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_myio.html b/8.x/mk/doc/api/doc_myio.html
new file mode 100644 (file)
index 0000000..f02adb7
--- /dev/null
@@ -0,0 +1,54 @@
+<html><head>
+       <title>Metakit sample code - MyIO</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - MyIO</h2><br clear=left>
+
+<p>This example demonstrates how to setup low-level datafile encryption with Metakit.</p>
+
+<p><b>What it does</b>: MyIO creates a simple view on disk, and then loads it back in.
+The data on disk is stored in a simple encrypted format.
+</p>
+
+<p><b>What it illustrates</b>: This sample program shows how to customize Metakit
+via its "Strategy" object. <p>Just to show it can be done, MyIO also disables all
+flush calls issued by Metakit.  This slightly reduces the fail-safe properties but
+improves performance with frequent commits on systems which implement caching using
+ "lazy writes" (such as Windows).<p>The source code of this
+application can be compiled for 32-bit Windows (as console application)
+as well as for 16-bit DOS targets. MyIO has no practical use, but it contains a 
+"CEncryptStrategy" class which you can adapt to suit your purposes. </p>
+
+<p><b>How to use it</b>: When you launch MYIO.EXE, it creates a datafile called "secret.dat",
+saves some string data to it, then reads that back and displays these strings.
+<p>Note that due to the encrypted
+storage format you can NOT use the Metakit dump utility to examine the contents of the data file.
+You can of course build your own version of it, since all the necessary source code is included.
+
+<p><b>Known problems</b>: None.</p>
+
+<p><b>Files in EXAMPLES\MYIO</b>: </p>
+
+<p>MYIO.CPP - MyIO main program 
+<br>MYIO.MAK, MYIO.MDP - MSVC 4.2 project makefiles for Win32 
+<br>MYIO16.MAK - MSVC 1.52 project makefile
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/doc_struct.html b/8.x/mk/doc/api/doc_struct.html
new file mode 100644 (file)
index 0000000..e10b0fc
--- /dev/null
@@ -0,0 +1,68 @@
+<html><head>
+       <title>Metakit sample code - Struct</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+
+<!--begin-->
+<h2><img src="e4app.gif" alt="App Icon" border=0 align=left>
+Metakit sample code - Struct</h2><br clear=left>
+
+<p>This application highlights some low-level aspects of the Metakit library.
+</p>
+
+<p><b>What it does</b>: Struct is a little utility which displays the data
+structure of any Metakit datafile on standard output. The output uses a
+text-mode graph to display the data structure, which can be useful to determine
+what information is stored in a specific Metakit datafile. </p>
+
+<p><b>What it illustrates</b>: For demonstration purposes, Struct has been
+compiled as a real-mode small-model MS-DOS utility program. It shows how you can extract
+structural information from a Metakit datafile without knowing anything
+about it. The sample code includes a general &quot;StructureMap&quot; class
+to generate text-based graphs. The size of the STRUCT.EXE program demonstrates
+how small a fully self-contained application using Metakit can be. </p>
+
+<p>Note that although Struct must respect the very severe 64 K memory limit imposed
+by small-model MS-DOS, you can still use this program to examine the structure of files
+of any reasonable size. The reason for this is that Metakit implements on-demand loading,
+and that Struct never accesses the actual data itself.</p>
+
+<p><b>How to use it</b>: To examine the structure of a datafile, simply
+run STRUCT.EXE from the MS-DOS prompt with the filename as argument. There
+are a few command-line options to control the output format, these are
+listed when you start Struct without a filename. They are: </p>
+
+<ul>
+<dl>
+       <dt><b>-d</b> </dt> <dd>Show a linear description instead of the default tree. </dd>
+       <dt><b>-t</b> </dt> <dd>Show a linear description of the structure, omitting the property names.</dd>
+       <dt><b>-c </b></dt> <dd>Show column structure instead of the deafult tree structure (advanced).</dd>
+</dl>
+</ul>
+
+<p>You can redirect the output to file, just as with any other MS-DOS program.
+</p>
+
+<p><b>Known problems</b>: None. </p>
+
+<p><b>Files in EXAMPLES\STRUCT</b>: </p>
+
+<p>STRUCT.CPP - Struct main program 
+<br>STRUCT.MAK - MSVC 1.52 project makefile </p>
+<!--end-->
+
+<center><p><hr size=1>
+||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; ||
+&nbsp; <a href="intro.html">Introduction</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/index.html b/8.x/mk/doc/api/index.html
new file mode 100644 (file)
index 0000000..bab0b45
--- /dev/null
@@ -0,0 +1,8 @@
+<html><head>
+       <title>The Metakit class library for persistent structured data</title>
+</head>
+
+<frameset  cols="*,160">
+       <frame name="k-main" src="roadmap.html">
+       <frame name="k-side" src="navbar.html">
+</frameset>
diff --git a/8.x/mk/doc/api/navbar.html b/8.x/mk/doc/api/navbar.html
new file mode 100644 (file)
index 0000000..a3144d4
--- /dev/null
@@ -0,0 +1,71 @@
+<html><head>
+       <title>Metakit Class Index</title>
+       <base target=k-main>
+</head><body bgcolor=white>
+
+<center>
+<a href="roadmap.html">Roadmap</a>
+<br><a href="classes.html">Class Index</a>
+<br><a href="samples.html">Sample Index</a>
+<br><a href="tips.html">Tips and Tricks</a>
+</center>
+
+<p><hr size=1>
+
+<font face="Helvetica" size=2>
+  
+       <br><a name="c4_Bytes" href="c4_Bytes.html">c4_Bytes</a>
+  
+       <br><a name="c4_BytesProp" href="c4_BytesProp.html">c4_BytesProp</a>
+  
+       <br><a name="c4_BytesRef" href="c4_BytesRef.html">c4_BytesRef</a>
+  
+       <br><a name="c4_Cursor" href="c4_Cursor.html">c4_Cursor</a>
+  
+       <br><a name="c4_CustomViewer" href="c4_CustomViewer.html">c4_CustomViewer</a>
+  
+       <br><a name="c4_DoubleProp" href="c4_DoubleProp.html">c4_DoubleProp</a>
+  
+       <br><a name="c4_DoubleRef" href="c4_DoubleRef.html">c4_DoubleRef</a>
+  
+       <br><a name="c4_FloatProp" href="c4_FloatProp.html">c4_FloatProp</a>
+  
+       <br><a name="c4_FloatRef" href="c4_FloatRef.html">c4_FloatRef</a>
+  
+       <br><a name="c4_IntProp" href="c4_IntProp.html">c4_IntProp</a>
+  
+       <br><a name="c4_IntRef" href="c4_IntRef.html">c4_IntRef</a>
+  
+       <br><a name="c4_MemoProp" href="c4_MemoProp.html">c4_MemoProp</a>
+  
+       <br><a name="c4_MemoRef" href="c4_MemoRef.html">c4_MemoRef</a>
+  
+       <br><a name="c4_Property" href="c4_Property.html">c4_Property</a>
+  
+       <br><a name="c4_Reference" href="c4_Reference.html">c4_Reference</a>
+  
+       <br><a name="c4_Row" href="c4_Row.html">c4_Row</a>
+  
+       <br><a name="c4_RowRef" href="c4_RowRef.html">c4_RowRef</a>
+  
+       <br><a name="c4_Sequence" href="c4_Sequence.html">c4_Sequence</a>
+  
+       <br><a name="c4_Storage" href="c4_Storage.html">c4_Storage</a>
+  
+       <br><a name="c4_Strategy" href="c4_Strategy.html">c4_Strategy</a>
+  
+       <br><a name="c4_Stream" href="c4_Stream.html">c4_Stream</a>
+  
+       <br><a name="c4_StringProp" href="c4_StringProp.html">c4_StringProp</a>
+  
+       <br><a name="c4_StringRef" href="c4_StringRef.html">c4_StringRef</a>
+  
+       <br><a name="c4_View" href="c4_View.html">c4_View</a>
+  
+       <br><a name="c4_ViewProp" href="c4_ViewProp.html">c4_ViewProp</a>
+  
+       <br><a name="c4_ViewRef" href="c4_ViewRef.html">c4_ViewRef</a>
+  
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/roadmap.html b/8.x/mk/doc/api/roadmap.html
new file mode 100644 (file)
index 0000000..f96e5c7
--- /dev/null
@@ -0,0 +1,210 @@
+<HTML><HEAD><TITLE>Metakit 2.0</TITLE></HEAD>
+<BODY  bgcolor="#FFFFFF" alink="#008000" vlink="#800080" link="#0000FF" text="#000000">
+
+<TABLE cellspacing=0 cellpadding=0 border=0 width="100%"><TR valign=top>
+       <TD width=100><A href="http://www.equi4.com/">
+               <IMG src=e4w.gif alt="E q u i 4" align=left width=97 height=35 hspace=0 border=0></A>
+       </TD><TD align=center>
+       <FONT size=+2>Metakit 2.0</FONT><BR>
+       <I>December 1999</I>
+       </TD><TD width=100></TD></Tr></TABLE>
+<P>
+
+
+<DL>
+<DT><H3>About these pages</H3><DD>
+
+As you can see on the right, this Metakit documentation is
+presented using a frames-based "browser" interface, which should make it
+easy to navigate and find specific information
+(<A href=index.html target="_top">click here</A>
+if you don't see the index pane).
+<P>
+
+The <B><A href=classes.html>Class Index</A></B> describes the API of
+all the public classes in Metakit.
+The <B><A href=samples.html>Sample Index</A></B> describes each of the
+samples supplied as part of the evaluation package.
+The <B><A href=tips.html>Tips and Tricks</A></B> section
+goes into issues such as performance and gives more advanced
+background information.
+
+<DT><H3>Class hierarchy</H3><DD>
+
+The following list only mentions the public API classes
+(<B>core classes</B> in bold):
+<P>
+
+<TABLE border=0 cellspacing=0 cellpadding=0>
+       <TR>
+               <TH align=left width=150>
+                       Base class:
+               </TH><TH align=left width=200>
+                       Derived classes:
+               </TH><TH align=left>
+                       Virtual:
+               </TH>
+       </TR>
+       <TR><TD>
+               <A href="c4_Bytes.html">c4_Bytes</A>
+       </TD><TD>-</TD><TD valign=top>No</TD></TR>
+       <TR><TD>
+               <A href="c4_Cursor.html">c4_Cursor</A>
+       </TD><TD>-</TD><TD valign=top>No</TD></TR>
+       <TR><TD>
+               <A href="c4_CustomViewer.html">c4_CustomViewer</A>
+       </TD><TD>-</TD><TD valign=top>Abstract</TD></TR>
+       <TR><TD>
+               <A href="c4_Property.html"><B>c4_Property</B></A>
+       </TD><TD>
+               <A href="c4_IntProp.html">c4_IntProp</A>,
+               <A href="c4_StringProp.html">c4_StringProp</A>, ...
+       </TD><TD valign=top>No</TD></TR>
+       <TR><TD>
+               <A href="c4_Reference.html">c4_Reference</A>
+       </TD><TD>
+               <A href="c4_IntRef.html">c4_IntRef</A>,
+               <A href="c4_StringRef.html">c4_StringRef</A>, ...
+               </TD><TD valign=top>No</TD></TR>
+       <TR><TD>
+               <A href="c4_RowRef.html"><B>c4_RowRef</B></A>
+       </TD><TD>
+               <A href="c4_Row.html">c4_Row</A>
+               </TD><TD valign=top>No</TD></TR>
+       <TR><TD>
+               <A href="c4_Sequence.html">c4_Sequence</A>
+       </TD><TD>-</TD><TD valign=top>Yes</TD></TR>
+       <TR><TD>
+               <A href="c4_Storage.html"><B>c4_Storage</B></A>
+       </TD><TD>-</TD><TD valign=top>No</TD></TR>
+       <TR><TD>
+               <A href="c4_Strategy.html">c4_Strategy</A>
+       </TD><TD>-</TD><TD valign=top>Yes</TD></TR>
+       <TR><TD>
+               <A href="c4_View.html"><B>c4_View</B></A>
+       </TD><TD>-</TD><TD valign=top>No</TD></Tr>
+</TABLE>
+
+<P>
+
+The class documentation was generated using
+[<A href="http://friga.mer.utexas.edu/mark/perl/perceps/" target="_top">Perceps</A>],
+by Mark Peskin.
+
+<DT><H3>Glossary</H3><DD>
+
+<TABLE border=0 cellspacing=0 cellpadding=0>
+<TR>
+       <TH align=left width=100>
+               Term:
+       </TH><TH align=left width=250>
+               Description:
+       </TH><TH align=left>
+               Similar to:
+       </TH>
+</TR>
+<TR>
+       <TD valign=top>
+               Attached
+       </TD><TD valign=top>
+               Managed by storage object
+       </TD><TD valign=top>
+               persistent, on file
+       </TD>
+</TR>
+<TR>
+       <TD valign=top>
+               Cursor
+       </TD><TD valign=top>
+               Position in a view
+       </TD><TD valign=top>
+               pointer, recnum
+       </TD>
+</TR>
+<TR>
+       <TD valign=top>
+               Property
+       </TD><TD valign=top>
+               One data-value in a row
+       </TD><TD valign=top>
+               field, item
+       </TD>
+</TR>
+<TR>
+       <TD valign=top>
+               Row
+       </TD><TD valign=top>
+               Zero or more related data-values
+       </TD><TD valign=top>
+               tuple
+       </TD>
+</TR>
+<TR>
+       <TD valign=top>
+               RowRef
+       </TD><TD valign=top>
+               A row, or an entry in a view
+       </TD><TD valign=top>
+               record, array element
+       </TD>
+</TR>
+<TR>
+       <TD valign=top>
+               Storage
+       </TD><TD valign=top>
+               Maintains a datafile
+       </TD><TD valign=top>
+               database
+       </TD>
+</TR>
+<TR>
+       <TD valign=top>
+               Streaming
+       </TD><TD valign=top>
+               Sequential I/O (no seeks)
+       </TD><TD valign=top>
+               flattening, serializing
+       </TD>
+</TR>
+<TR>
+       <TD valign=top>
+               View
+       </TD><TD valign=top>
+               An indexable collection of rows
+       </TD><TD valign=top>
+               table, vector
+       </TD>
+</Tr>
+</TABLE>
+
+<DT><H3>Where to find the latest news</H3><DD>
+
+The "official" <B>Metakit Homepage</B> is at: &nbsp;
+[<A href="http://www.equi4.com/metakit/" target="_top"><A href="http://www.equi4.com/metakit/">http://www.equi4.com/metakit/</A></a>]
+<BR>You can subscribe to topics in the <B>Support Forum</B> to
+be notified by email.
+
+<DT><H3>Technical support</H3><DD>
+
+Metakit is actively supported by its designer (yours truly).  
+If you run into unexpected problems with this library please get in touch.
+
+</DL>
+<P>
+-- Jean-Claude Wippler &lt;<A href="mailto:jcw@equi4.com"><A href="mailto:jcw@equi4.com">jcw@equi4.com</A></a>&gt;
+</font>
+<P>
+<HR size=1>
+<CENTER>
+&nbsp; <A href="index.html" target="_top">Roadmap</A>
+&nbsp; <A href="classes.html">Class Index</A>
+&nbsp; <A href="samples.html">Sample Index</A>
+&nbsp; <A href="tips.html">Tips and Tricks</A>
+</CENTER>
+
+
+<HR size=1>
+<FONT color="#000099" size=-1>&copy; 1999 Equi4 Software. All rights reserved.</FONT>
+
+</BODY>
+</HTML>
diff --git a/8.x/mk/doc/api/samples.html b/8.x/mk/doc/api/samples.html
new file mode 100644 (file)
index 0000000..51dd16a
--- /dev/null
@@ -0,0 +1,115 @@
+<html><head>
+       <title>Metakit Sample Index</title>
+</head><body bgcolor=white>
+
+<font face=Helvetica size=3>
+<table cellspacing=0 cellpadding=0 border=0 width="100%"><tr valign=top>
+       <td width=100><a href="http://www.equi4.com/">
+               <img src=e4w.gif alt="E q u i 4" align=left width=97 height=35 hspace=0 border=0></a>
+       </td><td align=center>
+       <font size=+2>Metakit Sample Index</font><br>
+       <i>December 1999</i>
+       </td><td width=100></td></tr></table>
+<p>
+<center>
+<!--begin-->
+<table border=0>
+       <tr>
+         <td valign=top><a href="doc_catfish.html"><b>CatFish</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>A complete disk catalog browser</b>
+         <br>Full source code of a complete Windows/MFC utility.
+         <br>Compiler: MSVC w/MFC (Win16)</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_catrecv.html"><b>CatRecv</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Receive and display a catalog tree over TCP/IP</b>
+         <br>How to load structured data from a network connection.
+         <br>Compiler: MSVC w/MFC (Win32), uses WinSock</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_catsend.html"><b>CatSend</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Send a catalog tree (or anything else) over TCP/IP</b>
+         <br>How to manipulate and send datafiles, regardless of contents.
+         <br>Compiler: MSVC w/MFC (Win32), uses WinSock</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_dbf2mk.html"><b>Dbf2mk</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Generic file converter for DBF/Xbase files</b>
+         <br>This utility illustrates how to set up a custom viewer.
+         <br>Compiler: MSVC w/MFC (Win32)</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_demo.html"><b>Demo</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>A very small example of how to use Metakit</b>
+         <br>Illustrates how to get started with Metakit.
+         <br>Compiler: DOS, Win, Mac, Unix</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_discat.html"><b>DisCat</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Scan a disk directory tree and save a catalog</b>
+         <br>Another simple disk scanner, to feed the other sample programs.
+         <br>Compiler: MSVC w/MFC (Win16 or Win32)</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_dump.html"><b>Dump</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>A very simple generic data dump utility</b>
+         <br>Can be used as debugging utility and to inspect any datafile.
+         <br>Compiler: DOS, Win, Mac, Unix</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_ftpcat.html"><b>FtpCat</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Scan an FTP site and save a catalog</b>
+         <br>Catalogs can be created in many ways, this utility works with FTP.
+         <br>Compiler: MSVC (Win32)</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_kbind.html"><b>KitBinder</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Embed ("bind") a datafile into an executable</b>
+         <br>Use Metakit as structured / platform-independent resource manager.
+         <br>Compiler: MSVC w/MFC (Win16 or Win32)</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_mkoptim.html"><b>MkOptim</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Metakit datafile optimizer</b>
+         <br>Convert datafiles to their latest and most compact format.
+         <br>Compiler: Win32, Mac, Unix</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_myio.html"><b>MyIO</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Custom strategy class, demonstrates encrypted storage</b>
+         <br>An example how to intercept all I/O for encrypted storage.
+         <br>Compiler: DOS, Win, Mac, Unix</td>
+       </tr>
+       <tr>
+         <td valign=top><a href="doc_struct.html"><b>Struct</b></a></td>
+         <td width=10></td>
+         <td><font face=Times><b>Display datafile structure (MS-DOS executable)</b>
+         <br>The core is small enough to build a "small-model" MS-DOS program.
+         <br>Compiler: DOS, Win, Mac, Unix</td>
+       </tr>
+</table>
+<!--end-->
+
+<p><hr size=1>
+&nbsp; ||
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+&nbsp; || 
+
+</center>
+</font>
+
+</body></html>
diff --git a/8.x/mk/doc/api/tips.html b/8.x/mk/doc/api/tips.html
new file mode 100644 (file)
index 0000000..c7dd7b7
--- /dev/null
@@ -0,0 +1,272 @@
+<html>
+<head>
+<title>Metakit Tips and Tricks</title>
+<meta name="generator" content="Frontier 5.0.1 Win95"></head>
+<body  bgcolor="#FFFFFF" alink="#008000" vlink="#800080" link="#0000FF" text="#000000">
+
+<table cellspacing=0 cellpadding=0 border=0 width="100%"><tr valign=top>
+       <td width=100><a href="http://www.equi4.com/">
+               <img src=e4w.gif alt="E q u i 4" align=left width=97 height=35 hspace=0 border=0></a>
+       </td><td align=center>
+       <font size=+2>Metakit Tips and Tricks</font><br>
+       <i>December 1999</i>
+       </td><td width=100></td></tr></table>
+<p>
+
+
+<i>This page list some ideas and background information
+related to the use of Metakit.
+If you have suggestions, please send them to <a href="mailto:jcw@equi4.com">jcw@equi4.com</a> ...</i>
+<br><br>
+
+<table border=0>
+       <tr>
+         <td valign=top align=center><a href="#streaming"><b>Streaming</b></a></td>
+         <td width=10></td>
+         <td>Some details about streaming and on-demand loading</td>
+       </tr>
+       <tr>
+         <td valign=top align=center><a href="#faster"><b>Faster</b></a></td>
+         <td width=10></td>
+         <td>What to do and what to avoid for maximum speed</td>
+       </tr>
+       <tr>
+         <td valign=top align=center><a href="#smaller"><b>Smaller</b></a></td>
+         <td width=10></td>
+         <td>How to manage data in the most compact format</td>
+       </tr>
+</table>
+</center>
+
+
+<dl>
+<dt><br><hr size=1><br><a name=streaming></a><b>Streaming</b> - 
+Some details about streaming and on-demand loading<p><dd><font face=Times>
+
+When saving data, Metakit uses different formats, depending on whether
+the data was saved with c4_Storage::Commit or with c4_Storage::SaveToStream.
+This has a number of consequences on how and when data is loaded back in:
+
+<blockquote><table cellpadding=5 cellspacing=0 border=1>
+       <tr>
+         <th>&nbsp; Saved using &nbsp;</th>
+         <th>&nbsp; Loaded as &nbsp;</th>
+         <th align=left>&nbsp; Comments &nbsp;</th>
+       </tr>
+       <tr>
+         <td align=center>
+               Commit<br>
+               Commit<br>
+               SaveToStream<br>
+               SaveToStream</td>
+         <td align=center>
+               File<br>
+               Stream<br>
+               File<br>
+               Stream</td>
+         <td>
+               The normal case, loads data on-demand<br>
+               This combination is <b>not</b> allowed!<br>
+               Ok, will load all data during open<br>
+               Loads all data serially right away</td>
+       </tr>
+</table></blockquote>
+
+As you can see in this overview, random-access and streaming can be mixed
+in three out of four ways.  Once loaded, you can again save using either
+c4_Storage::Commit or c4_Storage::SaveToStream.
+<p>
+When random-access and streaming are mixed on a storage object, the
+following will happen:<p>
+<ul><li>Files are only modified (conceptually) during a call to c4_Storage::Commit.
+<li>c4_Storage::SaveToStream makes a snapshot of the current (uncommitted) state.
+</ul><p>
+It is therefore possible to open a file, apply a few changes, save the
+changed contents to a stream, and then close the file without committing
+those changes.  Streaming does not interfere with the commit/rollback mechanism.
+
+</font><br>
+<dt><br><hr size=1><br><a name=faster></a><b>Faster</b> - 
+What to do and what to avoid for maximum speed<p><dd><font face=Times>
+
+The data structures used in Metakit can have surprising effects on performance,
+both positively and negatively.
+Here are a few suggestions which should help in most cases:
+<p>
+<li><b>Preallocate rows</b> - if the number or rows to add is known in advance,
+use c4_View::SetSize to set the view size accordingly.  Fixed-size properties
+will need to do fewer internal reallocations if pre-allocated.
+<p>
+When inserting several rows, consider inserting them all with a dummy value
+first, and then using a loop to adjust each of the inserted values.
+<p>
+<li><b>Limit the use of c4_Row objects</b> - The construction of c4_Row objects is
+relatively slow, and can often easily be avoided.  Here are three ways to
+accomplish the same thing:
+
+<blockquote><table cellpadding=5 cellspacing=0 border=1>
+       <tr>
+         <th>Slow</th>
+         <td>
+               for (int i = 0; i < n; ++i)<br>
+               {<br>
+               &nbsp; &nbsp; c4_Row temp;<br>
+               &nbsp; &nbsp; property (temp) = ...;<br>
+               &nbsp; &nbsp; view[i] = temp;<br>
+               }
+         </td>
+       </tr>
+       <tr>
+         <th>Faster</th>
+         <td>
+               c4_Row temp;<br>
+               for (int i = 0; i < n; ++i)<br>
+               {<br>
+               &nbsp; &nbsp; property (temp) = ...;<br>
+               &nbsp; &nbsp; view[i] = temp;<br>
+               }
+         </td>
+       </tr>
+       <tr>
+         <th>Fastest</th>
+         <td>
+               for (int i = 0; i < n; ++i)<br>
+               {<br>
+               &nbsp; &nbsp; c4_RowRef row = view[i];<br>
+               &nbsp; &nbsp; property (row) = ...;<br>
+               }
+         </td>
+       </tr>
+</table></blockquote>
+
+The last two statements could also have been combined as "property (view[i]) = ...;"
+<p>
+Note that "prop1 [value1] + prop2 [value2]" also creates several temporary
+c4_Row objects, and should be avoided when top performance is critical.
+<p>
+<li><b>Remove views before storage objects are destroyed</b> - If a view
+still exists when its underlying storage object is destroyed, Metakit has to 
+create a full copy of the data in memory before releasing the storage object,
+to avoid even more confusing side-effects.
+
+The following example illustrates a common source of suprises in Metakit:
+
+<blockquote><table cellpadding=5 cellspacing=0 border=1>
+       <tr>
+         <th>Very slow<br>(on close)</th>
+         <td>
+               {<br>
+               &nbsp; &nbsp; c4_View view;<br>
+               &nbsp; &nbsp; c4_Storage storage (...);<br>
+               &nbsp; &nbsp; view = storage.View(...);<br>
+               &nbsp; &nbsp; ...<br>
+               }
+         </td>
+       </tr>
+       <tr>
+         <th>Instant</th>
+         <td>
+               {<br>
+               &nbsp; &nbsp; c4_Storage storage (...);<br>
+               &nbsp; &nbsp; c4_View view = storage.View(...);<br>
+               &nbsp; &nbsp; ...<br>
+               }
+         </td>
+       </tr>
+</table></blockquote>
+
+In the first case, the view still exists as the storage object goes out of scope.
+There is a simple way to detach views from their storage objects, since they
+act merely as (reference-counted) pointers: just set "view = c4_View ();"
+<b>before</b> the storage object is destroyed.
+
+</font><br>
+<dt><br><hr size=1><br><a name=smaller></a><b>Smaller</b> - 
+How to manage data in the most compact format<p><dd><font face=Times>
+
+Metakit implements automatic "adaptive integer sizing" and will often create
+very compact data files as a result.  Strings and binary properties also use a
+variable format, and require no "field width" setting.  Some tips to
+allow you to make optimal use of these features:
+<p>
+<li><b>Attached views are more compact</b> - You can trade off size versus
+speed by selecting either views attached to a storage object (smallest), or
+unattached views (fastest).  Note that "storage" does not imply the need to
+store data on file in this context.  It is perfectly valid to use the following
+code to manage temporary data in memory without ever saving it to file:
+
+<blockquote><table cellpadding=5 cellspacing=0 border=1>
+       <tr>
+         <td>
+               c4_Storage storage;<br>
+               c4_View view = storage.GetAt("temp[prop1:I,prop2:I]");<br>
+               ...<br>
+               prop1 (view[i]) = ...;<br>
+               ...
+         </td>
+       </tr>
+</table></blockquote>
+
+In this example, the view would use "adaptive integer sizing" even though
+its data is valid only for the duration of each run.
+Unattached views always use 32 bits to store integers.
+<p>
+<li><b>Integer formats only increase in size</b> - The representation used to
+store integers in attached views (and on file)
+ is based on the largest value (in magnitude) ever stored in
+each property and view.  Storing large values in one subview will not affect
+the storage used by that same property in another subview.
+<p>
+For integers, the number of bits used to store values is determined as follows:
+
+<blockquote><table cellpadding=5 cellspacing=0 border=1>
+       <tr>
+         <th>&nbsp; Value range &nbsp;</th>
+         <th>&nbsp; Bits used &nbsp;</th>
+         <th align=left>&nbsp; Comments &nbsp;</th>
+       </tr>
+       <tr>
+         <td align=center>
+               0<br>
+               0 .. 1<br>
+               0 .. 3<br>
+               0 .. 15<br>
+               -128 .. 127<br>
+               -32768 .. 32727<br>
+               all others</td>
+         <td align=center>
+               0<br>
+               1<br>
+               2<br>
+               4<br>
+               8<br>
+               16<br>
+               32</td>
+         <td>
+               If all rows are 0, <b>no</b> storage space is used<br>
+               Booleans are stored as 8 rows per byte<br>
+               Tiny positive codes<br>
+               A hex nibble<br>
+               One byte<br>
+               A short integer<br>
+               A long integer</td>
+       </tr>
+</table></blockquote>
+
+</font><br>
+</dl>
+
+<hr size=1>
+<center>
+&nbsp; <a href="index.html" target="_top">Roadmap</a>
+&nbsp; <a href="classes.html">Class Index</a>
+&nbsp; <a href="samples.html">Sample Index</a>
+&nbsp; <a href="tips.html">Tips and Tricks</a>
+</center>
+
+
+<hr size=1>
+<font color="#000099" size=-1>&copy; 1998 Equi4 Software. All rights reserved.</font>
+
+</body>
+</html>
diff --git a/8.x/mk/doc/e4s.gif b/8.x/mk/doc/e4s.gif
new file mode 100755 (executable)
index 0000000..d387154
Binary files /dev/null and b/8.x/mk/doc/e4s.gif differ
diff --git a/8.x/mk/doc/format.html b/8.x/mk/doc/format.html
new file mode 100755 (executable)
index 0000000..b1c8596
--- /dev/null
@@ -0,0 +1,457 @@
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="Jean-Claude Wippler">
+   <title>An overview of the Metakit data format</title>
+</head>
+<body>
+
+<A HREF="http://www.equi4.com/"><IMG SRC="e4s.gif" vspace=3 WIDTH="97" HEIGHT="35" BORDER=0 align=right></A>
+<br clear=both><center>
+<h2>
+An overview of the Metakit data format</h2></center>
+
+<center><i>Jean-Claude Wippler</i>
+<br><i>Equi4 Software</i>
+<br><i>December 1999</i>
+<br>&nbsp;
+<br>&nbsp;</center>
+
+<b>INTRODUCTION</b>
+<p>Metakit is an efficient, small-footprint, robust, and platform-independent
+database library.&nbsp; The name "Metakit" is used as name for the file
+format, as well as for the implementation (coded in C++, with interfaces
+to Python and Tcl).&nbsp; Metakit 2.0 is freely available as open source, 
+with optional commercial support through my company, Equi4 Software.
+<p>This document describes some of the main elements of the design of the
+file format used in release 2.0 of Metakit - which
+reads all prior formats back to the 1.0 release of March 1996.
+<p>For general information about Metakit, you are kindly referred to information
+on the world wide web - the Metakit home page is at <a href="http://www.equi4.com/metakit/">http://www.equi4.com/metakit/</a>.
+For the purpose of this document, here is a summary with the capabilities
+of Metakit which most affect the design of the file format.
+<ul>
+<li>
+Data is stored in native format, reversed endian-ness is detected and dealt
+with on other platforms</li>
+
+<li>
+Transaction/commit uses "Stable Storage" techniques, with automatic rollback
+after catastrophic failure</li>
+
+<li>
+Data can be loaded on demand, or serialized for transport over any communication
+channel</li>
+
+<li>
+Integers use "adaptive sizing" to store each value in 1..32 bits, automatically
+adjusted to match the range</li>
+
+<li>
+Other formats include: 0-byte terminated strings, binary data (2 formats),
+and 4/8-byte IEEE floating point</li>
+
+<li>
+Multiple relational ("flat") and hierarchically structured datasets can
+be stored in a single file</li>
+
+<li>
+Datafiles are self-descriptive, generic utilities can be used to inspect
+and manipulate any Metakit datafile</li>
+
+<li>
+Metakit supports instant on-the-fly datafile restructuring, with full commit/rollback
+capability</li>
+</ul>
+Metakit is being used by hundreds of developers, in products ranging from
+custom-made client-server applications, software utilities, website databases,
+numerical/statistical data-storage, groupware, development tools, to financial
+applications such as POS and home banking.  It can be embedded into the
+application, requiring no installation - or used as a shared library (DLL).
+<br>&nbsp;
+<p><b>BASIC DATA STRUCTURE</b>
+<p>To describe the format used for the datafiles, it is necessary to introduce
+some terminology and to describe how data is organized.&nbsp; What Metakit
+does, is present a more or less relational perspective on data storage.
+<ul>
+<li>
+Data is stored in tabular format, called a <i><b>view</b>.</i></li>
+
+<li>
+Views consist of zero or more <b><i>rows</i></b> of information.</li>
+
+<li>
+Each row consists of one or more <b><i>properties</i></b> containing one
+data item.</li>
+
+<li>
+Properties can be strings, integers, floating point, binary data, but also
+<b><i>subviews</i></b>.</li>
+</ul>
+The first three of these are equivalent to the relational <i>table, record,
+</i>and
+<i>attribute</i>.&nbsp;
+The fourth makes it possible to store hierarchically structured data (subviews
+are an advanced feature and will not be further described here).
+<p>But the fundamental concept of Metakit, is that all data is stored <i>column-wise</i>.&nbsp;
+A <i>view</i> (table) with 10,000 <i>rows</i> (records), consisting of
+25 <i>properties</i> (attributes), is stored on file as a data structure
+pointing to 25 <i>columns</i> of bytes.&nbsp; Each of these columns may
+well have a different format - depending on their datatype, and each will
+contain 10,000 entries. Each column is stored as a single <i>contiguous</i>
+area on file, which can be reallocated (i.e. moved) to accommodate size
+changes later on.
+<p>This column-based data organization has far-reaching consequences for
+the implementation.&nbsp; For one, the implementation fully hides
+the column-wise structure and present a normal <i>container-like</i> row-wise
+API, which matches the conceptual / relational model.&nbsp; Furthermore,
+a range of techniques has been implemented to offer high performance.
+<br>&nbsp;
+<p><b>FILE FORMAT OVERVIEW</b>
+<p>Once you switch your mind to this column-wise approach, the format of
+Metakit datafiles becomes quite simple to describe:
+<ul>
+<li>
+An 8-byte header</li>
+
+<li>
+A structural definition of all views stored in this file (this is not necessarily
+right after the header)</li>
+
+<li>
+For each view: a row count and a number of &lt;offset,size> pairs, each
+defining a column in the file</li>
+
+<li>
+And - scattered all across the file - the actual columns of data</li>
+</ul>
+For a view of N rows by M columns, the row count of N plus the M column
+definitions fully describe its contents - just like a row count of N with
+N row definitions would in a traditional row-by-row database.
+<p>Note that the amount of information needed to define all views and columns
+can remain <i>very</i> small.&nbsp; The number of rows in each view affects
+only the size of each column, not the number of them.&nbsp; This effect
+is used while opening a datafile: Metakit quickly reads the header, description,
+and all column position/size information.&nbsp; From then on, access to
+data is basically instant - with seeks doing the rest (actually, most of
+it is memory-mapped file access).&nbsp; To use the previous example: a
+view with 10,000 rows of 25 properties ends up being managed as 25 columns
+on file - which is a very simple task.
+<p>The row counts and the &lt;offset,size> tuples defining all columns
+are stored in an tagged-byte format, with as many bytes as need to represent
+each integer value.&nbsp; This format is space efficient for small
+files, and is able to adapt to file sizes (and offsets) which are more
+than 32 bits.&nbsp; All values are stored consecutively and are loaded
+very quickly (this includes the more complex case when subviews are part
+of the data structure).
+<br>&nbsp;
+<p><b>STRUCTURE DEFINITION</b>
+<p>The description stored in each datafile is a string which precisely
+describes the name of all views and subviews, and the name and type of
+all properties in these subviews.&nbsp; An example of such a <i>definition
+string</i> (as stored on file) will make it clear how the information is
+represented:
+<p><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companies[name:S,offices[department:S,address:S,employees[name:S,salary:I,photo:M],phone:S],revenue:D]</font>
+<p>Datatypes are currently defined as one of the following:
+<blockquote><b><tt>S</tt></b> - string (null-byte terminated)
+<br><b><tt>I</tt></b> - integer (1..32 bits, adapting at run time)
+<br><b><tt>F</tt></b> - 32-bit floating point
+<br><b><tt>D</tt></b> - 64-bit floating point
+<br><b><tt>B</tt></b> - untyped binary data
+<br><b><tt>M</tt></b> - "memo" binary data (see below)</blockquote>
+The above example describes a datafiles with information about companies,
+each having a variable number of offices, which in turn have a varying
+number of employees.&nbsp; Other information can be added in the same file,
+it is not limited to a single <i>view</i> (companies in this case).
+<p>This string, as well as all strings stored as properties of rows, is
+stored in UTF-8 format, which allow storing Unicode strings while maintaining
+compatibility of datafiles across all platforms.
+<br>&nbsp;
+<p><b>STORING BINARY DATA</b>
+<p>The file format described so far is useful for small to medium-sized
+datasets (see the section on "performance" below), but as column sizes
+grow, performance tends to suffer in a number of ways.&nbsp; To meet requests
+to store larger amounts of data efficiently, "memo" properties were added
+in March 1998.&nbsp; These add a single level of indirection, and allow
+storing binary data as individually allocated objects in the datafile.&nbsp;
+This mechanism works well when rows hold data items which are each of up
+to 1 Mb or so.&nbsp; The current limitation is that each such <i>memo-item</i>
+is loaded and saved in one step.&nbsp; A future release will allow partial
+reading and writing of such items, and will in fact allow very efficient insertion
+and deletion at any position within such items.&nbsp; This will allow
+access, and storage of concurrent independently emitted data streams (it's
+mostly a matter of designing a proper API to get at the functionality -
+which is already present).
+<br>&nbsp;
+<p><b>FILE FORMAT DETAILS</b>
+<p>With all this conceptual information out of the way, it is now possible
+to describe the file format is somewhat more detail.
+<dl>
+<dt>
+<b>Header</b></dt>
+
+<dd>
+The 8-byte header contains: a 2-byte magic number, which is also used to
+detect endian-ness, 2 bytes reserved for future use, and a 4-byte file
+offset pointing to the structural information.</dd>
+
+<p><dt><b>Structural information</b>
+<dd>
+The offset in the header points to a block of data consisting of:</dd>
+
+<ul>
+<li>
+a <i>format code</i>, which is adjusted when file format revisions are
+made</li>
+
+<li>
+the <i>structure definition string</i>, as described above</li>
+
+<li>
+all <i>row counts</i>, and <i>&lt;offset,size></i> pairs, concatenated</li>
+</ul>
+
+<dd>
+The counts, offsets, and sizes are all stored using a varying number of
+bytes, most significant bits first: each byte contains a "final" bit (bit
+7), which is set only on the last byte, and 7 "payload" bits from the value
+itself (bits 0..6).  This format is compact and platform-neutral.</dd>
+
+<p><dt><b>Columns</b>
+<dd>
+Data columns contain all items of the corresponding property, concatenated
+into a single byte vector.&nbsp; The format and size of these columns is
+determined by their datatype:</dd>
+
+<ul>
+<li>
+Strings are concatenated, with the terminating zero bytes separating each
+item.</li>
+
+<li>
+Adaptive integers - using 1..32 bits per value, depending on the largest
+absolute value.</li>
+
+<li>
+Floats use 4 bytes per entry, doubles use 8 bytes per entry.</li>
+
+<li>
+Binary properties are stored using two columns (the data, plus adaptive ints for
+item sizes).</li>
+
+<li>
+Memo properties also use two columns (file offsets and
+item sizes - both are adaptive ints).</li>
+</ul>
+
+<dd>
+Each column contains items of a single type, and can be considered as highly
+optimized linear arrays of data.</dd>
+</dl>
+<i>Note: the 4-byte file offset in the header will be turned into a more
+general "extended header" in the next file format version to drop the current
+32-bit file size restriction.&nbsp; A number of changes are planned for the
+way structural information is stored, to make it possible to open
+datafiles more lazily and perform efficient partial commits.</i>
+<br>&nbsp;
+<p><b>FREE SPACE MANAGEMENT AND RECOVERY</b>
+<p>The datafile format of Metakit contains no other information than what
+has been described so far.&nbsp; Specifically, there is no "free space"
+pool.&nbsp; This is possible, because free space can be deduced from what
+is present in the file - it consists of those areas of the file which are
+not occupied by the information described so far (header, structure def,
+column defs, columns).
+<p>This lack of redundancy improves robustness (the potential for inconsistencies
+is reduced), is more efficient (less information to carry around), and
+reduces file size.
+<p>Recovery is based on "stable storage" - a very effective technique which
+makes the datafile resilient against catastrophic failure.&nbsp; It all
+works by never writing changes to a datafile <i>over</i> current data.&nbsp;
+All changes are allocated and written to currently unused areas of the
+file (extending it if necessary).&nbsp; Only changed data is rewritten.&nbsp;
+On commit, all changes are flushed,
+and when this has been completed, a single offset in the file header is
+overwritten (this is atomic) - pointing to the new state.&nbsp;
+Once the commit is complete, free space in the file is redefined to include
+old and now obsolete areas of the file, and to exclude the newly allocated
+data.
+<p>To date, with thousands of users known to be using software based on
+Metakit in production-grade commercial products, no case has ever been
+reported of a corrupted data file.&nbsp; Metakit does not contain any recovery/repair
+code - there is no need.
+<p>The trade-off is that datafiles which get modified can grow to roughly
+twice their optimum size.&nbsp; Despite this, Metakit datafile sizes are
+often <i>smaller</i> than with other approaches.&nbsp; The
+reasons for this are that Metakit supports variable-sized data with no
+overhead, that integers tend to be packed very densely, that there is <i>no</i>
+overhead per row, and that techniques such as B-trees with partially-filled
+nodes are not used.
+<p>It goes without saying that all unused data areas get re-used when possible
+- file size usually increases during the first few commits, and remains more or less
+stable after that.&nbsp; For those cases where slack is unacceptable, a
+simple full re-save can be used to produce a fresh, optimally-packed datafile.
+<br>&nbsp;
+<p><b>ON-THE-FLY RESTRUCTURING</b>
+<p>The column-wise datafile format makes it possible to restructure datafiles
+- i.e. add or delete properties - very efficiently.&nbsp; All it takes,
+is reading the structural data (which happens during open anyway), creating
+or deleting one or more columns, and storing the adjusted structural data.&nbsp;
+Since no rows are accessed at all, this is virtually instant.
+<p>This capability has recently been used to implement a <i>generic database
+server - </i>it starts out empty, with no idea what data it will store,
+and it adapts whenever clients connect.&nbsp; Although this is in itself
+an interesting technical feature, the value lies in <i>long-lived data</i>,
+since it is now possible to store information in whatever format seems
+appropriate right now, and to write software which evolves to work with
+more complex structures overtime.&nbsp; Whenever a datafile is opened,
+its format can be inspected, applying the transformations which are required
+to bring it up to date - instantly, during open.&nbsp; Even if the data
+is read-only, such on-the-fly adaptations can be used for the duration
+of the run (simply by never committing).
+<p>The restructuring capabiltity, and the fact that it can be done almost
+instantly, is very useful for <i>long-lived data</i>. It
+simplifies the task of writing software which can handle all file formats used
+in previous releases (backward compatibility).
+Adding or dropping information as new releases of
+a product are issued no longer leads to compatibility problems or lengthy
+conversions.  Furthermore, techniques are being developed to let <i>older</i>
+software deal with files created by <i>newer</i> releases (forward compatibility).
+This solves 
+a common problem in today's software, which forces users to continuously
+upgrade their software to be able to easily exchange files with others.
+<br>&nbsp;
+<p><b>PERFORMANCE</b>
+<p>The performance of this data format is <i>extremely </i>difficult to
+assess.&nbsp; During the evolution from version 1.0 to the current 2.0
+release, improvements have been made of some two orders of magnitude.&nbsp;
+This is probably not very informative, since it might simply reflect how
+bad the original design was.
+<p>But there are several factors which can help illustrate why this is
+probably not the case:
+<ul>
+<li>
+Performance matters only in those parts of the code which are frequently
+executed: <i>i.e. inside loops</i>.</li>
+
+<li>
+Locality of reference can have a dramatic impact on performance with today's
+CPU caches.</li>
+
+<li>
+Minimizing I/O requests has become meaningless, when memory-mapped files
+and paging is used.</li>
+
+<li>
+Many repetitive loops over data tend to process a large number or rows,
+but to access only a few columns.</li>
+</ul>
+It turns out that Metakit performance varies widely, depending on the design
+and use of the data structures.&nbsp; Note that there are virtually no
+<i>database
+indexes. </i>This is not a lack of functionality, but a deliberate design
+choice.&nbsp; Experience shows that Metakit frequently outperforms other
+approaches by mere brute-force.&nbsp; A recent test on a modern Pentium
+II / 400 MHz CPU, shows that search speeds exceed 500,000 string scans
+per second and 1,000,000 integer scans per second.&nbsp; There is a definite
+trade-off between indexing (with techniques such as B-trees and extensible
+hashing) and the overhead it imposes for updates - and mere scanning.
+<p>Evidently, at some point, it will be better to index by key values than
+to scan millions of strings for a match.&nbsp; This is where subviews in
+Metakit come in handy.&nbsp; By structuring data in a "slightly hierarchical"
+manner, searches again often end up being over just thousands or tens of
+thousands of entries.&nbsp; Also, keeping data sorted (in some sense) and then
+doing binary search can often be an effective option (this is part of the Metakit
+API).
+<p>Sequential searching is well suited for keyword searches and for <i>regex</i>
+pattern-matching, and by its very nature well suited for <i>ad-hoc</i>
+queries: all properties are searchable without the need to decide what
+key indexes to define up front.
+<p>Some further explanations why performance is high in Metakit:
+<ul>
+<li>
+No indexes means smaller datafiles, this increases memory residence and
+reduces random seeks</li>
+
+<li>
+Inner loops over a single column are very effective: data is contiguous
+on file and caching works optimally</li>
+
+<li>
+The code is simple, and therefore small - it is more likely to fit in the
+CPU cache in its entirety</li>
+
+<li>
+Row <i>width</i> does not affect search/access performance, nor does the
+number or size of extra properties.</li>
+</ul>
+In conclusion: compact data representations work increasingly well with
+today's fast CPU's and large RAM sizes. By turning a dataset which is 100
+Mb with traditional means, into a few columns requiring 20 Mb, databases
+not only end up being completely memory-resident, the column-wise structure
+for each property also makes CPU caches perform at their very best.
+<br>&nbsp;
+<p><b>LIMITATIONS</b>
+<p>There are some limitations in the current Metakit implementation,
+these are currently being addressed:
+<ul>
+<li>
+When column sizes grow, update performance suffers (the simplest solution
+is to introduce some subviews)</li>
+
+<li>
+Concurrent file updates are currently impossible due to cache coherence
+issues (solution: client/server or diff's)</li>
+
+<li>
+Data items straddling a 4 Kb page boundary get read in, instead of taking
+advantage of memory-mapped files</li>
+</ul>
+There are also some issues which affect the file format design (to be addressed
+in the next file format revision):
+<ul>
+<li>
+Open/commit performance is proportional to structural complexity (need
+a way to do partial opens/commits)</li>
+
+<li>
+There should be a way to adjust alignment of data stored on file, so memory-mapped
+files work better</li>
+<li>
+Additional safeguards are sometimes needed to detect currupted datafiles
+(such as file-transfer errors).
+</ul>
+Work is currently under way to address each of these issues.&nbsp; This
+will allow the efficient use of Metakit datafiles when they are in the Gb
+range.&nbsp; The changes will be made in such a way that backward compatibility
+can be maintained (i.e. new releases will retain the ability to read 2.0
+format datafiles, and will transparently perform adjustments when writing
+to them).
+<br>&nbsp;
+<p><b>CONCLUSION</b>
+<p>In the end, <i>the proof is in the pudding</i>.&nbsp; As it turns out,
+three years of Metakit use and evolution have shown that a lot of performance
+can be achieved as a result of reducing file format and implementation
+complexity.&nbsp; Robustness is achieved through minimizing redundancy,
+while fail-safety is achieved through a form of controlled duplication.
+<p>Both of these have led to a format which is very simple, flexible enough
+to evolve (half of the datatypes were added after the fact), and which
+has the capability of being instantly restructured to adapt to new data
+structures.&nbsp; This latter property of the Metakit datafile format is
+what makes it <i>future-proof</i> for application developers - in a very
+practical sense.
+<p>There are some drawbacks to using column-wise storage, but the current
+implementation shows that despite this, a number of technical "tricks"
+can lead to an implementation (consisting of 16,000 lines of C++) which
+shows excellent performance in databases scaling to 10,000
+views/subviews <i>or</i> 100,000 rows.&nbsp; Future versions will aim to make
+10,000 views/subviews <i>times</i> 100,000 rows efficient.
+<br>&nbsp;
+<br>&nbsp;
+<div align=right>
+<!--
+This document is [<a href="http://www.equi4.com/jcw/mkformat.html">http://www.equi4.com/jcw/mkformat.html</a>]
+<br> -->
+&copy; 1999 Jean-Claude Wippler &lt;<a href="mailto:jcw@equi4.com">jcw@equi4.com</a>></div>
+
+</body>
+</html>
diff --git a/8.x/mk/doc/metakit.png b/8.x/mk/doc/metakit.png
new file mode 100644 (file)
index 0000000..431ef44
Binary files /dev/null and b/8.x/mk/doc/metakit.png differ
diff --git a/8.x/mk/doc/python.html b/8.x/mk/doc/python.html
new file mode 100755 (executable)
index 0000000..f968caa
--- /dev/null
@@ -0,0 +1,293 @@
+<HTML><HEAD>
+<TITLE>Metakit for Python</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF"><A NAME="top"></A>
+<A HREF="http://www.python.org/"><IMG SRC="python.gif" WIDTH="87" HEIGHT="24" BORDER=0 align=left></A>
+<A HREF="http://www.equi4.com/"><IMG SRC="e4s.gif" vspace=3 WIDTH="97" HEIGHT="35" BORDER=0 align=right></A>
+<CENTER>
+<H2>Metakit for Python</H2>
+<I>The structured database which fits in the palm of your hand</I>
+<P>
+[ <A HREF="#Terminology">Terminology</A> 
+| <A HREF="#inst">Installation</A> 
+| <A HREF="#start">Getting started</A> 
+| <A HREF="#ref">Mk4py Reference</A> ]
+</CENTER>
+<P>
+<B>Buzzwords</B> - <A HREF=".">Metakit</A> is an embeddable database which runs on Unix, Windows, Macintosh, and other platforms.  It lets you build applications which store their data efficiently, in a portable way, and which will not need a complex runtime installation.  In terms of the data model, Metakit takes the middle ground between RDBMS, OODBMS, and flat-file databases - yet it is quite different from each of them.
+<P>
+<B>Technology</B> - Everything is stored variable-sized yet with efficient positional row access.  Changing an existing datafile structure is as simple as re-opening it with that new structure.  All changes are transacted.  You can mix and match software written in C++, Python, and Tcl.  Things can't get much more flexible...
+<P>
+<B>Python</B> - The extension for <A HREF="http://www.python.org/">Python</A> is called "Mk4py".  It provides a lower-level API for the Metakit C++ core extension than an earlier version of this interface, and uses <A HREF="http://starship.python.net/crew/gmcm/scxx.html">SCXX</A> by Gordon McMillan as C++ glue interface.
+<P>
+<B>Mk4py 2.4.9.7</B> - is a final/production release.  The <A HREF="http://www.equi4.com/metakit.html">homepage</A> points to a download area with pre-compiled shared libraries for Unix, Windows, and Macintosh.  The Metakit source distribution includes this documentation, the Mk4py C++ source code, a "MkMemoIO.py" class which provides efficient and fail-safe I/O (therefore also pickling) using Metakit memo fields, and a few more goodies.
+<P>
+<B>License and support</B> - Metakit 2 and up are distributed under the liberal
+X/MIT-style open source license. Commercial support is available through an Enterprise License.  See the <A HREF="http://www.equi4.com/mklicense.html">license</A> page for details.
+<P>
+<B>Credits</B> - Are due to Gordon McMillan for not stopping at the original Mk4py and coming up with a more Pythonic interface, and to Christian Tismer for pushing Mk4py way beyond its design goals.  Also to GvR and the Python community for taking scripting to such fascinating heights...
+<P>
+<P>
+<B>Updates</B> - The latest version of this document is at
+<a href="http://www.equi4.com/metakit/python.html">http://www.equi4.com/metakit/python.html</a>
+<A name="Terminology"><HR size=1></A><H2>Terminology</H2>
+    There are several ways to say the same thing, depending on where you're
+    coming from.  For example, the terms <I>table</I>, <I>list</I>, <I>collection</I>,
+    <I>array</I>, <I>sequence</I>, and <I>vector</I> all
+    denote a more or less similar concept.
+    To help avoid confusion, Metakit uses a simple
+    (but hopefully precise) terminology.
+<P>
+    The terms adopted by Metakit can be summarized as follows:
+<P>
+    <UL>
+        <LI>A <B>view</B> is an indexable collection of <B>rows</B>
+            (a <I>table</I> of <I>records</I>, an <I>array</I> of <I>elements</I>).
+        <LI>An <B>index</B> is a position in a <I>view</I>, used to specify a <I>row</I>
+            (the first row is at index zero).
+        <LI>Each view has an ordered
+            set of <B>properties</B>, used to refer to the data values of each row.
+        <LI>In Metakit, each (<I>view</I>, <I>index</I>, <I>property</I>) combination denotes
+            a single data value.
+        <LI>A different way to describe this combination would be:
+            (<I>matrix</I>, <I>row-index</I>, <I>column-id</I>).
+        <LI>Data values can be strings, numeric, untyped data,
+            or a nested view, called a <B>subview</B>.
+    </UL>
+<P>
+    A few more comments about the semantics of Metakit:
+<P>
+    <UL>
+        <LI>Views are <I>homogenous</I>: each row in a view contains the same type of
+            information.
+        <LI>This also implies that all subviews within the same view always
+            have the same structure.
+        <LI>Rows are either part of a view on file, or <I>temporary</I> (gone
+            when no longer referenced).
+    </UL>
+<P>
+<A NAME="inst"><HR size=1></A><H2>Installation</H2>
+
+<OL>
+<LI>Download the latest version from <A HREF="http://www.equi4.com/pub/mk/">http://www.equi4.com/pub/mk/</A>
+<LI>On Unix, rename the appropriate compiled extension to "Mk4py.so" (on Win/Mac, use the corresponding file)
+<LI>Place the Mk4py extension as well as the "metakit.py" wrapper somewhere on Python's module search path, <br> such as in the site-packages directory (or just leave it in ".")
+<LI>Do a small test, by running "demo.py".  If all is well, you should get some self-explanatory output
+</OL>
+<P>
+<A NAME="start"><HR size=1></A><H2>Getting started</H2>
+Create a database:
+<BLOCKQUOTE><PRE>import metakit
+db = metakit.storage("datafile.mk",1)</PRE></BLOCKQUOTE>
+Create a view (this is the Metakit term for "table"):
+<BLOCKQUOTE><PRE>vw = db.getas("people[first:S,last:S,shoesize:I]")</PRE></BLOCKQUOTE>
+Add two rows (this is the Metakit term for "record"):
+<BLOCKQUOTE><PRE>vw.append(first='John',last='Lennon',shoesize=44)
+vw.append(first='Flash',last='Gordon',shoesize=42)</PRE></BLOCKQUOTE>
+Commit the changes to file:
+<BLOCKQUOTE><PRE>db.commit()</PRE></BLOCKQUOTE>
+Show a list of all people:
+<BLOCKQUOTE><PRE>for r in vw: print r.first, r.last, r.shoesize</PRE></BLOCKQUOTE>
+Show a list of all people, sorted by last name:
+<BLOCKQUOTE><PRE>for r in vw.sort(vw.last): print r.first, r.last, r.shoesize</PRE></BLOCKQUOTE>
+Show a list of all people with first name 'John':
+<BLOCKQUOTE><PRE>for r in vw.select(first='John'): print r.first, r.last, r.shoesize</PRE></BLOCKQUOTE>
+<P>
+<A NAME="ref"><HR size=1></A>
+<!--BEGIN-->
+<A NAME="0"></A><H2>Mk4py Reference</H2>
+<OL>
+<LI><A HREF="#1">Module functions</A>
+<LI><A HREF="#2">Storage objects</A>
+<LI><A HREF="#3">View objects</A>
+<LI><A HREF="#4">Derived views</A>
+<LI><A HREF="#5">View operations</A>
+<LI><A HREF="#6">Mapping views</A>
+<LI><A HREF="#7">Rowref objects</A>
+<LI><A HREF="#8">Property objects</A>
+</OL>
+<HR SIZE=1>
+<H3><A NAME="1"></A><A HREF="#0">1.</A> Module functions</H3>These functions live at the module level.  You can use them
+            as described below after executing the following preamble:<BR><PRE><FONT COLOR="#000099">     import metakit
+     print metakit.version</FONT></PRE><P><B><FONT SIZE=-1>SYNOPSYS</FONT></B><BLOCKQUOTE><DL><DT><FONT COLOR="#990000"><I>db</I> = <I>metakit</I>.<B>storage</B>()</font><DD>Create an in-memory database (can't use commit/rollback)<DT><FONT COLOR="#990000"><I>db</I> = <I>metakit</I>.<B>storage</B>(<I>file</I>)</font><DD>Use a specified file object to build the storage on<DT><FONT COLOR="#990000"><I>db</I> = <I>metakit</I>.<B>storage</B>(<I>name</I>, <I>mode</I>)</font><DD>Open file, create if absent and rwflag is non-zero.
+        Open read-only if mode is 0, r/w if mode is 1 (cannot be shared),
+       or as commit-extend if mode is 2
+        (in mode 1 and 2, the file will be created if needed).<DT><FONT COLOR="#990000"><I>vw</I> = <I>metakit</I>.<B>view</B>()</font><DD>Create a standalone view; not in any storage object<DT><FONT COLOR="#990000"><I>pr</I> = <I>metakit</I>.<B>property</B>(<I>type</I>, <I>name</I>)</font><DD>Create a property (a column, when associated to a view)<DT><FONT COLOR="#990000"><I>vw</I> = <I>metakit</I>.<B>wrap</B>(<I>sequence</I>, <I>proplist</I>, <I>byPos</I>=0)</font><DD>Wraps a Python sequence as a view</DL></BLOCKQUOTE><B><FONT SIZE=-1>ADDITIONAL DETAILS</FONT></B><BLOCKQUOTE><DL><FONT COLOR="#990000"><B>storage</B></FONT> - When given a single argument, the file object must be a real
+            stdio file, not a class implementing the file r/w protocol.
+            When the storage object is destroyed (such as with
+            'db = None'), the associated datafile will be closed.
+           Be sure to keep a reference to it around as long as you use it.
+        <BR><BR><FONT COLOR="#990000"><B>wrap</B></FONT> - This call can be used to wrap any Python sequence, it assumes
+            that each item is either a dictionary or an object with attribute
+            names corresponding to the property names.  Alternately, if
+            byPos is nonzero, each item can be a list or tuple - they will
+            then be accessed by position instead.
+           Views created in this way can be used in
+            joins and any other view operations.
+        <BR><BR></DL></BLOCKQUOTE>
+<H3><A NAME="2"></A><A HREF="#0">2.</A> Storage objects</H3><B><FONT SIZE=-1>SYNOPSYS</FONT></B><BLOCKQUOTE><DL><DT><FONT COLOR="#990000"><I>vw</I> = <I>storage</I>.<B>getas</B>(<I>description</I>)</font><DD>Locate, define, or re-define a view stored in a storage object<DT><FONT COLOR="#990000"><I>vw</I> = <I>storage</I>.<B>view</B>(<I>viewname</I>)</font><DD>The normal way to retrieve an existing view<DT><FONT COLOR="#990000"><I>storage</I>.<B>rollback</B>(<I>full</I>=0)</font><DD>Revert data and structure as was last committed to disk.
+       In commit-aside mode, a &quot;full&quot; rollback reverts to the
+       state of the original file and forgets about the aside file.
+<br> After a rollback, your view objects are invalid (use the view
+or getas methods on your storage object to get them back).
+Furthermore, after a full rollback, the aside storage is detached from
+the main storage. Use the aside method on your main storage object to
+reattach it. If you do not reattach it, further commits will (try to)
+write to the main storage.
+       <DT><FONT COLOR="#990000"><I>storage</I>.<B>commit</B>(<I>full</I>=0)</font><DD>Permanently commit data and structure changes to disk
+       In commit-aside mode, a &quot;full&quot; commit save the latest
+       state in the original file and clears the aside datafile.<DT><FONT COLOR="#990000"><I>ds</I> = <I>storage</I>.<B>description</B>(<I>viewname</I>='')</font><DD>The description string is described under getas<DT><FONT COLOR="#990000"><I>vw</I> = <I>storage</I>.<B>contents</B>()</font><DD>Returns the View which holds the meta data for the Storage.<DT><FONT COLOR="#990000"><I>storage</I>.<B>autocommit</B>()</font><DD>Commit changes automatically when the storage object goes away<DT><FONT COLOR="#990000"><I>storage</I>.<B>load</B>(<I>fileobj</I>)</font><DD>Replace storage contents with data from file (or any other object
+       supporting read)<DT><FONT COLOR="#990000"><I>storage</I>.<B>save</B>(<I>fileobj</I>)</font><DD>Serialize storage contents to file (or any other object
+       supporting write)</DL></BLOCKQUOTE><B><FONT SIZE=-1>ADDITIONAL DETAILS</FONT></B><BLOCKQUOTE><DL><FONT COLOR="#990000"><B>description</B></FONT> - A description of the entire storage is retured if no viewname 
+            is specified, otherwise just the specified top-level view.
+        <BR><BR><FONT COLOR="#990000"><B>getas</B></FONT> - Side-effects: the structure of the view is changed.<BR>Notes: Normally used to create a new View, or alter the
+            structure of an existing one.
+        <BR>A description string looks like:<BR><PRE><FONT COLOR="#000099">     &quot;people[name:S,addr:S,city:S,state:S,zip:S]&quot;</FONT></PRE>That is &quot;&lt;viewname&gt;[&lt;propertyname&gt;:&lt;propertytype&gt;...]&quot;<BR>Where the property type is one of:<BR>
+       <TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
+       <TR><TD WIDTH=40></TD><TD>I</TD><TD WIDTH=20></TD><TD>adaptive integer (becomes Python int)</TD></TR>
+       <TR><TD WIDTH=40></TD><TD>L</TD><TD WIDTH=20></TD><TD>64-bit integer (becomes Python long)</TD></TR>
+       <TR><TD WIDTH=40></TD><TD>F</TD><TD WIDTH=20></TD><TD>C float (becomes Python float)</TD></TR>
+       <TR><TD WIDTH=40></TD><TD>D</TD><TD WIDTH=20></TD><TD>C double (is a Python float)</TD></TR>
+       <TR><TD WIDTH=40></TD><TD>S</TD><TD WIDTH=20></TD><TD>C null terminated string (becomes Python string)</TD></TR>
+       <TR><TD WIDTH=40></TD><TD>B</TD><TD WIDTH=20></TD><TD>C array of bytes (becomes Python string)</TD></TR>
+       </TABLE>Careful: do not include white space in the decription string.<BR><P>
+       In the Python binding, the difference between S and B types is not as
+       important as in C/C++, where S is used for zero-terminated text
+       strings.  In Python, the main distinctions are that B properties must
+       be used if the data can contain zero bytes, and that sort order of S
+       (stricmp) and B (memcmp) differ.  At some point, Unicode/UTF-8 will
+       also play a role for S properties, so it's best to use S for text.
+       <BR>
+       </DL></BLOCKQUOTE>
+<H3><A NAME="3"></A><A HREF="#0">3.</A> View objects</H3>View implements sequence (list) methods, including slicing, 
+            concatentation etc.  They behave as a sequence of &quot;rows&quot;,
+            which in turn have &quot;properties&quot;.
+            Indexing (getitem) returns a reference to a row, not a copy.
+        <BR><PRE><FONT COLOR="#000099">     r = view[0]
+     r.name = 'Julius Caesar'
+     view[0].name # will yield 'Julius Caesar'</FONT></PRE>A slice returns a modifiable view which is tied to the underlying
+           view.  As special case, however, you can create a fresh empty view
+           with the same structure as another view with:
+        <BR><PRE><FONT COLOR="#000099">     v2 = v[0:0]</FONT></PRE>Setting a slice changes the view:<BR><PRE><FONT COLOR="#000099">     v[:] = [] # empties the view</FONT></PRE>View supports getattr, which returns a Property
+            (eg view.shoesize can be used to refer to the shoesize column).
+            Views can be obtained from Storage objects:
+            view = db.view('inventory') or from other views
+            (see select, sort, flatten, join, project...) or empty,
+            columnless views can be created: vw = metakit.view()
+        <BR><P><B><FONT SIZE=-1>SYNOPSYS</FONT></B><BLOCKQUOTE><DL><DT><FONT COLOR="#990000"><I>view</I>.<B>insert</B>(<I>index</I>, <I>obj</I>)</font><DD>Coerce object to a Row and insert at index in View<DT><FONT COLOR="#990000"><I>ix</I> = <I>view</I>.<B>append</B>(<I>obj</I>)</font><DD>Object is coerced to Row and added to end of View<DT><FONT COLOR="#990000"><I>view</I>.<B>delete</B>(<I>index</I>)</font><DD>Row at index removed from View<DT><FONT COLOR="#990000"><I>lp</I> = <I>view</I>.<B>structure</B>()</font><DD>Return a list of property objects<DT><FONT COLOR="#990000"><I>cn</I> = <I>view</I>.<B>addproperty</B>(<I>fileobj</I>)</font><DD>Define a new property, return its column position<DT><FONT COLOR="#990000"><I>str</I> = <I>view</I>.<B>access</B>(<I>byteprop</I>, <I>rownum</I>, <I>offset</I>, <I>length</I>=0)</font><DD>Get (partial) byte property contents<DT><FONT COLOR="#990000"><I>view</I>.<B>modify</B>(<I>byteprop</I>, <I>rownum</I>, <I>string</I>, <I>offset</I>, <I>diff</I>=0)</font><DD>Store (partial) byte property contents.
+       A non-zero value of diff removes (&lt;0) or inserts (&gt;0) bytes.<DT><FONT COLOR="#990000">n = <I>view</I>.<B>itemsize</B>(<I>prop</I>, <I>rownum</I>=0)</font><DD>Return size of item (rownum only needed for S/B types).
+       With integer fields, a result of -1/-2/-4 means 1/2/4 bits
+       per value, respectively.<DT><FONT COLOR="#990000"><I>view</I>.<B>map</B>(<I>func</I>, <I>subset</I>=<I>None</I>)</font><DD>Apply func to each row of view, or (if subset specified)
+       to each row in view that is lso in subset.
+       Func must have the signature &quot;func(row)&quot;, and may mutate row.
+       Subset must be a subset of view: e.g.
+       &quot;customers.map(func, customers.select(...))&quot;.<DT><FONT COLOR="#990000"><I>rview</I> = <I>view</I>.<B>filter</B>(<I>func</I>)</font><DD>Return a view containing the indices of those rows
+       satisfying func.  Func must have signature &quot;func(row)&quot;
+       and must return a false value to omit the row.<DT><FONT COLOR="#990000"><I>obj</I> = <I>view</I>.<B>reduce</B>(<I>func</I>, <I>start</I>=0)</font><DD>Return the result of applying func(row, lastresult) to
+       each row in view.<DT><FONT COLOR="#990000"><I>view</I>.<B>remove</B>(<I>indices</I>)</font><DD>Remove all rows whose indices are in subset from view.
+       Not the same as minus, because unique is not required, 
+       and view is not reordered.<DT><FONT COLOR="#990000"><I>rview</I> = <I>view</I>.<B>indices</B>(<I>subset</I>)</font><DD>Returns a view containing the indices in view of the rows in
+       subset.<DT><FONT COLOR="#990000"><I>rview</I> = <I>view</I>.<B>copy</B>()</font><DD>Returns a copy of the view.</DL></BLOCKQUOTE><B><FONT SIZE=-1>ADDITIONAL DETAILS</FONT></B><BLOCKQUOTE><DL><FONT COLOR="#990000"><B>addproperty</B></FONT> - This adds properties which do not persist when committed.  To
+           make them persist, you should use storage.getas(...) when
+           defining (or restructuring) the view.
+        <BR><BR><FONT COLOR="#990000"><B>append</B></FONT> - Also support keyword args (colname=value...).<BR><BR><FONT COLOR="#990000"><B>insert</B></FONT> - coercion to a Row is driven by the View's columns, and works for:<BR><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><TR><TD WIDTH=40></TD><TD>dictionaries</TD><TD WIDTH=20></TD><TD>(column name -&gt; key)</TD></TR><TR><TD WIDTH=40></TD><TD>instances</TD><TD WIDTH=20></TD><TD>(column name -&gt; attribute name)</TD></TR><TR><TD WIDTH=40></TD><TD>lists</TD><TD WIDTH=20></TD><TD>(column number -&gt; list index) - watch out!</TD></TR></TABLE><BR></DL></BLOCKQUOTE>
+<H3><A NAME="4"></A><A HREF="#0">4.</A> Derived views</H3><B><FONT SIZE=-1>SYNOPSYS</FONT></B><BLOCKQUOTE><DL><DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>select</B>(<I>criteria</I>...)</font><DD>Return a view which has fields matching the given criteria<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>select</B>(<I>low</I>, <I>high</I>)</font><DD>Return a view with rows in the specified range (inclusive)<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>sort</B>()</font><DD>Sort view in &quot;native&quot; order, i.e. the definition order of its keys<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>sort</B>(<I>property</I>...)</font><DD>Sort view in the specified order<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>sortrev</B>((<I>propall</I>...), (<I>proprev</I>...))</font><DD>Sort view in specified order, with optionally some properties in reverse<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>project</B>(<I>property</I>...)</font><DD>Returns a derived view with only the named columns</DL></BLOCKQUOTE><B><FONT SIZE=-1>ADDITIONAL DETAILS</FONT></B><BLOCKQUOTE><DL><FONT COLOR="#990000"><B>select</B></FONT> - Example selections, returning the corresponding subsets:<BR><PRE><FONT COLOR="#000099">     result = inventory.select(shoesize=44)
+     result = inventory.select({'shoesize':40},{'shoesize':43})
+     result = inventory.select({},{'shoesize':43})</FONT></PRE>The derived view is &quot;connected&quot; to the base view.
+            Modifications of rows in the
+            derived view are reflected in the base view
+        <BR><BR><FONT COLOR="#990000"><B>sort</B></FONT> - Example, returning the sorted permutation:<BR><PRE><FONT COLOR="#000099">     result = inventory.sort(inventory.shoesize)</FONT></PRE>See notes for select concerning changes to the sorted view<BR><BR></DL></BLOCKQUOTE>
+<H3><A NAME="5"></A><A HREF="#0">5.</A> View operations</H3><B><FONT SIZE=-1>SYNOPSYS</FONT></B><BLOCKQUOTE>
+<DL>
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>flatten</B>(<I>subprop</I>, <I>outer</I>=0)</font>
+<DD>Produces one 'flat' view from a nested view
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>join</B>(<I>view</I>, <I>property</I>...,<I>outer</I>=0)</font>
+<DD>Both views must have a property (column) of that name and type
+<DT><FONT COLOR="#990000"><I>ix</I> = <I>view</I>.<B>find</B>(<I>criteria</I>..., <I>start</I>=0)</font>
+<DD>Returns the index of the found row, or -1
+<DT><FONT COLOR="#990000"><I>ix</I> = <I>view</I>.<B>search</B>(<I>criteria</I>...)</font>
+<DD>Binary search (native view order), returns match or insertion point
+<DT><FONT COLOR="#990000"><I>ix, cnt</I> = <I>view</I>.<B>locate</B>(<I>criteria</I>...)</font>
+<DD>Binary search, returns position and count as tuple (count can be zero)
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>unique</B>()</font>
+<DD>Returns a new view without duplicate rows (a set)
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>union</B>(<I>view2</I>)</font>
+<DD>Returns a new view which is the set union of view and view2
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>intersect</B>(<I>view2</I>)</font>
+<DD>Returns a new view which is the set intersection of view and view2
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>different</B>(<I>view2</I>)</font>
+<DD>Returns a new view which is the set XOR of view and view2
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>minus</B>(<I>view2</I>)</font>
+<DD>Returns a new view which is (in set terms) view - view.intersect(view2)
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>remapwith</B>(<I>view2</I>)</font>
+<DD>Remap rows according to the first (int) property in view2
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>pair</B>(<I>view2</I>)</font>
+<DD>Concatenate rows pairwise, side by side
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>rename</B>('<I>oldname</I>', '<I>newname</I>')</font>
+<DD>Returns a derived view with one property renamed
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>product</B>(<I>view</I>)</font>
+<DD>Returns the cartesian product of both views
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>groupby</B>(<I>property</I>..., '<I>subname</I>')</font>
+<DD>Groups on specified properties, with subviews to hold groups
+<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>counts</B>(<I>property</I>..., '<I>name</I>')</font>
+<DD>Groups on specified properties, replacing rest with a count field
+</DL></BLOCKQUOTE>
+<B><FONT SIZE=-1>ADDITIONAL DETAILS</FONT></B><BLOCKQUOTE>
+<DL><FONT COLOR="#990000"><B>find</B></FONT> - view[view.find(firstname='Joe')] is the same as
+              view.select(firstname='Joe')[0] but much faster
+            Subsequent finds use the &quot;start&quot; keyword:
+              view.find(firstname='Joe', start=3)
+        <BR><BR></DL></BLOCKQUOTE>
+<H3><A NAME="6"></A><A HREF="#0">6.</A> Mapping views</H3><B><FONT SIZE=-1>SYNOPSYS</FONT></B><BLOCKQUOTE><DL><DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>hash</B>(<I>mapview</I>, <I>numkeys</I>=1)</font><DD>Construct a hash mapping based on the first N fields.<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>blocked</B>(<I>blockview</I>)</font><DD>Construct a &quot;blocked&quot; view, which acts as if all segments together
+       form a single large view.<DT><FONT COLOR="#990000"><I>vw</I> = <I>view</I>.<B>ordered</B>(<I>numkeys</I>=1)</font><DD>Define a view which assumes and maintains sort order,
+       based on the first N fields.  When layered on top of a blocked
+       view, this implements a 2-level btree.</DL></BLOCKQUOTE><B><FONT SIZE=-1>ADDITIONAL DETAILS</FONT></B><BLOCKQUOTE><DL><FONT COLOR="#990000"><B>blocked</B></FONT> - This view acts like a large flat view, even though the actual
+           rows are stored in blocks, which are rebalanced automatically to
+           maintain a good trade-off between block size and number of blocks.
+       <BR>The underlying view must be defined with a single view property,
+           with the structure of the subview being as needed.
+        <BR><BR><FONT COLOR="#990000"><B>hash</B></FONT> - This view creates and manages a special hash map view, to implement
+           a fast find on the key.  The key is defined to consist of the
+           first numKeys_ properties of the underlying view.
+       <BR>The mapview must be empty the first time this hash view is used,
+           so that Metakit can fill it based on whatever rows are already
+           present in the underlying view.  After that, neither the underlying
+           view nor the map view may be modified other than through this
+           hash mapping layer.  The defined structure of the map view must be
+           &quot;_H:I,_R:I&quot;.
+       <BR>This view is modifiable.  Insertions and changes to key field
+           properties can cause rows to be repositioned to maintain hash
+           uniqueness.  Careful: when a row is changed in such a way that its
+           key is the same as in another row, that other row will be deleted
+           from the view.
+       <BR><BR><FONT COLOR="#990000"><B>ordered</B></FONT> - This is an identity view, which has as only use to inform Metakit
+           that the underlying view can be considered to be sorted on its
+           first numKeys properties.  The effect is that view.find() will
+           try to use binary search when the search includes key properties
+           (results will be identical to unordered views, the find will
+           just be more efficient).
+       <BR>This view is modifiable.  Insertions and changes to key field
+           properties can cause rows to be repositioned to maintain the sort
+           order.  Careful: when a row is changed in such a way that its key
+           is the same as in another row, that other row will be deleted from
+           the view.
+       <BR>This view can be combined with view.blocked(), to create a 2-level
+           btree structure.
+       <BR><BR></DL></BLOCKQUOTE>
+<H3><A NAME="7"></A><A HREF="#0">7.</A> Rowref objects</H3>RowRef allows setting and getting of attributes (columns)<BR>RowRef encapsulates a (view, ndx) tuple.<BR>Normally obtained from a view:  rowref = view[33]<BR>
+<H3><A NAME="8"></A><A HREF="#0">8.</A> Property objects</H3>Property has attributes name, id and type.
+        Example:    p = metakit.property('I', 'shoesize')
+    <BR>Note that a property is used to describe a column, but it is NOT the
+        same as a column. That is, in a given storage, the property
+        Property('I', 'shoesize') will be unique, (that is, no matter how many
+        instances you create, they will all have the same property.id). But that
+        one property can describe any number of columns, each one in a different
+        view. This is how joins are done, and why &quot;view.sort(view.firstname)&quot;
+        is the same as &quot;view.sort(metakit.property('S','firstname'))&quot;.
+    <BR>
+<!--END-->
+<P>
+<HR size=1>
+&copy; 2005 Jean-Claude Wippler &lt;<A HREF="mailto:jcw@equi4.com">jcw@equi4.com</A>&gt;
+</BODY>
+</HTML>
diff --git a/8.x/mk/doc/python.jpg b/8.x/mk/doc/python.jpg
new file mode 100755 (executable)
index 0000000..e831182
Binary files /dev/null and b/8.x/mk/doc/python.jpg differ
diff --git a/8.x/mk/doc/tcl.gif b/8.x/mk/doc/tcl.gif
new file mode 100755 (executable)
index 0000000..5649d7c
Binary files /dev/null and b/8.x/mk/doc/tcl.gif differ
diff --git a/8.x/mk/doc/tcl.html b/8.x/mk/doc/tcl.html
new file mode 100755 (executable)
index 0000000..d5c78f8
--- /dev/null
@@ -0,0 +1,646 @@
+<HTML><HEAD>
+<TITLE>Metakit for Tcl</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF"><A NAME="top"></A>
+<A HREF="http://www.scriptics.com/"><IMG SRC="tcl.gif" WIDTH="51" HEIGHT="75" BORDER=0 align=left></A>
+<A HREF="http://www.equi4.com/"><IMG SRC="e4s.gif" vspace=3 WIDTH="97" HEIGHT="35" BORDER=0 align=right></A>
+<CENTER>
+<H2>&nbsp; &nbsp; &nbsp; Metakit for Tcl</H2>
+<I>The structured database which fits in the palm of your hand &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </I>
+<P>
+[ <A href="#Overview">Overview</A> 
+| <A href="#Terminology">Terminology</A>
+| <A HREF="#inst">Installation</A> 
+| <A HREF="#start">Getting started</A>
+| <A HREF="#ref">Mk4tcl Reference</A>
+]
+</CENTER>
+<P>
+<B>Buzzwords</B> - <A HREF=".">Metakit</A> is an embeddable database which runs on Unix, Windows, Macintosh, and other platforms.  It lets you build applications which store their data efficiently, in a portable way, and which will not need a complex runtime installation.  In terms of the data model, Metakit takes the middle ground between RDBMS, OODBMS, and flat-file databases - yet it is quite different from each of them.
+<P>
+<B>Technology</B> - Everything is stored variable-sized yet with efficient positional row access.  Changing an existing datafile structure is as simple as re-opening it with that new structure.  All changes are transacted.  You can mix and match software written in C++, Python, and Tcl.  Things can't get much more flexible...
+<P>
+<B>Tcl/Tk</B> - The extension for <A HREF="http://www.tcl.tk/">Tcl</A> is called "Mk4tcl".  It is being used in a number of commercial projects, for in-house use as well as in commercially distributed products.
+<P>
+<B>Mk4tcl 2.4.9.7</B> - is a final/production release.  The <A HREF="http://www.equi4.com/metakit.html">homepage</A> points to a download area with pre-compiled shared libraries for Unix, Windows, and Macintosh.  The Metakit source distribution includes this documentation, the Mk4tcl C++ source code, a small Tcl test suite, a "mkshow.tcl" utility which lets you examine data in any Metakit datafile from the command line, and a few more goodies.
+<P>
+<B>License and support</B> - Metakit 2 and up are distributed under the liberal
+X/MIT-style open source license. Commercial support is available through an Enterprise License.  See the <A HREF="http://www.equi4.com/mklicense.html">license</A> page for details.
+<P>
+<B>Credits</B> - Are due to Mark Roseman for providing the initial incentive and feedback, and to Matt Newman for a range of suggestions and ideas.  Evidently, Mk4tcl could not exist without the Tcl/Tk scripting platform and its superb extensibility.
+<P>
+<B>Updates</B> - The latest version of this document is at
+<a href="http://www.equi4.com/metakit/tcl.html">http://www.equi4.com/metakit/tcl.html</a>.
+<A name="Overview"><HR size=1></A><H2>Overview</H2>
+    Metakit is a machine- and language-independent toolkit for storing and managing
+    structured data.    This is a description of the <I>Mk4tcl</I> extension, which 
+    allows you to create, access, and manipulate Metakit datafiles using Tcl.
+    Here is a Tcl script which selects, sorts,
+     and displays some previously stored results:
+    <PRE>
+    mk::file open db phonebook.dat -readonly
+    foreach i [mk::select db.persons -glob name "Jon*" -sort date] {
+        puts "Found [mk::get db.persons!$i name phone date]"
+    }</PRE>
+    This script illustrates how easy it is to access stored data from Tcl.
+    What it does not show, however, is that numeric data can be stored in binary
+    format (yet remain fully portable), that datafiles can contain complex (nested)
+    datastructures, that the structure of datafiles can be adjusted at any time,
+    and that all modifications use the commit / rollback transaction model.
+<P>
+    In actual use, Metakit resembles more an array manipulation
+    package than a database - with the main access mechanism being
+    <I>'by position'</I>, not by primary key.
+    The  Tcl interface does not yet cover
+    all operations provided by the complete C++ interface of Metakit,
+    but as the <I>mk::select</I> command illsutrates, it
+    does include quite flexible forms of searching and sorting.
+<P>
+<P><A name="Terminology"><HR size=1></A><H2>Terminology</H2>
+    There are several ways to say the same thing, depending on where you're
+    coming from.  For example, the terms <I>table</I>, <I>list</I>, <I>collection</I>,
+    <I>array</I>, <I>sequence</I>, and <I>vector</I> all
+    denote a more or less similar concept.
+    To help avoid confusion, Metakit uses a simple
+    (but hopefully precise) terminology.
+<P>
+    The terms adopted by Metakit can be summarized as follows:
+<P>
+    <UL>
+        <LI>A <B>view</B> is an indexable collection of <B>rows</B>
+            (a <I>table</I> of <I>records</I>, an <I>array</I> of <I>elements</I>).
+        <LI>An <B>index</B> is a position in a <I>view</I>, used to specify a <I>row</I>
+            (the first row is at index zero).
+        <LI>Each view has an ordered
+            set of <B>properties</B>, used to refer to the data values of each row.
+        <LI>In Metakit, each (<I>view</I>, <I>index</I>, <I>property</I>) combination denotes
+            a single data value.
+        <LI>A different way to describe this combination would be:
+            (<I>matrix</I>, <I>row-index</I>, <I>column-id</I>).
+        <LI>Data values can be strings, numeric, untyped data,
+            or a nested view, called a <B>subview</B>.
+        <LI>A <B>cursor</B> is a reference to a specific row in a specific view,
+            i.e. a (<I>view</I>, <I>index</I>) tuple.
+    </UL>
+<P>
+    The <I>Mk4tcl</I> extension adds several notational conventions:
+<P>
+    <UL>
+        <LI>A <B>tag</B> is an identifier used to refer to an open datafile.
+        <LI>Top-level views are specified as <B>tag.viewname</B>.
+        <LI>Row <B>N</B> in such a view can be specified as <B>tag.viewname!N</B>.
+        <LI>Subviews extend this notation, e.g. <B>tag.viewname!N.subview</B>.
+        <LI>Sub-rows continue in the same way, e.g. <B>tag.viewname!N.subview!M</B>.
+        <LI>The specification of a view (either top-level or subview) is called a <B>path</B>.
+        <LI>Thus, both <I>tag.viewname</I> and <I>tag.viewname!N.subview</I> are paths.
+        <LI>In <I>Mk4tcl</I>, a cursor placed at the Nth row is equivalent to the string "<B>path!N</B>".
+        <LI>A trailing row index is allowed and ignored wherever a path is expected.
+        <LI>As a result, cursors are allowed (and frequently used) as path arguments.
+    </UL>
+<P>
+    A few more comments about the semantics of Metakit:
+<P>
+    <UL>
+        <LI>Views are <I>homogenous</I>: each row in a view contains the same type of
+            information.
+        <LI>This also implies that all subviews within the same view always
+            have the same structure.
+        <LI>Rows are either part of a view on file, or <I>temporary</I> (gone
+            when no longer referenced).
+        <LI>A cursor need not point to an existing row
+            (its current position may be out of range).
+    </UL>
+<P>
+<A NAME="inst"><HR size=1></A><H2>Installation</H2>
+
+<OL>
+<LI>Download the latest version from <A HREF="http://www.equi4.com/pub/mk/">http://www.equi4.com/pub/mk/</A>
+<LI>On Unix, rename the appropriate compiled extension to "Mk4tcl.so" (on Win/Mac, use the corresponding file)
+<LI>Do a small test, by running "demo.tcl".  If all is well, you should get some self-explanatory output
+<LI>Place the extension somewhere on Tcl's package search path (or just leave it in ".")
+</OL>
+<P>
+<A NAME="start"><HR size=1></A><H2>Getting started</H2>
+Create a datafile:
+<BLOCKQUOTE><PRE>package require Mk4tcl
+mk::file open db datafile.mk</PRE></BLOCKQUOTE>
+Create a view (this is the Metakit term for "table"):
+<BLOCKQUOTE><PRE>set vw [mk::view layout db.people {first last shoesize:I}]</PRE></BLOCKQUOTE>
+Add two rows (this is the Metakit term for "record"):
+<BLOCKQUOTE><PRE>mk::row append $vw first "John" last "Lennon" shoesize 44
+mk::row append $vw first "Flash" last "Gordon" shoesize 42</PRE></BLOCKQUOTE>
+Commit the changes to file:
+<BLOCKQUOTE><PRE>mk::file commit db</PRE></BLOCKQUOTE>
+Show a list of all people:
+<BLOCKQUOTE><PRE>mk::loop c $vw {puts [mk::get $c first last shoesize]}</PRE></BLOCKQUOTE>
+Show a list of all people, sorted by last name:
+<BLOCKQUOTE><PRE>foreach r [mk::select $vw -sort last] {puts [mk::get $vw!$r]}</PRE></BLOCKQUOTE>
+Show a list of all people with first name 'John':
+<BLOCKQUOTE><PRE>foreach r [mk::select $vw first "John"] {puts [mk::get $vw!$r]}</PRE></BLOCKQUOTE>
+<P>
+<A NAME="ref"><hr size=1></A>
+<DL><DT><H2>Mk4tcl Reference</H2><DD>
+<TABLE cellspacing=0 cellpadding=0 border=0><TR><TD><A href="#mk_file">mk::file</A></TD><TD width=20></TD><TD>Opening, closing, and saving datafiles</TD>
+<TR><TD><A href="#mk_view">mk::view</A></TD><TD width=20></TD><TD>View structure and size operations</TD>
+<TR><TD><A href="#mk_cursor">mk::cursor</A></TD><TD width=20></TD><TD>Cursor variables for positioning</TD>
+<TR><TD><A href="#mk_row">mk::row</A></TD><TD width=20></TD><TD>Create, insert, and delete rows</TD>
+<TR><TD><A href="#mk_get">mk::get</A></TD><TD width=20></TD><TD>Fetch values</TD>
+<TR><TD><A href="#mk_set">mk::set</A></TD><TD width=20></TD><TD>Store values</TD>
+<TR><TD><A href="#mk_loop">mk::loop</A></TD><TD width=20></TD><TD>Iterate over the rows of a view</TD>
+<TR><TD><A href="#mkselect">mk::select</A></TD><TD width=20></TD><TD>Selection and sorting</Td>
+<TR><TD><A href="#mk_channel">mk::channel</A></TD><TD width=20></TD><TD>Channel interface (new in 1.2)</Td>
+</TABLE><BR>
+<P><DT><A name="mk_file"><HR size=1></A><H2>mk::file</H2><DD><H3>Opening, closing, and saving datafiles</H3>
+<P><DT>SYNOPSIS<DD><B>mk::file</B> &nbsp;<B>open</B> <BR>
+<B>mk::file</B> &nbsp;<B>open</B> &nbsp;<I>tag</I> <BR>
+<B>mk::file</B> &nbsp;<B>open</B> &nbsp;<I>tag</I> &nbsp;<I>filename</I> &nbsp;?-readonly? &nbsp;?-nocommit? &nbsp;?-extend? &nbsp;?-shared? &nbsp;<BR>
+<B>mk::file</B> &nbsp;<B>views</B> &nbsp;<I>tag</I> &nbsp;<BR>
+<B>mk::file</B> &nbsp;<B>close</B> &nbsp;<I>tag</I> &nbsp;<BR>
+<B>mk::file</B> &nbsp;<B>commit</B> &nbsp;<I>tag</I> &nbsp;?-full? &nbsp;<BR>
+<B>mk::file</B> &nbsp;<B>rollback</B> &nbsp;<I>tag</I> &nbsp;?-full? &nbsp;<BR>
+<B>mk::file</B> &nbsp;<B>load</B> &nbsp;<I>tag</I> &nbsp;<I>channel</I> &nbsp;<BR>
+<B>mk::file</B> &nbsp;<B>save</B> &nbsp;<I>tag</I> &nbsp;<I>channel</I> &nbsp;<BR>
+<B>mk::file</B> &nbsp;<B>aside</B> &nbsp;<I>tag</I> &nbsp;<I>tag2</I> &nbsp;<BR>
+<B>mk::file</B> &nbsp;<B>autocommit</B> &nbsp;<I>tag</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <I>mk::file</I> command is used to open and close Metakit datafiles.
+    It is also used to force pending changes to disk (<I>commit</I>),
+    to cancel the last changes (<I>rollback</I>), and to send/receive the entire
+    contents of a datafile over a Tcl <I>channel</I>, including sockets
+    (<I>load/save</I>).
+<P>
+    Without arguments, '<B>mk::file open</B>' returns the list of tags and filenames of all datasets which are currently open (of the form <I>tag1 name1 tag2 name2 ...</I>).
+<P>
+    The '<B>mk::file open</B>' command associates a datafile with a 
+    unique symbolic <I>tag</I>.  A tag must consist of alphanumeric characters,
+    and is used in the other commands to refer to a specfic open datafile.
+    If <I>filename</I> is omitted, a temporary in-memory dataset is created (which cannot use commit, but which you could save to an I/O channel).
+    When a datafile is closed, all pending changes will be written to file,
+    unless the <B>-nocommit</B> option is specified.  In that case, only an
+    explicit commit will save changes.  To open a file only for reading,
+    use the <B>-readonly</B> option.
+    Datafiles can be opened read-only by any number
+    of readers, or by a single writer (no other combinations are allowed).
+    There is an additional mode, specified by the <B>-extend</B> option: in this
+    case changes are always written at the end of the datafile.  This allows
+    modifications by one writer without affecting readers.  Readers can adjust
+    to new changes made that way by doing a "rollback" (see below).  The term
+    is slightly confusing in this case, since it really is a "roll-forward" ...
+    The <B>-shared</B> option causes an open datafile to be visible in every
+    Tcl interpreter, with thread locking as needed.  The datafile is still tied
+    to the current interpreter and will be closed when that interpreter is
+    terminated.
+<P>
+    The '<B>mk::file views</B>' command returns a list with the views
+    currently defined in the open datafile associated with <I>tag</I>.
+    You can use the <I>'mk::view layout'</I> command to determine the current
+    structure of each view.
+<P>
+    The '<B>mk::file close</B>' command closes the datafile and releases
+    all associated resources.  If not opened with <I>-readonly</I> or <I>-nocommit</I>,
+    all pending changes will be saved to file before closing it.  A <I>tag</I>
+    loses its special meaning after the corresponding datafile has been closed.
+<P>
+    The '<B>mk::file commit</B>' command flushes all pending changes to disk.
+    It should not be used on a file opened with the <I>-readonly</I> option.
+    The optional <I>-full</I> argument is only useful when a <I>commit-aside</I>
+    is active (see below).  In that case, changes are merged back into the main
+    datafile instead of being saved separately.  The aside dataset is cleared.
+<P>
+    The '<B>mk::file rollback</B>' command cancels all pending changes
+    and reverts the situation to match what was last stored on file.
+    When commit-aside is active, a full rollback cause the state to be
+    rollback to what it was without the aside changes.  The aside dataset 
+    will be ignored from now on.
+<P>
+    The '<B>mk::file load</B>' command replaces all views with
+    data read from any Tcl <I>channel</I>.  This data must have been
+    generated using '<B>mk::file save</B>'.  Changes are made permanent when
+    <I>commit</I> is called (explicitly or implicitly, when a datafile is closed),
+    or they can be reverted by calling <I>rollback</I>.
+<P>
+    The '<B>mk::file aside</B>' command starts a special "commit-aside" mode,
+    whereby changes are saved to a second database file.  This can be much
+    faster that standard commits, because only changes are saved.  In commit-
+    aside mode, the main datafile will not be modified it all, in fact it can
+    be opened in read-only mode.
+<P>
+    The '<B>mk::file autocommit</B>' command sets up a database file to
+    automatically issue a commit when the file is closed later.  This is
+    useful if the file was initially opened in <I>-nocommit</I> mode, but
+    you now want to change this setting (there is no way to return to
+    <I>-nocommit</I>, although a rollback has a similar effect).
+<P>
+<P><DT>EXAMPLES<DD>
+    Open a datafile (create it if necessary), for read-write access:
+    <PRE>
+    mk::file open db test.dat</PRE>
+
+    Display the structure of every view in the datafile:
+    <PRE>
+    foreach v [mk::file views db] {
+        puts [mk::view layout db.$v]
+    }</PRE>
+
+    Send all data across a TCP/IP socket connection:
+    <PRE>
+    set chan [socket 127.0.0.1 12345]
+    mk::file save db $chan
+    close $chan</PRE>
+
+    The trick to open a datafile stored inside another MK file (e.g. in VFS)
+    is to load/save data via an in-memory database - replace this:
+    <PRE>
+    mk::file open db test.dat -readonly</PRE>
+    by this:
+    <PRE>
+    mk::file open db
+    set fd [open test.dat]
+    mk::file load db $fd
+    close $fd</PRE>
+<P>
+<P><DT><A name="mk_view"><HR size=1></A><H2>mk::view</H2><DD><H3>View structure and size operations</H3>
+<P><DT>SYNOPSIS<DD><B>mk::view</B> &nbsp;<B>layout</B> &nbsp;<I>tag.view</I> &nbsp;<BR>
+<B>mk::view</B> &nbsp;<B>layout</B> &nbsp;<I>tag.view</I> &nbsp;<I>{structure}</I> &nbsp;<BR>
+<B>mk::view</B> &nbsp;<B>delete</B> &nbsp;<I>tag.view</I> &nbsp;<BR>
+<B>mk::view</B> &nbsp;<B>size</B> &nbsp;<I>path</I> &nbsp;<BR>
+<B>mk::view</B> &nbsp;<B>size</B> &nbsp;<I>path</I> &nbsp;<I>size</I> &nbsp;<BR>
+<B>mk::view</B> &nbsp;<B>info</B> &nbsp;<I>path</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <I>mk::view</I> command is used to query or alter the structure of
+    a <I>view</I> in a datafile (<I>layout</I>, <I>delete</I>),
+    as well as the number of rows it contains (<I>size</I>).
+    The last command (<I>info</I>) returns the list of properties
+    currently defined for a view.
+<P>
+    The '<B>mk::view layout</B>' command returns a description of the current
+    datastructure of <I>tag.view</I>.  If a structure is specified, the
+    current data is restructured to match that, by adding new properties
+    with a default value, deleting obsolete ones, and reordering them.
+<P>
+    Structure definitions consist of a list of properties.
+    Subviews are specified as a sublist of two entries: the name and the
+    list of properties in that subview.  Note that subviews add <I>two</I>
+    levels of nesting (see <I>phones</I> in the phonebook example below).
+    The type of a property is specified 
+    by appending a suffix to the property name (the default type is string):
+<P>
+    <UL><DL compact>
+        <DT> <B>:S</B> <DD>
+            A <B>string</B> property for storing strings of any size, but no null bytes.
+        <DT> <B>:I</B>  <DD>
+            An <B>integer</B> property for efficiently storing values as integers (1..32 bits).
+        <DT> <B>:L</B>  <DD>
+            An <B>long</B> property for storing values as 64-bit integers.
+        <DT> <B>:F</B>  <DD>
+            A <B>float</B> property for storing single-precision floating point values (32 bits).
+        <DT> <B>:D</B>  <DD>
+            A <B>double</B> property for storing double-precision floating point values (64 bits).
+        <DT> <B>:B</B>  <DD>
+            A <B>binary</B> property for untyped binary data (including null bytes).
+        <DT> <B>:M</B>  <DD>
+            Obsolete (now treated as <B>:B</B>).
+    </DL></UL>
+<P>
+    Properties which are not listed int the layout will only remain set while
+    the datafile is open, but not be stored.  To make properties persist,
+    you must list them in the layout definition, and do so <I>before</I> setting them.
+<P>
+    The '<B>mk::view delete</B>' command completely removes a view and all
+    the data it contains from a datafile.
+<P>
+    The '<B>mk::view size</B>' command returns the number of rows contained
+    in the view identified as <I>tag.view</I>.  If an argument is specified,
+    the size of the view is adjusted accordingly, dropping the highest
+    rows if the size is decreased or adding new empty ones if the size is
+    increased.  The command <I>'mk::view size 0'</I> deletes all rows from a
+    view, but keeps the view in the datafile so rows can be added again later
+    (unlike <I>'mk::view delete'</I>.
+<P>
+    The '<B>mk::view info</B>' returns the list of properties which are currently
+    defined for <I>path</I>.<BR>
+<P>
+    Note that the <I>layout</I> and <I>delete</I> sub-commands operate only on top-level
+    views (of the form <I>tag.view</I>), whereas <I>size</I> and
+    <I>info</I> take a <I>path</I> as arguments, which is either a top-level
+    view or a nested subview
+    (of the form 'tag.view!index.subview!subindex...<I>etc</I>...subview').
+<P>
+<P><DT>EXAMPLES<DD>
+    Define a phonebook view which can store more than one
+    phone number for each person:
+    <PRE>
+    mk::view layout db.book {name address {phones {category phone}}}</PRE>
+    Add a new phonebook entry:
+    <PRE>
+    mk::row append db.book name "Steve" address "Down-under"</PRE>
+    Add two phone numbers to phone book entry zero, i.e. "Steve":
+    <PRE>
+    mk::row append db.book!0.phones category "home" phone "1234567"
+    mk::row append db.book!0.phones category "mobile" phone "2345678"</PRE>
+    Restructure the view in the datafile, adding an integer date field:
+    <PRE>
+    mk::view layout db.book {name address {phones {category phone}} date:I}</PRE>
+    
+    Delete all phonebook entries as well as its definition from the datafile:
+    <PRE>
+    mk::view delete db.book</PRE>
+<P>
+<P><DT><A name="mk_cursor"><HR size=1></A><H2>mk::cursor</H2><DD><H3>Cursor variables for positioning</H3>
+<P><DT>SYNOPSIS<DD><B>mk::cursor</B> &nbsp;<B>create</B> &nbsp;<I>cursorName</I> &nbsp;<I>?path?</I> &nbsp;<I>?index?</I> &nbsp;<BR>
+<B>mk::cursor</B> &nbsp;<B>position</B> &nbsp;<I>cursorName</I> &nbsp;<BR>
+<B>mk::cursor</B> &nbsp;<B>position</B> &nbsp;<I>cursorName</I> &nbsp;<I>0</I> &nbsp;<BR>
+<B>mk::cursor</B> &nbsp;<B>position</B> &nbsp;<I>cursorName</I> &nbsp;<I>end</I> &nbsp;<BR>
+<B>mk::cursor</B> &nbsp;<B>position</B> &nbsp;<I>cursorName</I> &nbsp;<I>index</I> &nbsp;<BR>
+<B>mk::cursor</B> &nbsp;<B>incr</B> &nbsp;<I>cursorName</I> &nbsp;<I>?step?</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <I>mk::cursor</I> command is used to manipulate <I>'cursor variables'</I>,
+    which offer an efficient means of iterating and repositioning a 
+    <I>'reference to a row in a view'</I>.
+    Though cursors are equivalent to strings of the
+    form <I>somepath!N</I>, it is much more efficient to keep a cursor around
+    in a variable and to adjust it (using the <I>position</I> subcommand),
+    than evaluating a 'somepath!$index' expression every time a cursor is expected.
+<P>
+    The '<B>mk::cursor create</B>' command defines (or redefines) a cursor variable.
+    The <I>index</I> argument defaults to zero.  This is a convenience function, since
+    <I>'mk::cursor create X somePath N'</I> is equivalent to <I>'set X somePath!N'</I>.
+<P>
+    When both <I>path</I> and <I>index</I> arguments are omitted from
+    the <I>'mk::cursor create'</I> command,
+    a cursor pointing to an empty temporary view is created, 
+    which can be used as buffer for data not stored on file.
+<P>
+    The '<B>mk::cursor position</B>' command returns the current position of a cursor,
+    i.e. the 0-based index of the row it is pointing to.  If an extra argument is
+    specified, the cursor position will be adjusted accordingly.
+    The '<I>end</I>' pseudo-position
+    is the index of the last row (or -1 if the view is currently empty).
+    Note that if '<I>X</I>' is a cursor equivalent to <I>somePath!N</I>, then
+    <I>'mk::cursor position X M'</I> is equivalent to the far less efficient
+    <I>'set X somePath!M'</I>.
+<P>
+    The '<B>mk::cursor incr</B>' command adjusts the current position of a cursor
+    with a specified relative <I>step</I>, which can be positive as well as negative.
+    If <I>step</I> is zero, then this command does nothing.
+    The command <I>'mk::cursor incr X N'</I> is equivalent to
+    <I>'mk::cursor position X [expr {[mk::cursor position X] + N}]'</I>.
+<P>
+<P><DT><A name="mk_row"><HR size=1></A><H2>mk::row</H2><DD><H3>Create, insert, and delete rows</H3>
+<P><DT>SYNOPSIS<DD><B>mk::row</B> &nbsp;<B>create</B> &nbsp;<I>?prop</I> &nbsp;<I>value</I> &nbsp;<I>...?</I> &nbsp;<BR>
+<B>mk::row</B> &nbsp;<B>append</B> &nbsp;<I>path</I> &nbsp;<I>?prop</I> &nbsp;<I>value</I> &nbsp;<I>...?</I> &nbsp;<BR>
+<B>mk::row</B> &nbsp;<B>insert</B> &nbsp;<I>cursor</I> &nbsp;<I>count</I> &nbsp;<I>?cursor2?</I> &nbsp;<BR>
+<B>mk::row</B> &nbsp;<B>delete</B> &nbsp;<I>cursor</I> &nbsp;<I>?count?</I> &nbsp;<BR>
+<B>mk::row</B> &nbsp;<B>replace</B> &nbsp;<I>cursor</I> &nbsp;<I>?cursor2?</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <I>mk::row</I> command deals with one or more rows of information.
+    There is a command to allocate a temporary row which is not part of any
+    datafile (<I>create</I>), and the usual set of container operations:
+    appending, inserting, deleting, and replacing rows.
+<P>
+    The '<B>mk::row create</B>' command creates an empty temporary row, which
+    is not stored in any datafile.
+    Each temporary rows starts out without any properties.
+    Setting a property in a row will implicitly add that
+    property if necessary.
+    The return value is a unique <I>cursor</I>, pointing to
+    this temporary row.  The row (and all data stored in it)
+    will cease to exist when no cursor references to it remain.
+<P>
+    The '<B>mk::row append</B>' command extends the view with a new row,
+    optionally setting some properties in it to the specified values.
+<P>
+    The '<B>mk::row insert</B>' command is similar to the <I>append</I> sub-command,
+    inserting the new row in a specified position instead of at the end.
+    The <B>count</B> argument can be used to efficiently insert
+    multiple copies of a row.
+<P>
+    The '<B>mk::row delete</B>' command deletes one or more rows from a view, starting
+    at the row pointed to by <I>cursor</I>.
+<P>
+    The '<B>mk::row replace</B>' command replaces one row with a copy of another one,
+    or clears its contents if <I>cursor2</I> is not specified.
+<P>
+<P><DT>EXAMPLES<DD>
+    Define a cursor pointing to a new empty row:
+    <PRE>
+    set cursor [mk::row create]</PRE>
+
+    Initialize a temporary view with 100 copies of the string "Hello":
+    <PRE>
+    mk::cursor create cursor 
+    mk::row insert $cursor 100 [mk::row create text "Hello"]</PRE>
+<P>
+<P><DT><A name="mk_get"><HR size=1></A><H2>mk::get</H2><DD><H3>Fetch values</H3>
+<P><DT>SYNOPSIS<DD><B>mk::get</B> &nbsp;<I>cursor</I> &nbsp;?-size?<BR>
+<B>mk::get</B> &nbsp;<I>cursor</I> &nbsp;?-size? &nbsp;<I>prop</I> &nbsp;<I>...</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <B>mk::get</B> command fetches values from the row specified by <I>cursor</I>.
+<P>
+    Without argument, <I>get</I> returns a list of <I>'prop1 value1 prop2 value2 ...'</I>.
+    This format is most convenient for setting an array variable, as the following
+    example illustrates:
+    <PRE>
+    array set v [mk::get db.phonebook!0]
+    parray v</PRE>
+    Note that the <I>cursor</I> argument can be the value of a cursor variable,
+    or it can be synthesized on the spot, as in the above example.
+<P>
+       If the <b>-size</b> option is specified, the size of property values is
+       returned instead of their contents.  This is normally in bytes, but for 
+       integers it can be a negative value indicating the number of bits used
+       to store ints (-1, -2, or -4).  This is an efficient way to determine the
+       sizes of property values without fetching them.
+<P>
+    If arguments are specified in the <I>get</I> command, they are interpreted as
+    property names and a list will be returned
+    containing the values of these properties in the specified order.
+<P>
+    If <I>cursor</I> does not point to a valid row, default values are returned
+    instead (no properties, and empty strings or numeric zero's, according to
+    the property types).
+<P>
+<P><DT>EXAMPLES<DD>
+    Set up an array containing all the fields in the third row:
+    <PRE>
+    array set fields [mk::get db.phonebook!2]</PRE>
+
+    Created a line with some formatted fields:
+
+    <PRE>
+    puts [eval [list format {%-20s %d}] [mk::get db.phonebook!2 name date]]</PRE>
+<P>
+<P><DT><A name="mk_set"><HR size=1></A><H2>mk::set</H2><DD><H3>Store values</H3>
+<P><DT>SYNOPSIS<DD><B>mk::set</B> &nbsp;<I>cursor</I> &nbsp;<I>?prop</I> &nbsp;<I>value</I> &nbsp;<I>...?</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <B>mk::set</B> command stores values into the row specified by <I>cursor</I>.
+<P>
+    If a property is specified which does not exist, it will be appended as a new
+    definition for the containing view.  As an important side effect, all other
+    rows in this view will now also have such a property, with an appropriate
+    default value for the property.  Note that when new
+    properties are defined in this way, they will be created as string properties
+    unless qualified by a type suffix (see <I>'mk::view layout'</I> for details on
+    property types and their default values).
+<P>
+    Using <I>mk::set</I> command without specifying properties
+    returns the current value and is identical to <I>mk::get</I>.
+<P>
+    If <I>cursor</I> points to a non-existent row past the end of the view,
+    an appropriate number of empty rows will be inserted first.
+<P>
+<P><DT><A name="mk_loop"><HR size=1></A><H2>mk::loop</H2><DD><H3>Iterate over the rows of a view</H3>
+<P><DT>SYNOPSIS<DD><B>mk::loop</B> &nbsp;<I>cursorName</I> &nbsp;<I>{body}</I> &nbsp;<BR>
+<B>mk::loop</B> &nbsp;<I>cursorName</I> &nbsp;<I>path</I> &nbsp;<I>{body}</I> &nbsp;<BR>
+<B>mk::loop</B> &nbsp;<I>cursorName</I> &nbsp;<I>path</I> &nbsp;<I>first</I> &nbsp;<I>?limit?</I> &nbsp;<I>?step?</I> &nbsp;<I>{body}</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <B>mk::loop</B> command offers a convenient way to iterate over the
+    rows of a view.  Iteration can be restricted to a certain range, and
+    can optionally use a forward or backward step.  This is a convenience function
+    which is more efficient than performing explicit iteration over an
+    index and positioning a cursor.
+<P>
+    When called with just a <I>path</I> argument, the loop will iterate over all the rows
+    in the corresponding view.
+    The <I>cursorName</I> loop variable will be set (or reset) on each iteration,
+    and is created if it did not yet exist.
+<P>
+    When <I>path</I> is not specified, 
+    the <I>cursorName</I> variable must exist and be a valid
+    cursor, although its current position will be ignored.
+    The command <I>'mk::loop X {...}'</I> is identical to <I>'mk::loop X $X {...}'</I>.
+<P>
+    The <I>first</I> argument specifies
+    the first index position to use (default 0),
+    the <I>limit</I> argument specifies the last argument (default 'end'),
+    and the <I>step</I> argument specifies the increment (default 1).
+    If <I>step</I> is negative and <I>limit</I> exceeds <I>first</I>, then the loop body will 
+    never be executed.  A zero <I>step</I> value can lead to infinite
+    looping unless the <I>break</I> command is called inside the loop.
+<P>
+    The <I>first</I>, <I>limit</I>, and <I>step</I> arguments may be arbitrary integer
+    expressions and are evaluated exactly once when the loop is entered.
+<P>
+Note that you cannot easily use a loop to insert or delete rows, since changes to views do not adjust cursors pointing into that view.  Instead, you can use tricks like moving backwards (for deletions), or  splitting the work into two separate passes.
+        
+<P><DT><A name="mk_elect"><HR size=1></A><H2>mk::select</H2><DD><H3>Selection and sorting</H3>
+<P><DT>SYNOPSIS<DD><B>mk::select</B> &nbsp;<I>path</I> &nbsp;<I>?options</I> &nbsp;<I>...?</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <B>mk::select</B> command combines a flexible selection operation with a way to sort
+    the resulting set of rows.  The result is a list of row index numbers (possibly
+    empty), which can be used to reposition a cursor and to address rows directly.
+<P>
+    A selection is specified using any combination of these criteria:
+    <UL><DL>
+        <DT> <I>prop</I> <I>value</I> <DD>
+            Numeric or case-insensitive match
+        <DT> <B>-min</B> <I>prop</I> <I>value</I> <DD>
+            Property must be greater or equal to value (case is ignored)
+        <DT> <B>-max</B> <I>prop</I> <I>value</I> <DD>
+            Property must be less or equal to value (case is ignored)
+        <DT> <B>-exact</B> <I>prop</I> <I>value</I> <DD>
+            Exact case-sensitive string match
+        <DT> <B>-glob</B> <I>prop</I> <I>pattern</I> <DD>
+            Match "glob-style" expression wildcard
+        <DT> <B>-globnc</B> <I>prop</I> <I>pattern</I> <DD>
+            Match "glob-style" expression, ignoring case
+        <DT> <B>-regexp</B> <I>prop</I> <I>pattern</I> <DD>
+            Match specified regular expression
+        <DT> <B>-keyword</B> <I>prop</I> <I>word</I> <DD>
+            Match word as free text or partial prefix
+    </DL></UL>
+    If multiple criteria are specified, then
+    selection succeeds only if all criteria are satisfied.
+    If <I>prop</I> is a list, selection succeeds if <I>any</I> of the
+    given properties satisfies the corresponding match.
+<P>
+    Optional selection constraints:
+    <UL><DL>
+        <DT> <B>-first</B> <I>pos</I> <DD>
+            Selection starts at specified row index
+        <DT> <B>-count</B> <I>num</I> <DD>
+            Return no more than this many results
+    </DL></UL>
+    Note: not yet very useful with sorting, which is
+    done after these constraints have been applied.
+<P>
+    To sort the set of rows (with or without preliminary selection), use:
+    <UL><DL>
+        <DT> <B>-sort</B> <I>prop</I> <BR>
+             <B>-sort</B> {<I>prop</I> ...} <DD>
+            Sort on one or more properties, ascending
+        <DT> <B>-rsort</B> <I>prop</I> <BR>
+             <B>-rsort</B> {<I>prop</I> ...} <DD>
+            Sort on one or more properties, descending
+    </DL></UL>
+    Multiple sort options are combined in the order given.
+<P>
+<P><DT>EXAMPLES<DD>
+    Select a range of entries:
+    <PRE>
+    foreach i [mk::select db.phonebook -min date 19980101 -max date 19980131] {
+        puts "Dated Jan 1998: [mk::get db.phonebook!$i name]"
+    }</PRE>
+
+    Search for a unique match (<I>'-count 2'</I>
+    speeds up selection when many entries match):
+    <PRE>
+    set v [mk::select db.phonebook -count 2 -glob name "John*"]
+    switch [llength $v] {
+        0       {puts "not found"}
+        1       {puts "found: [mk::get db.phonebook![lindex $v 0] name]"}
+        2       {puts "there is more than one entry matching 'John*'"}
+    }</PRE>
+
+    Sort by descending date and by ascending name:
+    <PRE>
+    foreach i [mk::select db.phonebook -rsort date -sort name] {
+        puts "Change log: [mk::get db.phonebook!$i date name]"
+    }</PRE>
+<P>
+<P><DT><A name="mk_channel"><HR size=1></A><H2>mk::channel</H2><DD><H3>Channel interface</H3>
+<P><DT>SYNOPSIS<DD><B>mk::channel</B> &nbsp;<I>path</I> &nbsp;<I>prop</I> &nbsp;<I>?mode?</I> &nbsp;<BR>
+<P><DT>DESCRIPTION<DD>
+    The <B>mk::channel</B> command provides a channel interface to binary
+    fields.  It needs the <i>path</i> of a row and the name of a binary
+    <i>prop</i>, and returns a channel
+    descriptor which can be used to read or write from.
+<P>
+    Channels are opened in one of three modes:
+    <BLOCKQUOTE>
+             <B>read</B> - <I>open for reading existing contents (default)</I> <BR>
+             <B>write</B> - <I>clear contents and start saving data</I><BR>
+             <B>append</B> - <I>keep contents, set seek pointer to end</I>
+    </BLOCKQUOTE>
+<P>
+    Note: do not insert or delete rows in a view within which there are
+    open channels, because subsequent reads and writes may end up going
+    to the wrong memo property.
+<P>
+<DT>EXAMPLES<DD>
+    Write a few values (with line separators):
+    <PRE>
+    mk::view layout db.v {b:B}
+    mk::view size db.v 1
+
+    set fd [mk::channel db.v!0 b w]
+    puts $fd one
+    puts $fd two
+    puts $fd three
+    close $fd</PRE>
+    
+    Read values back, line by line:
+    <PRE>
+    set fd [mk::channel db.v!0 b]
+    while {[gets $fd text] >= 0} {
+        puts $text
+    }
+    close $fd</PRE>
+<P>
+</DL>
+<!--END-->
+<P>
+<HR size=1>
+&copy; 2005 Jean-Claude Wippler &lt;<A HREF="mailto:jcw@equi4.com">jcw@equi4.com</A>&gt;
+</BODY>
+</HTML>
diff --git a/8.x/mk/examples/README b/8.x/mk/examples/README
new file mode 100644 (file)
index 0000000..5ec88b6
--- /dev/null
@@ -0,0 +1,23 @@
+Sample scripts
+
+aside.py        commit extend and commit aside
+bigblock.tcl           storing 100,000,000 integers
+blockdels.tcl          blocked view deletion tests
+case.py         case sensitivity can be a bit tricky
+demo.py         trivial demo in Python
+demo.tcl        trivial demo in Tcl, new OO interface
+demold.tcl      trivial demo in Tcl, original API
+derived.py      derived views propagate changes
+find.py         find, binary search, and hashing performance
+mapped.tcl      performance of plain, hashed, ordered, blocked views
+millions.py     storing millions of row, using a trick (by Christian Tismer)
+mkhash.cpp      hashed / blocked / ordered view performance in C++
+mkmemoio.py     treating a memo (binary) property as an I/O stream
+pair.py         pairwise view combination
+random.tcl      test of 100,000 adds/mods/dels using a bytes property
+remap.py        new mapping views (like mapped.tcl), in Python
+selfref.py      defining a self-referential (recursive) structure
+selmap.tcl      illustrates mapping select results back to a view
+slow.tcl        hashed views performance in Tcl
+sort.tcl        sorting performance in Tcl
+wrap.py         wrapping provides a MK layer around anything
diff --git a/8.x/mk/examples/aside.py b/8.x/mk/examples/aside.py
new file mode 100644 (file)
index 0000000..f2a459e
--- /dev/null
@@ -0,0 +1,153 @@
+# The new MK 2.3 commit-aside feature, in Python
+#
+# Expected output:
+# 1 2 3 ok
+
+import os
+import Mk4py
+mk = Mk4py
+
+def t1(): # add several rows using commit-aside
+  try: os.remove("_f.mk")
+  except: pass
+  try: os.remove("_f.mka")
+  except: pass
+
+  db = mk.storage("_f.mk", 1)
+  vw = db.getas("a[i:I]")
+  vw.append(i=111)
+  vw.append(i=222)
+  vw.append(i=333)
+  db.commit()
+  del db
+
+  db = mk.storage("_f.mk", 0)
+  vw = db.view("a")
+  assert len(vw) == 3
+
+  dba = mk.storage("_f.mka", 1)
+  db.aside(dba)
+  vw = db.view("a")
+  assert len(vw) == 3
+
+  vw.append(i=444)
+  vw.append(i=555)
+  assert len(vw) == 5
+
+  db.commit()
+  dba.commit()
+  del db
+  del dba
+
+  db = mk.storage("_f.mk", 0)
+  vw = db.view("a")
+  assert len(vw) == 3 # now it has three rows
+  assert vw[0].i == 111
+  assert vw[1].i == 222
+  assert vw[2].i == 333
+
+  dba = mk.storage("_f.mka", 0)
+  db.aside(dba)
+  vw = db.view("a")
+  assert len(vw) == 5 # now it has five :)
+  assert vw[0].i == 111
+  assert vw[1].i == 222
+  assert vw[2].i == 333
+  assert vw[3].i == 444
+  assert vw[4].i == 555
+
+def t2(): # add second property using commit-aside
+  try: os.remove("_f.mk")
+  except: pass
+  try: os.remove("_f.mka")
+  except: pass
+
+  db = mk.storage("_f.mk", 1)
+  vw = db.getas("a[i:I]")
+  vw.append(i=111)
+  db.commit()
+  del db
+
+  db = mk.storage("_f.mk", 0)
+  vw = db.view("a")
+  assert len(vw) == 1
+
+  dba = mk.storage("_f.mka", 1)
+  db.aside(dba)
+  vw = db.getas("a[i:I,j:I]")
+  assert len(vw) == 1
+
+  vw.append(i=222,j=333)
+  assert len(vw) == 2
+
+  db.commit()
+  dba.commit()
+  del db
+  del dba
+
+  db = mk.storage("_f.mk", 0)
+  vw = db.view("a")
+  assert len(vw) == 1 # now it has one property and row
+  assert len(vw.structure()) == 1
+  assert vw[0].i == 111
+
+  dba = mk.storage("_f.mka", 0)
+  db.aside(dba)
+  vw = db.view("a")
+  assert len(vw) == 2 # now it has two of both :)
+  assert len(vw.structure()) == 2
+  assert vw[0].i == 111
+  assert vw[0].j == 0
+  assert vw[1].i == 222
+  assert vw[1].j == 333
+
+def t3(): # remove second property using commit-aside
+  try: os.remove("_f.mk")
+  except: pass
+  try: os.remove("_f.mka")
+  except: pass
+
+  db = mk.storage("_f.mk", 1)
+  vw = db.getas("a[i:I,j:I]")
+  vw.append(i=111,j=222)
+  db.commit()
+  del db
+
+  db = mk.storage("_f.mk", 0)
+  vw = db.view("a")
+  assert len(vw) == 1
+
+  dba = mk.storage("_f.mka", 1)
+  db.aside(dba)
+  vw = db.getas("a[i:I]")
+  assert len(vw) == 1
+
+  db.commit()
+  dba.commit()
+  del db
+  del dba
+
+  db = mk.storage("_f.mk", 0)
+  vw = db.view("a")
+  assert len(vw) == 1
+  assert len(vw.structure()) == 2 # now you see j
+  assert vw[0].i == 111
+  assert vw[0].j == 222
+
+  dba = mk.storage("_f.mka", 0)
+  db.aside(dba)
+  vw = db.view("a")
+  assert len(vw) == 1
+  assert len(vw.structure()) == 1 # now you don't :)
+  assert vw[0].i == 111
+
+print 1,
+t1()
+print 2,
+t2()
+print 3,
+t3()
+print "ok"
+
+os.remove("_f.mk")
+os.remove("_f.mka")
diff --git a/8.x/mk/examples/bigblock.tcl b/8.x/mk/examples/bigblock.tcl
new file mode 100644 (file)
index 0000000..c52cc73
--- /dev/null
@@ -0,0 +1,30 @@
+# Let's store 100 million integers
+
+catch { load ../builds/.libs/libmk4tcl[info sharedlibextension] Mk4tcl }
+puts "[info script] - Mk4tcl [package require Mk4tcl] - $tcl_platform(os)"
+
+file delete bigdata.mk
+mk::file open db bigdata.mk
+mk::view layout db.v {{_B {a:I}}}
+
+set bv [[mk::view open db.v] view blocked]
+
+set n 0
+
+puts " filled    commit   #blocks   filesize   memuse        total"
+
+for {set i 0} {$i < 20} {incr i} {
+
+  set s [clock seconds]
+  for {set j 0} {$j < 5000000} {incr j} {
+    $bv insert end a [incr n]
+  }
+  set t [expr {[clock seconds] - $s}]
+  set u [expr {[lindex [time {mk::file commit db}] 0]/1000.0}]
+  set v [mk::view size db.v]
+  set w [file size bigdata.mk]
+  set x [lindex [exec ps l --noheader [pid]] 7]
+  set y [$bv size]
+
+  puts [format {%6s s %7.1f ms %6d %10d b %6d K %10d rows} $t $u $v $w $x $y]
+}
diff --git a/8.x/mk/examples/blockdels.tcl b/8.x/mk/examples/blockdels.tcl
new file mode 100644 (file)
index 0000000..c3de75a
--- /dev/null
@@ -0,0 +1,69 @@
+# Blocked view deletion tests
+# jcw, 26-3-2002
+
+if [catch {package require Mk4tcl}] {
+  catch {load ./Mk4tcl.so mk4tcl}
+  catch {load ./Mk4tcl_d.dll mk4tcl}
+}
+
+proc fill {n} {
+  $::bv size 0
+  set ::vv {}
+  for {set i 0} {$i < $n} {incr i} {
+    $::bv insert end a $i
+    lappend ::vv $i
+  }
+}
+
+proc remove {from {count 1}} {
+  incr count -1
+  $::bv delete $from [incr count $from]
+  set ::vv [lreplace $::vv $from $count]
+}
+
+proc check {} {
+  set pos 0
+  foreach y $::vv {
+    set x [$::bv get $pos a]
+    if {$x != $y} { error "pos $pos is $x, should be $y" }
+    incr pos
+  }
+}
+
+mk::file open db
+mk::view layout db.v {{_B {a:I}}}
+
+set bv [[mk::view open db.v] view blocked]
+
+for {set j 1} {$j < 6} {incr j} {
+  fill 2000
+  remove 996 $j
+  check
+}
+
+for {set j 988} {$j < 1001} {incr j} {
+  fill 2000
+  remove $j 10
+  check
+}
+
+for {set j 1100} {$j < 1110} {incr j} {
+  fill 3000
+  remove 985 $j
+  check
+}
+
+set total 50000
+fill $total
+
+foreach x {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
+  puts -nonewline stderr "$x "
+  for {set i [expr {$total-1025}]} {$i > 0} {incr i -1000} {
+    remove $i 45
+    remove $i 45
+    incr total -90
+  }
+  check
+}
+
+puts stderr OK
diff --git a/8.x/mk/examples/case.py b/8.x/mk/examples/case.py
new file mode 100644 (file)
index 0000000..474bfa1
--- /dev/null
@@ -0,0 +1,32 @@
+# Properties are case-insensitive, but this can lead to some
+# surprising behavior: the first way a property is used will
+# determine how it ends up in the global symbol table.
+#
+# Sample output:
+#   Property('S', 'HeLLo') Property('S', 'HeLLo')
+#   2
+#   2
+#   135099576
+#   135033272
+#   0
+
+import metakit
+db = metakit.storage()
+v1 = db.getas('lo[HeLLo:S]')
+v2 = db.getas('hi[hello:S]')
+
+# surprise: this prints two mixed-case names
+print v1.HeLLo, v2.hello
+
+# this shows that the Metakit property is the same for both
+# reason: there is a single global case-insensitive symbol table
+print metakit.property('S','HeLLo').id
+print metakit.property('S','hello').id
+
+# this shows that the Python objects differ
+# reason: these are two wrapper objects around the same thing
+print id(metakit.property('S','HeLLo'))
+print id(metakit.property('S','hello'))
+
+# this causes a mismatch, it will have to be fixed one day
+print metakit.property('S','HeLLo') == metakit.property('S','hello')
diff --git a/8.x/mk/examples/demo.py b/8.x/mk/examples/demo.py
new file mode 100644 (file)
index 0000000..34193f4
--- /dev/null
@@ -0,0 +1,37 @@
+# Simple demo, can be used to verify proper Mk4py installation
+
+import Mk4py, sys
+mk = Mk4py
+print sys.argv[0], '- Mk4py', mk.version, '-', sys.platform
+
+# On first run, output should consist of 5 lines:
+#   John Lennon 44
+#   Flash Gordon 42
+#   Flash Gordon 42
+#   John Lennon 44
+#   John Lennon 44
+# Each following run will generate 5 more lines of output
+
+  # create a file called "demo.db"
+db = mk.storage("demo.db",1)
+  # define a view in it called "people", containing three fields
+vw = db.getas("people[first:S,last:S,shoesize:I]")
+
+  # let's append two rows to the end of the view
+vw.append(first='John',last='Lennon',shoesize=44)
+vw.append(first='Flash',last='Gordon',shoesize=42)
+
+  # commit the structure and data to file
+db.commit()
+
+  # a simple loop to print out all rows
+for r in vw:
+  print r.first, r.last, r.shoesize
+
+  # another way to loop, in sorted order
+for r in vw.sort(vw.last):
+  print r.first, r.last, r.shoesize
+
+  # this loop iterates over a selection 
+for r in vw.select(first='John'):
+  print r.first, r.last, r.shoesize
diff --git a/8.x/mk/examples/demo.tcl b/8.x/mk/examples/demo.tcl
new file mode 100644 (file)
index 0000000..32f16a1
--- /dev/null
@@ -0,0 +1,40 @@
+# Simple demo, can be used to verify proper Mk4tcl installation
+
+load ../builds/Mk4tcl[info sharedlibextension] Mk4tcl
+puts "[info script] - Mk4tcl [package require Mk4tcl] - $tcl_platform(os)"
+
+# On first run, output should consist of 5 lines:
+#   John Lennon 44
+#   Flash Gordon 42
+#   Flash Gordon 42
+#   John Lennon 44
+#   John Lennon 44
+# Each following run will generate 5 more lines of output
+
+  # create a file called "demo.db"
+mk::file open db demo.db -nocommit
+  # define a view in it called "people", containing three fields
+mk::view layout db.people {first last shoesize:I}
+set vw [mk::view open db.people]
+
+  # let's append two rows to the end of the view
+$vw insert end first John last Lennon shoesize 44
+$vw insert end first Flash last Gordon shoesize 42
+
+  # commit the structure and data to file
+mk::file commit db
+
+  # a simple loop to print out all rows
+for {set r 0} {$r < [$vw size]} {incr r} {
+  puts [$vw get $r first last shoesize]
+}
+
+  # another way to loop, in sorted order
+foreach r [$vw select -sort last] {
+  puts [$vw get $r first last shoesize]
+}
+
+  # this loop iterates over a selection 
+foreach r [$vw select first John] {
+  puts [$vw get $r first last shoesize]
+}
diff --git a/8.x/mk/examples/demold.tcl b/8.x/mk/examples/demold.tcl
new file mode 100644 (file)
index 0000000..c894d59
--- /dev/null
@@ -0,0 +1,39 @@
+# Simple demo, can be used to verify proper Mk4tcl/TclKit installation
+#
+# On first run, output should consist of 5 lines:
+#   John Lennon 44
+#   Flash Gordon 42
+#   first Flash last Gordon shoesize 42
+#   first John last Lennon shoesize 44
+#   first John last Lennon shoesize 44
+#
+# Every following run will generate 5 more lines of output
+
+package require Mk4tcl
+
+  # create a file called "demo.db"
+mk::file open db demo.db
+  # define a view in it called "people", containing three fields
+set vw [mk::view layout db.people {first last shoesize:I}]
+
+  # let's append two rows to the end of the view
+mk::row append $vw first John last Lennon shoesize 44
+mk::row append $vw first Flash last Gordon shoesize 42
+
+  # commit the structure and data to file
+mk::file commit db
+
+  # a simple loop to print out all rows
+mk::loop c $vw {
+  puts [mk::get $c first last shoesize]
+}
+
+  # another way to loop, in sorted order
+foreach r [mk::select $vw -sort last] {
+  puts [mk::get $vw!$r]
+}
+
+  # this loop iterates over a selection 
+foreach r [mk::select $vw first John] {
+  puts [mk::get $vw!$r]
+}
diff --git a/8.x/mk/examples/derived.py b/8.x/mk/examples/derived.py
new file mode 100644 (file)
index 0000000..af36cb6
--- /dev/null
@@ -0,0 +1,36 @@
+# Demo of derived view dynamics
+#
+# Output:
+# [1, 2, 3, 4, 5, 6]
+# [2, 3, 4, 5]
+# [2, 4, 5]
+# [2, 5]
+# [1, 2, 5, 6]
+
+import metakit
+db = metakit.storage()
+vw = db.getas('data[value:I]')
+
+def fill(l):
+  vw[:] = []
+  for i in l:
+    vw.append(value=i)
+
+def show(v):
+  print map((lambda x: x.value), v)
+
+fill([1,2,3,4,5,6])
+show(vw)
+
+  # select values in range [2..5]
+v2 = vw.select({'value':2},{'value':5})
+show(v2)
+
+  # a deletion in original "vw" affects derived "v2"
+vw.delete(2)
+show(v2)
+
+  # deletion in derived "v2" affects both (new in 2.3)
+v2.delete(1)
+show(v2)
+show(vw)
diff --git a/8.x/mk/examples/find.py b/8.x/mk/examples/find.py
new file mode 100644 (file)
index 0000000..1ae6b0a
--- /dev/null
@@ -0,0 +1,115 @@
+"""
+Some demo code to show find performance and some of the new indexing
+features in Metakit 2.3.  Sample output (SuSE Linux 6.4, PIII/650):
+
+  find.py - Mk4py 2.3.2 - linux2
+  filldb 100 rows: 0.015092 sec
+   find_raw 10000 times, key 50 -> 50: 1.20376 sec
+   find_raw 10000 times, key 101 -> -1: 1.82736 sec
+   find_ord 10000 times, key 50 -> 50: 0.722506 sec
+   find_ord 10000 times, key 101 -> -1: 0.670945 sec
+   hash_ini 1000 times, size 129: 0.487246 sec
+   hash_key 10000 times, key 50 -> 50: 0.658689 sec
+   hash_key 10000 times, key 101 -> -1: 0.592888 sec
+  filldb 1000 rows: 0.059973 sec
+   find_raw 1000 times, key 500 -> 500: 0.715116 sec
+   find_raw 1000 times, key 1001 -> -1: 1.35979 sec
+   find_ord 1000 times, key 500 -> 500: 0.0832601 sec
+   find_ord 1000 times, key 1001 -> -1: 0.0784379 sec
+   hash_ini 100 times, size 1025: 0.565817 sec
+   hash_key 10000 times, key 500 -> 500: 0.666233 sec
+   hash_key 10000 times, key 1001 -> -1: 0.714768 sec
+  filldb 10000 rows: 0.508873 sec
+   find_raw 100 times, key 5000 -> 5000: 0.669386 sec
+   find_raw 100 times, key 10001 -> -1: 1.30918 sec
+   find_ord 100 times, key 5000 -> 5000: 0.00834703 sec
+   find_ord 100 times, key 10001 -> -1: 0.00776601 sec
+   hash_ini 10 times, size 16385: 0.424207 sec
+   hash_key 10000 times, key 5000 -> 5000: 0.665882 sec
+   hash_key 10000 times, key 10001 -> -1: 0.640642 sec
+  filldb 100000 rows: 4.96599 sec
+   find_raw 10 times, key 50000 -> 50000: 0.625583 sec
+   find_raw 10 times, key 100001 -> -1: 1.23957 sec
+   find_ord 10 times, key 50000 -> 50000: 0.000901937 sec
+   find_ord 10 times, key 100001 -> -1: 0.00124598 sec
+   hash_ini 1 times, size 131073: 0.517645 sec
+   hash_key 10000 times, key 50000 -> 50000: 0.657581 sec
+   hash_key 10000 times, key 100001 -> -1: 0.628431 sec
+
+In a nutshell: unordered views use linear scan, which is extremely
+efficient but O(N), ordered views will switch to binary search, and
+if a hash mapping is used then you get the usual O(1) of hashing.
+
+The statement "vwo = vw.ordered(1)" sets up a view layer around vw,
+which allows Metakit to take advantage of sort order.  The numeric
+argument specifies how many of the first property define the key.
+The vwo view is modifiable, it will maintains order on insertions.
+
+The statement "vwh = vw.hash(map,1)" sets up a view layer around vw,
+using a secondary 'map' view to manage hashing.  As with ordered,
+the last argument specifies the number or properties to use as key.
+When vwh is modified, both vw and map will be adjusted.  The hash
+view can be set up after vw has been filled, this is probably a bit
+faster than setting up vwh first, and inserting into new data in vwh.
+The underlying vw and map views may *not* be altered directly once
+a hash is in use, unless you clear map and redefine the hash layer.
+
+Metakit 2.01 only supports find_raw (linear scanning).
+"""
+
+import sys; sys.path.append('../builds'); import Mk4py; mk = Mk4py
+print sys.argv[0], '-', 'Mk4py', mk.version, '-', sys.platform
+
+from time import time
+
+db = mk.storage()
+vw = db.getas('vw[p1:I,p2:I]')
+map = db.getas('map[_H:I,_R:I]')
+
+def filldb(n=1000):
+  del vw[:]
+  t0 = time();
+  for i in xrange(n):
+    vw.append(p1=i, p2=i+i)
+  print 'filldb %d rows: %g sec' % (n, time() - t0)
+
+# this find will do a linear scan
+def find_raw(k,n=1000):
+  t0 = time();
+  for i in xrange(n):
+    r = vw.find(p1=k)
+  print ' find_raw %d times, key %d -> %d: %g sec' % (n, k, r, time() - t0)
+
+# this find switches to binary search, because it knows the view is ordered
+def find_ord(k,n=1000):
+  t0 = time();
+  vwo = vw.ordered()
+  for i in xrange(n):
+    r = vwo.find(p1=k)
+  print ' find_ord %d times, key %d -> %d: %g sec' % (n, k, r, time() - t0)
+
+# setting up a hash view initializes it, since the map size is still zero
+def hash_ini(n=1000):
+  t0 = time();
+  for i in xrange(n):
+    del map[:]
+    vwh = vw.hash(map)
+  print ' hash_ini %d times, size %d: %g sec' % (n, len(map), time() - t0)
+# this lookup no longer initializes, find will now do a hash lookup
+def hash_key(k,n=1000):
+  t0 = time();
+  vwh = vw.hash(map)
+  for i in xrange(n):
+    r = vwh.find(p1=k)
+  print ' hash_key %d times, key %d -> %d: %g sec' % (n, k, r, time() - t0)
+
+for n in (100, 1000, 10000, 100000):
+  filldb(n)
+  find_raw(n/2, 1000000/n)
+  find_raw(n+1, 1000000/n)
+  find_ord(n/2, 1000000/n)
+  find_ord(n+1, 1000000/n)
+  hash_ini(100000/n)
+  hash_key(n/2, 10000)
+  hash_key(n+1, 10000)
diff --git a/8.x/mk/examples/mapped.tcl b/8.x/mk/examples/mapped.tcl
new file mode 100644 (file)
index 0000000..b30c40a
--- /dev/null
@@ -0,0 +1,228 @@
+# Some example and timing tests of the new hash/blocked/ordered views
+
+if [catch {package require Mk4tcl}] {
+  catch {load ./Mk4tcl.so mk4tcl}
+  catch {load ./Mk4tcl_d.dll mk4tcl}
+}
+
+proc timedRun {tag count args} {
+  set usec [lindex [time $args $count] 0]
+  if {$usec >= 1000000} {
+    set t [format {%.2f seconds} [expr {$usec/1000000.0}]]
+  } elseif {$usec >= 1000} {
+    set t [format {%.2f mSec} [expr {$usec/1000.0}]]
+  } else {
+    set t [format {%d uS} $usec]
+  }
+  puts [format {     %-10s %5dx -> %s} $tag $count $t]
+  return $usec
+}
+
+proc setupPlain {} {
+  global blocked_data
+
+  file delete _large.mk
+  mk::file open db _large.mk -nocommit
+
+  if $blocked_data {
+    mk::view layout db.words {{_B {k1 k2:I v:I}}}
+    mk::view open db.words rawdata
+    catch {rename words ""}
+    rename [rawdata view blocked] words
+  } else {
+    mk::view layout db.words {k1 k2:I v:I}
+    mk::view open db.words words
+  }
+}
+
+proc teardownPlain {} {
+  teardown
+}
+
+proc setupHash {} {
+  global blocked_data blocked_map
+
+  file delete _large.mk
+  mk::file open db _large.mk -nocommit
+
+  if $blocked_data {
+    mk::view layout db.words {{_B {k1 k2:I v:I}}}
+    mk::view open db.words rawdata
+    catch {rename data ""}
+    rename [rawdata view blocked] data
+  } else {
+    mk::view layout db.words {k1 k2:I v:I}
+    mk::view open db.words data
+  }
+
+  if $blocked_map {
+    mk::view layout db.words_map {{_B {_H:I _R:I}}}
+    mk::view open db.words_map rawmap
+    #catch {rename map ""}
+    #rename [rawmap view blocked] map
+    set map [rawmap view blocked]
+  } else {
+    mk::view layout db.words_map {_H:I _R:I}
+    mk::view open db.words_map map
+    set map map
+  }
+
+  #rename [data view hash map 2] words
+  rename [data view hash $map 2] words
+}
+
+proc teardownHash {} {
+  teardown
+}
+
+proc setupOrdered {} {
+  global blocked_data
+
+  file delete _large.mk
+  mk::file open db _large.mk -nocommit
+
+  if $blocked_data {
+    mk::view layout db.words {{_B {k1 k2:I v:I}}}
+    mk::view open db.words rawdata
+    catch {rename data ""}
+    rename [rawdata view blocked] data
+  } else {
+    mk::view layout db.words {k1 k2:I v:I}
+    mk::view open db.words data
+  }
+
+  rename [data view ordered 2] words
+}
+
+proc teardownOrdered {} {
+  teardown
+}
+
+proc setupBoth {} {
+  global blocked_data blocked_map
+
+  file delete _large.mk
+  mk::file open db _large.mk -nocommit
+
+  if $blocked_data {
+    mk::view layout db.words {{_B {k1 k2:I v:I}}}
+    mk::view open db.words rawdata
+    catch {rename data ""}
+    rename [rawdata view blocked] data
+  } else {
+    mk::view layout db.words {k1 k2:I v:I}
+    mk::view open db.words data
+  }
+
+  if $blocked_map {
+    mk::view layout db.words_map {{_B {_H:I _R:I}}}
+    mk::view open db.words_map rawmap
+    #catch {rename map ""}
+    #rename [rawmap view blocked] map
+    set map [rawmap view blocked]
+  } else {
+    mk::view layout db.words_map {_H:I _R:I}
+    mk::view open db.words_map map
+    set map map
+  }
+
+  #catch {rename hash ""}
+  #rename [data view hash map 2] hash
+  set hash [data view hash $map 2]
+
+  #rename [hash view ordered 2] words
+  rename [$hash view ordered 2] words
+}
+
+proc teardownBoth {} {
+  teardown
+}
+
+proc teardown {} {
+  rename words ""
+  rename hash ""
+  rename data ""
+  rename map ""
+
+  rename rawdata ""
+  rename rawmap ""
+
+  mk::file close db
+}
+
+proc filldb {n} {
+  puts -nonewline stderr " filldb $n ... "
+  set fd [open words]
+
+  set n0 [words size]
+  set t0 [clock clicks]
+  while {[gets $fd w] >= 0} {
+    words insert end k1 $w k2 $n v [expr {$n * [string length $w]}]
+    #if {[words size] % 1000 == 0} {puts -nonewline stderr *}
+  }
+  set usec [expr {[clock clicks]-$t0}]
+
+  close $fd
+  set rps [expr {int(([words size]-$n0) / ($usec / 1000000.0))}]
+  puts stderr "$rps adds/sec ($n0..[words size] rows)"
+}
+
+proc run {type bdata bmap runs finds} {
+  global blocked_data blocked_map
+  set blocked_data $bdata
+  set blocked_map $bmap
+
+  set s ""
+  if $bdata {append s " - data is blocked"}
+  if $bmap {append s " - map is blocked"}
+
+  puts "\n*** $type$s ***\n"
+
+  proc map {args} {return ?}
+  proc rawmap {args} {return ?}
+  proc data {args} {return ?}
+  proc rawdata {args} {return ?}
+  proc hash {args} {return ?}
+
+  setup$type
+
+  set runCounter 99
+
+  while {[incr runs -1] >= 0} {
+    timedRun Fill 1 filldb [incr runCounter]
+    timedRun Commit 1 mk::file commit db
+    timedRun Find $finds words find k1 iterator k2 $runCounter
+  }
+
+  puts " [words size] rows, [map size] hash slots,\
+      file size = [file size _large.mk]"
+  puts "     [rawdata size] data blocks, [rawmap size] map blocks"
+
+  teardown$type
+}
+
+  # plain table, append at end, find with linear scan
+run Plain 0 0 3 10
+run Plain 1 0 3 10
+
+  # hash table, with data and/or map optionally blocked
+run Hash 0 0 3 1000
+run Hash 0 1 3 1000
+run Hash 1 0 3 1000
+run Hash 1 1 3 1000
+
+  # binary search, with data optionally blocked
+run Ordered 0 0 3 1000
+run Ordered 1 0 3 1000
+
+  # combination of the above: hash access, rows kept in sort order
+run Both 0 0 2 1000
+run Both 0 1 2 1000
+run Both 1 0 2 1000
+run Both 1 1 2 1000
+
+  # create larger datasets, this takes a long time
+run Plain 1 0 10 10
+run Hash  1 0 10 1000
+run Ordered 1 0 10 1000
+run Both  1 0 10 1000
diff --git a/8.x/mk/examples/millions.py b/8.x/mk/examples/millions.py
new file mode 100755 (executable)
index 0000000..d132599
--- /dev/null
@@ -0,0 +1,207 @@
+"""
+Storing 25.000.000 rows in a Metakit file.
+
+(C) Christian Tismer, Professional Net Service
+  first version from 990822
+  update: improved, faster spreading.
+
+This implementation is hereby donated to JCW, therefore
+(C) Jean-Claude Wippler (Equi4 Software) 1999
+
+Data structure:
+We split the main view by some number of subviews.
+This gives us one level of indirection.
+
+First simple test:
+10 fields of tiny integers.
+Addressing is done only by row number.
+
+In order to allow for deletes and inserts, we keep
+a list of block sizes and do a little B-tree like
+juggling.
+
+"""
+
+import Mk4py
+mk=Mk4py
+
+import whrandom, string, sys, bisect
+
+class big_mk:
+  def __init__(self, dbpath, rw):
+    self.db = mk.storage(dbpath, rw)
+    
+  def getas(self, struc_str):
+    parts = string.split(struc_str, "[", 1)
+    if len(parts) < 2:
+      self.db.getas(parts[0])
+      return   # this was a delete
+    self.main_name, rest = parts
+    ret= big_view(self.db.getas("%s[data[%s]" % (self.main_name, rest)))
+    ret.big_db = self
+    return ret
+    
+  def commit(self): return self.db.commit()
+  def rollback(self): return self.db.rollback()
+  def description(self): return self.db.description()
+    
+class big_view:
+  def __init__(self, view):
+    self.view = view
+    if len(self.view) == 0:
+      self.view.append()
+    self.calc_recnos()
+    self.blocksize = blocksize
+    self.lower = self.blocksize *2/3
+    self.upper = self.blocksize *2 - self.lower
+    self.bisect = bisect.bisect
+    self.names = []
+    for prop in self.view[-1].data.structure():
+      self.names.append(prop.name)
+      
+  def __len__(self):
+    rn = self.recnos
+    if not rn: return 0
+    return rn[-1]+len(self.view[-1].data)
+    
+  def __getitem__(self, idx):
+    main, sub = self._seek(idx)
+    return self.view[main].data[sub]
+    
+  def __setitem__(self, idx, rec):
+    main, sub = self._seek(idx)
+    self.view[main].data[sub] = rec
+    
+  """
+  we can't do slices yet, since I have no idea
+  if this is necessary, and I don't see exactly
+  how this should work
+  """
+    
+  def append(self, record = None):
+    v = self.view
+    if not self.recnos or len(v[-1].data) >= self.blocksize:
+      v.append()
+      self.calc_recnos()
+    return self.recnos[-1] + v[-1].data.append(record)
+    
+  def insert(self, idx, rec=None):
+    main, sub = self._seek(idx)
+    view = self.view[main].data
+    view.insert(sub, rec)
+    if len(view) > self.upper:
+      self._balance(main)
+    self.calc_recnos()
+
+  def delete(self, idx):
+    main, sub = self._seek(idx)
+    view = self.view[main].data
+    view.delete(sub)
+    if len(view) <= self.lower:
+      self._balance(main)
+    self.calc_recnos()
+
+  def _seek(self, idx):
+    rn = self.recnos
+    pos = self.bisect(rn, idx)-1
+    base = rn[pos]
+    return pos, idx-base
+  
+  def calc_recnos(self):
+    v = self.view
+    res = [None] * len(v)
+    recno = 0
+    for i in range(len(res)):
+      res[i] = recno
+      recno = recno + len(v[i].data)
+    self.recnos = res
+    
+  def _balance(self, spot):
+    """
+    very simple approach: we merge about three 
+    blocks and spread them again.
+    """
+    v = self.view
+    if spot < 0 or spot > len(v) or len(v)==1 : return
+    if spot > 0:
+      spot = spot-1
+    self._merge(spot)
+    if spot < len(v)-1:
+      self._merge(spot)
+    self._spread(spot)
+      
+  def _merge(self, spot):
+    """
+    merge this block and the next one.
+    Delete the then empty next one
+    """
+    v = self.view
+    v[spot].data = v[spot].data + v[spot+1].data
+    v.delete(spot+1)
+    
+  def _spread(self, spot):
+    """
+    Spread this block into equally sized ones.
+    """
+    v = self.view
+    source = v[spot]
+    bs = self.blocksize
+    nblocks = (len(source.data)+bs-1) / bs
+    chunk = len(source.data) / nblocks +1
+    if chunk >= self.upper-10 or chunk < self.lower+10: chunk = bs
+    chunk, nextchunk = len(source.data) % chunk, chunk
+    if chunk < self.lower:
+      chunk = chunk + nextchunk
+    while len(source.data) > chunk:
+      self.view.insert(spot+1)
+      self.view[spot+1].data=source.data[-chunk:]
+      source.data = source.data[:-chunk]
+      chunk = nextchunk
+    return
+
+  def _getrec(self, subview):
+    res = []
+    ga = getattr
+    for name in self.names:
+      res.append(ga(subview, name))
+    return res
+    
+  def __del__(self):
+    del self.view
+
+view_struc = "big_test[A:I,B:I,C:I,D:I,E:I,F:I,G:I,H:I,J:I,K:I]"
+
+dbpath = "_bigfile.mk"
+
+n_fields = 10
+
+rand_len = 4096 + n_fields
+
+random_ints = map(lambda x:whrandom.randint(0,256), range(rand_len))
+
+blocksize = 10000 # default size for append, but not mandatory
+
+ds = None
+
+db = big_mk(dbpath, 1)
+
+ds = db.getas(view_struc)
+
+def make_rec(idx):
+  return random_ints[idx:idx+n_fields]
+  
+def add_recs(n=1000):
+  for i in range(n):
+    idx = len(ds) % rand_len
+    ds.append(make_rec(idx))
+
+if __name__ == '__main__':
+    # expect this to take hours (1000..2000 recs/sec on modern PII)
+    import sys
+    for i in xrange(25000):
+        add_recs()
+        sys.stdout.write(".")
+        sys.stdout.flush()
+        if i % 50 == 49:
+            db.commit()
+            sys.stdout.write("\n")
diff --git a/8.x/mk/examples/mkbug.cpp b/8.x/mk/examples/mkbug.cpp
new file mode 100755 (executable)
index 0000000..a93f5fd
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include "mk4.h"
+#include "mk4str.h"
+
+void QuickTest(int pos_, int len_)
+{
+  c4_ViewProp p1 ("_B");
+  c4_IntProp p2 ("p2");
+  
+  c4_Storage s1;
+  c4_View v1 = s1.GetAs("v1[_B[p2:I]]");
+
+  int n = 0;
+  static int sizes[] = {999, 999, 999, 3, 0};
+
+  for (int i = 0; sizes[i]; ++i) {
+    c4_View v;
+    for (int j = 0; j < sizes[i]; ++j)
+      v.Add(p2 [++n]);
+    v1.Add(p1 [v]);
+  }
+
+  c4_View v2 = v1.Blocked();
+  printf("%d\n", v2.GetSize());
+    
+  v2.RemoveAt(pos_, len_);
+  printf("%d\n", v2.GetSize());
+
+  puts("done");
+}
+
+int main(int argc, char** argv)
+{
+  QuickTest(999, 1200);
+}
diff --git a/8.x/mk/examples/mkhash.cpp b/8.x/mk/examples/mkhash.cpp
new file mode 100644 (file)
index 0000000..14c7800
--- /dev/null
@@ -0,0 +1,162 @@
+/* Hash timing test harness
+ *
+ * Usage: mkhash opts count
+ *
+ *     opts is a combination of the following flags (default "Dhs"):
+ *             d       store data view flat
+ *             D       store data view blocked
+ *             m       store map view flat
+ *             M       store map view blocked
+ *             h       use hashing
+ *             H       use hashing, after filling the view
+ *             o       use ordering
+ *             2       2-key hashing/ordering, instead of 1-key
+ *             s       time small (2-row add) commits, i.s.o. 1000 rows
+ *             f       do frequent commits, every 10 i.s.o. 1000 rows
+ *
+ *     count is the total number of rows added, default is 250,000
+ *      (it should be a multiple of 10,000 for proper reporting)
+ *
+ *  % g++ -Dq4_INLINE mkhash.cpp -lmk4
+ *  % for i in - d D dh Dh dmh Dmh do Do; do rm -f test.dat; a.out $i; done
+ *  [...]
+ */
+
+#include <mk4.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef WIN32
+  #define WIN32_LEAN_AND_MEAN
+  #include <windows.h>
+
+  long ticks ()
+  {
+    LARGE_INTEGER t;
+
+    static double f = 0.0;
+    if (f == 0.0) {
+      QueryPerformanceFrequency(&t);
+      f = (double) t.QuadPart / 1000000.0;
+    }
+
+    QueryPerformanceCounter(&t);
+    return (long) (f * t.QuadPart);
+  }
+#else
+  #include <sys/time.h>
+  #include <sys/types.h>
+  #include <sys/stat.h>
+
+  long ticks()
+  {
+    struct timeval tv;
+    struct timezone tz;
+    gettimeofday(&tv, &tz);
+    return tv.tv_sec * 1000000 + tv.tv_usec;
+  }
+#endif
+
+int main(int argc, char **argv)
+{
+  char buf [25];
+  c4_Row row;
+  long t;
+  int nkeys = 1;
+
+  //setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
+
+  c4_Storage storage ("test.dat", true);
+
+  c4_StringProp pKey ("key"), pKey2 ("key2");
+  c4_View data = pKey;
+
+  c4_IntProp pH ("_H"), pR ("_R");
+  c4_View map = (pH, pR);
+  const char *s = argc > 1 ? argv[1] : "Dhs";
+
+  if (strchr(s, '2')) {
+    // must create properties in same order as in the hash view (ouch!)
+    pKey (row) = "";
+    pKey2 (row) = "abcdefghijklmnopqrstuvwxyz";
+    nkeys = 2;
+    if (strchr(s, 'd'))
+      data = storage.GetAs("data[key:S,key2:S]");
+    if (strchr(s, 'D')) {
+      data = storage.GetAs("data[_B[key:S,key2:S]]");
+      data = data.Blocked();
+    }
+  } else {
+    if (strchr(s, 'd'))
+      data = storage.GetAs("data[key:S]");
+    if (strchr(s, 'D')) {
+      data = storage.GetAs("data[_B[key:S]]");
+      data = data.Blocked();
+    }
+  }
+
+  if (strchr(s, 'm'))
+    map = storage.GetAs("map[_H:I,_R:I]");
+  if (strchr(s, 'M')) {
+    map = storage.GetAs("map[_B[_H:I,_R:I]]");
+    map = map.Blocked();
+  }
+  if (strchr(s, 'h'))
+    data = data.Hash(map, nkeys);
+  if (strchr(s, 'o'))
+    data = data.Ordered(nkeys);
+  int cfreq = strchr(s, 'f') ? 10 : 1000;
+
+  int limit = 250000;
+  if (argc > 2)
+    limit = atoi(argv[2]);
+
+  puts(s);
+  puts("      ROW       ADD         FIND       COMMIT         SIZE");
+
+  for (int i = 1; i <= limit; ++i) {
+    sprintf(buf, "%10d%10d", 100000000 + i, 200000000 + i);
+
+    pKey (row) = buf;
+
+    t = ticks();
+    data.Add(row);
+    long at = ticks() - t;
+
+    if ((i+2) % cfreq == 0 && strchr(s, 's'))
+      storage.Commit();
+
+    if (i % cfreq == 0) {
+      t = ticks();
+      storage.Commit();
+      long ct = ticks() - t;
+
+      if (i % (limit/10) == 0) {
+       t = ticks();
+       int n = data.Find(row);
+       long ft = ticks() - t;
+             
+       if (n < 0) { puts(buf); return 1; }
+
+       printf("%9d %9d uS %9d uS %9d uS %9d bytes \n",
+               i, at, ft, ct, storage.Strategy().FileSize());
+      }
+    }
+  }
+
+  if (strchr(s, 'H')) {
+    t = ticks();
+    data = data.Hash(map, nkeys);
+    long ht = ticks() - t;
+
+    t = ticks();
+    storage.Commit();
+    long ct = ticks() - t;
+
+    printf("construct hash: %d uS, then commit: %d uS\n", ht, ct);
+    fflush(stdout);
+  }
+
+  return 0;
+}
diff --git a/8.x/mk/examples/mkmemoio.py b/8.x/mk/examples/mkmemoio.py
new file mode 100755 (executable)
index 0000000..79ef524
--- /dev/null
@@ -0,0 +1,155 @@
+# class MkMemoIO implements  file-like objects that read/write a
+# memo field in a Metakit database (either on file, or in memory).
+#
+# A simple adaptation of the StringIO.py module, by Jean-Claude Wippler.
+#
+# This implements (nearly) all stdio methods.
+#
+# f = MkMemoIO(view, memoprop, rownum) # setup for view[rownum].memoprop
+# f.close()       # explicitly release resources held
+# flag = f.isatty()   # always false
+# pos = f.tell()    # get current position
+# f.seek(pos)     # set current position
+# f.seek(pos, mode)   # mode 0: absolute; 1: relative; 2: relative to EOF
+# buf = f.read()    # read until EOF
+# buf = f.read(n)   # read up to n bytes
+# buf = f.readline()  # read until end of line ('\n') or EOF
+# list = f.readlines()# list of f.readline() results until EOF
+# f.write(buf)      # write at current position
+# f.writelines(list)  # for line in list: f.write(line)
+# f.getvalue()      # return whole file's contents as a string
+#
+# Notes:
+# - fileno() is left unimplemented so that code which uses it triggers
+# an exception early.
+# - Seeking beyond EOF and then writing will insert garbage, unlike the
+# StringIO class which clears, and from which this code was adapted.
+# - There's a simple test set (see end of this file).
+# - write() has an optional "resize" to insert (>0) or delete (<0) bytes.
+# To merely insert/delete, write an empty string.  The resize value is
+# adjusted to a "reasonable" range.  Inserted bytes are *not* cleared.
+
+import string, sys
+
+class MkMemoIO:
+  def __init__(self, view, memo, row):
+    self.view = view
+    self.memo = memo
+    self.row = row
+    self.pos = 0
+    self.closed = 0
+    self.softspace = 0
+  def close(self):
+    if not self.closed:
+      self.closed = 1
+      del self.view, self.memo, self.row, self.pos
+  def isatty(self):
+    if self.closed:
+      raise ValueError, "I/O operation on closed file"
+    return 0
+  def seek(self, pos, mode = 0):
+    if self.closed:
+      raise ValueError, "I/O operation on closed file"
+    if mode == 1:
+      pos = pos + self.pos
+    elif mode == 2:
+      pos = pos + self.view.itemsize(self.memo, self.row)
+    self.pos = max(0, pos)
+  def tell(self):
+    if self.closed:
+      raise ValueError, "I/O operation on closed file"
+    return self.pos
+  def read(self, n = -1):
+    if self.closed:
+      raise ValueError, "I/O operation on closed file"
+    if n == 0:
+      return ""
+    r = self.view.access(self.memo, self.row, self.pos, n)
+    self.pos = self.pos + len(r)
+    return r
+  def readline(self, length=None):
+    if self.closed:
+      raise ValueError, "I/O operation on closed file"
+    remain = self.view.itemsize(self.memo, self.row) - self.pos
+    if length is None:
+      length = remain
+    length = min(length, remain)
+    i = -1
+    oldpos = self.pos
+    for o in xrange(0, length, 100):
+      i = string.find(self.read(100), '\n')
+      if i >= 0:
+        break
+    self.pos = oldpos
+    if i >= 0:
+      length = o+i+1
+    return self.read(length)
+  def readlines(self):
+    lines = []
+    line = self.readline()
+    while line:
+      lines.append(line)
+      line = self.readline()
+    return lines
+  def write(self, s, resize=0):
+    if self.closed:
+      raise ValueError, "I/O operation on closed file"
+    self.view.modify(self.memo, self.row, s, self.pos, resize)
+    self.pos = self.pos + len(s)
+  def writelines(self, list):
+    for line in list: self.write(line)
+  def flush(self):
+    if self.closed:
+      raise ValueError, "I/O operation on closed file"
+  def getvalue(self):
+    return self.view.access(self.memo, self.row, 0)
+
+
+# A little test suite
+
+def test():
+  import Mk4py
+  mk=Mk4py
+  db=mk.storage()
+  vw=db.getas('v[m:M]')
+  vw.append()
+  if sys.argv[1:]:
+     file = sys.argv[1]
+  else:
+     file = '/etc/passwd'
+  lines = open(file, 'r').readlines()
+  text = open(file, 'r').read()
+  f = MkMemoIO(vw,vw.m,0)
+  for line in lines[:-2]:
+    f.write(line)
+  f.writelines(lines[-2:])
+  if f.getvalue() != text:
+    raise RuntimeError, 'write failed'
+  length = f.tell()
+  print 'File length =', length
+  f.seek(len(lines[0]))
+  f.write(lines[1])
+  f.seek(0)
+  print 'First line =', `f.readline()`
+  here = f.tell()
+  line = f.readline()
+  print 'Second line =', `line`
+  f.seek(-len(line), 1)
+  line2 = f.read(len(line))
+  if line != line2:
+    raise RuntimeError, 'bad result after seek back'
+  f.seek(len(line2), 1)
+  list = f.readlines()
+  line = list[-1]
+  f.seek(f.tell() - len(line))
+  line2 = f.read()
+  if line != line2:
+    raise RuntimeError, 'bad result after seek back from EOF'
+  print 'Read', len(list), 'more lines'
+  print 'File length =', f.tell()
+  if f.tell() != length:
+    raise RuntimeError, 'bad length'
+  f.close()
+
+if __name__ == '__main__':
+  test()
diff --git a/8.x/mk/examples/pair.py b/8.x/mk/examples/pair.py
new file mode 100644 (file)
index 0000000..f48e407
--- /dev/null
@@ -0,0 +1,26 @@
+# Small demo of v1.pair(v2)
+#
+# Expected output:
+#  s    i
+#  -----  -
+#  zero 0
+#  one  1
+#  two  2
+#  three  3
+#  four 4
+#  five 5
+#  -----  -
+#  Total: 6 rows
+
+import metakit
+
+db = metakit.storage()
+v1 = db.getas("one[s:S]")
+v2 = db.getas("two[i:I]")
+
+for v in ['zero','one','two','three','four','five']:
+  v1.append(s=v)
+for v in range(6):
+  v2.append(i=v)
+
+metakit.dump(v1.pair(v2))
diff --git a/8.x/mk/examples/random.tcl b/8.x/mk/examples/random.tcl
new file mode 100644 (file)
index 0000000..d00be89
--- /dev/null
@@ -0,0 +1,155 @@
+#! /usr/bin/env tclkit
+
+# Test script to do 100,000 adds/mods/dels of strings in a bytes prop field.
+# The changes are also applied to a list and compared regularly to make sure
+# that the stored data matches exactly what the mirror list contains.
+#
+# This was an attempt to track down a problem reported for 2.4.4, but no
+# problem was found with this script.
+#
+# Output:
+#
+#     0:      0 rows,        0 b  C==========C==========C==========C==========
+#  4000:    774 rows,   820166 b  C==========C==========C==========C==========
+#  8000:   1596 rows,  1724131 b  C==========C==========C==========C==========
+# 12000:   2381 rows,  1940124 b  C==========C==========C==========C==========
+# 16000:   3225 rows,  2453683 b  C==========C==========C==========C==========
+# 20000:   4063 rows,  2830557 b  C==========C==========C==========C==========
+# 24000:   4810 rows,  3273064 b  C==========C==========C==========C==========
+# 28000:   5599 rows,  3730358 b  C==========C==========C==========C==========
+# 32000:   6381 rows,  4136253 b  C==========C==========C==========C==========
+# 36000:   7200 rows,  4591425 b  C==========C==========C==========C==========
+# 40000:   8017 rows,  5117372 b  C==========C==========C==========C==========
+# 44000:   8844 rows,  5579832 b  C==========C==========C==========C==========
+# 48000:   9640 rows,  6071057 b  C==========C==========C==========C==========
+# 52000:   9997 rows,  7158289 b  C==========C==========C==========C==========
+# 56000:   9999 rows,  7821411 b  C==========C==========C==========C==========
+# 60000:   9999 rows,  8251942 b  C==========C==========C==========C==========
+# 64000:   9999 rows,  8560813 b  C==========C==========C==========C==========
+# 68000:  10000 rows,  8781565 b  C==========C==========C==========C==========
+# 72000:  10003 rows,  8910941 b  C==========C==========C==========C==========
+# 76000:  10000 rows,  8975682 b  C==========C==========C==========C==========
+# 80000:   9995 rows,  8975682 b  C==========C==========C==========C==========
+# 84000:  10002 rows,  8975682 b  C==========C==========C==========C==========
+# 88000:   9997 rows,  8975682 b  C==========C==========C==========C==========
+# 92000:  10000 rows,  8975682 b  C==========C==========C==========C==========
+# 96000:  10002 rows,  8975682 b  C==========C==========C==========C==========
+# Done.
+#
+# -jcw, 29-4-2002
+
+if {[catch {load "" Mk4tcl}]} { load ./Mk4tcl.so Mk4tcl }
+
+# returns a random integer less than the specified limit
+proc rand {limit} {
+  return [expr {int(rand() * $limit)}]
+}
+
+# returns true a certain percentage of the time
+proc onavg {percent} {
+  return [expr {rand() * 100 < $percent}]
+}
+
+# use the same random sequence each time around
+expr {srand(1234567)}
+
+# make sure the rand function works
+if 0 {
+  foreach x {a a a a a a a a a a a a a a a a a a a a} {
+    foreach y {a a a a a a a a a a a a a a a a a a a a} {
+      puts -nonewline [rand 10]
+      puts -nonewline [rand 10]
+      puts -nonewline [rand 10]
+    }
+    puts ""
+  }
+  puts ""
+  foreach x {a a a a a a a a a a a a a a a a a a a a} {
+    foreach y {a a a a a a a a a a a a a a a a a a a a} {
+      puts -nonewline [onavg 10]
+      puts -nonewline [onavg 10]
+      puts -nonewline [onavg 10]
+    }
+    puts ""
+  }
+  exit
+}
+
+file delete data.mk
+mk::file open db data.mk -nocommit
+mk::view layout db.v d:B
+
+set mirror {}
+
+set desiredsize        10000   ;# rows
+set minlength  90      ;# bytes
+set maxlength  1100    ;# bytes
+set emptypct   3       ;# percent
+set commitfreq 1000    ;# count
+set checkfreq  100     ;# count
+set displayfreq        4000    ;# count
+set runcount   100000  ;# count
+
+fconfigure stdout -buffering none
+
+set x 10000000
+
+for {set i 0} {$i < $runcount} {incr i} {
+  set n [llength $mirror]
+  if {[expr {$i % $displayfreq == 0}]} {
+    puts -nonewline [format "\n%7d: %6d rows, %8d b  " \
+                       $i [mk::view size db.v] [file size data.mk]]
+  }
+  if {[expr {$i % $commitfreq == 0}]} {
+    puts -nonewline C
+    mk::file commit db
+  }
+  if {[expr {$i % $checkfreq == 0}]} {
+    puts -nonewline =
+    if {[mk::view size db.v] != $n} {
+      puts "\n### $i: wrong size [mk::view size db.v] != $n"
+      error mismatch
+    }
+    for {set j 0} {$j < $n} {incr j} {
+      if {[mk::get db.v!$j d] != [lindex $mirror $j]} {
+        puts "\n### $i: mismatch [mk::get db.v!$j d] != [lindex $mirror $j]"
+       error mismatch
+      }
+    }
+  }
+
+  # under 100 rows just add items
+  set a [expr {$n < 100 ? 0 : [rand 5]}]
+  
+  # boundary cases 1 and 3 may become adds or deletes to reach desired size
+  switch $a {
+    1 { set a [expr {$n < $desiredsize ? 0 : 2}] }
+    3 { set a [expr {$n > $desiredsize ? 4 : 2}] }
+  }
+
+  # construct a test data value of the specified size
+  set l [expr {int(rand() * ($maxlength - $minlength)) + $minlength - 10}]
+  set t "[incr x]: [string repeat . $l]"
+  if {[onavg $emptypct]} { set t "" }
+
+  # randomly pick an existing row to modify
+  set p [rand $n]
+
+  # now make the change, to the mirror data list and to the view
+  switch $a {
+    0 { # add
+      lappend mirror $t
+      mk::row append db.v d $t
+    }
+    2 { # modify
+      lset mirror $p $t
+      mk::set db.v!$p d $t
+    }
+    4 { # delete
+      set mirror [lreplace $mirror $p $p]
+      mk::row delete db.v!$p
+    }
+  }
+}
+
+puts "\nDone."
diff --git a/8.x/mk/examples/remap.py b/8.x/mk/examples/remap.py
new file mode 100644 (file)
index 0000000..40ed770
--- /dev/null
@@ -0,0 +1,28 @@
+# Small demo of v1.remapwith(v2)
+#
+# Expected output:
+#  s    
+#  -----
+#  one  
+#  three
+#  five 
+#  two  
+#  four 
+#  one  
+#  three
+#  five 
+#  -----
+#  Total: 8 rows
+
+import metakit
+
+db = metakit.storage()
+v1 = db.getas("counts[s:S]")
+v2 = db.getas("map[i:I]")
+
+for v in ['zero','one','two','three','four','five']:
+  v1.append(s=v)
+for v in [1,3,5,2,4,1,3,5]:
+  v2.append(i=v)
+
+metakit.dump(v1.remapwith(v2))
diff --git a/8.x/mk/examples/selfref.py b/8.x/mk/examples/selfref.py
new file mode 100644 (file)
index 0000000..703c579
--- /dev/null
@@ -0,0 +1,48 @@
+# Demo of the new 2.3 self-referential view structures.
+#
+# Output:
+# 0
+# 00000 1
+# 11111 1
+# 22222 0
+# [Property('S', 's'), Property('V', 'sub')]
+# 00000 1
+# 11111 1
+# 22222 0
+# [Property('S', 's'), Property('I', 'i'), Property('V', 'sub')]
+# ok
+
+import os
+try: os.remove("_selfref.mk")
+except: pass
+
+import metakit
+db = metakit.storage('_selfref.mk',1)
+vw = db.getas('data[s:S,sub[^]]')
+
+print len(vw)
+
+v = vw
+for i in range(3):
+  v.append(s=`i`*5)
+  v = v[0].sub
+
+def show(vw):
+  for v in [vw[0], vw[0].sub[0], vw[0].sub[0].sub[0]]:
+    print v.s, len(v.sub)
+  print vw[0].sub[0].sub[0].sub.structure()
+  assert len(vw[0].sub[0].sub[0].sub) == 0
+  try:
+    metakit.dump(vw[0].sub[0].sub[0].sub[0].sub)
+  except IndexError:
+    pass
+
+show(vw)
+
+# note that (recursive!) on-the-fly restructuring works
+show(db.getas('data[s:S,i:I,sub[^]]'))
+
+db.commit()
+print 'ok'
+
+os.remove("_selfref.mk")
diff --git a/8.x/mk/examples/selmap.tcl b/8.x/mk/examples/selmap.tcl
new file mode 100644 (file)
index 0000000..ffcc07a
--- /dev/null
@@ -0,0 +1,77 @@
+# How to map a Tcl selection result back to a view
+#
+# Note: it'd be nice to have a "$view loop var { script ... }" in Mk4tcl
+
+if {[catch {package require Mk4tcl}] &&
+    [catch {load ./Mk4tcl.so mk4tcl}] &&
+    [catch {load ../builds/Mk4tcl.so mk4tcl}] &&
+    [catch {load ./Mk4tcl_d.dll mk4tcl}] &&
+    [catch {load ../builds/Mk4tcl_d.dll mk4tcl}]} {
+  error "cannot load Mk4tcl"
+}
+
+mk::file open db
+mk::view layout db.squares {x:I y:I}
+
+set count 50000
+mk::view size db.squares $count
+
+set t [clock seconds]
+
+mk::loop c db.squares {
+  set i [mk::cursor position c]
+  mk::set $c x $i y [expr {$i*$i}]
+}
+
+puts "init took [expr {[clock seconds] - $t}] seconds"
+
+puts "select timing: [time {set v [mk::select db.squares -regexp y 11111]}]"
+
+puts "results from select:"
+foreach i $v {
+  foreach {x y} [mk::get db.squares!$i x y] break
+  puts [format {%7i: %10d,%d} $i $x $y]
+}
+
+set v1 [mk::view new]
+foreach i $v {
+  $v1 insert end n:I $i
+}
+
+puts "contents of v1:"
+for {set i 0} {$i < [$v1 size]} {incr i} {
+  puts "  [$v1 get $i n]"
+}
+
+set v2 [mk::view open db.squares]
+puts "the squares view is called '$v2' and contains [$v2 size] rows"
+
+set v3 [$v2 view map $v1]
+
+puts "mapped view:"
+for {set i 0} {$i < [$v3 size]} {incr i} {
+  foreach {x y} [$v3 get $i x y] break
+  puts [format {%7i: %10d,%d} $i $x $y]
+}
+
+$v3 close
+$v2 close
+$v1 close
+
+# The output on this script should be:
+# 
+# init took 1 seconds
+# select timing: 443096 microseconds per iteration
+# results from select:
+#   10541:      10541,111112681
+#   33334:      33334,1111155556
+#   48310:      48310,-1961111196
+# contents of v1:
+#   10541
+#   33334
+#   48310
+# the squares view is called 'view1' and contains 100000 rows
+# mapped view:
+#       0:      10541,111112681
+#       1:      33334,1111155556
+#       2:      48310,-1961111196
diff --git a/8.x/mk/examples/slow.tcl b/8.x/mk/examples/slow.tcl
new file mode 100644 (file)
index 0000000..9dcc228
--- /dev/null
@@ -0,0 +1,135 @@
+# Trying to find out how hash performance degrades as size increases
+
+if [catch {package require Mk4tcl}] {
+  catch {load ./Mk4tcl[info sharedlibext] mk4tcl}
+  catch {load ./Mk4tcl_d.dll mk4tcl}
+}
+
+proc loadwords {step} {
+  global warray
+  set fd [open /usr/share/dict/words]
+  #set fd [open words]
+  for {set i 0} {$i < $step && [gets $fd line] >= 0} {incr i} {
+    set warray($line) $i
+  }
+  close $fd
+  return $line
+}
+
+proc timedRun {tag count args} {
+  set usec [lindex [time $args $count] 0]
+  lappend ::stats($tag) [expr {$count*$usec/1000.0}]
+}
+
+proc setup {keys type} {
+  file delete _large.mk
+  mk::file open db _large.mk -nocommit
+
+  set layout "$keys v"
+  if {$type == "b"} { set layout "{_B {$layout}}" }
+  mk::view layout db.words $layout
+
+  if {$type == "b"} {
+    mk::view open db.words rawdata
+    rename [rawdata view blocked] data
+  } else {
+    mk::view open db.words data
+  }
+  
+  mk::view layout db.words_map {_H:I _R:I}
+  mk::view open db.words_map map
+
+  rename [data view hash map [regsub -all k $keys {} x]] words
+}
+
+proc teardown {} {
+  catch { rename words "" }
+  catch { rename data "" }
+  catch { rename map "" }
+  catch { rename rawdata "" }
+
+  mk::file close db
+}
+
+proc fill1 {seq} {
+  global warray
+  foreach {k v} [array get warray] {
+    set x $k$seq 
+    words insert end k1 k1_$x v v_$x
+  }
+}
+
+proc fill2 {seq} {
+  global warray
+  foreach {k v} [array get warray] {
+    set x $k$seq 
+    words insert end k1 k1_$x k2 k2_$x
+  }
+}
+
+proc fill5 {seq} {
+  global warray
+  foreach {k v} [array get warray] {
+    set x $k$seq 
+    words insert end k1 k1_$x k2 k2_$x v1 v1_$x v2 v2_$x v3 v3_$x v v_$x
+  }
+}
+
+proc find1 {w} {
+  words find k1 k1_${w}5
+}
+
+proc find2 {w} {
+  words find k1 k1_${w}5 k2 k2_${w}5
+}
+
+proc find5 {w} {
+  words find k1 k1_${w}5 k2 k2_${w}5
+}
+
+set step 10000
+#set step 100
+set mult 50
+
+set w [loadwords $step]
+puts "w = $w"
+puts [clock format [clock seconds]]
+
+foreach type {f b} {
+  foreach keys {{k1} {k1 k2} {k1 k2 v1 v2 v3}} {
+    set nkeys [llength $keys]
+    set mode "$type$nkeys"
+    puts -nonewline stderr "$mode: "
+    setup $keys $type
+    for {set i 0} {$i < $mult} {incr i} {
+      timedRun $mode-fill 1 fill$nkeys $i
+      puts -nonewline stderr .
+    }
+    timedRun $mode-find 10000 find$nkeys $w
+    timedRun $mode-commit 1 mk::file commit db
+    puts stderr "  [words size] rows, [file size _large.mk] b"
+    for {set i 0} {$i < 3} {incr i} {
+      puts " $i: [words get $i]"
+    }
+    teardown
+  }
+}
+
+puts [clock format [clock seconds]]
+
+puts -nonewline "\n               "
+foreach x [lsort [array names stats *-fill]] {
+  puts -nonewline [format %8s [lindex [split $x -] 0]]
+  set i 0
+  foreach y $stats($x) {
+    incr i $step
+    append cols([format %6d $i]) [format {%8.2f} $y]
+  }
+  unset stats($x)
+}
+puts \n
+parray cols
+puts ""
+parray stats
+puts ""
+puts [clock format [clock seconds]]
diff --git a/8.x/mk/examples/sort.tcl b/8.x/mk/examples/sort.tcl
new file mode 100644 (file)
index 0000000..79ccdbe
--- /dev/null
@@ -0,0 +1,54 @@
+# Timing of the view sort operation
+
+package require Mk4tcl
+
+proc timedRun {tag count args} {
+  set usec [lindex [time $args $count] 0]
+  append ::stats($tag) [format {%9.2f} [expr {$count*$usec/1000.0}]]
+}
+
+proc fill {seq} {
+  global warray
+  foreach {k v} [array get warray] {
+    mk::row append db.words text $k$seq
+  }
+}
+
+set step 40000
+set mult 7
+
+#set fd [open /usr/share/dict/words]
+set fd [open words]
+for {set i 0} {$i < $step && [gets $fd line] >= 0} {incr i} {
+  set warray($line) $i
+}
+close $fd
+
+puts [clock format [clock seconds]]
+
+file delete _large.mk
+mk::file open db _large.mk -nocommit
+mk::view layout db.words text
+
+for {set i 0} {$i < $mult} {incr i} {
+  append stats(count) [format {%9d} [expr {($i+1)*$step}]]
+  timedRun fill 1 fill $i
+  timedRun sort 1 mk::select db.words -sort text
+  puts -nonewline stderr .
+}
+
+timedRun commit 1 mk::file commit db
+puts stderr "  [mk::view size db.words] rows, [file size _large.mk] b"
+
+for {set i 0} {$i < 3} {incr i} {
+  puts " $i: [mk::get db.words!$i]"
+}
+
+mk::file close db
+
+puts [clock format [clock seconds]]
+
+puts ""
+parray stats
+puts ""
+puts [clock format [clock seconds]]
diff --git a/8.x/mk/examples/wrap.py b/8.x/mk/examples/wrap.py
new file mode 100644 (file)
index 0000000..4313bce
--- /dev/null
@@ -0,0 +1,40 @@
+# Wrapping Python data as Metakit views
+#
+# Expected output (3 times):
+#    a      b      c
+#    -----  -----  -
+#    one    un     1
+#    two    deux   2
+#    three  trois  3
+#    -----  -----  -
+#    Total: 3 rows
+
+import metakit
+
+class C:
+    def __init__(self, a, b, c):
+       self.a, self.b, self.c = a, b, c
+
+dc = [ C ('one', 'un', 1),
+       C ('two', 'deux', 2),
+       C ('three', 'trois', 3)  ]
+
+dd = [ {'a':'one', 'b':'un', 'c':1}, 
+       {'a':'two', 'b':'deux', 'c':2}, 
+       {'a':'three', 'b':'trois', 'c':3}  ] 
+
+dt = [ ('one', 'un', 1), 
+       ('two', 'deux', 2), 
+       ('three', 'trois', 3)  ] 
+
+pl = [ metakit.property('S','a'),
+       metakit.property('S','b'),
+       metakit.property('I','c')  ]
+
+vc = metakit.wrap(dc, pl)
+vd = metakit.wrap(dd, pl)
+vt = metakit.wrap(dt, pl, 1)
+
+metakit.dump(vc, 'class objects:')
+metakit.dump(vd, 'dictionary elements:')
+metakit.dump(vt, 'tuples (by position):')
diff --git a/8.x/mk/include/mk4.h b/8.x/mk/include/mk4.h
new file mode 100755 (executable)
index 0000000..7e05653
--- /dev/null
@@ -0,0 +1,1058 @@
+// mk4.h --
+// $Id: mk4.h 1669 2007-06-16 00:23:25Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Main Metakit library include file
+ */
+
+#ifndef __MK4_H__
+#define __MK4_H__
+
+//---------------------------------------------------------------------------
+//
+//  TITLE
+//                                
+//      The Metakit Library, by Jean-Claude Wippler, Equi4 Software, NL.
+//      
+//  DESCRIPTION
+//                                
+//      Structured data storage with commit / rollback and on-demand loading.
+//  
+//  ACKNOWLEDGEMENTS
+//                                                                        
+//      To Liesbeth and Myra, for making this possible.
+//
+//---------------------------------------------------------------------------
+//
+//  NAMING CONVENTIONS        PREFIX    REMARKS
+//                              
+//      Compile time options    q4_     Always defined as 1 or 0, capitalized
+//      Preprocessor defines    d4_     Use with "#ifdef" or "#if defined()"
+//      Classes                 c4_     Classes, listed at start of headers
+//      Typedefs                t4_     Type definitions, if outside classes
+//      Global functions        f4_     Internal, these are rarely defined
+//
+//      Member functions                Start in uppercase
+//      Instance variables      _       And start in lowercase
+//      Static members          _       And start in uppercase
+//
+//      Local variable names            Start in lowercase
+//      Formal parameter names          Start lowercase, end with underscore
+//
+//---------------------------------------------------------------------------
+
+/// Current release = 100 * major + 10 * minor + maintenance
+#define d4_MetakitLibraryVersion 249    // 2.4.9.7 release, Jun 16, 2007
+#define d4_MetaKitLibraryVersion d4_MetakitLibraryVersion // compat, yuck
+
+//---------------------------------------------------------------------------
+// Declarations in this file
+
+class c4_View; // a view on underlying data
+class c4_Cursor; // an index into a view
+class c4_RowRef; // a reference to a row
+class c4_Row; // one row in a view
+class c4_Bytes; // used to pass around generic data
+class c4_Storage; // manages view persistence
+class c4_CustomViewer; // used for customizable views
+class c4_Stream; // abstract stream class
+class c4_Strategy; // system and file interface
+
+class c4_Property; // for access inside rows
+class c4_IntProp;
+class c4_LongProp;
+class c4_FloatProp;
+class c4_DoubleProp;
+class c4_StringProp;
+class c4_BytesProp;
+class c4_ViewProp;
+
+// Everything below is part of the implementation, not for public use
+
+class c4_Sequence; // a collection of rows
+
+class c4_Reference; // refers to the actual data values
+class c4_IntRef;
+class c4_LongRef;
+class c4_FloatRef;
+class c4_DoubleRef;
+class c4_BytesRef;
+class c4_StringRef;
+class c4_ViewRef;
+
+class c4_Dependencies; // not defined here
+class c4_Handler; // not defined here
+class c4_Notifier; // not defined here
+class c4_Persist; // not defined here
+
+//---------------------------------------------------------------------------
+
+// determine whether we need to include "mk4dll.h" to link as DLL
+#if defined (MKDLL_EXPORTS) && !defined (q4_KITDLL)
+#define q4_KITDLL 1
+#endif 
+
+// omit floats and doubles in small model 16-bit Intel builds
+#if defined (_DOS) && defined (_M_I86SM) && !defined (q4_TINY)
+#define q4_TINY 1
+#endif 
+
+// and here's the other end of the scale...
+#if !defined (_WIN32) && !defined (q4_LONG64)
+#if defined (_PA_RISC2_0) || defined (__powerpc64__) || defined(__sparcv9) || \
+defined(__x86_64__) || defined(__s390x__) || defined(__alpha) ||  \
+  (defined(__ia64) && (!defined(__HP_aCC) || defined(__LP64__)))
+#define q4_LONG64 1
+#endif 
+#endif 
+
+// default to inlining for maximum performance
+#if !defined (q4_INLINE)
+#define q4_INLINE 1
+#endif 
+
+//---------------------------------------------------------------------------
+
+// Borland C++ and C++ Builder
+#if defined (__BORLANDC__)
+// by default, if runtime is linked as a DLL, then so is Metakit
+#if defined (_RTLDLL) && !defined (q4_KITDLL)
+#define q4_KITDLL 1
+#endif 
+
+// Borland 5.0 supports the bool datatype
+#if __BORLANDC__ >= 0x500
+#define q4_BOOL 1
+#endif 
+#endif // __BORLANDC__
+
+// IRIX supports the bool datatype
+// define before gcc to cover both the gcc and MipsPRO compiler
+#if defined (sgi)
+#define q4_BOOL 1
+#undef bool
+#undef true
+#undef false
+#endif 
+
+// GNU gcc/egcs
+#if defined (__GNUC__)
+#ifndef q4_BOOL
+#define q4_BOOL 1
+#endif 
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG 1
+#endif 
+#endif 
+
+// HP aCC
+#if defined (__HP_aCC)
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG 1
+#endif 
+#endif 
+
+// Metrowerks CodeWarrior
+#if defined (__MWERKS__)
+#if __option(bool)
+#define q4_BOOL 1       // bool datatype is optionally supported
+// undef, these conflict with c4_Storage::c4_Storage overloading
+#undef bool
+#undef true
+#undef false
+#endif 
+#endif 
+
+// Microsoft Visual C++
+#if defined (_MSC_VER)
+// MSVC 5.0 supports the bool datatype, MSVC 4.x has no namespaces
+#if _MSC_VER >= 1100
+#define q4_BOOL 1
+#define LONG_LONG __int64
+#else 
+#define q4_NO_NS 1
+#endif 
+
+// a kludge to avoid having to use ugly DLL exprt defs in this header
+#pragma warning(disable: 4273) // inconsistent dll linkage
+#endif // _MSC_VER
+
+//---------------------------------------------------------------------------
+// Other definitions needed by the public Metakit library header files
+
+#if !q4_BOOL && !q4_STD         // define a bool datatype
+#define false 0
+#define true 1
+#define bool int
+#endif 
+
+#if q4_KITDLL                   // add declaration specifiers
+#include "mk4dll.h"
+#endif 
+
+#if q4_INLINE                   // enable inline expansion
+#define d4_inline inline
+#else 
+#define d4_inline
+#endif 
+
+typedef unsigned char t4_byte; // create typedefs for t4_byte, etc.
+
+#if q4_LONG64
+typedef int t4_i32; // if longs are 64b, then int must be 32b
+#else 
+typedef long t4_i32; // if longs aren't 64b, then they are 32b
+#endif 
+
+#if q4_LONG64           // choose a way to represent 64b integers
+typedef long t4_i64;
+#elif defined (LONG_LONG)
+typedef LONG_LONG t4_i64;
+#elif HAVE_LONG_LONG
+typedef long long t4_i64;
+#else 
+struct t4_i64 {
+    long l1;
+    long l2;
+};
+bool operator == (const t4_i64 a_, const t4_i64 b_);
+bool operator < (const t4_i64 a_, const t4_i64 b_);
+#endif 
+
+//---------------------------------------------------------------------------
+
+class c4_View {
+  protected:
+    c4_Sequence *_seq;
+
+  public:
+    /* Construction / destruction / assignment */
+    c4_View(c4_Sequence * = 0);
+    c4_View(c4_CustomViewer*);
+    c4_View(c4_Stream*);
+    c4_View(const c4_Property &property_);
+    c4_View(const c4_View &);
+    ~c4_View();
+
+    c4_View &operator = (const c4_View &);
+    c4_Persist *Persist()const; // added 16-11-2000 to simplify c4_Storage
+
+    /* Getting / setting the number of rows */
+    int GetSize()const;
+    void SetSize(int, int =  - 1);
+
+    void RemoveAll();
+
+    /*: Getting / setting individual elements */
+    c4_RowRef GetAt(int)const;
+    c4_RowRef operator[](int)const;
+
+    void SetAt(int, const c4_RowRef &);
+    c4_RowRef ElementAt(int);
+
+    bool GetItem(int, int, c4_Bytes &)const;
+    void SetItem(int, int, const c4_Bytes &)const;
+
+    /* These can increase the number of rows */
+    void SetAtGrow(int, const c4_RowRef &);
+    int Add(const c4_RowRef &);
+
+    /* Insertion / deletion of rows */
+    void InsertAt(int, const c4_RowRef &, int = 1);
+    void RemoveAt(int, int = 1);
+    void InsertAt(int, const c4_View &);
+
+    bool IsCompatibleWith(const c4_View &)const;
+    void RelocateRows(int, int, c4_View &, int);
+
+    /* Dealing with the properties of this view */
+    int NumProperties()const;
+    const c4_Property &NthProperty(int)const;
+    int FindProperty(int);
+    int FindPropIndexByName(const char*)const;
+    c4_View Duplicate()const;
+    c4_View Clone()const;
+    int AddProperty(const c4_Property &);
+    c4_View operator, (const c4_Property &)const;
+
+    const char *Description()const;
+
+    /* Derived views */
+    c4_View Sort()const;
+    c4_View SortOn(const c4_View &)const;
+    c4_View SortOnReverse(const c4_View &, const c4_View &)const;
+
+    c4_View Select(const c4_RowRef &)const;
+    c4_View SelectRange(const c4_RowRef &, const c4_RowRef &)const;
+
+    c4_View Project(const c4_View &)const;
+    c4_View ProjectWithout(const c4_View &)const;
+
+    int GetIndexOf(const c4_RowRef &)const;
+    int RestrictSearch(const c4_RowRef &, int &, int &);
+
+    /* Custom views */
+    c4_View Slice(int, int =  - 1, int = 1)const;
+    c4_View Product(const c4_View &)const;
+    c4_View RemapWith(const c4_View &)const;
+    c4_View Pair(const c4_View &)const;
+    c4_View Concat(const c4_View &)const;
+    c4_View Rename(const c4_Property &, const c4_Property &)const;
+
+    c4_View GroupBy(const c4_View &, const c4_ViewProp &)const;
+    c4_View Counts(const c4_View &, const c4_IntProp &)const;
+    c4_View Unique()const;
+
+    c4_View Union(const c4_View &)const;
+    c4_View Intersect(const c4_View &)const;
+    c4_View Different(const c4_View &)const;
+    c4_View Minus(const c4_View &)const;
+
+    c4_View JoinProp(const c4_ViewProp &, bool = false)const;
+    c4_View Join(const c4_View &, const c4_View &, bool = false)const;
+
+    c4_View ReadOnly()const;
+    c4_View Hash(const c4_View &, int = 1)const;
+    c4_View Blocked()const;
+    c4_View Ordered(int = 1)const;
+    c4_View Indexed(const c4_View &, const c4_View &, bool = false)const;
+
+    /* Searching */
+    int Find(const c4_RowRef &, int = 0)const;
+    int Search(const c4_RowRef &)const;
+    int Locate(const c4_RowRef &, int * = 0)const;
+
+    /* Comparing view contents */
+    int Compare(const c4_View &)const;
+
+    friend bool operator == (const c4_View &, const c4_View &);
+    friend bool operator != (const c4_View &, const c4_View &);
+    friend bool operator < (const c4_View &, const c4_View &);
+    friend bool operator > (const c4_View &, const c4_View &);
+    friend bool operator <= (const c4_View &, const c4_View &);
+    friend bool operator >= (const c4_View &, const c4_View &);
+
+  protected:
+    void _IncSeqRef();
+    void _DecSeqRef();
+
+    /// View references are allowed to peek inside view objects
+    friend class c4_ViewRef;
+
+    // DROPPED: Structure() const;
+    // DROPPED: Description(const c4_View& view_);
+};
+
+//---------------------------------------------------------------------------
+
+#if defined(os_aix) && defined(compiler_ibmcxx) && (compiler_ibmcxx > 500)
+bool operator == (const c4_RowRef &a_, const c4_RowRef &b_);
+bool operator != (const c4_RowRef &a_, const c4_RowRef &b_);
+bool operator <= (const c4_RowRef &a_, const c4_RowRef &b_);
+bool operator >= (const c4_RowRef &a_, const c4_RowRef &b_);
+bool operator > (const c4_RowRef &a_, const c4_RowRef &b_);
+bool operator < (const c4_RowRef &a_, const c4_RowRef &b_);
+#endif 
+
+class c4_Cursor {
+  public:
+    /// Pointer to the sequence
+    c4_Sequence *_seq;
+    /// Current index into the sequence
+    int _index;
+
+    /* Construction / destruction / dereferencing */
+    /// Construct a new cursor
+    c4_Cursor(c4_Sequence &, int);
+
+    /// Dereference this cursor to "almost" a row
+    c4_RowRef operator *()const;
+
+    /// This is the same as *(cursor + offset)
+    c4_RowRef operator[](int)const;
+
+    /* Stepping the iterator forwards / backwards */
+    /// Pre-increment the cursor
+    c4_Cursor &operator++();
+    /// Post-increment the cursor
+    c4_Cursor operator++(int);
+    /// Pre-decrement the cursor
+    c4_Cursor &operator--();
+    /// Post-decrement the cursor
+    c4_Cursor operator--(int);
+
+    /// Advance by a given offset
+    c4_Cursor &operator += (int);
+    /// Back up by a given offset
+    c4_Cursor &operator -= (int);
+
+    /// Subtract a specified offset
+    c4_Cursor operator - (int)const;
+    /// Return the distance between two cursors
+    int operator - (c4_Cursor)const;
+
+    /// Add specified offset
+    friend c4_Cursor operator + (c4_Cursor, int);
+    /// Add specified offset to cursor
+    friend c4_Cursor operator + (int, c4_Cursor);
+
+    /* Comparing row positions */
+    /// Return true if both cursors are equal
+    friend bool operator == (c4_Cursor, c4_Cursor);
+    /// Return true if both cursors are not equal
+    friend bool operator != (c4_Cursor, c4_Cursor);
+    /// True if first cursor is less than second cursor
+    friend bool operator < (c4_Cursor, c4_Cursor);
+    /// True if first cursor is greater than second cursor
+    friend bool operator > (c4_Cursor, c4_Cursor);
+    /// True if first cursor is less or equal to second cursor
+    friend bool operator <= (c4_Cursor, c4_Cursor);
+    /// True if first cursor is greater or equal to second cursor
+    friend bool operator >= (c4_Cursor, c4_Cursor);
+
+    /* Comparing row contents */
+    /// Return true if the contents of both rows are equal
+    friend bool operator == (const c4_RowRef &, const c4_RowRef &);
+    /// Return true if the contents of both rows are not equal
+    friend bool operator != (const c4_RowRef &, const c4_RowRef &);
+    /// True if first row is less than second row
+    friend bool operator < (const c4_RowRef &, const c4_RowRef &);
+    /// True if first row is greater than second row
+    friend bool operator > (const c4_RowRef &, const c4_RowRef &);
+    /// True if first row is less or equal to second row
+    friend bool operator <= (const c4_RowRef &, const c4_RowRef &);
+    /// True if first row is greater or equal to second row
+    friend bool operator >= (const c4_RowRef &, const c4_RowRef &);
+};
+
+//---------------------------------------------------------------------------
+
+class c4_RowRef {
+    /// A row reference is a cursor in disguise
+    c4_Cursor _cursor;
+
+  public:
+    /* General operations */
+    /// Assign the value of another row to this one
+    c4_RowRef operator = (const c4_RowRef &);
+    /// Return the cursor associated to this row
+    c4_Cursor operator &()const;
+    /// Return the underlying container view
+    c4_View Container()const;
+
+  protected:
+    /// Constructor, not for general use
+    c4_RowRef(c4_Cursor);
+
+    friend class c4_Cursor;
+    friend class c4_Row;
+};
+
+//---------------------------------------------------------------------------
+/// An entry in a collection with copy semantics.
+//
+//  Rows can exist by themselves and as contents of views.  Row assignment
+//  implies that a copy of the contents of the originating row is made.
+//
+//  A row is implemented as an unattached view with exactly one element.
+
+class c4_Row: public c4_RowRef {
+  public:
+    /// Construct a row with no properties
+    c4_Row();
+    /// Construct a row from another one
+    c4_Row(const c4_Row &);
+    /// Construct a row copy from a row reference
+    c4_Row(const c4_RowRef &);
+    /// Destructor
+    ~c4_Row();
+
+    /// Assign a copy of another row to this one
+    c4_Row &operator = (const c4_Row &);
+    /// Copy another row to this one
+    c4_Row &operator = (const c4_RowRef &);
+
+    /// Add all properties and values into this row
+    void ConcatRow(const c4_RowRef &);
+    /// Return a new row which is the concatenation of two others
+    friend c4_Row operator + (const c4_RowRef &, const c4_RowRef &);
+
+  private:
+    static c4_Cursor Allocate();
+    static void Release(c4_Cursor);
+};
+
+//---------------------------------------------------------------------------
+
+class c4_Bytes {
+    union {
+        t4_byte _buffer[16];
+        double _aligner; // on a Sparc, the int below wasn't enough...
+    };
+
+    t4_byte *_contents;
+    int _size;
+    bool _copy;
+
+  public:
+    c4_Bytes();
+    c4_Bytes(const void *, int);
+    c4_Bytes(const void *, int, bool);
+    c4_Bytes(const c4_Bytes &);
+    ~c4_Bytes();
+
+    c4_Bytes &operator = (const c4_Bytes &);
+    void Swap(c4_Bytes &);
+
+    int Size()const;
+    const t4_byte *Contents()const;
+
+    t4_byte *SetBuffer(int);
+    t4_byte *SetBufferClear(int);
+
+    friend bool operator == (const c4_Bytes &, const c4_Bytes &);
+    friend bool operator != (const c4_Bytes &, const c4_Bytes &);
+
+  private:
+    void _MakeCopy();
+    void _LoseCopy();
+};
+
+//---------------------------------------------------------------------------
+
+class c4_Storage: public c4_View {
+  public:
+    /// Construct streaming-only storage object
+    c4_Storage();
+    /// Construct a storage using the specified strategy handler
+    c4_Storage(c4_Strategy &, bool = false, int = 1);
+    /// Construct a storage object, keeping the current structure
+    c4_Storage(const char *, int);
+    /// Reconstruct a storage object from a suitable view
+    c4_Storage(const c4_View &);
+    /// Destructor, usually closes file, but does not commit by default
+    ~c4_Storage();
+
+    void SetStructure(const char*);
+    bool AutoCommit(bool = true);
+    c4_Strategy &Strategy()const;
+    const char *Description(const char * = 0);
+
+    bool SetAside(c4_Storage &);
+    c4_Storage *GetAside()const;
+
+    bool Commit(bool = false);
+    bool Rollback(bool = false);
+
+    c4_ViewRef View(const char*);
+    c4_View GetAs(const char*);
+
+    bool LoadFrom(c4_Stream &);
+    void SaveTo(c4_Stream &);
+
+    t4_i32 FreeSpace(t4_i32 *bytes_ = 0);
+
+    //DROPPED: c4_Storage (const char* filename_, const char* description_);
+    //DROPPED: c4_View Store(const char* name_, const c4_View& view_);
+    //DROPPED: c4_HandlerSeq& RootTable() const;
+    //DROPPED: c4_RowRef xContents() const;
+
+  private:
+    void Initialize(c4_Strategy &, bool, int);
+};
+
+//---------------------------------------------------------------------------
+
+class c4_Property {
+    short _id;
+    char _type;
+
+  public:
+    /// Construct a new property with the give type and id
+    c4_Property(char, int);
+    /// Construct a new property with the give type and name
+    c4_Property(char, const char*);
+    ~c4_Property();
+
+    c4_Property(const c4_Property &);
+    void operator = (const c4_Property &);
+
+    const char *Name()const;
+    char Type()const;
+
+    int GetId()const;
+
+    c4_Reference operator()(const c4_RowRef &)const;
+
+    void Refs(int)const;
+
+    c4_View operator, (const c4_Property &)const;
+
+    static void CleanupInternalData();
+};
+
+/// Integer properties.
+class c4_IntProp: public c4_Property {
+  public:
+    /// Construct a new property
+    c4_IntProp(const char*);
+    /// Destructor
+    ~c4_IntProp();
+
+    /// Get or set an integer property in a row
+    c4_IntRef operator()(const c4_RowRef &)const;
+    /// Get an integer property in a row
+    t4_i32 Get(const c4_RowRef &)const;
+    /// Set an integer property in a row
+    void Set(const c4_RowRef &, t4_i32)const;
+
+    /// Creates a row with one integer, shorthand for AsRow.
+    c4_Row operator[](t4_i32)const;
+    /// Creates a row with one integer.
+    c4_Row AsRow(t4_i32)const;
+};
+
+#if !q4_TINY
+
+/// Long int properties.
+class c4_LongProp: public c4_Property {
+  public:
+    /// Construct a new property
+    c4_LongProp(const char*);
+    /// Destructor
+    ~c4_LongProp();
+
+    /// Get or set a long int property in a row
+    c4_LongRef operator()(const c4_RowRef &)const;
+    /// Get a long int property in a row
+    t4_i64 Get(const c4_RowRef &)const;
+    /// Set a long int property in a row
+    void Set(const c4_RowRef &, t4_i64)const;
+
+    /// Creates a row with one long int, shorthand for AsRow.
+    c4_Row operator[](t4_i64)const;
+    /// Creates a row with one long int.
+    c4_Row AsRow(t4_i64)const;
+};
+
+/// Floating point properties.
+class c4_FloatProp: public c4_Property {
+  public:
+    /// Construct a new property
+    c4_FloatProp(const char*);
+    /// Destructor
+    ~c4_FloatProp();
+
+    /// Get or set a floating point property in a row
+    c4_FloatRef operator()(const c4_RowRef &)const;
+    /// Get a floating point property in a row
+    double Get(const c4_RowRef &)const;
+    /// Set a floating point property in a row
+    void Set(const c4_RowRef &, double)const;
+
+    /// Create a row with one floating point value, shorthand for AsRow
+    c4_Row operator[](double)const;
+    /// Create a row with one floating point value
+    c4_Row AsRow(double)const;
+};
+
+/// Double precision properties.
+class c4_DoubleProp: public c4_Property {
+  public:
+    /// Construct a new property.
+    c4_DoubleProp(const char*);
+    /// Destructor
+    ~c4_DoubleProp();
+
+    /// Get or set a double precision property in a row
+    c4_DoubleRef operator()(const c4_RowRef &)const;
+    /// Get a double precision property in a row
+    double Get(const c4_RowRef &)const;
+    /// Set a double precision property in a row
+    void Set(const c4_RowRef &, double)const;
+
+    /// Create a row with one double precision value, shorthand for AsRow
+    c4_Row operator[](double)const;
+    /// Create a row with one double precision value
+    c4_Row AsRow(double)const;
+};
+#endif // !q4_TINY
+
+/// String properties.
+class c4_StringProp: public c4_Property {
+  public:
+    /// Construct a new property
+    c4_StringProp(const char*);
+    /// Destructor
+    ~c4_StringProp();
+
+    /// Get or set a string property in a row
+    c4_StringRef operator()(const c4_RowRef &)const;
+    /// Get a string property in a row
+    const char *Get(const c4_RowRef &)const;
+    /// Set a string property in a row
+    void Set(const c4_RowRef &, const char*)const;
+
+    /// Create a row with one string, shorthand for AsRow
+    c4_Row operator[](const char*)const;
+    /// Create a row with one string
+    c4_Row AsRow(const char*)const;
+};
+
+/// Binary properties.
+class c4_BytesProp: public c4_Property {
+  public:
+    /// Construct a new property
+    c4_BytesProp(const char*);
+    /// Destructor
+    ~c4_BytesProp();
+
+    /// Get or set a bytes property in a row
+    c4_BytesRef operator()(const c4_RowRef &)const;
+    /// Get a bytes property in a row
+    c4_Bytes Get(const c4_RowRef &)const;
+    /// Set a bytes property in a row
+    void Set(const c4_RowRef &, const c4_Bytes &)const;
+
+    /// Create a row with one bytes object, shorthand for AsRow
+    c4_Row operator[](const c4_Bytes &)const;
+    /// Create a row with one bytes object
+    c4_Row AsRow(const c4_Bytes &)const;
+};
+
+/// View properties.
+class c4_ViewProp: public c4_Property {
+  public:
+    /// Construct a new property
+    c4_ViewProp(const char*);
+    /// Destructor
+    ~c4_ViewProp();
+
+    /// Get or set a view property in a row
+    c4_ViewRef operator()(const c4_RowRef &)const;
+    /// Get a view property in a row
+    c4_View Get(const c4_RowRef &)const;
+    /// Set a view property in a row
+    void Set(const c4_RowRef &, const c4_View &)const;
+
+    /// Create a row with one view, shorthand for AsRow
+    c4_Row operator[](const c4_View &)const;
+    /// Create a row with one view
+    c4_Row AsRow(const c4_View &)const;
+};
+
+//---------------------------------------------------------------------------
+
+class c4_CustomViewer {
+  protected:
+    /// Constructor, must be overriden in derived class
+    c4_CustomViewer();
+  public:
+    /// Destructor
+    virtual ~c4_CustomViewer();
+
+    /// Return the structure of this view (initialization, called once)
+    virtual c4_View GetTemplate() = 0;
+    /// Return the number of rows in this view
+    virtual int GetSize() = 0;
+    int Lookup(const c4_RowRef &, int &);
+    virtual int Lookup(c4_Cursor, int &);
+    /// Fetch one data item, return it as a generic data value
+    virtual bool GetItem(int, int, c4_Bytes &) = 0;
+    virtual bool SetItem(int, int, const c4_Bytes &);
+    bool InsertRows(int, const c4_RowRef &, int = 1);
+    virtual bool InsertRows(int, c4_Cursor, int = 1);
+    virtual bool RemoveRows(int, int = 1);
+};
+
+//---------------------------------------------------------------------------
+/// A stream is a virtual helper class to serialize in binary form.
+
+class c4_Stream {
+  public:
+    virtual ~c4_Stream();
+
+    /// Fetch some bytes sequentially
+    virtual int Read(void *, int) = 0;
+    /// Store some bytes sequentially
+    virtual bool Write(const void *, int) = 0;
+};
+
+//---------------------------------------------------------------------------
+/// A strategy encapsulates code dealing with the I/O system interface.
+
+class c4_Strategy {
+  public:
+    c4_Strategy();
+    virtual ~c4_Strategy();
+
+    virtual bool IsValid()const;
+    virtual int DataRead(t4_i32, void *, int);
+    virtual void DataWrite(t4_i32, const void *, int);
+    virtual void DataCommit(t4_i32);
+    virtual void ResetFileMapping();
+    virtual t4_i32 FileSize();
+    virtual t4_i32 FreshGeneration();
+
+    void SetBase(t4_i32);
+    t4_i32 EndOfData(t4_i32 =  - 1);
+
+    /// True if the storage format is not native (default is false)
+    bool _bytesFlipped;
+    /// Error code of last failed I/O operation, zero if I/O was ok
+    int _failure;
+    /// First byte in file mapping, zero if not active
+    const t4_byte *_mapStart;
+    /// Number of bytes filled with active data
+    t4_i32 _dataSize;
+    /// All file positions are relative to this offset
+    t4_i32 _baseOffset;
+    /// The root position of the shallow tree walks
+    t4_i32 _rootPos;
+    /// The size of the root column
+    t4_i32 _rootLen;
+};
+
+//---------------------------------------------------------------------------
+/// A sequence is an abstract base class for views on ranges of records.
+//
+//  Sequences represent arrays of rows (or indexed collections / tables).
+//  Insertion and removal of entries is allowed, but could take linear time.
+//  A reference count is maintained to decide when the object should go away.
+
+class c4_Sequence {
+    /// Reference count
+    int _refCount;
+    /// Pointer to dependency list, or null if nothing depends on this
+    c4_Dependencies *_dependencies;
+
+  protected:
+    /// Optimization: cached property index
+    int _propertyLimit;
+    /// Optimization: property map for faster access
+    short *_propertyMap; // see c4_HandlerSeq::Reset()
+    /// allocated on first use by c4_Sequence::Buffer()
+    c4_Bytes *_tempBuf;
+
+  public:
+    /* General */
+    /// Abstract constructor
+    c4_Sequence();
+
+    virtual int Compare(int, c4_Cursor)const;
+    virtual bool RestrictSearch(c4_Cursor, int &, int &);
+    void SetAt(int, c4_Cursor);
+    virtual int RemapIndex(int, const c4_Sequence*)const;
+
+    /* Reference counting */
+    void IncRef();
+    void DecRef();
+    int NumRefs()const;
+
+    /* Adding / removing rows */
+    /// Return the current number of rows
+    virtual int NumRows()const = 0;
+    void Resize(int, int =  - 1);
+
+    virtual void InsertAt(int, c4_Cursor, int = 1);
+    virtual void RemoveAt(int, int = 1);
+    virtual void Move(int, int);
+
+    /* Properties */
+    int NthPropId(int)const;
+    int PropIndex(int);
+    int PropIndex(const c4_Property &);
+
+    /// Return the number of data handlers in this sequence
+    virtual int NumHandlers()const = 0;
+    /// Return a reference to the N-th handler in this sequence
+    virtual c4_Handler &NthHandler(int)const = 0;
+    /// Return the context of the N-th handler in this sequence
+    virtual const c4_Sequence *HandlerContext(int)const = 0;
+    /// Add the specified data handler to this sequence
+    virtual int AddHandler(c4_Handler*) = 0;
+    /// Create a handler of the appropriate type
+    virtual c4_Handler *CreateHandler(const c4_Property &) = 0;
+
+    virtual const char *Description();
+
+    /* Element access */
+    /// Return width of specified data item
+    virtual int ItemSize(int, int);
+    /// Retrieve one data item from this sequence
+    virtual bool Get(int, int, c4_Bytes &);
+    /// Store a data item into this sequence
+    virtual void Set(int, const c4_Property &, const c4_Bytes &);
+
+    /* Dependency notification */
+    void Attach(c4_Sequence*);
+    void Detach(c4_Sequence*);
+    /// Return a pointer to the dependencies, or null
+    c4_Dependencies *GetDependencies()const;
+
+    virtual c4_Notifier *PreChange(c4_Notifier &);
+    virtual void PostChange(c4_Notifier &);
+
+    const char *UseTempBuffer(const char*);
+
+  protected:
+    virtual ~c4_Sequence();
+
+    void ClearCache();
+
+  public:
+    //! for c4_Table::Sequence setup
+    virtual void SetNumRows(int) = 0;
+    virtual c4_Persist *Persist()const;
+
+    c4_Bytes &Buffer();
+
+  private:
+    c4_Sequence(const c4_Sequence &); // not implemented
+    void operator = (const c4_Sequence &); // not implemented
+};
+
+//---------------------------------------------------------------------------
+/// A reference is used to get or set typed data, using derived classes.
+//
+//  Objects of this class are only intended to be used as a temporary handle
+//  while getting and setting properties in a row.  They are normally only
+//  constructed as result of function overload operators: "property (row)".
+
+class c4_Reference {
+  protected:
+    /// The cursor which points to the data
+    c4_Cursor _cursor;
+    /// The property associated to this reference
+    const c4_Property &_property;
+
+  public:
+    /// Constructor
+    c4_Reference(const c4_RowRef &, const c4_Property &);
+
+    /// Assignment of one data item
+    c4_Reference &operator = (const c4_Reference &);
+
+    /// Return width of the referenced data item
+    int GetSize()const;
+    /// Retrieve the value of the referenced data item
+    bool GetData(c4_Bytes &)const;
+    /// Store a value into the referenced data item
+    void SetData(const c4_Bytes &)const;
+
+    /// Return true if the contents of both references is equal
+    friend bool operator == (const c4_Reference &, const c4_Reference &);
+    /// Return true if the contents of both references is not equal
+    friend bool operator != (const c4_Reference &, const c4_Reference &);
+
+  private:
+    void operator &()const; // not implemented
+};
+
+//---------------------------------------------------------------------------
+
+/// Used to get or set integer values.
+class c4_IntRef: public c4_Reference {
+  public:
+    /// Constructor
+    c4_IntRef(const c4_Reference &);
+    /// Get the value as integer
+    operator t4_i32()const;
+    /// Set the value to the specified integer
+    c4_IntRef &operator = (t4_i32);
+};
+
+#if !q4_TINY
+
+/// Used to get or set long int values.
+class c4_LongRef: public c4_Reference {
+  public:
+    /// Constructor
+    c4_LongRef(const c4_Reference &);
+    /// Get the value as long int
+    operator t4_i64()const;
+    /// Set the value to the specified long int
+    c4_LongRef &operator = (t4_i64);
+};
+
+/// Used to get or set floating point values.
+class c4_FloatRef: public c4_Reference {
+  public:
+    /// Constructor
+    c4_FloatRef(const c4_Reference &);
+    /// Get the value as floating point
+    operator double()const;
+    /// Set the value to the specified floating point
+    c4_FloatRef &operator = (double);
+};
+
+/// Used to get or set double precision values.
+class c4_DoubleRef: public c4_Reference {
+  public:
+    /// Constructor
+    c4_DoubleRef(const c4_Reference &);
+    /// Get the value as floating point
+    operator double()const;
+    /// Set the value to the specified floating point
+    c4_DoubleRef &operator = (double);
+};
+
+#endif // !q4_TINY
+
+/// Used to get or set binary object values.
+class c4_BytesRef: public c4_Reference {
+  public:
+    /// Constructor
+    c4_BytesRef(const c4_Reference &);
+    /// Get the value as binary object
+    operator c4_Bytes()const;
+    /// Set the value to the specified binary object
+    c4_BytesRef &operator = (const c4_Bytes &);
+
+    /// Fetch data from the memo field, up to end if length is zero
+    c4_Bytes Access(t4_i32, int = 0, bool = false)const;
+    /// Store data, resize by diff_ bytes, return true if successful
+    bool Modify(const c4_Bytes &, t4_i32, int = 0)const;
+};
+
+/// Used to get or set string values.
+class c4_StringRef: public c4_Reference {
+  public:
+    /// Constructor
+    c4_StringRef(const c4_Reference &);
+    /// Get the value as string
+    operator const char *()const;
+    /// Set the value to the specified string
+    c4_StringRef &operator = (const char*);
+};
+
+/// Used to get or set view values.
+class c4_ViewRef: public c4_Reference {
+  public:
+    /// Constructor
+    c4_ViewRef(const c4_Reference &);
+    /// Get the value as view
+    operator c4_View()const;
+    /// Set the value to the specified view
+    c4_ViewRef &operator = (const c4_View &);
+};
+
+//---------------------------------------------------------------------------
+// Debug logging option, can generate log of changes for one/all properties
+
+#if q4_LOGPROPMODS
+FILE *f4_LogPropMods(FILE *fp_, int propId_);
+#else 
+#define f4_LogPropMods(a,b) 0
+#endif 
+
+//---------------------------------------------------------------------------
+
+#if q4_INLINE
+#include "mk4.inl"
+#endif 
+
+//---------------------------------------------------------------------------
+
+#endif // __MK4_H__
diff --git a/8.x/mk/include/mk4.inl b/8.x/mk/include/mk4.inl
new file mode 100755 (executable)
index 0000000..616c0bb
--- /dev/null
@@ -0,0 +1,874 @@
+// mk4.inl --
+// $Id: mk4.inl 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Public definitions which are usually inlined
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Reordered inlines so they are always defined before their first use
+d4_inline c4_Cursor c4_RowRef::operator& () const
+{
+  return _cursor;
+}
+
+/** Return a unique id for this property
+ *
+ *  A property object in fact merely represents an entry in a globally
+ *  maintained symbol table.  Each property is assigned a unique id,
+ *  which remains valid as long as some reference to that property
+ *  exists.  In general, property id's remain unique as long as the
+ *  application runs.  Do not store id's on file, since they are
+ *  not guaranteed to remain the same across program invocations.
+ *  All properties with the same name are given the same id.
+ */
+d4_inline int c4_Property::GetId() const
+{
+  return _id;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+#if !q4_LONG64 && !defined (LONG_LONG) && !HAVE_LONG_LONG
+
+d4_inline bool operator== (const t4_i64 a_, const t4_i64 b_)
+{
+  return a_.l1 == b_.l1 && a_.l2 == b_.l2;
+}
+
+d4_inline bool operator< (const t4_i64 a_, const t4_i64 b_)
+{
+  return a_.l2 < b_.l2 || a_.l2 == b_.l2 && a_.l2 < b_.l2;
+}
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////
+// c4_View
+
+/// Returns the number of entries in this view.
+d4_inline int c4_View::GetSize() const
+{
+  return _seq->NumRows();
+}
+
+/** Change the size of this view
+ * Since views act like dynamic arrays, you can quickly
+ * change their size.  Increasing the size will append rows
+ * with zero/empty values, while decreasing it will delete
+ * the last rows.  The growBy_ parameter is currently unused.
+ */
+d4_inline void c4_View::SetSize(int newSize_, int growBy_)
+{
+  _seq->Resize(newSize_, growBy_);
+}
+
+/// Removes all entries (sets size to zero).
+d4_inline void c4_View::RemoveAll()
+{
+  SetSize(0);
+}
+
+/// Return a pointer to the persistence handler, or zero
+d4_inline c4_Persist* c4_View::Persist() const
+{
+  return _seq->Persist();
+}
+
+/**
+ * Change the value of the specified entry.  If the new value has
+ * other properties, these will be added to the underlying view.
+ *
+ * @param index_ the zero-based row index
+ * @param newElem_ the row to copy to this view
+ */
+d4_inline void c4_View::SetAt(int index_, const c4_RowRef& newElem_)
+{
+  _seq->SetAt(index_, &newElem_);
+}
+
+/**
+ * Insert a copy of the contents of another view.  This is identical to
+ * inserting the specified number of default entries and then setting
+ * each of them to the new element value passed as argument.
+ */
+d4_inline void c4_View::InsertAt(
+       int index_, ///< zero-based row index
+       const c4_RowRef& newElem_, ///< the value to insert
+       int count_ ///< number of copies to insert, must be > 0
+    )
+{
+  _seq->InsertAt(index_, &newElem_, count_);
+}
+
+/**
+ * Remove entries starting at the given index.  Entries which have
+ * other view references may cause these views to be deleted if their
+ * reference counts drop to zero because of this removal.
+ *
+ * @param index_ the zero-based row index
+ * @param count_ the number of entries to remove
+ */
+d4_inline void c4_View::RemoveAt(int index_, int count_)
+{
+  _seq->RemoveAt(index_, count_);
+}
+
+/** Return the number of properties present in this view.
+ * @return A non-negative integer
+ */
+d4_inline int c4_View::NumProperties() const
+{
+  return _seq->NumHandlers();
+}
+
+/** Find the index of a property, given its id
+ * @param propId_ Unique id associated to a specific propoerty
+ * @return The index of the property, or -1 of it was not found
+ */
+d4_inline int c4_View::FindProperty(int propId_)
+{
+  return _seq->PropIndex(propId_);
+}
+
+    /// Return a decription if there is a fixed structure, else zero
+d4_inline const char* c4_View::Description() const
+{
+  return _seq->Description();
+}
+
+    /// Increase the reference count of the associated sequence
+d4_inline void c4_View::_IncSeqRef()
+{
+  _seq->IncRef();
+}
+
+    /// Decrease the reference count of the associated sequence
+d4_inline void c4_View::_DecSeqRef()
+{
+  _seq->DecRef();
+}
+
+/// Destructor, decrements reference count
+d4_inline c4_View::~c4_View ()
+{
+  _DecSeqRef();
+}
+
+    /// Return true if the contents of both views are equal
+d4_inline bool operator== (const c4_View& a_, const c4_View& b_)
+{
+  return a_.GetSize() == b_.GetSize() && a_.Compare(b_) == 0;
+}
+
+    /// Return true if the contents of both views are not equal
+d4_inline bool operator!= (const c4_View& a_, const c4_View& b_)
+{
+  return !(a_ == b_);
+}
+
+    /// True if first view is less than second view
+d4_inline bool operator< (const c4_View& a_, const c4_View& b_)
+{
+  return a_.Compare(b_) < 0;
+}
+
+    /// True if first view is greater than second view
+d4_inline bool operator> (const c4_View& a_, const c4_View& b_)
+{
+  return b_ < a_;
+}
+
+    /// True if first view is less or equal to second view
+d4_inline bool operator<= (const c4_View& a_, const c4_View& b_)
+{
+  return !(b_ < a_);
+}
+
+    /// True if first view is greater or equal to second view
+d4_inline bool operator>= (const c4_View& a_, const c4_View& b_)
+{                     
+  return !(a_ < b_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Cursor
+
+/** Constructs a new cursor.
+ *
+ * Cursor cannot be created without an underlying view, but you could
+ * define a global "nullView" object and then initialize the cursor with
+ * "&nullView[0]". This works because cursors need not point to a valid row.
+ */
+d4_inline c4_Cursor::c4_Cursor (c4_Sequence& seq_, int index_)
+    : _seq (&seq_), _index (index_)
+{
+}
+
+/// Pre-increments the cursor.
+d4_inline c4_Cursor& c4_Cursor::operator++ ()
+{
+  ++_index;
+  return *this;
+}
+
+/// Post-increments the cursor.
+d4_inline c4_Cursor c4_Cursor::operator++ (int)
+{
+  return c4_Cursor (*_seq, _index++);
+}
+
+/// Pre-decrements the cursor.
+d4_inline c4_Cursor& c4_Cursor::operator-- ()
+{
+  --_index;
+  return *this;
+}
+
+/// Post-decrements the cursor.
+d4_inline c4_Cursor c4_Cursor::operator-- (int)
+{
+  return c4_Cursor (*_seq, _index--);
+}
+
+/// Advances by a given offset.
+d4_inline c4_Cursor& c4_Cursor::operator+= (int offset_)
+{
+  _index += offset_;
+  return *this;
+}
+
+/// Backs up by a given offset.
+d4_inline c4_Cursor& c4_Cursor::operator-= (int offset_)
+{
+  _index -= offset_;
+  return *this;
+}
+
+/// Subtracts a specified offset.
+d4_inline c4_Cursor c4_Cursor::operator- (int offset_) const
+{
+  return c4_Cursor (*_seq, _index - offset_);
+}
+
+/// Returns the distance between two cursors.
+d4_inline int c4_Cursor::operator- (c4_Cursor cursor_) const
+{
+  return _index - cursor_._index;
+}
+
+/// Add a specified offset.
+d4_inline c4_Cursor operator+ (c4_Cursor cursor_, int offset_)
+{
+  return c4_Cursor (*cursor_._seq, cursor_._index + offset_);
+}
+
+/// Adds specified offset to cursor.
+d4_inline c4_Cursor operator+ (int offset_, c4_Cursor cursor_)
+{
+  return cursor_ + offset_;
+}
+
+d4_inline bool operator== (c4_Cursor a_, c4_Cursor b_)
+{
+  return a_._seq == b_._seq && a_._index == b_._index;
+}
+
+d4_inline bool operator!= (c4_Cursor a_, c4_Cursor b_)
+{
+  return !(a_ == b_);
+}
+
+d4_inline bool operator< (c4_Cursor a_, c4_Cursor b_)
+{
+  return a_._seq < b_._seq ||
+         a_._seq == b_._seq && a_._index < b_._index;
+}
+
+d4_inline bool operator> (c4_Cursor a_, c4_Cursor b_)
+{
+  return b_ < a_;
+}
+
+d4_inline bool operator<= (c4_Cursor a_, c4_Cursor b_)
+{
+  return !(b_ < a_);
+}
+
+d4_inline bool operator>= (c4_Cursor a_, c4_Cursor b_)
+{                     
+  return !(a_ < b_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_RowRef
+
+d4_inline c4_RowRef::c4_RowRef (c4_Cursor cursor_)
+    : _cursor (cursor_)
+{
+}
+
+d4_inline c4_RowRef c4_RowRef::operator= (const c4_RowRef& rowRef_)
+{
+  if (_cursor != rowRef_._cursor)
+    _cursor._seq->SetAt(_cursor._index, &rowRef_);
+  
+  return *this;
+}
+
+d4_inline c4_View c4_RowRef::Container() const
+{
+  return _cursor._seq;
+}
+
+d4_inline bool operator== (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+  return (&a_)._seq->Compare((&a_)._index, &b_) == 0;
+}               
+
+d4_inline bool operator!= (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+  return !(a_ == b_);
+}
+
+d4_inline bool operator< (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+      // 25-5-1998: don't exchange a and b, this comparison is -not- symmetric
+  return (&a_)._seq->Compare((&a_)._index, &b_) < 0;
+}               
+
+d4_inline bool operator> (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+      // 25-5-1998: don't exchange a and b, this comparison is -not- symmetric
+  return (&a_)._seq->Compare((&a_)._index, &b_) > 0;
+}
+
+d4_inline bool operator<= (const c4_RowRef& a_, const c4_RowRef& b_)
+{
+  return !(a_ > b_);
+}
+
+d4_inline bool operator>= (const c4_RowRef& a_, const c4_RowRef& b_)
+{                     
+  return !(a_ < b_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Bytes
+
+    /// Construct an empty binary object
+d4_inline c4_Bytes::c4_Bytes ()
+    : _size (0), _copy (false)
+{ 
+  _contents = 0; // moved out of intializers for DEC CXX 5.7
+}
+
+    /// Construct an object with contents, no copy
+d4_inline c4_Bytes::c4_Bytes (const void* buf_, int len_)
+    : _size (len_), _copy (false)
+{
+  _contents = (t4_byte*) buf_; // moved out of intializers for DEC CXX 5.7
+}
+
+/// Returns a pointer to the contents.
+d4_inline const t4_byte* c4_Bytes::Contents() const
+{
+  return _contents;
+}
+
+/// Returns the number of bytes of its contents.
+d4_inline int c4_Bytes::Size() const
+{
+  return _size;
+}
+
+d4_inline void c4_Bytes::_LoseCopy()
+{
+  if (_copy)
+    delete [] (char*) _contents;
+}
+
+/// Returns true if the contents of both objects is not equal.
+d4_inline bool operator!= (const c4_Bytes& a_, const c4_Bytes& b_)
+{
+  return !(a_ == b_);
+}
+
+/// Destructor, if a copy was made, it will be released here.
+d4_inline c4_Bytes::~c4_Bytes ()
+{
+  _LoseCopy();
+}
+    
+/////////////////////////////////////////////////////////////////////////////
+// c4_Reference
+
+d4_inline c4_Reference::c4_Reference (const c4_RowRef& rowRef_,
+                                        const c4_Property& prop_)
+    : _cursor (&rowRef_), _property (prop_)
+{
+}
+
+d4_inline int c4_Reference::GetSize() const
+{
+  return _cursor._seq->ItemSize(_cursor._index, _property.GetId());
+}
+
+d4_inline bool c4_Reference::GetData(c4_Bytes& buf_) const
+{
+  return _cursor._seq->Get(_cursor._index, _property.GetId(), buf_);
+}
+
+d4_inline void c4_Reference::SetData(const c4_Bytes& buf_) const
+{
+  _cursor._seq->Set(_cursor._index, _property, buf_);
+}
+
+d4_inline bool operator!= (const c4_Reference& a_, const c4_Reference& b_)
+{
+  return !(a_ == b_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_IntRef
+
+d4_inline c4_IntRef::c4_IntRef (const c4_Reference& value_)
+    : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#if !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+// c4_LongRef
+
+d4_inline c4_LongRef::c4_LongRef (const c4_Reference& value_)
+    : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FloatRef
+
+d4_inline c4_FloatRef::c4_FloatRef (const c4_Reference& value_)
+    : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_DoubleRef
+
+d4_inline c4_DoubleRef::c4_DoubleRef (const c4_Reference& value_)
+    : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+// c4_BytesRef
+
+d4_inline c4_BytesRef::c4_BytesRef (const c4_Reference& value_)
+    : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_StringRef
+
+d4_inline c4_StringRef::c4_StringRef (const c4_Reference& value_)
+    : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_ViewRef
+
+d4_inline c4_ViewRef::c4_ViewRef (const c4_Reference& value_)
+    : c4_Reference (value_)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Property
+
+d4_inline c4_Property::c4_Property (char type_, int id_)
+    : _id ((short) id_), _type (type_)
+{
+}
+
+    /// Get or set this untyped property in a row
+d4_inline c4_Reference c4_Property::operator() (const c4_RowRef& rowRef_) const
+{
+  return c4_Reference (rowRef_, *this);
+}
+
+    /// Return a view like the first, with a property appended to it
+d4_inline c4_View c4_Property::operator, (const c4_Property& prop_) const
+{
+  return c4_View (*this), prop_;
+}
+
+    /// Return the type of this property
+d4_inline char c4_Property::Type() const
+{
+  return _type;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_IntProp
+
+d4_inline c4_IntProp::c4_IntProp (const char* name_) 
+    : c4_Property ('I', name_)
+{
+}
+
+d4_inline c4_IntProp::~c4_IntProp ()
+{
+}
+
+d4_inline c4_IntRef c4_IntProp::operator() (const c4_RowRef& rowRef_) const
+{
+  return c4_Reference (rowRef_, *this);
+}
+
+d4_inline t4_i32 c4_IntProp::Get(const c4_RowRef& rowRef_) const
+{
+  return operator() (rowRef_);
+}
+
+d4_inline void c4_IntProp::Set(const c4_RowRef& rowRef_, t4_i32 value_) const
+{
+  operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_IntProp::AsRow(t4_i32 value_) const
+{
+  c4_Row row;
+  operator() (row) = value_;
+  return row;
+}
+    
+d4_inline c4_Row c4_IntProp::operator[] (t4_i32 value_) const
+{
+  return AsRow(value_);
+}
+    
+/////////////////////////////////////////////////////////////////////////////
+#if !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+// c4_LongProp
+
+d4_inline c4_LongProp::c4_LongProp (const char* name_) 
+    : c4_Property ('L', name_)
+{
+}
+
+d4_inline c4_LongProp::~c4_LongProp ()
+{
+}
+
+d4_inline c4_LongRef c4_LongProp::operator() (const c4_RowRef& rowRef_) const
+{
+  return c4_Reference (rowRef_, *this);
+}
+
+d4_inline t4_i64 c4_LongProp::Get(const c4_RowRef& rowRef_) const
+{
+  return operator() (rowRef_);
+}
+
+d4_inline void c4_LongProp::Set(const c4_RowRef& rowRef_, t4_i64 value_) const
+{
+  operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_LongProp::AsRow(t4_i64 value_) const
+{
+  c4_Row row;
+  operator() (row) = value_;
+  return row;
+}
+    
+d4_inline c4_Row c4_LongProp::operator[] (t4_i64 value_) const
+{
+  return AsRow(value_);
+}
+    
+/////////////////////////////////////////////////////////////////////////////
+// c4_FloatProp
+
+d4_inline c4_FloatProp::c4_FloatProp (const char* name_) 
+    : c4_Property ('F', name_)
+{
+}
+
+d4_inline c4_FloatProp::~c4_FloatProp ()
+{
+}
+
+d4_inline c4_FloatRef c4_FloatProp::operator() (const c4_RowRef& rowRef_) const
+{
+  return c4_Reference (rowRef_, *this);
+}
+
+d4_inline double c4_FloatProp::Get(const c4_RowRef& rowRef_) const
+{
+  return operator() (rowRef_);
+}
+
+d4_inline void c4_FloatProp::Set(const c4_RowRef& rowRef_, double value_) const
+{
+  operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_FloatProp::AsRow(double value_) const
+{
+  c4_Row row;
+  operator() (row) = value_;
+  return row;
+}
+    
+d4_inline c4_Row c4_FloatProp::operator[] (double value_) const
+{
+  return AsRow(value_);
+}
+    
+/////////////////////////////////////////////////////////////////////////////
+// c4_DoubleProp
+
+d4_inline c4_DoubleProp::c4_DoubleProp (const char* name_) 
+    : c4_Property ('D', name_)
+{
+}
+
+d4_inline c4_DoubleProp::~c4_DoubleProp ()
+{
+}
+
+d4_inline c4_DoubleRef c4_DoubleProp::operator() (const c4_RowRef& rowRef_) const
+{
+  return c4_Reference (rowRef_, *this);
+}
+
+d4_inline double c4_DoubleProp::Get(const c4_RowRef& rowRef_) const
+{
+  return operator() (rowRef_);
+}
+
+d4_inline void c4_DoubleProp::Set(const c4_RowRef& rowRef_, double value_) const
+{
+  operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_DoubleProp::AsRow(double value_) const
+{
+  c4_Row row;
+  operator() (row) = value_;
+  return row;
+}
+    
+d4_inline c4_Row c4_DoubleProp::operator[] (double value_) const
+{
+  return AsRow(value_);
+}
+    
+/////////////////////////////////////////////////////////////////////////////
+#endif // !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+// c4_BytesProp
+
+d4_inline c4_BytesProp::c4_BytesProp (const char* name_) 
+    : c4_Property ('B', name_)
+{
+}
+    
+d4_inline c4_BytesProp::~c4_BytesProp ()
+{
+}
+
+d4_inline c4_BytesRef c4_BytesProp::operator() (const c4_RowRef& rowRef_) const
+{
+  return c4_Reference (rowRef_, *this);
+}
+
+d4_inline c4_Bytes c4_BytesProp::Get(const c4_RowRef& rowRef_) const
+{
+  return operator() (rowRef_);
+}
+
+d4_inline void c4_BytesProp::Set(const c4_RowRef& rowRef_, const c4_Bytes& value_) const
+{
+  operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_BytesProp::AsRow(const c4_Bytes& value_) const
+{
+  c4_Row row;
+  operator() (row) = value_;
+  return row;
+}
+    
+d4_inline c4_Row c4_BytesProp::operator[] (const c4_Bytes& value_) const
+{
+  return AsRow(value_);
+}
+    
+/////////////////////////////////////////////////////////////////////////////
+// c4_StringProp
+
+d4_inline c4_StringProp::c4_StringProp (const char* name_) 
+    : c4_Property ('S', name_)
+{
+}
+    
+d4_inline c4_StringProp::~c4_StringProp ()
+{
+}
+
+d4_inline c4_StringRef c4_StringProp::operator() (const c4_RowRef& rowRef_) const
+{
+  return c4_Reference (rowRef_, *this);
+}
+
+d4_inline const char* c4_StringProp::Get(const c4_RowRef& rowRef_) const
+{
+  return operator() (rowRef_);
+}
+
+d4_inline void c4_StringProp::Set(const c4_RowRef& rowRef_, const char* value_) const
+{
+  operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_StringProp::AsRow(const char* value_) const
+{
+  c4_Row row;
+  operator() (row) = value_;
+  return row;
+}
+    
+d4_inline c4_Row c4_StringProp::operator[] (const char* value_) const
+{
+  return AsRow(value_);
+}
+    
+/////////////////////////////////////////////////////////////////////////////
+// c4_ViewProp
+
+d4_inline c4_ViewProp::c4_ViewProp (const char* name_)
+    : c4_Property ('V', name_)
+{
+}
+    
+d4_inline c4_ViewProp::~c4_ViewProp ()
+{
+}
+
+d4_inline c4_ViewRef c4_ViewProp::operator() (const c4_RowRef& rowRef_) const
+{
+  return c4_Reference (rowRef_, *this);
+}
+
+d4_inline c4_View c4_ViewProp::Get(const c4_RowRef& rowRef_) const
+{
+  return operator() (rowRef_);
+}
+
+d4_inline void c4_ViewProp::Set(const c4_RowRef& rowRef_, const c4_View& value_) const
+{
+  operator() (rowRef_) = value_;
+}
+
+d4_inline c4_Row c4_ViewProp::AsRow(const c4_View& value_) const
+{
+  c4_Row row;
+  operator() (row) = value_;
+  return row;
+}
+    
+d4_inline c4_Row c4_ViewProp::operator[] (const c4_View& value_) const
+{
+  return AsRow(value_);
+}
+    
+/////////////////////////////////////////////////////////////////////////////
+// c4_Strategy
+
+    /// True if we can do I/O with this object
+d4_inline bool c4_Strategy::IsValid() const
+{ 
+  return false; 
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_CustomViewer
+
+d4_inline c4_CustomViewer::c4_CustomViewer()
+{
+}
+
+d4_inline int c4_CustomViewer::Lookup(const c4_RowRef& r_, int& n_)
+{
+  return Lookup(&r_, n_); // c4_Cursor
+}
+
+d4_inline bool c4_CustomViewer::InsertRows(int p_, const c4_RowRef& r_, int n_)
+{
+  return InsertRows(p_, &r_, n_); // c4_Cursor
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Sequence
+
+d4_inline c4_Dependencies* c4_Sequence::GetDependencies() const
+{
+  return _dependencies;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Reordered inlines so they are always used after their definition
+/// Dereferences this cursor to "almost" a row.
+d4_inline c4_RowRef c4_Cursor::operator* () const
+{
+  return *(c4_Cursor*) this; // cast avoids a const problem with BCPP 4.52
+}
+
+/// This is the same as *(cursor + offset).
+d4_inline c4_RowRef c4_Cursor::operator[] (int offset_) const
+{
+  return *(*this + offset_);
+}
+
+/// Returns a reference to specified entry, for use as RHS or LHS
+d4_inline c4_RowRef c4_View::GetAt(int index_) const
+{
+  return * c4_Cursor (*_seq, index_);
+}
+
+/** Element access, shorthand for GetAt
+ * @return A reference to the specified row in the view.
+ * This reference can be used on either side of the assignment operator.
+ */
+d4_inline c4_RowRef c4_View::operator[] (
+       int index_ ///< zero-based row index
+    ) const
+{
+  return GetAt(index_);
+}
+    
+/** Element access, shorthand for GetAt
+ * @return A reference to the specified row in the view.
+ * This reference can be used on either side of the assignment operator.
+ */
+d4_inline c4_RowRef c4_View::ElementAt(
+       int index_ ///< zero-based row index
+    )
+{
+  return GetAt(index_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/include/mk4dll.h b/8.x/mk/include/mk4dll.h
new file mode 100755 (executable)
index 0000000..7035c5c
--- /dev/null
@@ -0,0 +1,111 @@
+// mk4dll.h --
+// $Id: mk4dll.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+//
+//  Import declarations for DLLs
+
+#ifndef __MK4_H__
+#error This file is included by "mk4.h", it cannot be used standalone
+#endif 
+
+#ifndef d4_DLL
+#ifdef _WIN32
+#ifdef _USRDLL
+#define d4_DLL      __declspec(dllexport)
+#else 
+#define d4_DLL      __declspec(dllimport)
+#endif 
+#else 
+#define d4_DLL          
+#endif 
+#endif 
+
+#ifndef d4_DLLSPEC
+#ifdef _MSC_VER
+#define d4_DLLSPEC(t)   d4_DLL t
+#else 
+#define d4_DLLSPEC(t)   t d4_DLL
+#endif 
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+class d4_DLL c4_Bytes;
+class d4_DLL c4_BytesProp;
+class d4_DLL c4_BytesRef;
+class d4_DLL c4_Cursor;
+class d4_DLL c4_CustomViewer;
+class d4_DLL c4_DoubleProp;
+class d4_DLL c4_DoubleRef;
+class d4_DLL c4_FileStrategy;
+class d4_DLL c4_FileStream;
+class d4_DLL c4_FloatProp;
+class d4_DLL c4_FloatRef;
+class d4_DLL c4_IntProp;
+class d4_DLL c4_IntRef;
+class d4_DLL c4_LongRef;
+class d4_DLL c4_Property;
+class d4_DLL c4_Reference;
+class d4_DLL c4_Row;
+class d4_DLL c4_RowRef;
+class d4_DLL c4_Sequence;
+class d4_DLL c4_Storage;
+class d4_DLL c4_Strategy;
+class d4_DLL c4_Stream;
+class d4_DLL c4_StringProp;
+class d4_DLL c4_StringRef;
+class d4_DLL c4_View;
+class d4_DLL c4_ViewProp;
+class d4_DLL c4_ViewRef;
+
+#if !q4_MFC
+class d4_DLL c4_String;
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+d4_DLLSPEC(bool)operator == (const c4_View &a_, const c4_View &b_);
+d4_DLLSPEC(bool)operator != (const c4_View &a_, const c4_View &b_);
+d4_DLLSPEC(bool)operator < (const c4_View &a_, const c4_View &b_);
+d4_DLLSPEC(bool)operator > (const c4_View &a_, const c4_View &b_);
+d4_DLLSPEC(bool)operator <= (const c4_View &a_, const c4_View &b_);
+d4_DLLSPEC(bool)operator >= (const c4_View &a_, const c4_View &b_);
+
+d4_DLLSPEC(bool)operator == (c4_Cursor a_, c4_Cursor b_);
+d4_DLLSPEC(bool)operator != (c4_Cursor a_, c4_Cursor b_);
+d4_DLLSPEC(bool)operator < (c4_Cursor a_, c4_Cursor b_);
+d4_DLLSPEC(bool)operator > (c4_Cursor a_, c4_Cursor b_);
+d4_DLLSPEC(bool)operator <= (c4_Cursor a_, c4_Cursor b_);
+d4_DLLSPEC(bool)operator >= (c4_Cursor a_, c4_Cursor b_);
+d4_DLLSPEC(c4_Cursor)operator + (c4_Cursor cursor_, int offset_);
+d4_DLLSPEC(c4_Cursor)operator + (int offset_, c4_Cursor cursor_);
+
+d4_DLLSPEC(bool)operator == (const c4_RowRef &a_, const c4_RowRef &b_);
+d4_DLLSPEC(bool)operator != (const c4_RowRef &a_, const c4_RowRef &b_);
+d4_DLLSPEC(bool)operator < (const c4_RowRef &a_, const c4_RowRef &b_);
+d4_DLLSPEC(bool)operator > (const c4_RowRef &a_, const c4_RowRef &b_);
+d4_DLLSPEC(bool)operator <= (const c4_RowRef &a_, const c4_RowRef &b_);
+d4_DLLSPEC(bool)operator >= (const c4_RowRef &a_, const c4_RowRef &b_);
+d4_DLLSPEC(c4_Row)operator + (const c4_RowRef &a_, const c4_RowRef &b_);
+
+d4_DLLSPEC(bool)operator == (const c4_Bytes &a_, const c4_Bytes &b_);
+d4_DLLSPEC(bool)operator != (const c4_Bytes &a_, const c4_Bytes &b_);
+
+d4_DLLSPEC(bool)operator == (const c4_Reference &, const c4_Reference &);
+d4_DLLSPEC(bool)operator != (const c4_Reference &, const c4_Reference &);
+
+#if !q4_MFC
+d4_DLLSPEC(c4_String)operator + (const c4_String &, const c4_String &);
+d4_DLLSPEC(c4_String)operator + (const c4_String &, const char*);
+d4_DLLSPEC(c4_String)operator + (const char *, const c4_String &);
+
+d4_DLLSPEC(bool)operator == (const c4_String &, const c4_String &);
+d4_DLLSPEC(bool)operator != (const c4_String &, const c4_String &);
+d4_DLLSPEC(bool)operator == (const c4_String &s1, const char *s2);
+d4_DLLSPEC(bool)operator == (const char *s1, const c4_String &s2);
+d4_DLLSPEC(bool)operator != (const c4_String &s1, const char *s2);
+d4_DLLSPEC(bool)operator != (const char *s1, const c4_String &s2);
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/include/mk4io.h b/8.x/mk/include/mk4io.h
new file mode 100755 (executable)
index 0000000..72e889e
--- /dev/null
@@ -0,0 +1,64 @@
+// mk4io.h --
+// $Id: mk4io.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Declaration of the file stream and strategy classes.
+ */
+
+#ifndef __MK4IO_H__
+#define __MK4IO_H__
+
+#include <stdio.h>
+
+/////////////////////////////////////////////////////////////////////////////
+/// A file stream can be used to serialize using the stdio library.
+
+class c4_FileStream: public c4_Stream {
+  public:
+    c4_FileStream(FILE *stream_, bool owned_ = false);
+    virtual ~c4_FileStream();
+
+    virtual int Read(void *buffer_, int length_);
+    virtual bool Write(const void *buffer_, int length_);
+
+    FILE *_stream;
+    bool _owned;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+/// A file strategy encapsulates code dealing with all file I/O.
+
+class c4_FileStrategy: public c4_Strategy {
+  public:
+    /// Construct a new strategy object
+    c4_FileStrategy(FILE *file_ = 0);
+    virtual ~c4_FileStrategy();
+
+    /// True if we can do I/O with this object
+    virtual bool IsValid()const;
+    /// Open a data file by name
+    virtual bool DataOpen(const char *fileName_, int mode_);
+    /// Read a number of bytes
+    virtual int DataRead(t4_i32 pos_, void *buffer_, int length_);
+    /// Write a number of bytes, return true if successful
+    virtual void DataWrite(t4_i32 pos_, const void *buffer_, int length_);
+    /// Flush and truncate file
+    virtual void DataCommit(t4_i32 newSize_);
+    /// Support for memory-mapped files
+    virtual void ResetFileMapping();
+    /// Report total size of the datafile
+    virtual t4_i32 FileSize();
+    /// Return a good value to use as fresh generation counter
+    virtual t4_i32 FreshGeneration();
+
+  protected:
+    /// Pointer to file object
+    FILE *_file;
+    /// Pointer to same file object, if it must be deleted at end
+    FILE *_cleanup;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __MK4IO_H__
diff --git a/8.x/mk/include/mk4str.h b/8.x/mk/include/mk4str.h
new file mode 100755 (executable)
index 0000000..2ba1d47
--- /dev/null
@@ -0,0 +1,179 @@
+// mk4str.h --
+// $Id: mk4str.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Declarations of the string package.
+ */
+
+#ifndef __MK4STR_H__
+#define __MK4STR_H__
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_MFC                      // Microsoft Foundation Classes
+
+#ifdef _WINDOWS
+#include <afxwin.h>
+#else 
+#include <afxcoll.h>
+#endif 
+
+#if _MSC_VER == 800
+// MSVC 1.52 thinks a typedef has no constructor, use define instead
+#define c4_String CString
+#elif _MSC_VER >= 1300
+// VC 7.0 does not like "class" (6-2-2002, Zhang Dehua)
+typedef CString c4_String;
+#else 
+typedef class CString c4_String;
+#endif 
+
+#elif q4_STD                    // STL and standard strings
+
+#include <string>
+
+#if !defined (d4_std)           // the default is to use namespaces
+#define d4_std std
+#endif 
+
+/// STL-based string class, modeled after the MFC version
+class c4_String: public d4_std::string {
+    typedef d4_std::string string;
+
+  public:
+    c4_String();
+    c4_String(char ch, int nDup = 1);
+    c4_String(const char *str);
+    c4_String(const void *ptr, int len);
+    c4_String(const d4_std::string &s);
+    c4_String(const c4_String &s);
+    ~c4_String();
+
+    const c4_String &operator = (const c4_String &);
+
+    operator const char *()const;
+
+    char operator[](int i)const;
+
+    friend c4_String operator + (const c4_String &, const c4_String &);
+    friend c4_String operator + (const c4_String &, const char*);
+    friend c4_String operator + (const char *, const c4_String &);
+
+    const c4_String &operator += (const c4_String &s);
+    const c4_String &operator += (const char *s);
+
+    int GetLength()const;
+    bool IsEmpty()const;
+    void Empty();
+
+    c4_String Mid(int nFirst, int nCount = 25000)const;
+    c4_String Left(int nCount)const;
+    c4_String Right(int nCount)const;
+
+    int Compare(const char *str)const;
+    int CompareNoCase(const char *str)const;
+
+    bool operator < (const c4_String &str)const;
+
+    int Find(char ch)const;
+    int ReverseFind(char ch)const;
+    int FindOneOf(const char *set)const;
+
+    int Find(const char *sub)const;
+
+    c4_String SpanIncluding(const char *set)const;
+    c4_String SpanExcluding(const char *set)const;
+};
+
+bool operator == (const c4_String &, const c4_String &);
+bool operator != (const c4_String &, const c4_String &);
+
+d4_inline bool operator == (const c4_String &s1, const char *s2);
+d4_inline bool operator == (const char *s1, const c4_String &s2);
+
+d4_inline bool operator != (const c4_String &s1, const char *s2);
+d4_inline bool operator != (const char *s1, const c4_String &s2);
+
+#else // Universal replacement classes
+
+/// An efficient string class, modeled after the MFC version
+class c4_String {
+  public:
+    c4_String();
+    c4_String(char ch, int nDup = 1);
+    c4_String(const char *str);
+    c4_String(const unsigned char *str);
+    c4_String(const void *ptr, int len);
+    c4_String(const c4_String &s);
+    ~c4_String();
+
+    const c4_String &operator = (const c4_String &);
+
+    operator const char *()const;
+    operator const unsigned char *()const;
+
+    char operator[](int i)const;
+
+    friend c4_String operator + (const c4_String &, const c4_String &);
+    friend c4_String operator + (const c4_String &, const char*);
+    friend c4_String operator + (const char *, const c4_String &);
+    //  friend c4_String operator+ (const c4_String&, char);
+    //  friend c4_String operator+ (char, const c4_String&);
+
+    const c4_String &operator += (const c4_String &s);
+    const c4_String &operator += (const char *s);
+    //  const c4_String& operator+= (char c);
+
+    int GetLength()const;
+    bool IsEmpty()const;
+    void Empty(); // free up the data
+
+    c4_String Mid(int nFirst, int nCount = 25000)const;
+    c4_String Left(int nCount)const; // first nCount chars
+    c4_String Right(int nCount)const; // last nCount chars
+
+    friend bool operator == (const c4_String &, const c4_String &); // memcmp
+    friend bool operator != (const c4_String &, const c4_String &); // opposite
+
+    // only defined for strings having no zero bytes inside them:
+
+    int Compare(const char *str)const; // strcmp
+    int CompareNoCase(const char *str)const; // stricmp
+
+    bool operator < (const c4_String &str)const;
+
+    int Find(char ch)const; // strchr
+    int ReverseFind(char ch)const; // strrchr
+    int FindOneOf(const char *set)const; // strpbrk
+
+    int Find(const char *sub)const; // strstr
+
+    c4_String SpanIncluding(const char *set)const; // strspn
+    c4_String SpanExcluding(const char *set)const; // strcspn
+
+  private:
+    void Init(const void *p, int n);
+    const char *Data()const;
+    int FullLength()const;
+
+    unsigned char *_value;
+};
+
+bool operator == (const c4_String &s1, const char *s2);
+bool operator == (const char *s1, const c4_String &s2);
+
+bool operator != (const c4_String &s1, const char *s2);
+bool operator != (const char *s1, const c4_String &s2);
+
+#endif // q4_MFC elif q4_STD else q4_UNIV
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "mk4str.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // __MK4STR_H__
diff --git a/8.x/mk/include/mk4str.inl b/8.x/mk/include/mk4str.inl
new file mode 100755 (executable)
index 0000000..0ed056c
--- /dev/null
@@ -0,0 +1,299 @@
+// mk4str.inl --
+// $Id: mk4str.inl 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Members of the string package which are usually inlined
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_String
+
+#if q4_MFC                      // Microsoft Foundation Classes
+    
+#elif q4_STD                    // STL and standard strings
+
+/// Construct empty string
+d4_inline c4_String::c4_String ()
+{
+}
+
+d4_inline c4_String::c4_String (char ch_, int nDup_)
+    : string (nDup_, ch_)
+{
+}
+
+d4_inline c4_String::c4_String (const char* str_)
+    : string (str_)
+{
+}
+
+d4_inline c4_String::c4_String (const void* ptr_, int len_)
+    : string ((const char*) ptr_, len_)
+{
+}
+
+d4_inline c4_String::c4_String (const d4_std::string& s_)
+    : string (s_)
+{
+}
+
+d4_inline c4_String::c4_String (const c4_String& s_)
+    : string (s_)
+{
+}
+
+d4_inline c4_String::~c4_String ()
+{
+}
+
+d4_inline const c4_String& c4_String::operator= (const c4_String& s_)
+{
+    *(string*) this = s_;
+    return *this;
+}
+
+d4_inline c4_String::operator const char* () const
+{
+    return c_str();
+}
+
+d4_inline char c4_String::operator[] (int i) const
+{
+    return at(i);
+}
+    
+d4_inline c4_String operator+ (const c4_String& a_, const c4_String& b_)
+{
+    return (d4_std::string) a_ + (d4_std::string) b_; 
+}
+
+d4_inline c4_String operator+ (const c4_String& a_, const char* b_)
+{
+    return (d4_std::string) a_ + (d4_std::string) b_; 
+}
+
+d4_inline c4_String operator+ (const char* a_, const c4_String& b_)
+{
+    return (d4_std::string) a_ + (d4_std::string) b_; 
+}
+
+d4_inline const c4_String& c4_String::operator+= (const c4_String& s_)
+{
+    *(string*) this += s_;
+    return *this;
+}
+
+d4_inline const c4_String& c4_String::operator+= (const char* s_)
+{
+    *(string*) this += s_;
+    return *this;
+}
+
+d4_inline int c4_String::GetLength() const
+{
+    return length();
+}
+
+d4_inline bool c4_String::IsEmpty() const
+{
+    return empty();
+}
+
+d4_inline void c4_String::Empty()
+{
+    erase();
+}
+
+d4_inline c4_String c4_String::Left(int nCount_) const
+{
+    if (nCount_ > length())
+        nCount_ = length();
+    return substr(0, nCount_);
+}
+
+d4_inline c4_String c4_String::Right(int nCount_) const
+{
+    if (nCount_ > length())
+        nCount_ = length();
+    return substr(length() - nCount_, nCount_);
+}
+                
+d4_inline int c4_String::Compare(const char* str_) const
+{
+    return compare(str_);
+}
+
+d4_inline bool c4_String::operator< (const c4_String& str_) const
+{
+    return compare(str_) < 0;
+}
+
+d4_inline int c4_String::Find(char ch_) const
+{
+    return find(ch_);
+}
+
+d4_inline int c4_String::ReverseFind(char ch_) const
+{
+    return rfind(ch_);
+}
+
+d4_inline int c4_String::FindOneOf(const char* set_) const
+{
+    return find_first_of(set_);
+}
+
+d4_inline int c4_String::Find(const char* sub_) const
+{
+    return find(sub_);
+}
+
+d4_inline c4_String c4_String::SpanIncluding(const char* set_) const
+{
+    return substr(0, find_first_not_of(set_));
+}
+
+d4_inline c4_String c4_String::SpanExcluding(const char* set_) const
+{
+    return substr(0, find_first_of(set_));
+}
+
+d4_inline bool operator== (const c4_String& a_, const c4_String& b_)
+{
+    return (d4_std::string) a_ == (d4_std::string) b_;
+}
+
+d4_inline bool operator!= (const c4_String& a_, const c4_String& b_)
+{
+    return (d4_std::string) a_ != (d4_std::string) b_;
+}
+    
+d4_inline bool operator== (const c4_String& a_, const char* b_)
+{
+    return (d4_std::string) a_ == (d4_std::string) b_;
+}
+
+d4_inline bool operator== (const char* a_, const c4_String& b_)
+{
+    return (d4_std::string) a_ == (d4_std::string) b_;
+}
+
+d4_inline bool operator!= (const c4_String& a_, const char* b_)
+{
+    return (d4_std::string) a_ != (d4_std::string) b_;
+}
+
+d4_inline bool operator!= (const char* a_, const c4_String& b_)
+{
+    return (d4_std::string) a_ != (d4_std::string) b_;
+}
+
+#else                           // Universal replacement classes
+
+/// Construct empty string
+d4_inline c4_String::c4_String ()
+{
+    Init(0, 0);
+}
+
+/// Construct string from Pascal-style <count,chars...> data
+d4_inline c4_String::c4_String (const unsigned char* ptr)
+{
+    Init(ptr + 1, ptr ? *ptr : 0);
+}
+
+/// Construct string from a specified area in memory
+d4_inline c4_String::c4_String (const void* ptr, int len)
+{
+    Init(ptr, len);
+}
+
+d4_inline const c4_String& c4_String::operator+= (const c4_String& s)
+{
+    return *this = *this + s;
+}
+
+d4_inline const c4_String& c4_String::operator+= (const char* s)
+{
+    return *this += (c4_String) s;
+}
+
+d4_inline const char* c4_String::Data() const
+{
+    return (const char*) (_value + 2);
+}
+
+d4_inline c4_String::operator const char* () const
+{
+    return Data();
+}
+
+d4_inline c4_String::operator const unsigned char* () const
+{
+    return (unsigned char*) Data() - 1;
+}
+
+d4_inline char c4_String::operator[] (int i) const
+{
+    return Data()[i];
+}
+    
+d4_inline int c4_String::GetLength() const
+{
+    return _value[1] != 255 ? _value[1] : FullLength();
+}
+
+d4_inline bool c4_String::IsEmpty() const
+{
+    return GetLength() == 0;
+}
+
+d4_inline void c4_String::Empty()
+{
+    *this = "";
+}
+
+d4_inline bool c4_String::operator< (const c4_String& a) const
+{
+    return Compare(a) < 0;
+}
+
+d4_inline c4_String operator+ (const char* a, const c4_String& b)
+{
+    return (c4_String) a + b;
+}
+
+d4_inline c4_String operator+ (const c4_String& a, const char* b)
+{
+    return a + (c4_String) b;
+}
+
+d4_inline bool operator== (const char* a, const c4_String& b)
+{
+    return b.Compare(a) == 0;
+}
+
+d4_inline bool operator== (const c4_String& a, const char* b)
+{
+    return a.Compare(b) == 0;
+}
+
+d4_inline bool operator!= (const c4_String& a, const c4_String& b)
+{
+    return !(a == b);
+}
+
+d4_inline bool operator!= (const char* a, const c4_String& b)
+{
+    return b.Compare(a) != 0;
+}
+
+d4_inline bool operator!= (const c4_String& a, const char* b)
+{
+    return a.Compare(b) != 0;
+}
+
+#endif // q4_UNIV
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/license.terms b/8.x/mk/license.terms
new file mode 100644 (file)
index 0000000..485f3c4
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 1996-2007 Jean-Claude Wippler
+
+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.
diff --git a/8.x/mk/python/.cvsignore b/8.x/mk/python/.cvsignore
new file mode 100644 (file)
index 0000000..0d20b64
--- /dev/null
@@ -0,0 +1 @@
+*.pyc
diff --git a/8.x/mk/python/PyHead.h b/8.x/mk/python/PyHead.h
new file mode 100755 (executable)
index 0000000..0a2f0f9
--- /dev/null
@@ -0,0 +1,26 @@
+// PyHead.h --
+// $Id: PyHead.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of MetaKit, see http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  Common object header class
+
+#if !defined INCLUDE_PYHEAD_H
+#define INCLUDE_PYHEAD_H
+
+#include <Python.h>
+
+class PyHead: public PyObject {
+  public:
+    PyHead(PyTypeObject &t) {
+#ifdef Py_TRACE_REFS
+        _ob_next = 0;
+        _ob_prev = 0;
+        _Py_AddToAllObjects(this, 0);
+#endif 
+        ob_refcnt = 1;
+        ob_type = &t;
+    }
+};
+
+#endif
diff --git a/8.x/mk/python/PyProperty.cpp b/8.x/mk/python/PyProperty.cpp
new file mode 100755 (executable)
index 0000000..cc30f71
--- /dev/null
@@ -0,0 +1,89 @@
+// PyProperty.cpp --
+// $Id: PyProperty.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of MetaKit, the homepage is http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  Property class implementation
+
+#include "PyProperty.h"
+#include <PWONumber.h>
+#include <PWOSequence.h>
+
+static PyMethodDef PropertyMethods[] =  {
+   {
+    0, 0, 0, 0
+  }
+};
+
+static void PyProperty_dealloc(PyProperty *o) {
+  delete o;
+}
+
+static int PyProperty_print(PyProperty *o, FILE *f, int) {
+  fprintf(f, "Property('%c', '%s')", o->Type(), o->Name());
+  return 0;
+}
+
+static PyObject *PyProperty_getattr(PyProperty *o, char *nm) {
+  try {
+    if (nm[0] == 'n' && strcmp(nm, "name") == 0) {
+      PWOString rslt(o->Name());
+      return rslt.disOwn();
+    }
+    if (nm[0] == 't' && strcmp(nm, "type") == 0) {
+      char s = o->Type();
+      PWOString rslt(&s, 1);
+      return rslt.disOwn();
+    }
+    if (nm[0] == 'i' && strcmp(nm, "id") == 0) {
+      PWONumber rslt(o->GetId());
+      return rslt.disOwn();
+    }
+    return Py_FindMethod(PropertyMethods, o, nm);
+  } catch (...) {
+    return 0;
+  }
+}
+
+static int PyProperty_compare(PyProperty *o, PyObject *ob) {
+  PyProperty *other;
+  int myid, hisid;
+  try {
+    if (!PyProperty_Check(ob))
+      return  - 1;
+    other = (PyProperty*)ob;
+    myid = o->GetId();
+    hisid = other->GetId();
+    if (myid < hisid)
+      return  - 1;
+    else if (myid == hisid)
+      return 0;
+    return 1;
+  } catch (...) {
+    return  - 1;
+  }
+}
+
+PyTypeObject PyPropertytype =  {
+  PyObject_HEAD_INIT(&PyType_Type)0, "PyProperty", sizeof(PyProperty), 0, 
+    (destructor)PyProperty_dealloc,  /*tp_dealloc*/
+  (printfunc)PyProperty_print,  /*tp_print*/
+  (getattrfunc)PyProperty_getattr,  /*tp_getattr*/
+  0,  /*tp_setattr*/
+  (cmpfunc)PyProperty_compare,  /*tp_compare*/
+  0,  /*tp_repr*/
+  0,  /*tp_as_number*/
+  0,  /*tp_as_sequence*/
+  0,  /*tp_as_mapping*/
+};
+
+PyObject *PyProperty_new(PyObject *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOString typ(args[0]);
+    PWOString nam(args[1]);
+    return new PyProperty(*(const char*)typ, nam);
+  } catch (...) {
+    return 0;
+  }
+}
diff --git a/8.x/mk/python/PyProperty.h b/8.x/mk/python/PyProperty.h
new file mode 100755 (executable)
index 0000000..33dc9b4
--- /dev/null
@@ -0,0 +1,29 @@
+// PyProperty.h --
+// $Id: PyProperty.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of MetaKit, see http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  Property class header
+
+#if !defined INCLUDE_PYPROPERTY_H
+#define INCLUDE_PYPROPERTY_H
+
+#include <mk4.h>
+#include "PyHead.h"
+
+#define PyProperty_Check(ob) ((ob)->ob_type == &PyPropertytype)
+
+extern PyTypeObject PyPropertytype;
+
+class PyProperty: public PyHead, public c4_Property {
+  public:
+    //PyProperty();
+    PyProperty(const c4_Property &o): PyHead(PyPropertytype), c4_Property(o){}
+    PyProperty(char t, const char *n): PyHead(PyPropertytype), c4_Property(t, n)
+      {}
+    ~PyProperty(){}
+};
+
+PyObject *PyProperty_new(PyObject *o, PyObject *_args);
+
+#endif
diff --git a/8.x/mk/python/PyRowRef.cpp b/8.x/mk/python/PyRowRef.cpp
new file mode 100755 (executable)
index 0000000..1cc7d5b
--- /dev/null
@@ -0,0 +1,305 @@
+// PyRowRef.cpp --
+// $Id: PyRowRef.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of MetaKit, the homepage is http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  RowRef class implementation
+
+#include <PWOSequence.h>
+#include <PWONumber.h>
+#include "PyRowRef.h"
+#include "PyView.h"
+
+#if defined(PY_LONG_LONG) && !defined(LONG_LONG)
+#define LONG_LONG PY_LONG_LONG
+#endif 
+
+static PyMethodDef RowRefMethods[] =  {
+   {
+    0, 0, 0, 0
+  }
+};
+
+static void PyRowRef_dealloc(PyRowRef *o) {
+  //o->~PyRowRef();
+  delete o;
+}
+
+static int PyRowRef_print(PyRowRef *o, FILE *f, int) {
+  fprintf(f, "<PyRowRef object at %p>", (void*)o);
+  return 0;
+}
+
+static int PyRORowRef_print(PyRowRef *o, FILE *f, int) {
+  fprintf(f, "<PyRORowRef object at %p>", (void*)o);
+  return 0;
+}
+
+static PyObject *PyRowRef_getattr(PyRowRef *o, char *nm) {
+  try {
+    if (nm[0] == '_' && nm[1] == '_') {
+      if (strcmp(nm, "__attrs__") == 0) {
+        c4_View parent = o->Container();
+        int nprops = parent.NumProperties();
+        PyObject *out = PyList_New(nprops);
+        for (int i = 0; i < nprops; i++) {
+          PyList_SetItem(out, i, new PyProperty(parent.NthProperty(i)));
+        }
+        return out;
+      } else if (strcmp(nm, "__view__") == 0) {
+        return new PyView(o->Container());
+      } else if (strcmp(nm, "__index__") == 0) {
+        return PyInt_FromLong((&(*o))._index);
+      }
+    }
+
+    PyObject *attr = o->getPropertyValue(nm);
+    if (attr)
+      return attr;
+    PyErr_Clear();
+    return Py_FindMethod(RowRefMethods, (PyObject*)o, nm);
+  } catch (...) {
+    return NULL;
+  }
+}
+
+static int PyRowRef_setattr(PyRowRef *o, char *nm, PyObject *v) {
+  try {
+    PyProperty *p = o->getProperty(nm);
+    if (p) {
+      if (v)
+        PyRowRef::setFromPython(*o,  *p, v);
+      else
+        PyRowRef::setDefault(*o,  *p);
+      Py_DECREF(p);
+      return 0;
+    }
+    PyErr_SetString(PyExc_AttributeError, "delete of nonexistent attribute");
+    return  - 1;
+  } catch (...) {
+    return  - 1;
+  }
+}
+
+PyTypeObject PyRowReftype =  {
+  PyObject_HEAD_INIT(&PyType_Type)0, "PyRowRef", sizeof(PyRowRef), 0, 
+    (destructor)PyRowRef_dealloc,  /*tp_dealloc*/
+  (printfunc)PyRowRef_print,  /*tp_print*/
+  (getattrfunc)PyRowRef_getattr,  /*tp_getattr*/
+  (setattrfunc)PyRowRef_setattr,  /*tp_setattr*/
+  (cmpfunc)0,  /*tp_compare*/
+  (reprfunc)0,  /*tp_repr*/
+  0,  /*tp_as_number*/
+  0,  /*tp_as_sequence*/
+  0,  /*tp_as_mapping*/
+};
+PyTypeObject PyRORowReftype =  {
+  PyObject_HEAD_INIT(&PyType_Type)0, "PyRORowRef", sizeof(PyRowRef), 0, 
+    (destructor)PyRowRef_dealloc,  /*tp_dealloc*/
+  (printfunc)PyRORowRef_print,  /*tp_print*/
+  (getattrfunc)PyRowRef_getattr,  /*tp_getattr*/
+  (setattrfunc)0,  /*tp_setattr*/
+  (cmpfunc)0,  /*tp_compare*/
+  (reprfunc)0,  /*tp_repr*/
+  0,  /*tp_as_number*/
+  0,  /*tp_as_sequence*/
+  0,  /*tp_as_mapping*/
+};
+
+
+PyRowRef::PyRowRef(const c4_RowRef &o, int immutable): PyHead(PyRowReftype),
+  c4_RowRef(o) {
+  if (immutable)
+    ob_type = &PyRORowReftype;
+  c4_Cursor c = &(*(c4_RowRef*)this);
+  c._seq->IncRef();
+}
+
+// with thanks to Niki Spahiev for improving conversions and error checks
+void PyRowRef::setFromPython(const c4_RowRef &row, const c4_Property &prop,
+  PyObject *attr) {
+  switch (prop.Type()) {
+    case 'I':
+      if (PyInt_Check(attr)) {
+        long number = PyInt_AsLong(attr);
+        if (number ==  - 1 && PyErr_Occurred() != NULL)
+          Fail(PyExc_ValueError, "int too large to convert to C long");
+        ((const c4_IntProp &)prop)(row) = number;
+      }
+       else if (attr != Py_None) {
+        PWONumber number(attr);
+        ((const c4_IntProp &)prop)(row) = (long)number;
+      }
+      break;
+#ifdef HAVE_LONG_LONG
+    case 'L':
+      if (PyLong_Check(attr)) {
+        LONG_LONG number = PyLong_AsLongLong(attr);
+        if (number ==  - 1 && PyErr_Occurred() != NULL)
+          Fail(PyExc_ValueError, "long int too large to convert to C long long")
+            ;
+        ((const c4_LongProp &)prop)(row) = number;
+      }
+       else if (PyInt_Check(attr)) {
+        long number = PyInt_AsLong(attr);
+        if (number ==  - 1 && PyErr_Occurred() != NULL)
+          Fail(PyExc_ValueError, "int too large to convert to C long");
+        ((const c4_LongProp &)prop)(row) = number;
+      }
+       else if (attr != Py_None) {
+        PWONumber number(attr);
+        ((const c4_LongProp &)prop)(row) = (LONG_LONG)number;
+      }
+      break;
+#endif 
+    case 'F':
+      if (PyFloat_Check(attr))
+        ((const c4_FloatProp &)prop)(row) = PyFloat_AS_DOUBLE(attr);
+      else if (attr != Py_None) {
+        PWONumber number(attr);
+        ((const c4_FloatProp &)prop)(row) = (double)number;
+      }
+      break;
+    case 'D':
+      if (PyFloat_Check(attr))
+        ((const c4_DoubleProp &)prop)(row) = PyFloat_AS_DOUBLE(attr);
+      else if (attr != Py_None) {
+        PWONumber number(attr);
+        ((const c4_DoubleProp &)prop)(row) = (double)number;
+      }
+      break;
+    case 'S':
+      if (attr != Py_None) {
+#ifdef HAVE_UNICODEOBJECT_H
+        bool is_unicode = PyUnicode_Check(attr);
+        if (is_unicode)
+          attr = PyUnicode_AsUTF8String(attr);
+#else 
+        const bool is_unicode = false;
+#endif 
+        PWOString string(attr);
+        if (is_unicode)
+          Py_DECREF(attr);
+
+        size_t size = string.size();
+        const char *cstring = string;
+        if (size != strlen(cstring))
+          Fail(PyExc_ValueError, "string contains embedded nulls; try 'B' type")
+            ;
+        c4_Bytes temp(cstring, size + 1, false);
+        prop(row).SetData(temp);
+      }
+      break;
+    case 'V':
+      if (PyView_Check(attr)) {
+        PyView *obj = (PyView*)attr;
+        ((const c4_ViewProp &)prop)(row) =  *obj;
+      }
+       else {
+        //((const c4_ViewProp&) prop) (row) = c4_View ();
+        PyView tmp(((const c4_ViewProp &)prop)(row));
+        PWOSequence lst(attr);
+        tmp.SetSize(lst.len());
+        for (int i = 0; i < lst.len(); i++) {
+          PyObject *entry = lst[i];
+          tmp.setItem(i, entry);
+          Py_DECREF(entry);
+        }
+      }
+      break;
+    case 'B':
+    case 'M':
+      if (PyString_Check(attr)) {
+        c4_Bytes temp(PyString_AS_STRING(attr), PyString_GET_SIZE(attr), false);
+        prop(row).SetData(temp);
+      }
+       else if (attr != Py_None)
+        Fail(PyExc_TypeError, "wrong type for ByteProp");
+      break;
+    default:
+      PyErr_Format(PyExc_TypeError, "unknown property type '%c'", prop.Type());
+      throw PWDPyException;
+  }
+}
+
+void PyRowRef::setDefault(const c4_RowRef &row, const c4_Property &prop) {
+  switch (prop.Type()) {
+    case 'I':
+      ((const c4_IntProp &)prop)(row) = 0;
+      break;
+#ifdef HAVE_LONG_LONG
+    case 'L':
+      ((const c4_LongProp &)prop)(row) = 0;
+      break;
+#endif 
+    case 'F':
+      ((const c4_FloatProp &)prop)(row) = 0.0;
+      break;
+    case 'D':
+      ((const c4_DoubleProp &)prop)(row) = 0.0;
+      break;
+    case 'S':
+      ((const c4_StringProp &)prop)(row) = "";
+      break;
+    case 'V':
+      ((const c4_ViewProp &)prop)(row) = c4_View();
+      break;
+    case 'B':
+    case 'M':
+       {
+        c4_Bytes temp;
+        prop(row).SetData(temp);
+      }
+      break;
+    default:
+      PyErr_Format(PyExc_TypeError, "unknown property type '%c'", prop.Type());
+      throw PWDPyException;
+  }
+}
+
+PyObject *PyRowRef::asPython(const c4_Property &prop) {
+  switch (prop.Type()) {
+    case 'I':
+       {
+        PWONumber rslt(((const c4_IntProp &)prop)(*this));
+        return rslt.disOwn();
+      }
+#ifdef HAVE_LONG_LONG
+    case 'L':
+       {
+        return PyLong_FromLongLong((LONG_LONG)((const c4_LongProp &)prop)(*this)
+          );
+      }
+#endif 
+    case 'F':
+       {
+        PWONumber rslt(((const c4_FloatProp &)prop)(*this));
+        return rslt.disOwn();
+      }
+    case 'D':
+       {
+        PWONumber rslt(((const c4_DoubleProp &)prop)(*this));
+        return rslt.disOwn();
+      }
+    case 'S':
+       {
+        PWOString rslt(((c4_StringProp &)prop).Get(*this));
+        return rslt.disOwn();
+      }
+    case 'V':
+       {
+        return new PyView(((const c4_ViewProp &)prop)(*this));
+      }
+    case 'B':
+    case 'M':
+       {
+        c4_Bytes temp;
+        prop(*this).GetData(temp);
+        PWOString rslt((const char*)temp.Contents(), temp.Size());
+        return rslt.disOwn();
+      }
+    default:
+      return PyErr_Format(PyExc_TypeError, "unknown property type '%c'",
+        prop.Type());
+  }
+}
diff --git a/8.x/mk/python/PyRowRef.h b/8.x/mk/python/PyRowRef.h
new file mode 100755 (executable)
index 0000000..d5c1bb8
--- /dev/null
@@ -0,0 +1,58 @@
+// PyRowRef.h --
+// $Id: PyRowRef.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of MetaKit, see http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  RowRef class header
+
+#if !defined INCLUDE_PYROWREF_H
+#define INCLUDE_PYROWREF_H
+
+#include <mk4.h>
+#include "PyHead.h"
+#include <PWOSequence.h>
+#include "PyView.h"
+#include "PyProperty.h"
+
+#define PyRowRef_Check(ob) ((ob)->ob_type == &PyRowReftype)
+#define PyRORowRef_Check(ob) ((ob)->ob_type == &PyRORowReftype)
+#define PyGenericRowRef_Check(ob) (PyRowRef_Check(ob) || PyRORowRef_Check(ob))
+
+extern PyTypeObject PyRowReftype;
+extern PyTypeObject PyRORowReftype;
+
+class PyRowRef: public PyHead, public c4_RowRef {
+  public:
+    //PyRowRef();
+    PyRowRef(const c4_RowRef &o, int immutable = 0);
+    //PyRowRef(c4_Row row);
+    ~PyRowRef() {
+        c4_Cursor c = &(*(c4_RowRef*)this);
+        c._seq->DecRef();
+    }
+    PyProperty *getProperty(char *nm) {
+        c4_View cntr = Container();
+        int ndx = cntr.FindPropIndexByName(nm);
+        if (ndx >  - 1) {
+            return new PyProperty(cntr.NthProperty(ndx));
+        }
+        return 0;
+    };
+
+    PyObject *getPropertyValue(char *nm) {
+        PyProperty *prop = getProperty(nm);
+        if (prop) {
+            PyObject *result = asPython(*prop);
+            Py_DECREF(prop);
+            return result;
+        }
+        return 0;
+    };
+
+    static void setFromPython(const c4_RowRef &row, const c4_Property &prop,
+      PyObject *val);
+    static void setDefault(const c4_RowRef &row, const c4_Property &prop);
+    PyObject *asPython(const c4_Property &prop);
+};
+
+#endif
diff --git a/8.x/mk/python/PyStorage.cpp b/8.x/mk/python/PyStorage.cpp
new file mode 100755 (executable)
index 0000000..49261d9
--- /dev/null
@@ -0,0 +1,550 @@
+// PyStorage.cpp --
+// $Id: PyStorage.cpp 1669 2007-06-16 00:23:25Z jcw $
+// This is part of MetaKit, the homepage is http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  Storage class implementation and main entry point
+
+#include <Python.h>
+#include "PyStorage.h"
+#include <PWOSequence.h>
+#include <PWONumber.h>
+#include "PyView.h"
+#include "PyProperty.h"
+#include "PyRowRef.h"
+#include "mk4str.h"
+#include "mk4io.h"
+
+#if !defined _WIN32
+#define __declspec(x)
+#endif 
+
+static char mk4py_module_documentation[] = 
+  "This is the Python interface of the embeddable MetaKit database library.\n"
+  "Example of use:\n""\n""  import Mk4py\n""  mk = Mk4py\n""\n"
+  "  s = mk.storage('demo.dat', 1)\n"
+  "  v = s.getas('people[first:S,last:S,shoesize:I]')\n""\n"
+  "  v.append(first='John',last='Lennon',shoesize=44)\n"
+  "  v.append(first='Flash',last='Gordon',shoesize=42)\n""  s.commit()\n""\n"
+  "  def dump(v):\n""    print len(v)\n"
+  "    for r in v: print r.first, r.last, r.shoesize\n""\n"
+  "  v2 = v.sort(v.last)\n""  dump(v2)\n""  v[0].last = 'Doe'\n""  dump(v2)\n"
+  "  v2 = v.select(last='Doe')\n""  dump(v2)\n""  del s\n""\n"
+  "See the website at http://www.equi4.com/metakit.html for full details.\n";
+
+///////////////////////////////////////////////////////////////////////////////
+
+class c4_PyStream: public c4_Stream {
+    PyObject *_stream;
+
+  public:
+    c4_PyStream(PyObject *stream_);
+
+    virtual int Read(void *buffer_, int length_);
+    virtual bool Write(const void *buffer_, int length_);
+};
+
+c4_PyStream::c4_PyStream(PyObject *stream_): _stream(stream_){}
+
+int c4_PyStream::Read(void *buffer_, int length_) {
+  PyObject *o = PyObject_CallMethod(_stream, "read", "i", length_);
+  int n = o != 0 ? PyString_Size(o): 0;
+  if (n > 0)
+    memcpy(buffer_, PyString_AsString(o), n);
+  return n;
+}
+
+bool c4_PyStream::Write(const void *buffer_, int length_) {
+  PyObject_CallMethod(_stream, "write", "s#", buffer_, length_);
+  return true; //!! how do we detect write errors here?
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// A "storage in a storage" strategy class for MetaKit
+
+class SiasStrategy: public c4_Strategy {
+    c4_Storage &_storage;
+    c4_View _view;
+    c4_BytesProp _memo;
+    int _row;
+
+  public:
+    SiasStrategy(c4_Storage &storage_, const c4_View &view_, const c4_BytesProp
+      &memo_, int row_): _storage(storage_), _view(view_), _memo(memo_), _row
+      (row_) {
+        // set up mapping if the memo itself is mapped in its entirety
+        c4_Strategy &strat = storage_.Strategy();
+        if (strat._mapStart != 0) {
+            c4_RowRef r = _view[_row];
+            c4_Bytes data = _memo(r).Access(0);
+            const t4_byte *ptr = data.Contents();
+            if (data.Size() == _memo(r).GetSize() && strat._mapStart != 0 &&
+              ptr >= strat._mapStart && ptr - strat._mapStart < strat._dataSize)
+              {
+                _mapStart = ptr;
+                _dataSize = data.Size();
+            }
+        }
+    }
+
+    virtual ~SiasStrategy() {
+        _view = c4_View();
+        _mapStart = 0;
+        _dataSize = 0;
+    }
+
+    virtual int DataRead(t4_i32 pos_, void *buffer_, int length_) {
+        int i = 0;
+
+        while (i < length_) {
+            c4_Bytes data = _memo(_view[_row]).Access(pos_ + i, length_ - i);
+            int n = data.Size();
+            if (n <= 0)
+              break;
+            memcpy((char*)buffer_ + i, data.Contents(), n);
+            i += n;
+        }
+
+        return i;
+    }
+
+    virtual void DataWrite(t4_i32 pos_, const void *buffer_, int length_) {
+        c4_Bytes data(buffer_, length_);
+        if (!_memo(_view[_row]).Modify(data, pos_))
+          ++_failure;
+    }
+
+    virtual void DataCommit(t4_i32 newSize_) {
+        if (newSize_ > 0)
+          _memo(_view[_row]).Modify(c4_Bytes(), newSize_);
+    }
+
+    virtual void ResetFileMapping() {
+        _mapStart = 0; // never called, but just in case
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static char *autocommit__doc = 
+  "autocommit() -- turn on autocommit (i.e. commit when storage object is deleted)";
+
+static PyObject *PyStorage_Autocommit(PyStorage *o, PyObject *_args) {
+  try {
+    o->AutoCommit();
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *contents__doc = 
+  "contents() -- return view with one row, representing entire storage (internal use)";
+
+static PyObject *PyStorage_Contents(PyStorage *o, PyObject *_args) {
+  try {
+    return new PyView(*o);
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *description__doc = 
+  "description(name='') -- return a description of named view, or of entire storage";
+
+static PyObject *PyStorage_Description(PyStorage *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOString nm("");
+    if (args.len() > 0)
+      nm = args[0];
+    const char *descr = o->Description(nm);
+    if (descr) {
+      PWOString rslt(descr);
+      return rslt.disOwn();
+    }
+    Fail(PyExc_KeyError, nm);
+  } catch (...){}
+  return 0; /* satisfy compiler */
+}
+
+static char *commit__doc = 
+  "commit(full=0) -- permanently commit data and structure changes to disk";
+
+static PyObject *PyStorage_Commit(PyStorage *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWONumber flag(0);
+    if (args.len() > 0)
+      flag = args[0];
+    if (!o->Commit((int)flag != 0))
+      Fail(PyExc_IOError, "commit failed");
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *rollback__doc = 
+  "rollback(full=0) -- revert data and structure as was last committed to disk";
+
+static PyObject *PyStorage_Rollback(PyStorage *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWONumber flag(0);
+    if (args.len() > 0)
+      flag = args[0];
+    if (!o->Rollback((int)flag != 0))
+      Fail(PyExc_IOError, "rollback failed");
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *aside__doc = 
+  "aside() -- revert data and structure as was last committed to disk";
+
+static PyObject *PyStorage_Aside(PyStorage *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (!PyStorage_Check((PyObject*)args[0]))
+      Fail(PyExc_TypeError, "First arg must be a storage");
+    c4_Storage &storage = *(PyStorage*)(PyObject*)args[0];
+    if (!o->SetAside(storage))
+      Fail(PyExc_IOError, "aside failed");
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *view__doc = 
+  "view(viewname) -- return top-level view in storage, given its name";
+
+static PyObject *PyStorage_View(PyStorage *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOString nm(args[0]);
+    return new PyView(o->View(nm));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *getas__doc = 
+  "getas(description) -- return view, create / restructure as needed to match";
+
+static PyObject *PyStorage_GetAs(PyStorage *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOString descr(args[0]);
+    return new PyView(o->GetAs(descr));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *load__doc = 
+  "load(file) -- replace storage object contents from file (or any obj supporting read)";
+
+static PyObject *PyStorage_load(PyStorage *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (args.len() != 1)
+      Fail(PyExc_ValueError, "load requires a file-like object");
+
+    c4_PyStream stream(args[0]);
+    o->LoadFrom(stream);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *save__doc = 
+  "save(file) -- store storage object contents to file (or any obj supporting write)";
+
+static PyObject *PyStorage_save(PyStorage *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (args.len() != 1)
+      Fail(PyExc_ValueError, "save requires a file-like object");
+
+    c4_PyStream stream(args[0]);
+    o->SaveTo(stream);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static PyMethodDef StorageMethods[] =  {
+   {
+    "getas", (PyCFunction)PyStorage_GetAs, METH_VARARGS, getas__doc
+  }
+  ,  {
+    "view", (PyCFunction)PyStorage_View, METH_VARARGS, view__doc
+  }
+  ,  {
+    "rollback", (PyCFunction)PyStorage_Rollback, METH_VARARGS, rollback__doc
+  }
+  ,  {
+    "commit", (PyCFunction)PyStorage_Commit, METH_VARARGS, commit__doc
+  }
+  ,  {
+    "aside", (PyCFunction)PyStorage_Aside, METH_VARARGS, aside__doc
+  }
+  ,  {
+    "description", (PyCFunction)PyStorage_Description, METH_VARARGS,
+      description__doc
+  }
+  ,  {
+    "contents", (PyCFunction)PyStorage_Contents, METH_VARARGS, contents__doc
+  }
+  ,  {
+    "autocommit", (PyCFunction)PyStorage_Autocommit, METH_VARARGS,
+      autocommit__doc
+  }
+  ,  {
+    "load", (PyCFunction)PyStorage_load, METH_VARARGS, load__doc
+  }
+  ,  {
+    "save", (PyCFunction)PyStorage_save, METH_VARARGS, save__doc
+  }
+  ,  {
+    0, 0, 0, 0
+  }
+};
+
+static void PyStorage_dealloc(PyStorage *o) {
+  //o->~PyStorage();
+  delete o;
+}
+
+static int PyStorage_print(PyStorage *o, FILE *f, int) {
+  fprintf(f, "<PyStorage object at %lx>", (long)o);
+  return 0;
+}
+
+static PyObject *PyStorage_getattr(PyStorage *o, char *nm) {
+  return Py_FindMethod(StorageMethods, o, nm);
+}
+
+PyTypeObject PyStoragetype =  {
+  PyObject_HEAD_INIT(&PyType_Type)0, "PyStorage", sizeof(PyStorage), 0, 
+    (destructor)PyStorage_dealloc,  /*tp_dealloc*/
+  (printfunc)PyStorage_print,  /*tp_print*/
+  (getattrfunc)PyStorage_getattr,  /*tp_getattr*/
+  0,  /*tp_setattr*/
+  (cmpfunc)0,  /*tp_compare*/
+  (reprfunc)0,  /*tp_repr*/
+  0,  /*tp_as_number*/
+  0,  /*tp_as_sequence*/
+  0,  /*tp_as_mapping*/
+};
+
+static char *storage__doc = 
+  "storage() -- create a new in-memory storage (can load/save, but not commit/rollback)\n""storage(file) -- attach a storage object to manage an already opened stdio file\n""storage(filename, rw) -- open file, rw=0: r/o, rw=1: r/w, rw=2: extend";
+
+static PyObject *PyStorage_new(PyObject *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PyStorage *ps = 0;
+    switch (args.len()) {
+      case 0:
+        ps = new PyStorage;
+        break;
+      case 1:
+        if (!PyFile_Check((PyObject*)args[0])) {
+          if (PyString_Check((PyObject*)args[0]))
+            Fail(PyExc_TypeError, "rw parameter missing");
+          else
+            Fail(PyExc_TypeError, "argument not an open file");
+          break;
+        }
+        ps = new PyStorage(*new c4_FileStrategy(PyFile_AsFile(args[0])), true);
+        break;
+      case 4:
+         { // Rrrrrr...
+          if (!PyStorage_Check((PyObject*)args[0]))
+            Fail(PyExc_TypeError, "First arg must be a storage object");
+          c4_Storage &storage = *(PyStorage*)(PyObject*)args[0];
+          if (!PyView_Check((PyObject*)args[1]))
+            Fail(PyExc_TypeError, "Second arg must be a view object");
+          c4_View &view = *(PyView*)(PyObject*)args[1];
+          if (!PyProperty_Check((PyObject*)args[2]))
+            Fail(PyExc_TypeError, "Third arg must be a property object");
+          c4_BytesProp &prop = *(c4_BytesProp*)(c4_Property*)(PyProperty*)
+            (PyObject*)args[2];
+          int row = PWONumber(args[3]);
+
+          ps = new PyStorage(*new SiasStrategy(storage, view, prop, row), true);
+          break;
+        }
+      case 2:
+         {
+          char *fnm;
+          int mode;
+          if (!PyArg_ParseTuple(args, "esi", "utf_8", &fnm, &mode))
+            Fail(PyExc_TypeError, "bad argument type");
+          ps = new PyStorage(fnm, mode);
+          PyMem_Free(fnm);
+          if (!ps->Strategy().IsValid()) {
+            delete ps;
+            ps = 0;
+            Fail(PyExc_IOError, "can't open storage file");
+          }
+          break;
+        }
+      default:
+        Fail(PyExc_ValueError, "storage() takes at most 4 arguments");
+    }
+    return ps;
+  } catch (...) {
+    return 0;
+  }
+}
+
+class PyViewer: public c4_CustomViewer {
+    PWOSequence _data;
+    c4_View _template;
+    c4_Row _tempRow;
+    bool _byPos;
+
+  public:
+    PyViewer(const PWOSequence &data_, const c4_View &template_, bool byPos_);
+    virtual ~PyViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    virtual bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+};
+
+PyViewer::PyViewer(const PWOSequence &data_, const c4_View &template_, bool
+  byPos_): _data(data_), _template(template_), _byPos(byPos_){}
+
+PyViewer::~PyViewer(){}
+
+c4_View PyViewer::GetTemplate() {
+  return _template;
+}
+
+int PyViewer::GetSize() {
+  return _data.len();
+}
+
+bool PyViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  const c4_Property &prop = _template.NthProperty(col_);
+  if (_byPos) {
+    PWOSequence item(_data[row_]);
+    PyRowRef::setFromPython(_tempRow, prop, item[col_]);
+    return prop(_tempRow).GetData(buf_);
+  }
+  PyObject *item = _data[row_];
+  if (PyInstance_Check(item)) {
+    PyObject *attr = PyObject_GetAttrString(item, (char*)prop.Name());
+    PyRowRef::setFromPython(_tempRow, prop, attr);
+    return prop(_tempRow).GetData(buf_);
+  }
+  if (PyDict_Check(item)) {
+    PyObject *attr = PyDict_GetItemString(item, (char*)prop.Name());
+    PyRowRef::setFromPython(_tempRow, prop, attr);
+    return prop(_tempRow).GetData(buf_);
+  }
+  if (_template.NumProperties() == 1) {
+    PyRowRef::setFromPython(_tempRow, prop, _data[row_]);
+    return prop(_tempRow).GetData(buf_);
+  }
+  Fail(PyExc_ValueError, "Object has no usable attributes");
+  return false;
+  // create a row with just this single property value
+  // this detour handles dicts and objects, because makeRow does
+  /*  c4_Row one;
+  PyView v (prop); // nasty, stack-based temp to get at makeRow
+  v.makeRow(one, _data[row_]);
+  return prop (one).GetData(buf_); */
+}
+
+bool PyViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  const c4_Property &prop = _template.NthProperty(col_);
+  c4_Row one;
+  prop(one).SetData(buf_);
+
+  PyRowRef r(one); // careful, stack-based temp
+  PyObject *item = r.asPython(prop);
+
+  if (_byPos) {
+    PWOSequence item(_data[row_]);
+    item[col_] = item;
+  } else if (PyDict_Check((PyObject*)_data))
+    PyDict_SetItemString(_data, (char*)prop.Name(), item);
+  else
+    PyObject_SetAttrString(_data, (char*)prop.Name(), item);
+
+  Py_DECREF(item);
+  return true;
+}
+
+static PyObject *PyView_wrap(PyObject *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOSequence seq(args[0]);
+    PWOSequence types(args[1]);
+    PWONumber usetuples(0);
+    if (args.len() > 2)
+      usetuples = args[2];
+
+    c4_View templ;
+    for (int i = 0; i < types.len(); ++i) {
+      const c4_Property &prop = *(PyProperty*)(PyObject*)types[i];
+      templ.AddProperty(prop);
+    }
+
+    c4_View cv = new PyViewer(seq, templ, (int)usetuples != 0);
+    return new PyView(cv, 0, ROVIEWER);
+  } catch (...) {
+    return 0;
+  }
+}
+
+static PyMethodDef Mk4Methods[] =  {
+   {
+    "view", PyView_new, METH_VARARGS, "view() - create a new unattached view"
+  }
+  ,  {
+    "storage", PyStorage_new, METH_VARARGS, storage__doc
+  }
+  ,  {
+    "property", PyProperty_new, METH_VARARGS, 
+      "property(type, name) -- create a property of given type and name"
+  }
+  ,  {
+    "wrap", PyView_wrap, METH_VARARGS, 
+      "wrap(seq,props,usetuples=0) - wrap a sequence as a read-only view"
+  }
+  ,  {
+    0, 0, 0, 0
+  }
+};
+
+extern "C"__declspec(dllexport)
+void initMk4py() {
+  PyObject *m = Py_InitModule4("Mk4py", Mk4Methods, mk4py_module_documentation,
+    0, PYTHON_API_VERSION);
+  PyObject_SetAttrString(m, "version", PyString_FromString("2.4.9.7"));
+  PyObject_SetAttrString(m, "ViewType", (PyObject*) &PyViewtype);
+  PyObject_SetAttrString(m, "ViewerType", (PyObject*) &PyViewertype);
+  PyObject_SetAttrString(m, "ROViewerType", (PyObject*) &PyROViewertype);
+  PyObject_SetAttrString(m, "RowRefType", (PyObject*) &PyRowReftype);
+  PyObject_SetAttrString(m, "RORowRefType", (PyObject*) &PyRORowReftype);
+}
diff --git a/8.x/mk/python/PyStorage.h b/8.x/mk/python/PyStorage.h
new file mode 100755 (executable)
index 0000000..6fa4fc6
--- /dev/null
@@ -0,0 +1,33 @@
+// PyStorage.h --
+// $Id: PyStorage.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of MetaKit, see http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  Storage class header
+
+#if !defined INCLUDE_PYSTORAGE_H
+#define INCLUDE_PYSTORAGE_H
+
+#include <mk4.h>
+#include "PyHead.h"
+
+extern PyTypeObject PyStoragetype;
+class SiasStrategy;
+
+#define PyStorage_Check(v) ((v)->ob_type==&PyStoragetype)
+
+class PyStorage: public PyHead, public c4_Storage {
+  public:
+    PyStorage(): PyHead(PyStoragetype){}
+    PyStorage(c4_Strategy &strategy_, bool owned_ = false, int mode_ = 1):
+      PyHead(PyStoragetype), c4_Storage(strategy_, owned_, mode_){}
+    PyStorage(const char *fnm, int mode): PyHead(PyStoragetype), c4_Storage(fnm,
+      mode){}
+    PyStorage(const c4_Storage &storage_): PyHead(PyStoragetype), c4_Storage
+      (storage_){}
+    //  PyStorage(const char *fnm, const char *descr) 
+    //    : PyHead(PyStoragetype), c4_Storage(fnm, descr) { }
+    ~PyStorage(){}
+};
+
+#endif
diff --git a/8.x/mk/python/PyView.cpp b/8.x/mk/python/PyView.cpp
new file mode 100755 (executable)
index 0000000..a2d9385
--- /dev/null
@@ -0,0 +1,1610 @@
+// PyView.cpp --
+// $Id: PyView.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of MetaKit, the homepage is http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  View class implementation
+//  setsize method added by J. Barnard
+
+#include "PyView.h"
+#include "PyProperty.h"
+#include "PyRowRef.h"
+#include <PWOMSequence.h>
+#include <PWONumber.h>
+#include <PWOMapping.h>
+#include <PWOCallable.h>
+
+// see pep 353 at http://www.python.org/dev/peps/pep-0353/
+#if PY_VERSION_HEX < 0x02050000
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif 
+
+static void MustBeView(PyObject *o) {
+  if (!PyGenericView_Check(o))
+    Fail(PyExc_TypeError, "Arg must be a view object");
+}
+
+static char *setsize__doc = 
+  "setsize(nrows) -- adjust the number of rows in a view";
+
+static PyObject *PyView_setsize(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (args.len() != 1)
+      Fail(PyExc_TypeError, "setsize() takes exactly one argument");
+    PWONumber nrows = PWONumber(args[0]);
+    o->SetSize((int)nrows);
+    return nrows.disOwn();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *structure__doc = "structure() -- return list of properties";
+
+static PyObject *PyView_structure(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (args.len() != 0)
+      Fail(PyExc_TypeError, "method takes no arguments");
+    return o->structure();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *properties__doc = 
+  "properties() -- return a dictionary mapping property names to property objects";
+
+static PyObject *PyView_properties(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (args.len() != 0)
+      Fail(PyExc_TypeError, "method takes no arguments");
+    return o->properties();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *insert__doc = 
+  "insert(position, obj) -- coerce obj (or keyword args) to row and insert before position";
+
+static PyObject *PyView_insert(PyView *o, PyObject *_args, PyObject *kwargs) {
+  try {
+    PWOSequence args(_args);
+    int argcount = args.len();
+    if (argcount == 0 || argcount > 2) {
+      Fail(PyExc_TypeError, 
+        "insert() takes exactly two arguments, or one argument and keyword arguments");
+    } else {
+      int size = PWONumber(o->GetSize()), ndx = PWONumber(args[0]);
+      if (ndx < 0) {
+        ndx += size;
+        if (ndx < 0) {
+          ndx = 0;
+        }
+      } else if (ndx > size) {
+        ndx = size;
+      }
+      if (argcount == 1)
+        o->insertAt(ndx, kwargs);
+      else if (argcount == 2)
+        o->insertAt(ndx, args[1]);
+      Py_INCREF(Py_None);
+      return Py_None;
+    }
+  } catch (...){}
+  return 0; /* satisfy compiler */
+}
+
+static char *append__doc = 
+  "append(obj) -- coerce obj (or keyword args) to row and append, returns position";
+
+static PyObject *PyView_append(PyView *o, PyObject *_args, PyObject *kwargs) {
+  try {
+    PWOSequence args(_args);
+    PWONumber ndx(o->GetSize());
+    int argcount = args.len();
+    if (argcount == 0)
+      o->insertAt(ndx, kwargs);
+    else if (argcount == 1)
+      o->insertAt(ndx, args[0]);
+    else
+      Fail(PyExc_TypeError, 
+        "append() takes exactly one argument, or multiple keyword arguments");
+    return ndx.disOwn();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *delete__doc = 
+  "delete(position) -- delete row at specified position";
+
+static PyObject *PyView_delete(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    int ndx = PWONumber(args[0]);
+    PWOTuple seq;
+    o->setSlice(ndx, ndx + 1, seq);
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *addproperty__doc = 
+  "addproperty(property) -- add temp column to view (use getas() for persistent columns)";
+
+static PyObject *PyView_addproperty(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOBase prop(args[0]);
+    if (!PyProperty_Check((PyObject*)prop))
+      Fail(PyExc_TypeError, "Not a Property object");
+    PWONumber rslt(o->AddProperty(*(PyProperty*)(PyObject*)prop));
+    return rslt.disOwn();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *select__doc = 
+  "select(criteria) -- return virtual view with selected rows\n"
+  "select(crit_lo, crit_hi) -- select rows in specified range (inclusive)\n"
+  "  criteria may be keyword args or dictionary";
+
+static PyObject *PyView_select(PyView *o, PyObject *_args, PyObject *kwargs) {
+  try {
+    c4_Row temp;
+    PWOSequence args(_args);
+    if (args.len() == 0) {
+      o->makeRow(temp, kwargs, false);
+      return new PyView(o->Select(temp), o, o->computeState(NOTIFIABLE));
+    }
+    if (args.len() == 1) {
+      o->makeRow(temp, args[0], false);
+      return new PyView(o->Select(temp), o, o->computeState(NOTIFIABLE));
+    }
+
+    if (PyObject_Length(args[0]) > 0)
+      o->makeRow(temp, args[0], false);
+
+    c4_Row temp2; // force an error if neither boundary has useful values
+    if (temp.Container().NumProperties() == 0 || PyObject_Length(args[1]) > 0)
+      o->makeRow(temp2, args[1], false);
+
+    return new PyView(o->SelectRange(temp, temp2), o, o->computeState
+      (NOTIFIABLE));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *sort__doc = 
+  "sort() -- return virtual sorted view (native key order)\n"
+  "sort(property...) -- sort on the specified properties";
+
+static PyObject *PyView_sort(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (args.len()) {
+      PyView crit;
+      crit.addProperties(args);
+      return new PyView(o->SortOn(crit), o, o->computeState(FINALNOTIFIABLE));
+    }
+    return new PyView(o->Sort(), o, o->computeState(FINALNOTIFIABLE));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *sortrev__doc = 
+  "sortrev(props,propsdown) -- return sorted view, with optional reversed order\n"" arguments are lists of properties";
+
+static PyObject *PyView_sortrev(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+
+    PWOSequence all(args[0]);
+    PyView propsAll;
+    propsAll.addProperties(all);
+
+    PWOSequence down(args[1]);
+    PyView propsDown;
+    propsDown.addProperties(down);
+
+    return new PyView(o->SortOnReverse(propsAll, propsDown), 0, o->computeState
+      (FINALNOTIFIABLE));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *project__doc = 
+  "project(property...) -- returns virtual view with only the named columns";
+
+static PyObject *PyView_project(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PyView crit;
+    crit.addProperties(args);
+    return new PyView(o->Project(crit), 0, o->computeState(NOTIFIABLE));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *flatten__doc = 
+  "flatten(subview_property, outer) -- produces 'flat' view from nested view\n"
+  " outer defaults to 0";
+
+static PyObject *PyView_flatten(PyView *o, PyObject *_args, PyObject *_kwargs) {
+  try {
+    PWOSequence args(_args);
+    PWOMapping kwargs;
+    if (_kwargs)
+      kwargs = PWOBase(_kwargs);
+    if (!PyProperty_Check((PyObject*)args[0]))
+      Fail(PyExc_TypeError, 
+        "First arg must be a property object identifying the subview");
+    const c4_Property &subview = *(PyProperty*)(PyObject*)args[0];
+    bool outer = false;
+    if (args.len() > 1) {
+      PWONumber flag(args[1]);
+      if ((int)flag > 0)
+        outer = true;
+    }
+    if (kwargs.hasKey("outer")) {
+      if (int(PWONumber(kwargs["outer"])))
+        outer = true;
+    }
+    return new PyView(o->JoinProp((const c4_ViewProp &)subview, outer), 0, o
+      ->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *join__doc = 
+  "join(otherview, property..., outer) -- join views on properties of same name and type\n"" outer defaults to 0";
+
+static PyObject *PyView_join(PyView *o, PyObject *_args, PyObject *_kwargs) {
+  PWOMapping kwargs;
+  try {
+    PWOSequence args(_args);
+    if (_kwargs)
+      kwargs = PWOBase(_kwargs);
+    MustBeView(args[0]);
+    PyView *other = (PyView*)(PyObject*)args[0];
+    bool outer = false;
+    int last = args.len();
+    if (PyInt_Check((PyObject*)args[last - 1])) {
+      PWONumber flag(args[--last]);
+      if ((int)flag > 0)
+        outer = true;
+    }
+    if (kwargs.hasKey("outer")) {
+      if (int(PWONumber(kwargs["outer"])))
+        outer = true;
+    }
+    PyView crit;
+    crit.addProperties(args.getSlice(1, last));
+    return new PyView(o->Join(crit,  *other, outer), 0, o->computeState
+      (ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *groupby__doc = 
+  "groupby(property..., 'subname') -- group by given properties, creating subviews";
+
+static PyObject *PyView_groupby(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    int last = args.len();
+    PWOString subname(args[--last]);
+    PyView crit;
+    crit.addProperties(args.getSlice(0, last));
+    c4_ViewProp sub(subname);
+    return new PyView(o->GroupBy(crit, sub), 0, o->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *counts__doc = 
+  "counts(property..., 'name') -- group by given properties, adding a count property";
+
+static PyObject *PyView_counts(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    int last = args.len();
+    PWOString name(args[--last]);
+    PyView crit;
+    crit.addProperties(args.getSlice(0, last));
+    c4_IntProp count(name);
+    return new PyView(o->Counts(crit, count), 0, o->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *rename__doc = 
+  "rename('oldname', 'newname') -- derive a view with one property renamed";
+
+static PyObject *PyView_rename(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+
+    PWOString oldName(args[0]);
+    int n = o->FindPropIndexByName(oldName);
+    if (n < 0)
+      Fail(PyExc_TypeError, "Property not found in view");
+    const c4_Property &oProp = o->NthProperty(n);
+
+    PWOString newName(args[1]);
+    c4_Property nProp(oProp.Type(), newName);
+
+    return new PyView(o->Rename(oProp, nProp), 0, o->computeState(RWVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *unique__doc = 
+  "unique() -- returns a view without duplicate rows, i.e. a set";
+
+static PyObject *PyView_unique(PyView *o, PyObject *_args) {
+  try {
+    return new PyView(o->Unique(), 0, o->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *product__doc = 
+  "product(view2) -- produce the cartesian product of both views";
+
+static PyObject *PyView_product(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+    return new PyView(o->Product(*(PyView*)(PyObject*)args[0]), 0, o
+      ->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *union__doc = "union(view2) -- produce the set union of both views";
+
+static PyObject *PyView_union(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+    return new PyView(o->Union(*(PyView*)(PyObject*)args[0]), 0, o
+      ->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *intersect__doc = 
+  "intersect(view2) -- produce the set intersection of both views";
+
+static PyObject *PyView_intersect(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+    return new PyView(o->Intersect(*(PyView*)(PyObject*)args[0]), 0, o
+      ->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *different__doc = 
+  "different(view2) -- produce the set difference of both views (XOR)";
+
+static PyObject *PyView_different(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+    return new PyView(o->Different(*(PyView*)(PyObject*)args[0]), 0, o
+      ->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *minus__doc = "minus(view2) -- all rows in view, but not in view2";
+
+static PyObject *PyView_minus(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+    return new PyView(o->Minus(*(PyView*)(PyObject*)args[0]), 0, o
+      ->computeState(ROVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *remapwith__doc = 
+  "remapwith(view2) -- remap rows according to first (int) prop in view2";
+
+static PyObject *PyView_remapwith(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+    return new PyView(o->RemapWith(*(PyView*)(PyObject*)args[0]), 0, o
+      ->computeState(RWVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *pair__doc = 
+  "pair(view2) -- concatenate rows pairwise, side by side";
+
+static PyObject *PyView_pair(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+    return new PyView(o->Pair(*(PyView*)(PyObject*)args[0]), 0, o->computeState
+      (MVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *hash__doc = 
+  "hash(mapview,numkeys) -- create a hashed view mapping\n"
+  " numkeys defaults to 1\n"
+  " without args, creates a temporary hash on one key";
+
+static PyObject *PyView_hash(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+
+    c4_View map;
+    if (args.len() > 0) {
+      MustBeView(args[0]);
+      map = *(PyView*)(PyObject*)args[0];
+    }
+    int numkeys = args.len() <= 1 ? 1 : (int)PWONumber(args[1]);
+    return new PyView(o->Hash(map, numkeys), 0, o->computeState(MVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *blocked__doc = 
+  "blocked() -- create a blocked/balanced view mapping";
+
+static PyObject *PyView_blocked(PyView *o, PyObject *_args) {
+  try {
+    return new PyView(o->Blocked(), 0, o->computeState(MVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *ordered__doc = 
+  "ordered(numkeys) -- create a order-maintaining view mapping\n"
+  " numkeys defaults to 1";
+
+static PyObject *PyView_ordered(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    int numkeys = args.len() <= 0 ? 1 : (int)PWONumber(args[0]);
+    return new PyView(o->Ordered(numkeys), 0, o->computeState(MVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *indexed__doc = 
+  "indexed(map, property..., unique) -- create a mapped view which manages an index\n"" unique defaults to 0 (not unique)";
+
+static PyObject *PyView_indexed(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+    PyView *other = (PyView*)(PyObject*)args[0];
+    bool unique = false;
+    int last = args.len();
+    if (PyInt_Check((PyObject*)args[last - 1])) {
+      PWONumber flag(args[--last]); //XXX kwargs?
+      if ((int)flag > 0)
+        unique = true;
+    }
+    PyView crit;
+    crit.addProperties(args.getSlice(1, last));
+    return new PyView(o->Indexed(crit,  *other, unique), 0, o->computeState
+      (MVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *find__doc = 
+  "find(criteria, start) -- return index of row found, matching criteria\n"
+  " criteria maybe keyword args, or a dictionary";
+
+static PyObject *PyView_find(PyView *o, PyObject *_args, PyObject *_kwargs) {
+  PWONumber start(0);
+  PWOMapping crit;
+  try {
+    PWOSequence args(_args);
+    if (_kwargs) {
+      PWOMapping kwargs(_kwargs);
+      if (kwargs.hasKey("start")) {
+        start = kwargs["start"];
+        kwargs.delItem("start");
+      }
+      crit = kwargs;
+    }
+    int numargs = args.len();
+    for (int i = 0; i < numargs; ++i) {
+      if (PyNumber_Check((PyObject*)args[i]))
+        start = args[i];
+      else
+        crit = args[i];
+    }
+    c4_Row temp;
+    o->makeRow(temp, crit, false);
+    return PWONumber(o->Find(temp, start)).disOwn();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *search__doc = 
+  "search(criteria) -- binary search (native view order), returns match or insert pos";
+
+static PyObject *PyView_search(PyView *o, PyObject *_args, PyObject *kwargs) {
+  try {
+    PWOSequence args(_args);
+    if (args.len() != 0)
+      kwargs = args[0];
+    c4_Row temp;
+    o->makeRow(temp, kwargs, false);
+    return PWONumber(o->Search(temp)).disOwn();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *locate__doc = 
+  "locate(criteria) -- binary search, returns tuple with pos and count";
+
+static PyObject *PyView_locate(PyView *o, PyObject *_args, PyObject *kwargs) {
+  try {
+    PWOSequence args(_args);
+    if (args.len() != 0)
+      kwargs = args[0];
+    c4_Row temp;
+    o->makeRow(temp, kwargs, false);
+    int pos = 0;
+    PWONumber n(o->Locate(temp, &pos));
+    PWONumber r(pos);
+    PWOTuple tmp(2);
+    tmp.setItem(0, r);
+    tmp.setItem(1, n);
+    return tmp.disOwn();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *access__doc = 
+  "access(memoprop, rownum, offset, length=0) -- get (partial) memo property contents";
+
+static PyObject *PyView_access(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (!PyProperty_Check((PyObject*)args[0]))
+      Fail(PyExc_TypeError, "First arg must be a property");
+
+    c4_BytesProp &prop = *(c4_BytesProp*)(c4_Property*)(PyProperty*)(PyObject*)
+      args[0];
+
+    int index = PyInt_AsLong(args[1]);
+    if (index < 0 || index >= o->GetSize())
+      Fail(PyExc_IndexError, "Index out of range");
+
+    c4_RowRef row = o->GetAt(index);
+
+    long offset = PyInt_AsLong(args[2]);
+    int length = args.len() == 3 ? 0 : PyInt_AsLong(args[3]);
+    if (length <= 0) {
+      length = prop(row).GetSize() - offset;
+      if (length < 0)
+        length = 0;
+    }
+
+    PyObject *buffer = PyString_FromStringAndSize(0, length);
+    int o = 0;
+
+    while (o < length) {
+      c4_Bytes buf = prop(row).Access(offset + o, length - o);
+      int n = buf.Size();
+      if (n == 0)
+        break;
+      memcpy(PyString_AS_STRING(buffer) + o, buf.Contents(), n);
+      o += n;
+    }
+
+    if (o < length)
+      _PyString_Resize(&buffer, o);
+
+    return buffer;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *modify__doc = 
+  "modify(memoprop, rownum, string, offset, diff=0) -- store (partial) memo contents\n""diff removes (<0) or inserts (>0) bytes, and is adjusted to within sensible range";
+
+static PyObject *PyView_modify(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (!PyProperty_Check((PyObject*)args[0]))
+      Fail(PyExc_TypeError, "First arg must be a property");
+
+    c4_BytesProp &prop = *(c4_BytesProp*)(c4_Property*)(PyProperty*)(PyObject*)
+      args[0];
+
+    int index = PWONumber(args[1]);
+    if (index < 0 || index >= o->GetSize())
+      Fail(PyExc_IndexError, "Index out of range");
+
+    c4_RowRef row = o->GetAt(index);
+
+    PWOString buffer(args[2]);
+    c4_Bytes data((void*)(const char*)buffer, buffer.len());
+
+    long offset = PWONumber(args[3]);
+    int diff = args.len() == 4 ? 0 : (int)PWONumber(args[4]);
+
+    if (!prop(row).Modify(data, offset, diff))
+      Fail(PyExc_TypeError, "Failed to modify memo field");
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *itemsize__doc = 
+  "itemsize(prop, rownum=0) -- return size of item (rownum only needed for S/B/M types)\n""with integer fields, a result of -1/-2/-4 means 1/2/4 bits per value, respectively";
+
+static PyObject *PyView_itemsize(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (!PyProperty_Check((PyObject*)args[0]))
+      Fail(PyExc_TypeError, "First arg must be a property");
+
+    c4_BytesProp &prop = *(c4_BytesProp*)(c4_Property*)(PyProperty*)(PyObject*)
+      args[0];
+    int index = args.len() == 1 ? 0 : (int)PWONumber(args[1]);
+    if (index < 0 || index >= o->GetSize())
+      Fail(PyExc_IndexError, "Index out of range");
+
+    return PWONumber(prop(o->GetAt(index)).GetSize()).disOwn();
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *relocrows__doc = 
+  "relocrows(from, count, dest, pos) -- relocate rows within views of same storage\n""from is source offset, count is number of rows, pos is destination offset\n""both views must have a compatible structure (field names may differ)";
+
+static PyObject *PyView_relocrows(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    if (!PyView_Check((PyObject*)args[2]))
+      Fail(PyExc_TypeError, "Third arg must be a view object");
+
+    PyView &dest = *(PyView*)(PyObject*)args[2];
+
+    int from = PWONumber(args[0]);
+    if (from < 0)
+      from += o->GetSize();
+    int count = PWONumber(args[1]);
+    if (from < 0 || count < 0 || from + count > o->GetSize())
+      Fail(PyExc_IndexError, "Source index out of range");
+
+    int pos = PWONumber(args[3]);
+    if (pos < 0)
+      pos += dest.GetSize();
+    if (pos < 0 || pos > dest.GetSize())
+      Fail(PyExc_IndexError, "Destination index out of range");
+
+    if (!o->IsCompatibleWith(dest))
+      Fail(PyExc_TypeError, "Views are not compatible");
+
+    o->RelocateRows(from, count, dest, pos);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *map__doc = 
+  "map(func, subset=None) -- apply func to each row of view,\n"
+  "or (if subset specified) to each row in view that is also in subset.\n"
+  "Returns None: view is mutated\n"
+  "func must have the signature func(row), and may mutate row.\n"
+  "subset must be a subset of view: eg, customers.map(func, customers.select(....)).\n";
+
+static PyObject *PyView_map(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOCallable func(args[0]);
+    if (args.len() > 1) {
+      if (!PyView_Check((PyObject*)args[1]))
+        Fail(PyExc_TypeError, "Second arg must be a view object");
+
+      PyView &subset = *(PyView*)(PyObject*)args[1];
+
+      o->map(func, subset);
+    } else
+      o->map(func);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *filter__doc = 
+  "filter(func) -- return a new view containing the indices of those rows satisfying func.\n""  func must have the signature func(row), and should return a false value to omit row.";
+
+static PyObject *PyView_filter(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOCallable func(args[0]);
+    return o->filter(func);
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *reduce__doc = 
+  "reduce(func, start=0) -- return the result of applying func(row, lastresult) to\n""each row in view.\n";
+
+static PyObject *PyView_reduce(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    PWOCallable func(args[0]);
+    PWONumber start(0);
+    if (args.len() > 1)
+      start = args[1];
+    return o->reduce(func, start);
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *remove__doc = 
+  "remove(indices) -- remove all rows whose indices are in subset from view\n"
+  "Not the same as minus, because unique is not required, and view is not reordered.\n";
+
+static PyObject *PyView_remove(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+
+    PyView &subset = *(PyView*)(PyObject*)args[0];
+    o->remove(subset);
+    Py_INCREF(Py_None);
+    return Py_None;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *indices__doc = 
+  "indices(subset) -- returns a view containing the indices in view of the rows of subset";
+
+static PyObject *PyView_indices(PyView *o, PyObject *_args) {
+  try {
+    PWOSequence args(_args);
+    MustBeView(args[0]);
+
+    PyView &subset = *(PyView*)(PyObject*)args[0];
+    return o->indices(subset);
+  } catch (...) {
+    return 0;
+  }
+}
+
+static char *copy__doc = "copy() -- returns a copy of the view\n";
+
+static PyObject *PyView_copy(PyView *o, PyObject *_args) {
+  try {
+    return new PyView(o->Duplicate());
+  } catch (...) {
+    return 0;
+  }
+}
+
+static PyMethodDef ViewMethods[] =  {
+   {
+    "setsize", (PyCFunction)PyView_setsize, METH_VARARGS, setsize__doc
+  }
+  ,  {
+    "insert", (PyCFunction)PyView_insert, METH_VARARGS | METH_KEYWORDS,
+      insert__doc
+  }
+  ,  {
+    "append", (PyCFunction)PyView_append, METH_VARARGS | METH_KEYWORDS,
+      append__doc
+  }
+  ,  {
+    "delete", (PyCFunction)PyView_delete, METH_VARARGS, delete__doc
+  }
+  ,  {
+    "structure", (PyCFunction)PyView_structure, METH_VARARGS, structure__doc
+  }
+  ,  {
+    "select", (PyCFunction)PyView_select, METH_VARARGS | METH_KEYWORDS,
+      select__doc
+  }
+  ,  {
+    "addproperty", (PyCFunction)PyView_addproperty, METH_VARARGS,
+      addproperty__doc
+  }
+  ,  {
+    "sort", (PyCFunction)PyView_sort, METH_VARARGS, sort__doc
+  }
+  ,  {
+    "sortrev", (PyCFunction)PyView_sortrev, METH_VARARGS, sortrev__doc
+  }
+  ,  {
+    "project", (PyCFunction)PyView_project, METH_VARARGS, project__doc
+  }
+  ,  {
+    "flatten", (PyCFunction)PyView_flatten, METH_VARARGS | METH_KEYWORDS,
+      flatten__doc
+  }
+  ,  {
+    "join", (PyCFunction)PyView_join, METH_VARARGS | METH_KEYWORDS, join__doc
+  }
+  ,  {
+    "groupby", (PyCFunction)PyView_groupby, METH_VARARGS, groupby__doc
+  }
+  ,  {
+    "counts", (PyCFunction)PyView_counts, METH_VARARGS, counts__doc
+  }
+  ,  {
+    "product", (PyCFunction)PyView_product, METH_VARARGS, product__doc
+  }
+  ,  {
+    "union", (PyCFunction)PyView_union, METH_VARARGS, union__doc
+  }
+  ,  {
+    "intersect", (PyCFunction)PyView_intersect, METH_VARARGS, intersect__doc
+  }
+  ,  {
+    "different", (PyCFunction)PyView_different, METH_VARARGS, different__doc
+  }
+  ,  {
+    "minus", (PyCFunction)PyView_minus, METH_VARARGS, minus__doc
+  }
+  ,  {
+    "remapwith", (PyCFunction)PyView_remapwith, METH_VARARGS, remapwith__doc
+  }
+  ,  {
+    "pair", (PyCFunction)PyView_pair, METH_VARARGS, pair__doc
+  }
+  ,  {
+    "rename", (PyCFunction)PyView_rename, METH_VARARGS, rename__doc
+  }
+  ,  {
+    "unique", (PyCFunction)PyView_unique, METH_VARARGS, unique__doc
+  }
+  ,  {
+    "hash", (PyCFunction)PyView_hash, METH_VARARGS, hash__doc
+  }
+  ,  {
+    "blocked", (PyCFunction)PyView_blocked, METH_VARARGS, blocked__doc
+  }
+  ,  {
+    "ordered", (PyCFunction)PyView_ordered, METH_VARARGS, ordered__doc
+  }
+  ,  {
+    "indexed", (PyCFunction)PyView_indexed, METH_VARARGS, indexed__doc
+  }
+  ,  {
+    "find", (PyCFunction)PyView_find, METH_VARARGS | METH_KEYWORDS, find__doc
+  }
+  ,  {
+    "search", (PyCFunction)PyView_search, METH_VARARGS | METH_KEYWORDS,
+      search__doc
+  }
+  ,  {
+    "locate", (PyCFunction)PyView_locate, METH_VARARGS | METH_KEYWORDS,
+      locate__doc
+  }
+  ,  {
+    "access", (PyCFunction)PyView_access, METH_VARARGS, access__doc
+  }
+  ,  {
+    "modify", (PyCFunction)PyView_modify, METH_VARARGS, modify__doc
+  }
+  ,  {
+    "itemsize", (PyCFunction)PyView_itemsize, METH_VARARGS, itemsize__doc
+  }
+  , 
+  // {"relocrows", (PyCFunction)PyView_relocrows, METH_VARARGS, relocrows__doc},
+   {
+    "map", (PyCFunction)PyView_map, METH_VARARGS, map__doc
+  }
+  ,  {
+    "filter", (PyCFunction)PyView_filter, METH_VARARGS, filter__doc
+  }
+  ,  {
+    "reduce", (PyCFunction)PyView_reduce, METH_VARARGS, reduce__doc
+  }
+  ,  {
+    "remove", (PyCFunction)PyView_remove, METH_VARARGS, remove__doc
+  }
+  ,  {
+    "indices", (PyCFunction)PyView_indices, METH_VARARGS, indices__doc
+  }
+  ,  {
+    "copy", (PyCFunction)PyView_copy, METH_VARARGS, copy__doc
+  }
+  ,  {
+    "properties", (PyCFunction)PyView_properties, METH_VARARGS, properties__doc
+  }
+  ,  {
+    0, 0, 0, 0
+  }
+};
+static PyMethodDef ViewerMethods[] =  {
+   {
+    "structure", (PyCFunction)PyView_structure, METH_VARARGS, structure__doc
+  }
+  ,  {
+    "select", (PyCFunction)PyView_select, METH_VARARGS | METH_KEYWORDS,
+      select__doc
+  }
+  ,  {
+    "addproperty", (PyCFunction)PyView_addproperty, METH_VARARGS,
+      addproperty__doc
+  }
+  ,  {
+    "sort", (PyCFunction)PyView_sort, METH_VARARGS, sort__doc
+  }
+  ,  {
+    "sortrev", (PyCFunction)PyView_sortrev, METH_VARARGS, sortrev__doc
+  }
+  ,  {
+    "project", (PyCFunction)PyView_project, METH_VARARGS, project__doc
+  }
+  ,  {
+    "flatten", (PyCFunction)PyView_flatten, METH_VARARGS | METH_KEYWORDS,
+      flatten__doc
+  }
+  ,  {
+    "join", (PyCFunction)PyView_join, METH_VARARGS | METH_KEYWORDS, join__doc
+  }
+  ,  {
+    "groupby", (PyCFunction)PyView_groupby, METH_VARARGS, groupby__doc
+  }
+  ,  {
+    "counts", (PyCFunction)PyView_counts, METH_VARARGS, counts__doc
+  }
+  ,  {
+    "product", (PyCFunction)PyView_product, METH_VARARGS, product__doc
+  }
+  ,  {
+    "union", (PyCFunction)PyView_union, METH_VARARGS, union__doc
+  }
+  ,  {
+    "intersect", (PyCFunction)PyView_intersect, METH_VARARGS, intersect__doc
+  }
+  ,  {
+    "different", (PyCFunction)PyView_different, METH_VARARGS, different__doc
+  }
+  ,  {
+    "minus", (PyCFunction)PyView_minus, METH_VARARGS, minus__doc
+  }
+  ,  {
+    "remapwith", (PyCFunction)PyView_remapwith, METH_VARARGS, remapwith__doc
+  }
+  ,  {
+    "pair", (PyCFunction)PyView_pair, METH_VARARGS, pair__doc
+  }
+  ,  {
+    "rename", (PyCFunction)PyView_rename, METH_VARARGS, rename__doc
+  }
+  ,  {
+    "unique", (PyCFunction)PyView_unique, METH_VARARGS, unique__doc
+  }
+  ,  {
+    "hash", (PyCFunction)PyView_hash, METH_VARARGS, hash__doc
+  }
+  ,  {
+    "blocked", (PyCFunction)PyView_blocked, METH_VARARGS, blocked__doc
+  }
+  ,  {
+    "ordered", (PyCFunction)PyView_ordered, METH_VARARGS, ordered__doc
+  }
+  ,  {
+    "indexed", (PyCFunction)PyView_indexed, METH_VARARGS, indexed__doc
+  }
+  ,  {
+    "find", (PyCFunction)PyView_find, METH_VARARGS | METH_KEYWORDS, find__doc
+  }
+  ,  {
+    "search", (PyCFunction)PyView_search, METH_VARARGS | METH_KEYWORDS,
+      search__doc
+  }
+  ,  {
+    "locate", (PyCFunction)PyView_locate, METH_VARARGS | METH_KEYWORDS,
+      locate__doc
+  }
+  ,  {
+    "access", (PyCFunction)PyView_access, METH_VARARGS, access__doc
+  }
+  ,  {
+    "modify", (PyCFunction)PyView_modify, METH_VARARGS, modify__doc
+  }
+  ,  {
+    "itemsize", (PyCFunction)PyView_itemsize, METH_VARARGS, itemsize__doc
+  }
+  , 
+  //{"map", (PyCFunction)PyView_map, METH_VARARGS, map__doc},
+   {
+    "filter", (PyCFunction)PyView_filter, METH_VARARGS, filter__doc
+  }
+  ,  {
+    "reduce", (PyCFunction)PyView_reduce, METH_VARARGS, reduce__doc
+  }
+  ,  {
+    "indices", (PyCFunction)PyView_indices, METH_VARARGS, indices__doc
+  }
+  ,  {
+    "copy", (PyCFunction)PyView_copy, METH_VARARGS, copy__doc
+  }
+  ,  {
+    "properties", (PyCFunction)PyView_properties, METH_VARARGS, properties__doc
+  }
+  ,  {
+    0, 0, 0, 0
+  }
+};
+
+/*
+Duplicate(deep=0)  (__copy__ and __deepcopy__ as methods, too)
+Clone()
+ */
+static Py_ssize_t PyView_length(PyObject *_o) {
+  PyView *o = (PyView*)_o;
+
+  try {
+    return o->GetSize();
+  } catch (...) {
+    return  - 1;
+  }
+}
+
+static PyObject *PyView_concat(PyObject *_o, PyObject *_other) {
+  PyView *o = (PyView*)_o;
+  PyView *other = (PyView*)_other;
+
+  try {
+    if (!PyGenericView_Check(other))
+      Fail(PyExc_TypeError, "Not a PyView(er)");
+    return new PyView(o->Concat(*other), 0, o->computeState(RWVIEWER));
+  } catch (...) {
+    return 0;
+  }
+}
+
+static PyObject *PyView_repeat(PyObject *_o, Py_ssize_t n) {
+  PyView *o = (PyView*)_o;
+
+  try {
+    PyView *tmp = new PyView(*o, 0, o->computeState(RWVIEWER));
+    while (--n > 0) {
+      //!! a huge stack of views?
+      PyView *tmp1 = new PyView(tmp->Concat(*o), 0, o->computeState(RWVIEWER));
+      delete tmp;
+      tmp = tmp1;
+    }
+    return tmp;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static PyObject *PyView_getitem(PyObject *_o, Py_ssize_t n) {
+  PyView *o = (PyView*)_o;
+
+  try {
+    PyObject *rslt = o->getItem(n);
+    if (rslt == 0)
+      PyErr_SetString(PyExc_IndexError, "row index out of range");
+    return rslt;
+  } catch (...) {
+    return 0;
+  }
+}
+
+static PyObject *PyView_getslice(PyObject *_o, Py_ssize_t s, Py_ssize_t e) {
+  PyView *o = (PyView*)_o;
+
+  try {
+    return o->getSlice(s, e);
+  } catch (...) {
+    return 0;
+  }
+}
+
+static int PyView_setitem(PyObject *_o, Py_ssize_t n, PyObject *v) {
+  PyView *o = (PyView*)_o;
+
+  try {
+    if (n < 0)
+      n += o->GetSize();
+    if (n >= o->GetSize() || n < 0)
+      Fail(PyExc_IndexError, "Index out of range");
+    if (v == 0) {
+      o->RemoveAt(n);
+      return 0;
+    }
+
+    return o->setItem(n, v);
+  } catch (...) {
+    return  - 1;
+  }
+}
+
+static int PyView_setslice(PyObject *_o, Py_ssize_t s, Py_ssize_t e, PyObject
+  *v) {
+  PyView *o = (PyView*)_o;
+
+  try {
+    if (v == 0) {
+      PWOTuple seq;
+      return o->setSlice(s, e, seq);
+    }
+
+    PWOSequence seq(v);
+    return o->setSlice(s, e, seq);
+  } catch (...) {
+    return  - 1;
+  }
+}
+
+static PySequenceMethods ViewAsSeq =  {
+  PyView_length,  //sq_length
+  PyView_concat,  //sq_concat
+  PyView_repeat,  //sq_repeat
+  PyView_getitem,  //sq_item
+  PyView_getslice,  //sq_slice
+  PyView_setitem,  //sq_ass_item
+  PyView_setslice,  //sq_ass_slice
+};
+
+static PySequenceMethods ViewerAsSeq =  {
+  PyView_length,  //sq_length
+  PyView_concat,  //sq_concat
+  PyView_repeat,  //sq_repeat
+  PyView_getitem,  //sq_item
+  PyView_getslice,  //sq_slice
+  0,  //sq_ass_item
+  0,  //sq_ass_slice
+};
+
+static void PyView_dealloc(PyView *o) {
+  //o->~PyView();
+  delete o;
+}
+
+static int PyView_print(PyView *o, FILE *f, int) {
+  fprintf(f, "<PyView object at %p>", (void*)o);
+  return 0;
+}
+
+static int PyViewer_print(PyView *o, FILE *f, int) {
+  fprintf(f, "<PyViewer object at %p>", (void*)o);
+  return 0;
+}
+
+static int PyROViewer_print(PyView *o, FILE *f, int) {
+  fprintf(f, "<PyROViewer object at %p>", (void*)o);
+  return 0;
+}
+
+static PyObject *PyView_getattr(PyView *o, char *nm) {
+  PyObject *rslt;
+  try {
+    rslt = Py_FindMethod(ViewMethods, o, nm);
+    if (rslt)
+      return rslt;
+    PyErr_Clear();
+    int ndx = o->FindPropIndexByName(nm);
+    if (ndx >  - 1)
+      return new PyProperty(o->NthProperty(ndx));
+    Fail(PyExc_AttributeError, nm);
+  } catch (...) {
+    return 0;
+  }
+  return 0;
+}
+
+static PyObject *PyViewer_getattr(PyView *o, char *nm) {
+  PyObject *rslt;
+  try {
+    rslt = Py_FindMethod(ViewerMethods, o, nm);
+    if (rslt)
+      return rslt;
+    PyErr_Clear();
+    int ndx = o->FindPropIndexByName(nm);
+    if (ndx >  - 1)
+      return new PyProperty(o->NthProperty(ndx));
+    Fail(PyExc_AttributeError, nm);
+  } catch (...) {
+    return 0;
+  }
+  return 0;
+}
+
+
+PyTypeObject PyViewtype =  {
+  PyObject_HEAD_INIT(&PyType_Type)0, "PyView", sizeof(PyView), 0, (destructor)
+    PyView_dealloc,  /*tp_dealloc*/
+  (printfunc)PyView_print,  /*tp_print*/
+  (getattrfunc)PyView_getattr,  /*tp_getattr*/
+  0,  /*tp_setattr*/
+  (cmpfunc)0,  /*tp_compare*/
+  (reprfunc)0,  /*tp_repr*/
+  0,  /*tp_as_number*/
+   &ViewAsSeq,  /*tp_as_sequence*/
+  0,  /*tp_as_mapping*/
+};
+PyTypeObject PyViewertype =  {
+  PyObject_HEAD_INIT(&PyType_Type)0, "PyViewer", sizeof(PyView), 0, (destructor)
+    PyView_dealloc,  /*tp_dealloc*/
+  (printfunc)PyViewer_print,  /*tp_print*/
+  (getattrfunc)PyViewer_getattr,  /*tp_getattr*/
+  0,  /*tp_setattr*/
+  (cmpfunc)0,  /*tp_compare*/
+  (reprfunc)0,  /*tp_repr*/
+  0,  /*tp_as_number*/
+   &ViewerAsSeq,  /*tp_as_sequence*/
+  0,  /*tp_as_mapping*/
+};
+PyTypeObject PyROViewertype =  {
+  PyObject_HEAD_INIT(&PyType_Type)0, "PyROViewer", sizeof(PyView), 0, 
+    (destructor)PyView_dealloc,  /*tp_dealloc*/
+  (printfunc)PyROViewer_print,  /*tp_print*/
+  (getattrfunc)PyViewer_getattr,  /*tp_getattr*/
+  0,  /*tp_setattr*/
+  (cmpfunc)0,  /*tp_compare*/
+  (reprfunc)0,  /*tp_repr*/
+  0,  /*tp_as_number*/
+   &ViewerAsSeq,  /*tp_as_sequence*/
+  0,  /*tp_as_mapping*/
+};
+int PyView::computeState(int targettype) {
+  int newtype = _state | targettype;
+  if (newtype > FINALNOTIFIABLE)
+    newtype = ROVIEWER;
+  if (_state == FINALNOTIFIABLE)
+    newtype = ROVIEWER;
+  return newtype;
+}
+
+PyTypeObject *getTypeObject(int type) {
+  switch (type) {
+    case BASE:
+    case MVIEWER:
+      return  &PyViewtype;
+      break;
+    case NOTIFIABLE:
+    case RWVIEWER:
+    case FINALNOTIFIABLE:
+      return  &PyViewertype;
+    case ROVIEWER:
+      return  &PyROViewertype;
+  }
+  return  &PyViewtype;
+}
+
+
+PyObject *PyView_new(PyObject *o, PyObject *_args) {
+  return new PyView;
+}
+
+PyView::PyView(): PyHead(PyViewtype), _base(0), _state(BASE){}
+
+PyView::PyView(const c4_View &o, PyView *owner, int state): PyHead(PyViewtype),
+  c4_View(o), _base(owner), _state(state) {
+  ob_type = getTypeObject(_state);
+  if (owner && owner->_base)
+    _base = owner->_base;
+}
+
+/* For dicts, use the Python names so MK's case insensitivity works */
+void PyView::makeRowFromDict(c4_Row &tmp, PyObject *o, bool useDefaults) {
+  PWOMapping dict(o);
+  PWOList keys = dict.keys();
+  for (int i = 0; i < dict.len(); ++i) {
+    PWOString key = keys[i];
+    int ndx = FindPropIndexByName(key);
+    if (ndx >  - 1) {
+      const c4_Property &prop = NthProperty(ndx);
+      PyRowRef::setFromPython(tmp, prop, dict[(const char*)key]);
+    }
+  }
+}
+
+void PyView::makeRow(c4_Row &tmp, PyObject *o, bool useDefaults) {
+  /* can't just check if mapping type; strings are mappings in Python 2.3
+  (but not in 2.2 or earlier) */
+  if (o && PyDict_Check(o))
+    makeRowFromDict(tmp, o, useDefaults);
+  else {
+    enum {
+      instance, sequence, none
+    } pyobject_type = none;
+    int n = NumProperties();
+
+    if (!o) {
+      pyobject_type = none;
+    } else if (PyInstance_Check(o)) {
+      /* instances of new-style classes (Python 2.2+) do not return true */
+      pyobject_type = instance;
+    } else if (PySequence_Check(o)) {
+      int seq_length = PyObject_Length(o);
+      if (seq_length > n) {
+        PyErr_Format(PyExc_IndexError, 
+          "Sequence has %d elements; view has %d properties", seq_length, n);
+        throw PWDPyException;
+      }
+      n = seq_length;
+      pyobject_type = sequence;
+    } else {
+      /* new-style class, not a number */
+      if (PyObject_HasAttrString(o, "__class__") && !PyNumber_Check(o)) {
+        pyobject_type = instance;
+      } else {
+        Fail(PyExc_TypeError, 
+          "Argument is not an instance, sequence or dictionary: cannot be coerced to row");
+      }
+    }
+
+    for (int i = 0; i < n; i++) {
+      const c4_Property &prop = NthProperty(i);
+      PyObject *attr = 0;
+      if (pyobject_type == instance) {
+        attr = PyObject_GetAttrString(o, (char*)prop.Name());
+        if (attr == 0 && i == 0 && NumProperties() == 1) {
+          PyErr_Clear();
+          attr = o;
+          Py_XINCREF(attr);
+        }
+      } else if (pyobject_type == sequence) {
+        attr = PySequence_GetItem(o, i);
+      }
+      if (attr) {
+        try {
+          PyRowRef::setFromPython(tmp, prop, attr);
+        } catch (...) {
+          Py_DECREF(attr);
+          throw;
+        }
+        Py_DECREF(attr);
+      } else {
+        PyErr_Clear();
+        if (useDefaults)
+          PyRowRef::setDefault(tmp, prop);
+      }
+    }
+  }
+  if (!useDefaults)
+    if (tmp.Container().NumProperties() == 0)
+      Fail(PyExc_ValueError, "Object has no usable attributes");
+}
+
+void PyView::insertAt(int i, PyObject *o) {
+  if (PyGenericView_Check(o))
+    InsertAt(i, *(PyView*)o);
+  else {
+    c4_Row temp;
+    makeRow(temp, o);
+    InsertAt(i, temp);
+  }
+}
+
+PyObject *PyView::structure() {
+  int n = NumProperties();
+  //  PyObject* list=PyList_New(n);
+  //  for (int i = 0; i < n; i++)
+  //    PyList_SET_ITEM(list, i, new PyProperty(NthProperty(i)));
+  //  return list;
+  PWOList rslt(n);
+  for (int i = 0; i < n; i++) {
+    PyProperty *prop = new PyProperty(NthProperty(i));
+    rslt.setItem(i, prop);
+  }
+  return rslt.disOwn();
+}
+
+
+PyObject *PyView::properties() {
+  int n = NumProperties();
+  PWOMapping rslt;
+  for (int i = 0; i < n; i++) {
+    PyProperty *item = new PyProperty(NthProperty(i));
+    rslt.setItem(item->Name(), item);
+    Py_DECREF(item);
+  }
+  return rslt.disOwn();
+}
+
+
+PyView *PyView::getSlice(int s, int e) {
+  int sz = GetSize();
+  if (s < 0)
+    s += sz;
+  if (e < 0)
+    e += sz;
+  if (e > sz)
+    e = sz;
+  if (s >= 0 && s < sz)
+    if (e > s && e <= sz)
+      return new PyView(Slice(s, e), 0, computeState(RWVIEWER));
+  return new PyView(Clone());
+}
+
+int PyView::setSlice(int s, int e, const PWOSequence &lst) {
+  int sz = GetSize();
+  if (s < 0)
+    s += sz;
+  if (e < 0)
+    e += sz;
+  if (e > sz)
+    e = sz;
+  int i = 0;
+  for (; i < lst.len() && s < e; i++, s++)
+    setItem(s, lst[i]);
+  for (; i < lst.len(); i++, s++) {
+    if (_base)
+      Fail(PyExc_RuntimeError, "Can't insert in this view");
+    insertAt(s, lst[i]);
+  }
+  if (s < e)
+    if (_base)
+  while (s < e) {
+    int ndx = _base->GetIndexOf(GetAt(s));
+    _base->RemoveAt(ndx, 1);
+    --e;
+  } else
+    RemoveAt(s, e-s);
+  return 0;
+}
+
+PyRowRef *PyView::getItem(int i) {
+  if (i < 0)
+    i += GetSize();
+  if (i >= GetSize() || i < 0)
+    return 0;
+  if (_base && !(_state &IMMUTABLEROWS)) {
+    c4_RowRef derived = GetAt(i);
+    int ndx = _base->GetIndexOf(derived);
+    if (ndx >= 0)
+      return new PyRowRef(_base->GetAt(ndx), _state &IMMUTABLEROWS);
+  }
+  return new PyRowRef(GetAt(i), _state &IMMUTABLEROWS);
+}
+
+int PyView::setItem(int i, PyObject *v) {
+  if (PyGenericRowRef_Check(v))
+    return setItemRow(i, *(PyRowRef*)v);
+  c4_Row temp;
+  makeRow(temp, v, false);
+  return setItemRow(i, temp);
+}
+
+void PyView::addProperties(const PWOSequence &lst) {
+  for (int i = 0; i < lst.len(); i++) {
+    if (PyProperty_Check((PyObject*)lst[i])) {
+      AddProperty(*(PyProperty*)(PyObject*)lst[i]);
+    }
+  }
+}
+
+void PyView::map(const PWOCallable &func) {
+  PWOTuple tmp(1);
+  for (int i = 0; i < GetSize(); ++i) {
+    PyRowRef *row = new PyRowRef(GetAt(i));
+    PWOBase r2(row);
+    tmp.setItem(0, r2);
+    func.call(tmp);
+    Py_DECREF(row);
+  }
+}
+
+void PyView::map(const PWOCallable &func, const PyView &subset) {
+  int sz = subset.GetSize();
+  PWOTuple tmp(1);
+  for (int i = 0; i < sz; ++i) {
+    PyRowRef *row = new PyRowRef(GetAt(GetIndexOf(subset.GetAt(i))));
+    PWOBase r2(row);
+    tmp.setItem(0, r2);
+    func.call(tmp);
+    Py_DECREF(row);
+  }
+}
+
+static c4_IntProp _index("index");
+
+PyView *PyView::indices(const PyView &subset) {
+  c4_View tmp(_index);
+  tmp.SetSize(subset.GetSize());
+  c4_Row row;
+  for (int i = 0; i < subset.GetSize(); ++i) {
+    _index(row) = GetIndexOf(subset.GetAt(i));
+    tmp.SetAt(i, row);
+  }
+  return new PyView(tmp);
+}
+
+void PyView::remove(const PyView &indices) {
+  c4_View tmp = indices.Sort();
+  for (int i = indices.GetSize() - 1; i >= 0; --i)
+    RemoveAt(_index(tmp.GetAt(i)));
+}
+
+PyView *PyView::filter(const PWOCallable &func) {
+  c4_View indices(_index);
+  c4_Row ndx;
+  PWOTuple tmp(1);
+  for (int i = 0; i < GetSize(); ++i) {
+    PyRowRef *row = new PyRowRef(GetAt(i));
+    PWOBase r2(row);
+    tmp.setItem(0, r2);
+    PWOBase rslt(func.call(tmp));
+    if (rslt.isTrue()) {
+      _index(ndx) = i;
+      indices.Add(ndx);
+    }
+    Py_DECREF(row);
+  }
+  return new PyView(indices);
+}
+
+PyObject *PyView::reduce(const PWOCallable &func, PWONumber &start) {
+  PWONumber accum = start;
+  PWOTuple tmp(2);
+  for (int i = 0; i < GetSize(); ++i) {
+    PyRowRef *row = new PyRowRef(GetAt(i));
+    PWOBase r2(row);
+    tmp.setItem(0, r2);
+    tmp.setItem(1, accum);
+    PWOBase rslt(func.call(tmp));
+    accum = rslt;
+    Py_DECREF(row);
+  }
+  return accum;
+}
diff --git a/8.x/mk/python/PyView.h b/8.x/mk/python/PyView.h
new file mode 100755 (executable)
index 0000000..53234c2
--- /dev/null
@@ -0,0 +1,74 @@
+// PyView.h --
+// $Id: PyView.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of MetaKit, see http://www.equi4.com/metakit.html
+// Copyright (C) 1999-2004 Gordon McMillan and Jean-Claude Wippler.
+//
+//  View class header
+
+#if !defined INCLUDE_PYVIEW_H
+#define INCLUDE_PYVIEW_H
+
+#include <mk4.h>
+#include <PWOSequence.h>
+#include <PWOCallable.h>
+#include <PWONumber.h>
+#include "PyHead.h"
+
+#define PyView_Check(v) ((v)->ob_type==&PyViewtype)
+#define PyViewer_Check(v) ((v)->ob_type==&PyViewertype)
+#define PyROViewer_Check(v) ((v)->ob_type==&PyROViewertype)
+#define PyGenericView_Check(v) (PyView_Check(v) || PyViewer_Check(v) || \
+  PyROViewer_Check(v))
+
+class PyView;
+class PyRowRef;
+
+extern PyTypeObject PyViewtype;
+extern PyTypeObject PyViewertype;
+extern PyTypeObject PyROViewertype;
+
+#define BASE 0              //0000
+#define MVIEWER 4           //0100
+#define RWVIEWER 5          //0101
+#define NOTIFIABLE 1        //0001
+#define FINALNOTIFIABLE 9   //1001
+#define ROVIEWER 7          //0111
+#define IMMUTABLEROWS 2
+
+class PyView: public PyHead, public c4_View {
+    PyView *_base;
+    int _state;
+  public:
+    PyView();
+    PyView(const c4_View &o, PyView *owner = 0, int state = BASE);
+    ~PyView(){}
+    void insertAt(int i, PyObject *o);
+    PyRowRef *getItem(int i);
+    PyView *getSlice(int s, int e);
+    int setItemRow(int i, const c4_RowRef &v) {
+        if (i < 0)
+          i += GetSize();
+        if (i > GetSize() || i < 0)
+          Fail(PyExc_IndexError, "Index out of range");
+        SetAt(i, v);
+        return 0;
+    };
+    int setItem(int i, PyObject *v);
+    void addProperties(const PWOSequence &lst);
+    int setSlice(int s, int e, const PWOSequence &lst);
+    PyObject *structure();
+    void makeRow(c4_Row &temp, PyObject *o, bool useDefaults = true);
+    void makeRowFromDict(c4_Row &temp, PyObject *o, bool useDefaults = true);
+    void map(const PWOCallable &func);
+    void map(const PWOCallable &func, const PyView &subset);
+    PyView *filter(const PWOCallable &func);
+    PyObject *reduce(const PWOCallable &func, PWONumber &start);
+    void remove(const PyView &indices);
+    PyView *indices(const PyView &subset);
+    int computeState(int targetstate);
+    PyObject *properties();
+};
+
+PyObject *PyView_new(PyObject *o, PyObject *_args);
+
+#endif
diff --git a/8.x/mk/python/README-dmn b/8.x/mk/python/README-dmn
new file mode 100644 (file)
index 0000000..2eeb011
--- /dev/null
@@ -0,0 +1,100 @@
+From: David McNab <david@rebirthing.co.nz>
+Date: March 3, 2004 3:21:09 CET
+To: metakit@equi4.com
+Subject: [Metakit] Instructions for Legacy Pythons
+
+Hi,
+
+Below are instructions for people needing to build the python metakit wrapper
+for non-latest python versions.
+
+With the web app framework I'm building, I was using SQLObject for database
+storage. But given the fact that most public web hosts offering Python have
+version 2.1 or earlier, I've decided life is easiest for all if my framework can
+be made to work with python1.5.2 or later.
+
+These simple instructions walk people through the building of the Mk4py.so
+module for Python 1.5.2 or later, and can be used to help people compile a
+binary Mk4py.so locally, and drop it (with metakit.py) into their web hosting
+file tree.
+
+The need for this comes from the fact that, while most reasonable public web
+hosts support python, most of these have python1.5.2 or python2.1, and no
+Metakit.
+
+I hope the metakit devs might see fit to include these instructions in
+Metakitreleases.
+
+Cheers David
+
+---------------------------
+
+INSTRUCTIONS FOR BUILDING AND USING METAKIT ON EARLY PYTHON VERSIONS
+
+1. PREPARATION
+
+cd into top-level Metakit directory, then:
+
+ $ mkdir buildsx.x
+
+ (here and below we use 'x.x' to mean the python version you want to build for,
+eg '1.5')
+
+2. PRE-CONFIGURATION
+
+cd into the 'unix' directory, then:
+
+ $ cp configure configurex.x
+
+Then, edit configurex.x, search for the 'case "$with_python in' line. Look down
+a bit, and change the PY_INCLUDE_DIR and PY_LIB_DIR lines, to reference the
+version of python you're building for
+
+3. CONFIGURE AND BUILD
+
+cd into the buildsx.x directory, and type:
+
+ $ ../pythonx.x/configurex.x --with-python=/usr
+
+ (If your python doesn't live in /usr, change to /usr/local or wherever)
+
+ $ make
+
+4. INSTALLATION
+
+While still in your buildsx.x directory, type:
+
+ $ cp Mk4py.so /usr/lib/pythonx.x/site-packages
+
+ (you may need /usr/local/lib instead /usr/lib)
+
+Then, cd into the python directory:
+
+ $ cd ../python
+
+Note that you can build Metakit Mk4py.so for Python 1.5.2, and use it quite
+happily in all later python versions. However, you will probably want to
+suppress the API warning. To do this, edit the metakit.py file, and add the
+following lines right after the docstring:
+
+ import warnings warnings.filterwarnings('ignore', '.*Mk4py.*', RuntimeWarning)
+
+Then, just copy metakit.py into your python load path:
+
+ $ cp metakit.py /usr/lib/pythonx.x/site-packages
+
+ (change /usr/lib to /usr/local/lib or whatever if needed)
+
+5. TESTING
+
+Start up your chosen python interpreter:
+
+ $ pythonx.x
+
+And verify that you can load Metakit:
+
+ >>> from metakit import *
+
+_____________________________________________ 
+Metakit mailing list -Metakit@equi4.com 
+http://www.equi4.com/mailman/listinfo/metakit
diff --git a/8.x/mk/python/metakit.py b/8.x/mk/python/metakit.py
new file mode 100644 (file)
index 0000000..8ac2ed2
--- /dev/null
@@ -0,0 +1,84 @@
+"""
+metakit.py -- Utility code for the Python interface to Metakit
+$Id: metakit.py 1669 2007-06-16 00:23:25Z jcw $
+This is part of Metakit, see http://www.equi4.com/metakit.html
+
+This wraps the raw Mk4py compiled extension interface.
+To use Metakit through this interface, simply do:
+  import metakit
+After that, things like metakit.storage(...) are available,
+as well as utilities defined below.  This assumes that both
+both metakit.py and Mk4py.{dll,so} can be found by Python.
+"""
+
+_oldname = __name__
+__name__ = "metakit"
+__version__ = "2.4.9.7"
+__description__ = "Python bindings to the Metakit database library"
+__author__ = "Gordon McMillan / Jean-Claude Wippler"
+__email__ = "jcw@equi4.com"
+__url__ = "http://www.equi4.com/metakit/python.html"
+__license__ = "X/MIT style, see: http://www.equi4.com/mklicense.html"
+from Mk4py import *
+import string
+
+def dump(view, title=None):
+  """pretty printer for MK views"""
+
+  widths = []
+  cols = []
+  justs = []
+
+  props = view.structure()
+  for prop in props:
+    widths.append(len(prop.name))
+    cols.append([None])
+    if prop.type in ('I','F','D','V'):
+      justs.append(string.rjust)
+    else:
+      justs.append(string.ljust)
+
+  for row in view:
+    for c in range(len(props)):
+      attr = getattr(row, props[c].name, None)
+      if type(attr) is type(view):
+        text = '%d rows' % len(attr)
+      else:
+        text = str(attr)
+        if len(text) > 20:
+          text = text[0:17] + '...'
+      widths[c] = max(widths[c],len(text))
+      cols[c].append(text)
+
+  if title: print title
+
+  for c in range(len(props)):
+    cols[c][0] = widths[c] * '-'
+    cols[c].append(cols[c][0])
+    print '', string.ljust(props[c].name, widths[c]),
+  print
+
+  for r in xrange(len(view)+2):
+    for c in range(len(props)):
+      print '', justs[c](cols[c][r], widths[c]),
+    print
+
+  print " Total: %d rows" % len(view)
+
+if _oldname == '__main__':
+  db = storage()
+  f = db.getas('frequents[drinker,bar,perweek:I]')
+  s = db.getas('serves[bar,beer,quantity:I]')
+
+  f.append(drinker='adam', bar='lolas', perweek=1)
+  f.append(drinker='woody', bar='cheers', perweek=5)
+  f.append(drinker='sam', bar='cheers', perweek=5)
+  f.append(drinker='lola', bar='lolas', perweek=6)
+
+  s.append(bar='cheers', beer='bud', quantity=500)
+  s.append(bar='cheers', beer='samaddams', quantity=255)
+  s.append(bar='lolas', beer='mickies', quantity=1515)
+
+  dump(f, 'frequents:')
+  dump(s, 'serves:')
+  dump(f.join(s, s.bar), 'join on "bar":')
diff --git a/8.x/mk/python/scxx/PWOBase.h b/8.x/mk/python/scxx/PWOBase.h
new file mode 100755 (executable)
index 0000000..18394d0
--- /dev/null
@@ -0,0 +1,139 @@
+/******************************************** 
+copyright 1999 McMillan Enterprises, Inc.
+www.mcmillan-inc.com
+ *********************************************/
+// PWOBase.h: interface for the PWOBase class.
+
+#if !defined(PWOBASE_H_INCLUDED_)
+#define PWOBASE_H_INCLUDED_
+
+#include <Python.h>
+#include <limits.h>
+
+// Dummy, minimal exception thrown when a Python exception is generated
+// (after PyErr_Format, PyErr_SetString, etc.)
+class PWDException {
+  public:
+    PWDException(){}
+}
+
+extern const &PWDPyException;
+
+// functions throw PWDPyException
+void Fail(PyObject *, const char *msg);
+void FailIfPyErr();
+
+class PWOBase {
+  protected:
+    PyObject *_obj;
+
+    // incref new owner, decref old owner, and adjust to new owner
+    void GrabRef(PyObject *newObj);
+    // decrease reference count without destroying the object
+    static PyObject *LoseRef(PyObject *o) {
+        if (o != 0)
+          --(o->ob_refcnt);
+        return o;
+    }
+
+  private:
+    PyObject *_own; // set to _obj if we "own" a reference to _obj, else zero
+
+  public:
+    PWOBase(): _obj(0), _own(0){}
+    PWOBase(const PWOBase &other): _obj(0), _own(0) {
+        GrabRef(other);
+    }
+    PWOBase(PyObject *obj): _obj(0), _own(0) {
+        GrabRef(obj);
+    }
+
+    virtual ~PWOBase() {
+        Py_XDECREF(_own);
+    }
+
+    PWOBase &operator = (const PWOBase &other) {
+        GrabRef(other);
+        return  *this;
+    };
+    operator PyObject *()const {
+        return _obj;
+    };
+    int print(FILE *f, int flags)const {
+        return PyObject_Print(_obj, f, flags);
+    };
+    bool hasAttr(const char *nm)const {
+        return PyObject_HasAttrString(_obj, (char*)nm) == 1;
+    };
+    //bool hasAttr(PyObject* nm) const {
+    //      return PyObject_HasAttr(_obj, nm);
+    //};
+    PyObject *getAttr(const char *nm)const {
+        return LoseRef(PyObject_GetAttrString(_obj, (char*)nm));
+    };
+    PyObject *getAttr(const PWOBase &nm)const {
+        return LoseRef(PyObject_GetAttr(_obj, nm));
+    };
+    int setAttr(const char *nm, PWOBase &val) {
+        return PyObject_SetAttrString(_obj, (char*)nm, val);
+    };
+    int setAttr(PyObject *nm, PWOBase &val) {
+        return PyObject_SetAttr(_obj, nm, val);
+    };
+    int delAttr(const char *nm) {
+        return PyObject_DelAttrString(_obj, (char*)nm);
+    };
+    int delAttr(const PWOBase &nm) {
+        return PyObject_DelAttr(_obj, nm);
+    };
+    int cmp(const PWOBase &other)const {
+        int rslt = 0;
+        int rc = PyObject_Cmp(_obj, other, &rslt);
+        if (rc ==  - 1)
+          Fail(PyExc_TypeError, "cannot make the comparison");
+        return rslt;
+    };
+    bool operator == (const PWOBase &other)const {
+        return cmp(other) == 0;
+    };
+    bool operator != (const PWOBase &other)const {
+        return cmp(other) != 0;
+    };
+    bool operator > (const PWOBase &other)const {
+        return cmp(other) > 0;
+    };
+    bool operator < (const PWOBase &other)const {
+        return cmp(other) < 0;
+    };
+    bool operator >= (const PWOBase &other)const {
+        return cmp(other) >= 0;
+    };
+    bool operator <= (const PWOBase &other)const {
+        return cmp(other) <= 0;
+    };
+
+    PyObject *repr()const {
+        return LoseRef(PyObject_Repr(_obj));
+    };
+    PyObject *str()const {
+        return LoseRef(PyObject_Str(_obj));
+    };
+    bool isCallable()const {
+        return PyCallable_Check(_obj) == 1;
+    };
+    int hash()const {
+        return PyObject_Hash(_obj);
+    };
+    bool isTrue()const {
+        return PyObject_IsTrue(_obj) == 1;
+    };
+    PyObject *type()const {
+        return LoseRef(PyObject_Type(_obj));
+    };
+    PyObject *disOwn() {
+        _own = 0;
+        return _obj;
+    };
+};
+
+#endif // !defined(PWOBASE_H_INCLUDED_)
diff --git a/8.x/mk/python/scxx/PWOCallable.h b/8.x/mk/python/scxx/PWOCallable.h
new file mode 100644 (file)
index 0000000..36132a1
--- /dev/null
@@ -0,0 +1,41 @@
+/******************************************** 
+copyright 2000 McMillan Enterprises, Inc.
+www.mcmillan-inc.com
+ *********************************************/
+#if !defined(PWOCALLABLE_H_INCLUDED_)
+#define PWOCALLABLE_H_INCLUDED_
+
+#include "PWOBase.h"
+#include "PWOSequence.h"
+#include "PWOMapping.h"
+
+class PWOCallable: public PWOBase {
+  public:
+    PWOCallable(): PWOBase(){}
+    ;
+    PWOCallable(PyObject *obj): PWOBase(obj) {
+        _violentTypeCheck();
+    };
+    virtual ~PWOCallable(){}
+    ;
+    virtual PWOCallable &operator = (const PWOCallable &other) {
+        GrabRef(other);
+        return  *this;
+    };
+    PWOCallable &operator = (const PWOBase &other) {
+        GrabRef(other);
+        _violentTypeCheck();
+        return  *this;
+    };
+    virtual void _violentTypeCheck() {
+        if (!isCallable()) {
+            GrabRef(0);
+            Fail(PyExc_TypeError, "Not a callable object");
+        }
+    };
+    PWOBase call()const;
+    PWOBase call(PWOTuple &args)const;
+    PWOBase call(PWOTuple &args, PWOMapping &kws)const;
+};
+
+#endif
diff --git a/8.x/mk/python/scxx/PWOImp.cpp b/8.x/mk/python/scxx/PWOImp.cpp
new file mode 100755 (executable)
index 0000000..7753045
--- /dev/null
@@ -0,0 +1,73 @@
+/******************************************** 
+copyright 1999 McMillan Enterprises, Inc.
+www.mcmillan-inc.com
+ *********************************************/
+#include "PWOSequence.h"
+#include "PWOMSequence.h"
+#include "PWOMapping.h"
+#include "PWOCallable.h"
+
+// dummy exception singleton
+const PWDException PWDPyExceptionObj;
+const PWDException &PWDPyException = PWDPyExceptionObj;
+
+// incref new owner, and decref old owner, and adjust to new owner
+void PWOBase::GrabRef(PyObject *newObj) {
+  // be careful to incref before decref if old is same as new
+  Py_XINCREF(newObj);
+  Py_XDECREF(_own);
+  _own = _obj = newObj;
+}
+
+PWOTuple::PWOTuple(const PWOList &list): PWOSequence(PyList_AsTuple(list)) {
+  LoseRef(_obj);
+}
+
+PWOListMmbr::PWOListMmbr(PyObject *obj, PWOList &parent, int ndx): PWOBase(obj),
+  _parent(parent), _ndx(ndx){}
+
+PWOListMmbr &PWOListMmbr::operator = (const PWOBase &other) {
+  GrabRef(other);
+  //Py_XINCREF(_obj); // this one is for setItem to steal
+  _parent.setItem(_ndx,  *this);
+  return  *this;
+}
+
+PWOMappingMmbr &PWOMappingMmbr::operator = (const PWOBase &other) {
+  GrabRef(other);
+  _parent.setItem(_key,  *this);
+  return  *this;
+}
+
+PWOBase PWOCallable::call()const {
+  static PWOTuple _empty;
+  PyObject *rslt = PyEval_CallObjectWithKeywords(*this, _empty, NULL);
+  if (rslt == 0)
+    throw PWDPyException;
+  return rslt;
+}
+
+PWOBase PWOCallable::call(PWOTuple &args)const {
+  PyObject *rslt = PyEval_CallObjectWithKeywords(*this, args, NULL);
+  if (rslt == 0)
+    throw PWDPyException;
+  return rslt;
+}
+
+PWOBase PWOCallable::call(PWOTuple &args, PWOMapping &kws)const {
+  PyObject *rslt = PyEval_CallObjectWithKeywords(*this, args, kws);
+  if (rslt == 0)
+    throw PWDPyException;
+  return rslt;
+}
+
+void Fail(PyObject *exc, const char *msg) {
+  PyErr_SetString(exc, msg);
+  throw PWDPyException;
+}
+
+void FailIfPyErr() {
+  PyObject *exc = PyErr_Occurred();
+  if (exc != NULL)
+    throw PWDPyException;
+}
diff --git a/8.x/mk/python/scxx/PWOMSequence.h b/8.x/mk/python/scxx/PWOMSequence.h
new file mode 100755 (executable)
index 0000000..a852d7f
--- /dev/null
@@ -0,0 +1,153 @@
+/******************************************** 
+copyright 1999 McMillan Enterprises, Inc.
+www.mcmillan-inc.com
+ *********************************************/
+#if !defined(PWOMSEQUENCE_H_INCLUDED_)
+#define PWOMSEQUENCE_H_INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#include "PWOBase.h"
+#include "PWOSequence.h"
+
+
+class PWOList;
+
+class PWOListMmbr: public PWOBase {
+    PWOList &_parent;
+    int _ndx;
+  public:
+    PWOListMmbr(PyObject *obj, PWOList &parent, int ndx);
+    virtual ~PWOListMmbr(){}
+    ;
+    PWOListMmbr &operator = (const PWOBase &other);
+};
+
+class PWOList: public PWOSequence {
+  public:
+    PWOList(int size = 0): PWOSequence(PyList_New(size)) {
+        LoseRef(_obj);
+    }
+    PWOList(const PWOList &other): PWOSequence(other){}
+    ;
+    PWOList(PyObject *obj): PWOSequence(obj) {
+        _violentTypeCheck();
+    };
+    virtual ~PWOList(){}
+    ;
+
+    virtual PWOList &operator = (const PWOList &other) {
+        GrabRef(other);
+        return  *this;
+    };
+    PWOList &operator = (const PWOBase &other) {
+        GrabRef(other);
+        _violentTypeCheck();
+        return  *this;
+    };
+    virtual void _violentTypeCheck() {
+        if (!PyList_Check(_obj)) {
+            //should probably check the sequence methods for non-0 setitem
+            GrabRef(0);
+            Fail(PyExc_TypeError, "Not a mutable sequence");
+        }
+    };
+    //PySequence_DelItem    ##lists
+    bool delItem(int i) {
+        int rslt = PySequence_DelItem(_obj, i);
+        if (rslt ==  - 1)
+          Fail(PyExc_RuntimeError, "cannot delete item");
+        return true;
+    };
+    //PySequence_DelSlice   ##lists
+    bool delSlice(int lo, int hi) {
+        int rslt = PySequence_DelSlice(_obj, lo, hi);
+        if (rslt ==  - 1)
+          Fail(PyExc_RuntimeError, "cannot delete slice");
+        return true;
+    };
+    //PySequence_GetItem    ##lists - return PWOListMmbr (mutable) otherwise just a PWOBase
+    PWOListMmbr operator[](int i) {
+        // can't be virtual
+        //PyObject* o = PySequence_GetItem(_obj, i); assumes item is valid
+        PyObject *o = PyList_GetItem(_obj, i); // get a "borrowed" refcount
+        //Py_XINCREF(o);
+        //if (o == 0)
+        //      Fail(PyExc_IndexError, "index out of range");
+        return PWOListMmbr(o,  *this, i); // this increfs
+    };
+    //PySequence_SetItem    ##Lists
+    void setItem(int ndx, PWOBase &val) {
+        //int rslt = PySequence_SetItem(_obj, ndx, val); - assumes old item is valid
+        int rslt = PyList_SetItem(_obj, ndx, val);
+        val.disOwn(); //when using PyList_SetItem, he steals my reference
+        if (rslt ==  - 1)
+          Fail(PyExc_IndexError, "Index out of range");
+    };
+    void setItem(int ndx, PyObject *val) {
+        //int rslt = PySequence_SetItem(_obj, ndx, val); - assumes old item is valid
+        int rslt = PyList_SetItem(_obj, ndx, val);
+        if (rslt ==  - 1)
+          Fail(PyExc_IndexError, "Index out of range");
+    };
+    //PySequence_SetSlice   ##Lists
+    void setSlice(int lo, int hi, const PWOSequence &slice) {
+        int rslt = PySequence_SetSlice(_obj, lo, hi, slice);
+        if (rslt ==  - 1)
+          Fail(PyExc_RuntimeError, "Error setting slice");
+    };
+    //PyList_Append
+    PWOList &append(const PWOBase &other) {
+        int rslt = PyList_Append(_obj, other);
+        if (rslt ==  - 1) {
+            PyErr_Clear(); //Python sets one 
+            Fail(PyExc_RuntimeError, "Error appending");
+        };
+        return  *this;
+    };
+    //PyList_AsTuple
+    // problem with this is it's created on the heap
+    //virtual PWOTuple& asTuple() const {
+    //      PyObject* rslt = PyList_AsTuple(_obj);
+    //      PWOTuple rtrn = new PWOTuple(rslt);
+    //      Py_XDECREF(rslt);       //AsTuple set refcnt to 1, PWOTuple(rslt) increffed
+    //      return *rtrn;
+    //};
+    //PyList_GetItem - inherited OK
+    //PyList_GetSlice - inherited OK
+    //PyList_Insert
+    PWOList &insert(int ndx, PWOBase &other) {
+        int rslt = PyList_Insert(_obj, ndx, other);
+        if (rslt ==  - 1) {
+            PyErr_Clear(); //Python sets one 
+            Fail(PyExc_RuntimeError, "Error inserting");
+        };
+        return  *this;
+    };
+    //PyList_New
+    //PyList_Reverse
+    PWOList &reverse() {
+        int rslt = PyList_Reverse(_obj);
+        if (rslt ==  - 1) {
+            PyErr_Clear(); //Python sets one 
+            Fail(PyExc_RuntimeError, "Error reversing");
+        };
+        return  *this; //HA HA - Guido can't stop me!!!
+    };
+    //PyList_SetItem - using abstract
+    //PyList_SetSlice - using abstract
+    //PyList_Size - inherited OK
+    //PyList_Sort
+    PWOList &sort() {
+        int rslt = PyList_Sort(_obj);
+        if (rslt ==  - 1) {
+            PyErr_Clear(); //Python sets one 
+            Fail(PyExc_RuntimeError, "Error sorting");
+        };
+        return  *this; //HA HA - Guido can't stop me!!!
+    };
+};
+
+#endif // PWOMSEQUENCE_H_INCLUDED_
diff --git a/8.x/mk/python/scxx/PWOMapping.h b/8.x/mk/python/scxx/PWOMapping.h
new file mode 100755 (executable)
index 0000000..dfaa66c
--- /dev/null
@@ -0,0 +1,141 @@
+/******************************************** 
+copyright 1999 McMillan Enterprises, Inc.
+www.mcmillan-inc.com
+ *********************************************/
+#if !defined(PWOMAPPING_H_INCLUDED_)
+#define PWOMAPPING_H_INCLUDED_
+
+#include "PWOBase.h"
+#include "PWOMSequence.h"
+
+class PWOMapping;
+
+class PWOMappingMmbr: public PWOBase {
+    PWOMapping &_parent;
+    PyObject *_key;
+  public:
+    PWOMappingMmbr(PyObject *obj, PWOMapping &parent, PyObject *key): PWOBase
+      (obj), _parent(parent), _key(key) {
+        Py_XINCREF(_key);
+    };
+    virtual ~PWOMappingMmbr() {
+        Py_XDECREF(_key);
+    };
+    PWOMappingMmbr &operator = (const PWOBase &other);
+};
+
+class PWOMapping: public PWOBase {
+  public:
+    PWOMapping(): PWOBase(PyDict_New()) {
+        LoseRef(_obj);
+    }
+    PWOMapping(const PWOMapping &other): PWOBase(other){}
+    ;
+    PWOMapping(PyObject *obj): PWOBase(obj) {
+        _violentTypeCheck();
+    };
+    virtual ~PWOMapping(){}
+    ;
+
+    virtual PWOMapping &operator = (const PWOMapping &other) {
+        GrabRef(other);
+        return  *this;
+    };
+    PWOMapping &operator = (const PWOBase &other) {
+        GrabRef(other);
+        _violentTypeCheck();
+        return  *this;
+    };
+    virtual void _violentTypeCheck() {
+        if (!PyMapping_Check(_obj)) {
+            GrabRef(0);
+            Fail(PyExc_TypeError, "Not a mapping");
+        }
+    };
+
+    //PyMapping_GetItemString
+    //PyDict_GetItemString
+    PWOMappingMmbr operator[](const char *key) {
+        // note: this PyMapping call creates a new reference
+        PyObject *rslt = PyMapping_GetItemString(_obj, (char*)key);
+        if (rslt == NULL)
+          PyErr_Clear();
+        Py_XDECREF(rslt);
+        PWOString _key(key);
+        return PWOMappingMmbr(rslt,  *this, _key);
+    };
+    //PyDict_GetItem
+    PWOMappingMmbr operator[](PyObject *key) {
+        PyObject *rslt = PyDict_GetItem(_obj, key);
+        //if (rslt == NULL)
+        //  Fail(PyExc_KeyError, "Key not found");
+        return PWOMappingMmbr(rslt,  *this, key);
+    };
+    //PyMapping_HasKey
+    bool hasKey(PyObject *key)const {
+        return PyMapping_HasKey(_obj, key) == 1;
+    };
+    //PyMapping_HasKeyString
+    bool hasKey(const char *key)const {
+        return PyMapping_HasKeyString(_obj, (char*)key) == 1;
+    };
+    //PyMapping_Length
+    //PyDict_Size
+    int len()const {
+        return PyMapping_Length(_obj);
+    };
+    //PyMapping_SetItemString
+    //PyDict_SetItemString
+    void setItem(const char *key, PyObject *val) {
+        int rslt = PyMapping_SetItemString(_obj, (char*)key, val);
+        if (rslt ==  - 1)
+          Fail(PyExc_RuntimeError, "Cannot add key / value");
+    };
+    //PyDict_SetItem
+    void setItem(PyObject *key, PyObject *val)const {
+        int rslt = PyDict_SetItem(_obj, key, val);
+        if (rslt ==  - 1)
+          Fail(PyExc_KeyError, "Key must be hashable");
+    };
+    //PyDict_Clear
+    void clear() {
+        PyDict_Clear(_obj);
+    };
+    //PyDict_DelItem
+    void delItem(PyObject *key) {
+        int rslt = PyMapping_DelItem(_obj, key);
+        if (rslt ==  - 1)
+          Fail(PyExc_KeyError, "Key not found");
+    };
+    //PyDict_DelItemString
+    void delItem(const char *key) {
+        int rslt = PyDict_DelItemString(_obj, (char*)key);
+        if (rslt ==  - 1)
+          Fail(PyExc_KeyError, "Key not found");
+    };
+    //PyDict_Items
+    PWOList items()const {
+        PyObject *rslt = PyMapping_Items(_obj);
+        if (rslt == 0)
+          Fail(PyExc_RuntimeError, "Failed to get items");
+        return LoseRef(rslt);
+    };
+    //PyDict_Keys
+    PWOList keys()const {
+        PyObject *rslt = PyMapping_Keys(_obj);
+        if (rslt == 0)
+          Fail(PyExc_RuntimeError, "Failed to get keys");
+        return LoseRef(rslt);
+    };
+    //PyDict_New - default constructor
+    //PyDict_Next
+    //PyDict_Values
+    PWOList values()const {
+        PyObject *rslt = PyMapping_Values(_obj);
+        if (rslt == 0)
+          Fail(PyExc_RuntimeError, "Failed to get values");
+        return LoseRef(rslt);
+    };
+};
+
+#endif // PWOMAPPING_H_INCLUDED_
diff --git a/8.x/mk/python/scxx/PWONumber.h b/8.x/mk/python/scxx/PWONumber.h
new file mode 100755 (executable)
index 0000000..b8e2882
--- /dev/null
@@ -0,0 +1,212 @@
+/******************************************** 
+copyright 1999 McMillan Enterprises, Inc.
+www.mcmillan-inc.com
+ *********************************************/
+#if !defined(PWONUMBER_H_INCLUDED_)
+#define PWONUMBER_H_INCLUDED_
+
+#include "PWOBase.h"
+#include "PWOSequence.h"
+
+#if defined(PY_LONG_LONG) && !defined(LONG_LONG)
+#define LONG_LONG PY_LONG_LONG
+#endif 
+
+class PWONumber: public PWOBase {
+  public:
+    PWONumber(): PWOBase(){}
+    ;
+    PWONumber(int i): PWOBase(PyInt_FromLong(i)) {
+        LoseRef(_obj);
+    }
+    PWONumber(long i): PWOBase(PyInt_FromLong(i)) {
+        LoseRef(_obj);
+    }
+    PWONumber(unsigned long i): PWOBase(PyLong_FromUnsignedLong(i)) {
+        LoseRef(_obj);
+    }
+#ifdef HAVE_LONG_LONG
+    PWONumber(LONG_LONG i): PWOBase(PyLong_FromLongLong(i)) {
+        LoseRef(_obj);
+    }
+#endif 
+    PWONumber(double d): PWOBase(PyFloat_FromDouble(d)) {
+        LoseRef(_obj);
+    }
+
+    PWONumber(const PWONumber &other): PWOBase(other){}
+    ;
+    PWONumber(PyObject *obj): PWOBase(obj) {
+        _violentTypeCheck();
+    };
+    virtual ~PWONumber(){}
+    ;
+
+    virtual PWONumber &operator = (const PWONumber &other) {
+        GrabRef(other);
+        return  *this;
+    };
+     /*virtual*/PWONumber &operator = (const PWOBase &other) {
+        GrabRef(other);
+        _violentTypeCheck();
+        return  *this;
+    };
+    virtual void _violentTypeCheck() {
+        if (!PyNumber_Check(_obj)) {
+            GrabRef(0);
+            Fail(PyExc_TypeError, "not a number");
+        }
+    };
+    //PyNumber_Absolute
+    PWONumber abs()const {
+        PyObject *rslt = PyNumber_Absolute(_obj);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Failed to get absolute value");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Add
+    PWONumber operator + (const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Add(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for +");
+        return LoseRef(rslt);
+    };
+    //PyNumber_And
+    PWONumber operator &(const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_And(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for &");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Coerce
+    //PyNumber_Divide
+    PWONumber operator / (const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Divide(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for /");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Divmod
+    PWOSequence divmod(const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Divmod(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for divmod");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Float
+    operator double()const {
+        PyObject *F = PyNumber_Float(_obj);
+        if (F == NULL)
+          Fail(PyExc_TypeError, "Cannot convert to double");
+        double r = PyFloat_AS_DOUBLE(F);
+        Py_DECREF(F);
+        return r;
+    };
+    /* // no easy, safe way to do this 
+    operator float () const {
+    double rslt = (double) *this;
+    return (float) rslt;
+    }; */
+    //PyNumber_Int
+    operator long()const {
+        PyObject *Int = PyNumber_Int(_obj);
+        if (Int == NULL)
+          Fail(PyExc_TypeError, "can't convert to int");
+        long r = PyInt_AsLong(_obj);
+        if (r ==  - 1)
+          FailIfPyErr();
+        return r;
+    };
+    operator int()const {
+        long rslt = (long) *this;
+        if (rslt > INT_MAX)
+          Fail(PyExc_ValueError, "int too large to convert to C int");
+        return (int)rslt;
+    };
+    //PyNumber_Invert
+    PWONumber operator ~()const {
+        PyObject *rslt = PyNumber_Invert(_obj);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper type for ~");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Long
+#ifdef HAVE_LONG_LONG
+    operator LONG_LONG()const {
+        PyObject *Long = PyNumber_Long(_obj);
+        if (Long == NULL)
+          Fail(PyExc_TypeError, "can't convert to long int");
+        LONG_LONG r = PyLong_AsLongLong(Long);
+        if (r ==  - 1 && PyErr_Occurred() != NULL)
+          Fail(PyExc_ValueError, "long int too large to convert to C long long")
+            ;
+        Py_DECREF(Long);
+        return r;
+    };
+#endif 
+    //PyNumber_Lshift
+    PWONumber operator << (const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Lshift(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for <<");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Multiply
+    PWONumber operator *(const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Multiply(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for *");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Negative
+    PWONumber operator - ()const {
+        PyObject *rslt = PyNumber_Negative(_obj);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper type for unary -");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Or
+    PWONumber operator | (const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Or(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for |");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Positive
+    PWONumber operator + ()const {
+        PyObject *rslt = PyNumber_Positive(_obj);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper type for unary +");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Remainder
+    PWONumber operator % (const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Remainder(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for %");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Rshift
+    PWONumber operator >> (const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Rshift(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for >>");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Subtract
+    PWONumber operator - (const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Subtract(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for -");
+        return LoseRef(rslt);
+    };
+    //PyNumber_Xor
+    PWONumber operator ^ (const PWONumber &rhs)const {
+        PyObject *rslt = PyNumber_Xor(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for ^");
+        return LoseRef(rslt);
+    };
+};
+
+#endif //PWONUMBER_H_INCLUDED_
diff --git a/8.x/mk/python/scxx/PWOSequence.h b/8.x/mk/python/scxx/PWOSequence.h
new file mode 100755 (executable)
index 0000000..3348ec5
--- /dev/null
@@ -0,0 +1,182 @@
+/******************************************** 
+copyright 1999 McMillan Enterprises, Inc.
+www.mcmillan-inc.com
+ *********************************************/
+#if !defined(PWOSEQUENCE_H_INCLUDED_)
+#define PWOSEQUENCE_H_INCLUDED_
+
+#include "PWOBase.h"
+
+class PWOSequence: public PWOBase {
+  public:
+    PWOSequence(): PWOBase(){}
+    ;
+    PWOSequence(const PWOSequence &other): PWOBase(other){}
+    ;
+    PWOSequence(PyObject *obj): PWOBase(obj) {
+        _violentTypeCheck();
+    };
+    virtual ~PWOSequence(){}
+
+    virtual PWOSequence &operator = (const PWOSequence &other) {
+        GrabRef(other);
+        return  *this;
+    };
+     /*virtual*/PWOSequence &operator = (const PWOBase &other) {
+        GrabRef(other);
+        _violentTypeCheck();
+        return  *this;
+    };
+    virtual void _violentTypeCheck() {
+        if (!PySequence_Check(_obj)) {
+            GrabRef(0);
+            Fail(PyExc_TypeError, "Not a sequence");
+        }
+    };
+    //PySequence_Concat
+    PWOSequence operator + (const PWOSequence &rhs)const {
+        PyObject *rslt = PySequence_Concat(_obj, rhs);
+        if (rslt == NULL)
+          Fail(PyExc_TypeError, "Improper rhs for +");
+        return LoseRef(rslt);
+    };
+    //PySequence_Count
+    int count(const PWOBase &value)const {
+        int rslt = PySequence_Count(_obj, value);
+        if (rslt ==  - 1)
+          Fail(PyExc_RuntimeError, "failure in count");
+        return rslt;
+    };
+    //PySequence_GetItem  ##lists - return PWOListMmbr (mutable) otherwise just a PWOBase
+    PWOBase operator[](int i)const {
+        //can't be virtual
+        PyObject *o = PySequence_GetItem(_obj, i);
+        if (o == 0)
+          Fail(PyExc_IndexError, "index out of range");
+        return LoseRef(o);
+    };
+    //PySequence_GetSlice
+    //virtual PWOSequence& operator [] (PWSlice& x) {...};
+    PWOSequence getSlice(int lo, int hi)const {
+        PyObject *o = PySequence_GetSlice(_obj, lo, hi);
+        if (o == 0)
+          Fail(PyExc_IndexError, "could not obtain slice");
+        return LoseRef(o);
+    };
+    //PySequence_In
+    bool in(const PWOBase &value)const {
+        int rslt = PySequence_In(_obj, value);
+        if (rslt ==  - 1)
+          Fail(PyExc_RuntimeError, "problem in in");
+        return (rslt == 1);
+    };
+    //PySequence_Index
+    int index(const PWOBase &value)const {
+        int rslt = PySequence_Index(_obj, value);
+        if (rslt ==  - 1)
+          Fail(PyExc_IndexError, "value not found");
+        return rslt;
+    };
+    //PySequence_Length
+    int len()const {
+        return PySequence_Length(_obj);
+    };
+    //PySequence_Repeat
+    PWOSequence operator *(int count)const {
+        PyObject *rslt = PySequence_Repeat(_obj, count);
+        if (rslt == NULL)
+          Fail(PyExc_RuntimeError, "sequence repeat failed");
+        return LoseRef(rslt);
+    };
+    //PySequence_Tuple
+};
+
+class PWOList;
+
+class PWOTuple: public PWOSequence {
+  public:
+    PWOTuple(int sz = 0): PWOSequence(PyTuple_New(sz)) {
+        LoseRef(_obj);
+    }
+    PWOTuple(const PWOTuple &other): PWOSequence(other){}
+    PWOTuple(PyObject *obj): PWOSequence(obj) {
+        _violentTypeCheck();
+    }
+    PWOTuple(const PWOList &list);
+    virtual ~PWOTuple(){}
+    ;
+
+    virtual PWOTuple &operator = (const PWOTuple &other) {
+        GrabRef(other);
+        return  *this;
+    };
+     /*virtual*/PWOTuple &operator = (const PWOBase &other) {
+        GrabRef(other);
+        _violentTypeCheck();
+        return  *this;
+    };
+    virtual void _violentTypeCheck() {
+        if (!PyTuple_Check(_obj)) {
+            GrabRef(0);
+            Fail(PyExc_TypeError, "Not a Python Tuple");
+        }
+    };
+    void setItem(int ndx, PWOBase &val) {
+        int rslt = PyTuple_SetItem(_obj, ndx, val);
+        val.disOwn(); //when using PyTuple_SetItem, he steals my reference
+        if (rslt ==  - 1)
+          Fail(PyExc_IndexError, "Index out of range");
+    };
+};
+
+class PWOString: public PWOSequence {
+  public:
+    PWOString(): PWOSequence(){}
+    ;
+    PWOString(const char *s): PWOSequence(PyString_FromString((char*)s)) {
+        LoseRef(_obj);
+    }
+    PWOString(const char *s, int sz): PWOSequence(PyString_FromStringAndSize(
+      (char*)s, sz)) {
+        LoseRef(_obj);
+    }
+    PWOString(const PWOString &other): PWOSequence(other){}
+    ;
+    PWOString(PyObject *obj): PWOSequence(obj) {
+        _violentTypeCheck();
+    };
+    PWOString(const PWOBase &other): PWOSequence(other) {
+        _violentTypeCheck();
+    };
+    virtual ~PWOString(){}
+    ;
+
+    virtual PWOString &operator = (const PWOString &other) {
+        GrabRef(other);
+        return  *this;
+    };
+    PWOString &operator = (const PWOBase &other) {
+        GrabRef(other);
+        _violentTypeCheck();
+        return  *this;
+    };
+    virtual void _violentTypeCheck() {
+        if (!PyString_Check(_obj)) {
+            GrabRef(0);
+            Fail(PyExc_TypeError, "not a Python string");
+        }
+    };
+    operator const char *()const {
+        return PyString_AsString(_obj);
+    };
+    int size()const {
+        return PyString_GET_SIZE(_obj);
+    };
+    static PWOString format(const PWOString &fmt, PWOTuple &args) {
+        PyObject *rslt = PyString_Format(fmt, args);
+        if (rslt == NULL)
+          Fail(PyExc_RuntimeError, "string format failed");
+        return LoseRef(rslt);
+    };
+};
+#endif // PWOSEQUENCE_H_INCLUDED_
diff --git a/8.x/mk/python/scxx/README.txt b/8.x/mk/python/scxx/README.txt
new file mode 100755 (executable)
index 0000000..9696ef1
--- /dev/null
@@ -0,0 +1,106 @@
+Overview
+========
+
+ SCXX (Simplified CXX) is a lightweight C++ wrapper for dealing with PyObjects.
+ It is inspired by Paul Dubois' CXX (available from LLNL), but is much simpler.
+ It does not use templates, so almost any compiler should work. It does not try
+ to hide things like the Python method tables, or the init function. In fact, it
+ only covers wrapping the most common PyObjects. No extra support is added (for
+ example, you'll only get STL support for Python sequences from CXX).
+
+ It lets you write C++ that looks a lot more like Python than the C API. Reference
+ counts are handled automatically. It has not been optimized - it generally uses
+ the highest possible level of the Python C API.
+
+Classes
+=======
+ PWOBase       Base class; wraps any PyObject *
+ PWONumber     Uses PyNumber_xxx calls. Automatically does the right thing.
+ PWOSequence    Base class for all Python sequences. 
+  PWOTuple     
+  PWOString
+  PWOList
+ PWOMapping    Wraps a dictionary
+
+internal
+--------
+ PWOMappingMmbr        Used to give PWOMappings Python (reference) semantics.
+ PWOListMmbr   Used to give PWOLists Python (reference) semantics.
+
+error
+-----
+ PWException   A C++ class that holds appropriate Python exception info.
+
+General Notes
+=============
+
+ These classes can be used to create new Python objects, or wrap existing ones.
+
+ Wrapping an existing one forces a typecheck (except for PWOBase, which doesn't
+ care). So "PWOMapping dict(d);" will throw an exception if d is not a Python
+ Mapping object (a set with one member - dicts). Or you can use the Python C API
+ by casting to a PyObject * (e.g. "Pyxxx_Check((PyObject *)x)"). 
+
+ Since errors are normally reported through exceptions, use code like this:
+
+  try {
+    //....
+  }
+  catch(PWException e) {
+    return e.toPython();
+  }
+
+ To signal errors in your own code, use:
+  throw PWException(PyExc_xxxx, msg);
+
+ That is: throw a stack-based instance (not heap based), and give it the appropriate
+ PyExc_xxx type and a string that the Python exception can show.
+
+ To return a PWOxxx wrapped (or created) instance to Python, use disOwn():
+
+  return PWONumber(7.0).disOwn();
+
+ Without the disOwn(), the object would be deallocated before Python can get it.
+
+ Note that the PWOxxx classes are generally designed to be created on the stack. The
+ corresponding PyObject is on the heap. When the PWOxxx instance goes out of scope, 
+ the PyObject is automatically decreffed (unless you've used disOwn()).
+
+ See the MkWrap (http://www.equi4.com/metakit/mk4py/mkwrap/) project for extensive 
+ use of SCXX. Just don't confuse the PWOxxx classes (which _wrap_ Python objects) and 
+ the classes exposed by MkWrap (which are _both_ C++ objects _and_ Python objects).
+
+Why SCXX
+========
+
+ I realize that a lot of effort has gone into CXX and some of the initiatives on
+ the C++ SIG. I applaud those efforts; indeed, SCXX was inspired by CXX. But CXX
+ uses fairly up to date features of C++, and wouldn't compile with most of the
+ compilers I have, (I have to keep old versions around to support clients who still
+ use them). On the one where it worked, it produced bloated code (because of the 
+ way the compiler handles templates).
+
+ For my purposes, I really only wanted one thing: wrap Python objects, and take
+ care of the refcounts. The result is lightweight, and has the great advantage 
+ (like CXX) that using PyObjects in C++ looks very much like using them in Python.
+
+Instructions for use
+====================
+
+ Point to the installation directory with a -I directive.
+ Include PWOImp.cpp in your make.
+
+License
+=======
+
+ No restrictions on usage, modification or redistribution, as long as the copyright
+ notice is maintained. No warranty whatsoever.
+
+Contact
+=======
+
+ Gordon McMillan (McMillan Enterprises, Inc.) gmcm@hypernet.com.
+
+
\ No newline at end of file
diff --git a/8.x/mk/python/setup.py b/8.x/mk/python/setup.py
new file mode 100755 (executable)
index 0000000..0fbaff0
--- /dev/null
@@ -0,0 +1,197 @@
+from distutils.core import setup, Extension, Command
+from distutils.command.build import build
+from distutils.command.build_ext import build_ext
+from distutils.command.config import config
+from distutils.msvccompiler import MSVCCompiler
+from distutils import sysconfig
+import string
+import sys
+
+mkobjs = ['column', 'custom', 'derived', 'fileio', 'field',
+          'format', 'handler', 'persist', 'remap', 'std',
+          'store', 'string', 'table', 'univ', 'view', 'viewx']
+
+class config_mk(config):
+    
+    def run(self):
+        # work around bug in Python 2.2-supplied check_header, fixed
+        # in Python 2.3; body needs to be a valid, non-zero-length string
+        if self.try_cpp(body="/* body */", headers=['unicodeobject.h'],
+                        include_dirs=[sysconfig.get_python_inc()]):
+            build = self.distribution.reinitialize_command('build_ext')
+            build.define = 'HAVE_UNICODEOBJECT_H'
+        # trust that mk4.h provides the correct HAVE_LONG_LONG value,
+        # since Mk4py doesn't #include "config.h"
+
+class build_mk(build):
+    def initialize_options(self):
+        # build in builds directory by default, unless specified otherwise
+        build.initialize_options(self)
+        self.build_base = '../builds'
+
+class build_mkext(build_ext):
+    def finalize_options(self):
+        self.run_command('config')
+
+        # force use of C++ compiler (helps on some platforms)
+        import os
+        cc = os.environ.get('CXX', sysconfig.get_config_var('CXX'))
+        if not cc:
+            cc = sysconfig.get_config_var('CCC') # Python 1.5.2
+        if cc:
+            os.environ['CC'] = cc
+
+        build_ext.finalize_options(self)
+
+    def build_extension(self, ext):
+        # work around linker problem with MacPython 2.3
+        if sys.platform == 'darwin':
+            try:
+                self.compiler.linker_so.remove("-Wl,-x")
+            except: pass
+        # work around linker problem with Linux, Python 2.2 and earlier:
+        # despite setting $CC above, still uses Python compiler
+        if sys.platform == 'linux2':
+            try:
+                ext.libraries.append("stdc++")
+            except: pass
+        if ext.name == "Mk4py":
+            if isinstance(self.compiler, MSVCCompiler):
+                suffix = '.obj'
+                if self.debug:
+                    prefix = '../builds/msvc60/mklib/Debug/'
+                else:
+                    prefix = '../builds/msvc60/mklib/Release/'
+            else:
+                suffix = '.o'
+                prefix = '../builds/'
+            for i in range(len(ext.extra_objects)):
+                nm = ext.extra_objects[i]
+                if nm in mkobjs:
+                    if string.find(nm, '.') == -1:
+                        nm = nm + suffix
+                    nm = prefix + nm
+                    ext.extra_objects[i] = nm
+        build_ext.build_extension(self, ext)
+    
+class test_regrtest(Command):
+    # Original version of this class posted
+    # by Berthold Hoellmann to distutils-sig@python.org
+    description = "test the distribution prior to install"
+
+    user_options = [
+        ('build-base=', 'b',
+         "base build directory (default: 'build.build-base')"),
+        ('build-purelib=', None,
+         "build directory for platform-neutral distributions"),
+        ('build-platlib=', None,
+         "build directory for platform-specific distributions"),
+        ('build-lib=', None,
+         "build directory for all distribution (defaults to either " +
+         "build-purelib or build-platlib"),
+        ('test-dir=', None,
+         "directory that contains the test definitions"),
+        ('test-options=', None,
+         "command-line options to pass to test.regrtest")
+        ]
+
+    def initialize_options(self):
+        self.build_base = None
+        # these are decided only after 'build_base' has its final value
+        # (unless overridden by the user or client)
+        self.build_purelib = None
+        self.build_platlib = None
+        self.test_dir = 'test'
+        self.test_options = None
+        
+    def finalize_options(self):
+        build = self.distribution.get_command_obj('build')
+        build_options = ('build_base', 'build_purelib', 'build_platlib')
+        for option in build_options:
+            val = getattr(self, option)
+            if val:
+                setattr(build, option, getattr(self, option))
+        build.ensure_finalized()
+        for option in build_options:
+            setattr(self, option, getattr(build, option))
+
+    def run(self):
+        
+        # Invoke the 'build' command to "build" pure Python modules
+        # (ie. copy 'em into the build tree)
+        self.run_command('build')
+
+        # remember old sys.path to restore it afterwards
+        old_path = sys.path[:]
+
+        # extend sys.path
+        sys.path.insert(0, self.build_purelib)
+        sys.path.insert(0, self.build_platlib)
+        sys.path.insert(0, self.test_dir)
+        
+        # Use test.regrtest, unlike the original version of this class
+        import test.regrtest
+
+       # jcw 2004-04-26 - why do I need to add these here to find the tests?
+       #import leaktest - not very portable
+       import test_inttypes
+       import test_stringtype
+       #import test_hash - doesn't work
+       # jcw end
+
+        test.regrtest.STDTESTS = []
+        test.regrtest.NOTTESTS = []
+
+        if self.test_options:
+            sys.argv[1:] = string.split(self.test_options, ' ')
+        else:
+            del sys.argv[1:]
+
+        # remove stale modules
+        del sys.modules['metakit']
+        try:
+            del sys.modules['Mk4py']
+        except:
+            pass
+
+        self.announce("running tests")
+        test.regrtest.main(testdir=self.test_dir)
+
+        # restore sys.path
+        sys.path = old_path[:]
+
+#try:
+#    import metakit
+#except:
+#    metakit = sys.modules['metakit']
+
+setup(name             = "metakit",
+      version          = "2.4.9.7",
+      description      = "Python bindings to the Metakit database library",
+      #long_description = metakit.__doc__,
+      author           = "Gordon McMillan / Jean-Claude Wippler",
+      author_email     = "jcw@equi4.com",
+      url              = "http://www.equi4.com/metakit/python.html",
+      maintainer       = "Jean-Claude Wippler",
+      maintainer_email = "jcw@equi4.com",
+      license         = "X/MIT style, see: http://www.equi4.com/mklicense.html",
+      keywords         = ['database'],
+      py_modules       = ['metakit'],
+      cmdclass         = {'build': build_mk, 'build_ext': build_mkext,
+                          'test': test_regrtest, 'config': config_mk},
+      ext_modules      = [Extension("Mk4py",
+                                    sources=["PyProperty.cpp",
+                                             "PyRowRef.cpp",
+                                             "PyStorage.cpp",
+                                             "PyView.cpp",
+                                             "scxx/PWOImp.cpp",
+                                             ],
+                                    include_dirs=["scxx",
+                                                  "../include"],
+                                    extra_objects=mkobjs,
+                                    )]
+      )
+
+## Local Variables:
+## compile-command: "python setup.py build -b ../builds"
+## End:
diff --git a/8.x/mk/python/test/.cvsignore b/8.x/mk/python/test/.cvsignore
new file mode 100644 (file)
index 0000000..0d20b64
--- /dev/null
@@ -0,0 +1 @@
+*.pyc
diff --git a/8.x/mk/python/test/all.py b/8.x/mk/python/test/all.py
new file mode 100644 (file)
index 0000000..5391f01
--- /dev/null
@@ -0,0 +1,39 @@
+# all.py -- Run all tests for the Metakit Python bindings
+# $Id: all.py 1230 2007-03-09 15:58:53Z jcw $
+# This is part of Metakit, see http://www.equi4.com/metakit/
+
+import sys
+import os
+import test.regrtest
+
+def canonicalPath(path):
+    """Do everything but resolve symbolic links to create an absolute path."""
+    return os.path.abspath(os.path.expanduser(os.path.expandvars(path)))
+
+# from Python 2.2's test.regrtest module
+def findtestdir():
+    if __name__ == '__main__':
+        file = sys.argv[0]
+    else:
+        file = __file__
+    testdir = os.path.dirname(file) or os.curdir
+    return testdir
+
+testdir = canonicalPath(findtestdir())
+
+# Make sure 'import metakit' works, assuming metakit modules are
+# in the directory above that containing this script.
+sys.path.insert(0, os.path.dirname(testdir))
+
+# Make sure we're using modules from the builds directory, assuming
+# that's the current directory at the time we're run.  (While this
+# directory is probably named 'test', it isn't a module, so it
+# shouldn't interfere with references to the Python 'test' module).
+sys.path.insert(0, os.getcwd())
+
+# Don't run the standard Python tests, just run Metakit tests
+test.regrtest.STDTESTS = []
+test.regrtest.NOTTESTS = []
+
+# Run all tests
+test.regrtest.main(testdir=testdir)
diff --git a/8.x/mk/python/test/mktestsupport.py b/8.x/mk/python/test/mktestsupport.py
new file mode 100644 (file)
index 0000000..acdeab7
--- /dev/null
@@ -0,0 +1,173 @@
+# mktestsupport.py -- Support code used by multiple test modules
+# $Id: mktestsupport.py 1230 2007-03-09 15:58:53Z jcw $
+# This is part of Metakit, see http://www.equi4.com/metakit/
+
+from test.test_support import TestFailed, verbose
+import metakit
+import sys
+import string
+
+# for overflow testing
+MAXINT = sys.maxint
+MININT = -MAXINT - 1
+MAXLONGLONG = 2**63 - 1
+MINLONGLONG = -2**63
+MAXULONGLONG = 2**64 - 1
+
+# Check for int/long integration (should fail in Python 2.2, pass in 2.3)
+try:
+    MAXLONGLONG = int(MAXLONGLONG)
+    int_long_integrated = True
+    int_long_error = OverflowError
+except OverflowError: # long int too large to convert to int
+    int_long_integrated = False
+    int_long_error = TypeError
+
+# Check for Unicode support (should fail in Python 1.5.2 or --disable-unicode, pass in 1.6)
+try:
+    UnicodeType = type(unicode(''))
+except NameError: # no Unicode support
+    UnicodeType = None
+    unicode = None
+    
+class Failure:
+    """Keeps track of failures as they happen, but doesn't die on the first
+    one unless it's unrecoverable.  If failure_count > 0 when script
+    finishes, raise TestFailed."""
+
+    def __init__(self):
+        self.failure_count = 0
+    
+    def fail(self, op, args, err=None, expected=None, actual=None):
+        print 'FAIL:', op, args
+        print '     ',
+        if err is not None: print err,
+        if actual is not None: print 'got', actual, actual.__class__,
+        if expected is not None: print 'expected', expected,
+        print
+        self.failure_count = self.failure_count + 1
+
+    def assess(self):
+        if self.failure_count > 0:
+            raise TestFailed(
+                '%d failures; run in verbose mode for details' % self.failure_count)
+
+class ViewTester:
+    """Inserts rows into view and Python array"""
+    
+    def __init__(self, description):
+        self.storage = metakit.storage()
+        self.v = self.storage.getas(description)
+        self.arr = []
+        self.failure = Failure()
+        self.fail = self.failure.fail
+        self.columns = map(lambda c: string.split(c, ':')[0], string.split(description[string.index(description, '[') + 1:-1], ','))
+
+    def dump_view(self):
+        metakit.dump(self.v, 'VIEW CONTENTS:')
+
+    def checklen(self, args):
+        alen = len(self.arr)
+        vlen = len(self.v)
+        if alen != vlen:
+            self.fail('append', args, 'view length mismatch',
+                      actual=vlen, expected=alen)
+            try:
+                print 'ARRAY CONTENTS:'
+                for arow in self.arr: print arow
+                self.dump_view()
+            except: pass
+            raise TestFailed('unexpected number of rows in view, aborting; run in verbose mode for details')
+
+    def _append(self, args):
+        self.arr.append(args)
+
+    def insert(self, *args, **kw):
+        if kw:
+            if args:
+                raise TestFailed("can't have both positional and keyword arguments")
+            args = kw
+        try:
+            self.v.append(args)
+            self._append(args)
+        except Exception, e:
+            self.fail('append', args, actual=e)
+        try:
+            self.checklen(args)
+        except TestFailed:
+            raise
+        except Exception, e:
+            self.fail('append', args, 'spurious', actual=e)
+
+    def reject(self, exception_class=Exception, **args):
+        try:
+            ix = self.v.append(args)
+            self.fail('append', args, 'succeeded', expected=exception_class)
+            self.v.delete(ix)
+        except Exception, e:
+            if isinstance(e, exception_class):
+                if verbose:
+                    print 'PASS: rejected', args
+                    print '      as expected <%s> %s' % (e.__class__, e)
+            else:
+                self.fail('append', args, expected=exception_class, actual=e)
+        try:
+            self.checklen(args)
+        except TestFailed:
+            raise
+        except Exception, e:
+            self.fail('append', args, 'spurious', actual=e)
+
+    def finished(self):
+        if verbose:
+            self.dump_view()
+
+        # compare view with array
+        for arow, vrow in zip(self.arr, self.v):
+            failed = False
+            for f in arow.keys():
+                try:
+                    vf = getattr(vrow, f)
+                    af = arow[f]
+                    # Fix up Unicode
+                    if type(af) == UnicodeType:
+                        vf = unicode(vf, 'utf-8')
+                    if af == vf:
+                        continue
+                    # Perform the same implicit coercion as Mk4py should
+                    if type(af) != type(vf):
+                        try:
+                            af = type(vf)(af)
+                            if af == vf:
+                                continue
+                        except:
+                            pass
+                    # If we get here, we got an exception or the values didn't match
+                    # even with coercion
+                    failed = True
+                    self.fail('%s access' % f, arow, expected=af, actual=vf)
+                except Exception, e:
+                    failed = True
+                    self.fail('%s access' % f, arow, expected=arow[f], actual=e)
+            if not failed:
+                if verbose:
+                    print 'PASS: retrieved', arow
+
+        self.failure.assess()
+
+class HashedViewTester(ViewTester):
+    """Inserts rows into hashed view and Python array (where appropriate)"""
+
+    def __init__(self, description, numkeys):
+        ViewTester.__init__(self, description)
+        hv = self.storage.getas('hv[_H:I,_R:I]')
+        self.v = self.v.hash(hv, numkeys)
+
+    def _append(self, args):
+        if not hasattr(args, 'keys'): # operator module is broken in Python 2.3
+            argdict = {}
+            for i in range(len(args)):
+                argdict[self.columns[i]] = args[i]
+            args = argdict
+        if args not in self.arr:
+            self.arr.append(args)
diff --git a/8.x/mk/python/test/test_hash.py b/8.x/mk/python/test/test_hash.py
new file mode 100644 (file)
index 0000000..22b6d01
--- /dev/null
@@ -0,0 +1,16 @@
+# test_hash.py -- Test Metakit Python bindings for hashed views
+# $Id: test_hash.py 1230 2007-03-09 15:58:53Z jcw $
+# This is part of Metakit, see http://www.equi4.com/metakit/
+
+from mktestsupport import *
+
+works = 't[z:I,pizza:S]', 'pizza'
+fails = 't[z:I,a:S]', 'a'
+
+for struc, field in (works, fails):
+    v = HashedViewTester(struc, 1)
+    for i in range(4):
+        v.insert(1, 'A')
+    for i in range(4):
+        v.insert(**{field: 'A', 'z': 1})
+    v.finished()
diff --git a/8.x/mk/python/test/test_inttypes.py b/8.x/mk/python/test/test_inttypes.py
new file mode 100644 (file)
index 0000000..0522364
--- /dev/null
@@ -0,0 +1,63 @@
+# test_inttypes.py -- Test Metakit Python bindings for integral types
+# $Id: test_inttypes.py 1230 2007-03-09 15:58:53Z jcw $
+# This is part of Metakit, see http://www.equi4.com/metakit/
+
+from mktestsupport import *
+
+v = ViewTester('test[intf:I,longf:L]')
+
+# defaults
+v.insert(intf=0, longf=0)
+
+# int field
+v.insert(intf=1, longf=0)
+v.insert(intf=-5, longf=0)
+v.insert(intf=MAXINT, longf=0)
+v.insert(intf=MININT, longf=0)
+v.reject(int_long_error, intf=MAXINT + 1, longf=0)
+v.reject(int_long_error, intf=MININT - 1, longf=0)
+if int_long_integrated:
+    v.reject(OverflowError, intf=MAXLONGLONG, longf=0)
+    v.reject(OverflowError, intf=MINLONGLONG, longf=0)
+
+# long field
+v.insert(intf=0, longf=-1L)
+v.insert(intf=0, longf=5L)
+v.insert(intf=0, longf=MAXLONGLONG)
+v.insert(intf=0, longf=MINLONGLONG)
+v.reject(ValueError, intf=0, longf=MAXULONGLONG)
+v.reject(ValueError, intf=0, longf=MAXLONGLONG + 1)
+v.reject(ValueError, intf=0, longf=MAXULONGLONG)
+v.reject(ValueError, intf=0, longf=MINLONGLONG - 1)
+
+# mixed valid int/long
+v.insert(intf=1, longf=2)
+v.insert(intf=-5, longf=-2**30)
+
+# implicit conversion to int
+v.insert(intf=14L, longf=0)
+v.insert(intf=-30L, longf=0)
+v.insert(intf=45.0, longf=0)
+v.insert(intf=21.4, longf=0)
+v.reject(int_long_error, intf=float(MAXINT + 1), longf=0)
+v.reject(int_long_error, intf=float(MININT - 1), longf=0)
+v.reject(TypeError, intf='215', longf=0)
+v.reject(TypeError, intf='-318.19', longf=0)
+v.reject(TypeError, intf=str(MAXINT + 1), longf=0)
+
+# implicit conversion to long
+v.insert(intf=0, longf=278)
+v.insert(intf=0, longf=-213)
+v.insert(intf=0, longf=95.0)
+v.insert(intf=0, longf=27.3)
+v.reject(ValueError, intf=0, longf=float(2 * MAXLONGLONG))
+v.reject(ValueError, intf=0, longf=float(2 * MINLONGLONG))
+v.reject(TypeError, intf=0, longf=str(MAXLONGLONG))
+v.reject(TypeError, intf=0, longf=str(MINLONGLONG))
+v.reject(TypeError, intf=0, longf='-21.39')
+v.reject(TypeError, intf=0, longf=str(MAXULONGLONG))
+
+# XXX should repeat with assignment instead of appending
+# XXX test v.select()
+
+v.finished()
diff --git a/8.x/mk/python/test/test_stringtype.py b/8.x/mk/python/test/test_stringtype.py
new file mode 100644 (file)
index 0000000..16a9406
--- /dev/null
@@ -0,0 +1,31 @@
+# test_stringtype.py -- Test Metakit Python bindings for string type
+# $Id: test_stringtype.py 1230 2007-03-09 15:58:53Z jcw $
+# This is part of Metakit, see http://www.equi4.com/metakit/
+
+from mktestsupport import *
+
+v = ViewTester('test[a:S,b:S]')
+
+# defaults
+v.insert(a='', b='')
+
+# ASCII strings
+v.insert(a='asdasdfasdfasdfsa', b='!@*%$#@#$%^&*()')
+v.reject(TypeError, a=3, b='')
+
+# Null termination
+v.reject(ValueError, a='\0', b='hi\0')
+v.reject(ValueError, a='abcdabcdabcd\0hi', b='lo')
+v.reject(ValueError, a='\0\0hi', b='lo')
+
+# Unicode and UTF-8 strings
+if UnicodeType:
+    v.insert(a=unicode('hi there', 'utf-8'), b='hi')
+    v.insert(a=unicode('\xe2\x82\xac', 'utf-8'), b='hi')
+    v.insert(a=unicode('Sample\xe2\x82\xacTesting', 'utf-8'), b='')
+    v.reject(ValueError, a=unicode('Sample\0blahblah', 'utf-8'), b='yo')
+
+# Non-ASCII 8-bit strings
+v.insert(a='', b='\xe2\x82\xacHi there')
+
+v.finished()
diff --git a/8.x/mk/python/test/test_unittest.py b/8.x/mk/python/test/test_unittest.py
new file mode 100644 (file)
index 0000000..d4ee4eb
--- /dev/null
@@ -0,0 +1,625 @@
+import unittest, Mk4py, sys
+from test import test_support
+from mktestsupport import *
+
+class Dummy:
+    def __init__(self, **kws):
+        self.__dict__.update(kws)
+
+try:
+    # new-style class declaration; fails on Python 2.1 and earlier
+    new_dummy = """class NewDummy(object):
+    def __init__(self, **kws):
+        self.__dict__.update(kws)"""
+    eval(compile(new_dummy, '', 'single'))
+except:
+    NewDummy = None
+
+class SequenceCounter:
+    def __init__(self, initial_value):
+        self.beginning = self.count = initial_value
+
+    def begin(self):
+        self.beginning = self.count
+
+    # ideally, this wants to be a generator...
+    # but then we'd have a more complex interface, and lose compatibility with
+    # older Python versions
+    def __call__(self):
+        self.count += 1
+        return self.count - 1
+        
+##class StorageTestCase(unittest.TestCase):
+    #storge(), storage(file), storage(fnm, rw=[0,1,2])
+    #getas
+    #view
+    #rollback
+    #commit
+    #aside
+    #description
+    #contents
+    #autocommit
+    #load
+    #save
+##    def testX(self):
+##        pass
+
+#class WrapTestCase(unittest.TestCase):
+    #wrap(seq, props, usetuples=0) -> RO view
+    #pass
+
+class ViewerTestCase(unittest.TestCase):
+    def setUpViews(self):
+        self.s = s = Mk4py.storage()
+        self.v0 = s.getas('v0[s:S,i:I]')
+        self.v1 = s.getas('v1[s:S,f:D]')
+        self.v2 = s.getas('v2[i:I,b:M]')
+        for vals in [('a',1),('b',2),('c',3)]:
+            self.v0.append(vals)
+        for vals in [('c',1.0),('b',2.0),('a',3.0)]:
+            self.v1.append(vals)
+        for vals in [(2,'\2'),(3,'\3'),(4,'\4')]:
+            self.v2.append(vals)
+        t = self.v1.rename('s', 't')
+        self.p0 = t.product(self.v0)
+        self.g0 = self.p0.groupby(self.p0.t, self.p0.f, 'details')
+        self.f0 = self.g0.flatten(self.g0.details)
+        self.f1 = self.f0[3:]
+        self.m0 = self.f1.copy()
+        def f(row):
+            row.i = row.i + 1
+        self.m0.map(f)
+            
+    def setUp(self):
+        self.setUpViews()
+        self.v0 = self.v0.unique()
+        # unique sorts, so v1 needs to be put back in reverse order
+        self.v1 = self.v1.unique().sortrev([self.v1.s],[self.v1.s])
+        self.v2 = self.v2.unique()
+        self.p0 = self.p0.unique()
+        
+    def testStructure(self):
+        proplist = self.v0.structure()
+        self.assertEqual(type(proplist), type([]))
+        self.assertEqual(len(proplist), 2)
+        propdict = self.v0.properties()
+        self.assertEqual(type(propdict), type({}))
+        self.assertEqual(len(propdict), 2)
+        for prop in proplist:
+            prop2 = propdict[prop.name]
+            self.assertEqual(prop2.name, prop.name)
+            self.assertEqual(prop2.type, prop.type)
+            self.assertEqual(prop2.id, prop.id)
+
+    def testSimple(self):
+        self.assertEqual(len(self.v0),3)
+        self.assertEqual(self.v0[0].s, 'a')
+        self.assertEqual(self.v0[0].i, 1)
+        v1 = self.v0[1:]
+        self.assertEqual(len(v1), 2)
+        self.assertEqual(v1[0].s, 'b')
+        self.assertEqual(v1[0].i, 2)
+        
+    def testFind(self):
+        self.assertEqual(self.v0.find(s='c'), 2)
+        self.assertEqual(self.v0.find(i=2), 1)
+        self.assertEqual(self.v0.find(s='z'), -1)
+        
+    def testSearch(self):
+        #search - v0 is ordered on  s 
+        self.assertEqual(self.v0.search(s='c'), 2)
+        self.assertEqual(self.v0.search(s='b'), 1)
+        self.assertEqual(self.v0.search(s='a'), 0)
+        self.assertEqual(self.v0.search(s=' '), 0)
+        self.assertEqual(self.v0.search(s='z'), 3)
+        
+    def testLocate(self):
+        #locate - v0 is ordered on  s
+        self.assertEqual(self.v0.locate(s='c'), (2,1))
+        self.assertEqual(self.v0.locate(s='b'), (1,1))
+        self.assertEqual(self.v0.locate(s='a'), (0,1))
+        self.assertEqual(self.v0.locate(s=' '), (0,0))
+        self.assertEqual(self.v0.locate(s='z'), (3,0))
+        
+        #itemsize
+        #self.assertEqual(v0.itemsize(v0.i), -2)  
+        #self.assertEqual(v0.itemsize(v0.s, 0), 2) 
+        
+    def testCopy(self):
+        #copy
+        w0 = self.v0.copy()
+        self.assertEqual(len(w0), len(self.v0))
+        self.assertEqual(w0.structure(), self.v0.structure())
+        self.assertEqual(type(w0), Mk4py.ViewType)
+        
+    def testConcat(self):
+        #v1 + v2
+        w0 = self.v0.copy()
+        x0 = w0 + self.v0
+        x1 = self.v0 + w0
+        self.assertEqual(len(x0), len(x1))
+        self.assertEqual(len(x0), 2*len(self.v0))
+        self.assertEqual(x0.structure(), self.v0.structure())
+        self.assertEqual(x1.structure(), self.v0.structure())
+        
+    def testRepeat(self):
+        #v1 * 2
+        x1 = self.v0 * 2
+        self.assertEqual(len(x1), 2*len(self.v0))
+        self.assertEqual(x1.structure(), self.v0.structure())
+        
+    def testRename(self):
+        #rename
+        self.assertEqual(self.v0.s, Mk4py.property('S','s'))
+        x2 = self.v0.rename('s', 'stringprop')
+        self.assertEqual(x2.stringprop, Mk4py.property('S','stringprop'))
+        self.assertNotEqual(x2.structure(), self.v0.structure())
+        self.assertEqual(len(x2.structure()), 2)
+        self.assertEqual(x2.i, self.v0.i)
+
+    def testSelect(self):
+        #select
+        t0 = self.v0.select(s='b')
+        self.assertEqual(len(t0), 1)
+        self.assertEqual(t0[0].s, 'b')
+        t0 = self.v0.select({'s':'a'},{'s':'b'})
+        self.assertEqual(len(t0), 2)
+        self.assertEqual(t0[1].s, 'b')
+        t0 = self.v0.select({'s':'a','i':2},{'s':'b','i':4})
+        self.assertEqual(len(t0), 1)
+        self.assertEqual(t0[0].s, 'b')
+        
+    def testSort(self):
+        #sort
+        t0 = self.v0.sort()  # already in order
+        self.assertEqual(len(t0), len(self.v0))
+        for i in range(1, len(t0)):
+            self.assertEqual( cmp(t0[i-1].s,t0[i].s), -1)
+        t0 = self.v1.sort(self.v1.s)  # reverses native order
+        self.assertEqual(len(t0), len(self.v1))
+        for i in range(1, len(t0)):
+            self.assertEqual( cmp(t0[i-1].s,t0[i].s), -1)
+            
+    def testSortrev(self):
+        #sortrev
+        t0 = self.v0.sortrev([self.v0.s],[self.v0.s])  # reverses order
+        self.assertEqual(len(t0), len(self.v0))
+        for i in range(1, len(t0)):
+            self.assertEqual( cmp(t0[i-1].s,t0[i].s), 1)
+        t0 = self.v1.sortrev([self.v1.s],[self.v1.s])  # native order
+        self.assertEqual(len(t0), len(self.v1))
+        for i in range(1, len(t0)):
+            self.assertEqual( cmp(t0[i-1].s,t0[i].s), 1)
+            
+    def testProject(self):
+        #project
+        t0 = self.v0.project(self.v0.s)
+        s = t0.structure()
+        self.assertEqual(len(s), 1)
+        self.assertEqual(s[0], self.v0.s)
+        
+    def testProduct(self):
+        #product
+        self.assertEqual(len(self.p0), 9)
+        self.assertEqual(len(self.p0.select(s='a')), 3)
+        self.assertEqual(len(self.p0.select(t='a')), 3)
+        
+    def testCounts(self):
+        #counts
+        t1 = self.p0.counts(self.p0.t, self.p0.f, 'details')
+        self.assertEqual(len(t1), 3)
+        self.assertEqual(len(t1.select(t='a')), 1)
+        for i in range(len(t1)):
+            self.assertEqual(t1[i].details, len(self.v0))
+            
+    def testGroupby(self):
+        #groupby
+        self.assertEqual(len(self.g0), 3)
+        self.assertEqual(len(self.g0.select(t='a')), 1)
+        for i in range(len(self.g0)):
+            self.assertEqual(len(self.g0[i].details), len(self.v0))
+            self.assertEqual(len(self.g0[i].details.select(s='a')), 1)
+               
+    def testFlatten(self): 
+        #flatten
+        self.assertEqual(len(self.f0), 9)
+        self.assertEqual(len(self.f0.select(s='a')), 3)
+        self.assertEqual(len(self.f0.select(t='a')), 3)
+        
+    def testUnion(self):
+        #union
+        u0 = self.p0.union(self.f0)   # these 2 are the same
+        self.assertEqual(len(u0), 9)
+        self.assertEqual(len(u0.select(s='a')), 3)
+        self.assertEqual(len(u0.select(t='a')), 3)
+        u1 = self.p0.union(self.f1)   # strict subset
+        self.assertEqual(len(u1), 9)
+        u2 = self.p0.union(self.m0)
+        self.assertEqual(len(u2), len(self.p0)+len(self.m0))
+              
+    def testIntersect(self):  
+        #intersect
+        i0 = self.p0.intersect(self.f0)   # these 2 are the same
+        self.assertEqual(len(i0), 9)
+        self.assertEqual(len(i0.select(s='a')), 3)
+        self.assertEqual(len(i0.select(t='a')), 3)
+        i1 = self.p0.intersect(self.f1)   # strict subset  
+        self.assertEqual(len(i1), len(self.f1))
+        i2 = self.p0.intersect(self.m0)
+        self.assertEqual(len(i2), 0)
+        
+    def testDifferent(self):
+        #different
+        d0 = self.p0.different(self.f0)   # these 2 are the same
+        self.assertEqual(len(d0),0)
+        d1 = self.p0.different(self.f1)   # strict subset  
+        self.assertEqual(len(d1), len(self.p0)-len(self.f1))
+        d2 = self.f1.different(self.p0)
+        self.assertEqual(len(d2), len(self.p0)-len(self.f1))
+        d3 = self.p0.different(self.m0)
+        self.assertEqual(len(d3), len(self.p0)+len(self.m0))
+        
+    def testMinus(self):
+        #minus
+        m0 = self.p0.minus(self.f0)   # these 2 are the same
+        self.assertEqual(len(m0),0)
+        m1 = self.p0.minus(self.f1)   # strict subset
+        self.assertEqual(len(m1), len(self.p0)-len(self.f1))
+        m2 = self.f1.minus(self.p0)
+        self.assertEqual(len(m2), 0)
+        m3 = self.p0.minus(self.m0)
+        self.assertEqual(len(m3), len(self.p0))
+        
+    def testJoin(self):
+        #join
+        j1 = self.v0.join(self.v1, self.v0.s)
+        self.assertEqual(len(j1),3)
+        self.assertEqual(j1[0].s, 'a')
+        self.assertEqual(j1[0].i, 1)
+        self.assertEqual(j1[0].f, 3.0)
+        j2 = self.v0.join(self.v2, self.v0.i)
+        self.assertEqual(len(j2),2)
+        self.assertEqual(j2[0].s, 'b')
+        self.assertEqual(j2[0].i, 2)
+        self.assertEqual(j2[0].b, '\2')
+        # outerjoin
+        j3 = self.v0.join(self.v2, self.v0.i, 1)
+        self.assertEqual(len(j3),3)
+        self.assertEqual(j3[0].s, 'a')
+        self.assertEqual(j3[0].i, 1)
+        self.assertEqual(j3[0].b, '')
+        
+    def testIndices(self):
+        #indices
+        subset = self.p0.select(s='a')
+        iv = self.p0.indices(subset)
+        self.assertEqual(len(iv), len(subset))
+        self.assertEqual(len(iv.structure()), 1)
+        for i in range(len(iv)):
+            self.assertEqual(self.p0[iv[i].index].s, 'a')
+            
+    def testRemapwith(self):
+        #remapwith
+        subset = self.p0.select(s='a')
+        iv = self.p0.indices(subset)
+        r0 = self.p0.remapwith(iv)
+        self.assertEqual(len(r0), len(iv))
+        for row in r0:
+            self.assertEqual(row.s, 'a')
+           
+    def testPair(self): 
+        #pair
+        p0 = self.v1.pair(self.v2)
+        self.assertEqual(len(p0), len(self.v1))
+        self.assertEqual(p0[0].s, 'c')
+        self.assertEqual(p0[0].f, 1.0)
+        self.assertEqual(p0[0].i, 2)
+        self.assertEqual(p0[0].b, '\2')
+        p1 = self.v1.pair(self.v2 * 2)
+        self.assertEqual(len(p1), len(self.v1))
+        
+    def testUnique(self):
+        #unique
+        t = self.v0 * 2
+        u = t.unique()
+        self.assertEqual(len(u), len(self.v0))
+        self.assertEqual(len(u.minus(self.v0)), 0)
+
+    def testFilter(self): 
+        #filter
+        t = self.v0.filter(lambda row: row.s < 'b' or row.s > 'b')
+        self.assertEqual(len(t), 2)
+        for row in t:
+            self.assertNotEqual(self.v0[row.index], 'b')
+
+    def testReduce(self):            
+        #reduce
+        self.assertEqual(self.v0.reduce(lambda row, last: last+row.i), 6)
+        
+class ViewTestCase(ViewerTestCase):
+    def setUp(self):
+        self.setUpViews()
+        
+    def testAddProperty(self):
+        x0 = self.v0.copy()
+        x0.addproperty(Mk4py.property('I','shoesize'))
+        self.assertEqual(len(x0.structure()), 3)
+        self.assertEqual(x0.shoesize, x0.structure()[-1]) 
+
+    def testSetsize(self):
+        #setsize
+        x = self.v0.copy()
+        self.assertEqual(x.setsize(6), 6)
+        self.assertRaises(TypeError, x.setsize, 1, 2)
+        self.assertRaises(TypeError, x.setsize, 'a')
+        self.assertEqual(len(x), 6)
+        for row in x[3:]:
+            self.assertEqual(row.s, '')
+            self.assertEqual(row.i, 0)
+        self.assertEqual(x.setsize(0), 0)
+        self.assertEqual(len(x), 0)
+
+    def testInsert(self):
+        #insert
+        x = self.v0.copy()
+
+        # Most of insert()'s attribute handling is tested by append(),
+        # so just test the features unique to insert() here.
+        def insert(index, i):
+            a = [r.i for r in x]
+            x.insert(index, i=i)
+            if index < 0:
+                index += len(a) # default behavior in Python 2.3 and later
+            a.insert(index, i)
+            self.assertEqual(a, [r.i for r in x])
+
+        insert(0, 7)
+        insert(1, 4)
+        insert(2, 8)
+        insert(-1, 6)
+        insert(-2, 9)
+        insert(500, 48)
+        insert(MAXINT, 300)
+        insert(MININT, 21)
+        self.assertRaises(TypeError, x.insert, 'hi', i=2)
+        self.assertRaises(TypeError, x.insert, None, i=2)
+        self.assertRaises(TypeError, x.insert)
+        self.assertRaises(int_long_error, x.insert, MAXINT + 1, i=2)
+        self.assertRaises(int_long_error, x.insert, MININT - 1, i=2)
+
+    def testAppend(self):
+        #append
+        x = self.v0.copy()
+        c = SequenceCounter(3)
+
+        self.assertEqual(x.append(['hi', 2]), c())
+        self.assertRaises(TypeError, x.append, 1, 2)
+        self.assertRaises(IndexError, x.append, [1, 2, 3]) # could also be TypeError
+        self.assertRaises(IndexError, x.append, 'abc')
+        self.assertRaises(IndexError, x.append, ['hi', 2, 3])
+        self.assertEqual(x.append(s='hi',i=2), c())
+        self.assertEqual(x.append(i=2,s='hi'), c())
+        self.assertRaises(TypeError, x.append, [1, 's'])
+        self.assertRaises(TypeError, x.append, ['s', 't'])
+        self.assertRaises(TypeError, x.append, 'hi')
+        self.assertEqual(x.append(('hi', 2)), c())
+        self.assertEqual(x.append(Dummy(s='hi', i=2)), c())
+        self.assertEqual(x.append(Dummy(s='hi', i=2, j=4)), c())
+        self.assertRaises(TypeError, x.append, Dummy(s=1))
+        self.assertRaises(TypeError, x.append, Dummy(s=Dummy()))
+        if NewDummy:
+            self.assertEqual(x.append(NewDummy(s='hi', i=2)), c())
+            self.assertEqual(x.append(NewDummy(s='hi', i=2, j=4)), c())
+            self.assertRaises(TypeError, x.append, NewDummy(s=1))
+            self.assertRaises(TypeError, x.append, NewDummy(s=NewDummy()))
+        for row in x[c.beginning:]:
+            self.assertEqual(row.s, 'hi')
+            self.assertEqual(row.i, 2)
+            
+        c.begin()
+        self.assertEqual(x.append(s='hi'), c())
+        self.assertEqual(x.append(s='hi',j=2), c())
+        self.assertEqual(x.append(['hi']), c())
+        self.assertRaises(TypeError, x.append, [1])
+        self.assertRaises(TypeError, x.append, 1)
+        self.assertEqual(x.append(Dummy(s='hi')), c())
+        self.assertEqual(x.append(Dummy(s='hi', j=2)), c())
+        if NewDummy:
+            self.assertEqual(x.append(NewDummy(s='hi')), c())
+            self.assertEqual(x.append(NewDummy(s='hi', j=2)), c())
+        for row in x[c.beginning:]:
+            self.assertEqual(row.s, 'hi')
+            self.assertEqual(row.i, 0)
+            
+        c.begin()
+        self.assertEqual(x.append(), c())
+        self.assertEqual(x.append(()), c())
+        self.assertEqual(x.append(Dummy()), c())
+        self.assertEqual(x.append(Dummy(k=Dummy())), c())
+        if NewDummy:
+            self.assertEqual(x.append(NewDummy()), c())
+            self.assertEqual(x.append(NewDummy(k=NewDummy())), c())
+        for row in x[c.beginning:]:
+            self.assertEqual(row.s, '')
+            self.assertEqual(row.i, 0)
+
+        # XXX test 'L', 'D', 'M'/'B' types
+        # XXX test other view types (necessary?)
+        
+        #delete
+        #remove
+        #map
+        #v[n] = x
+        #v[m:n] = x       
+        #hash
+        #blocked
+        #ordered
+        #indexed
+        
+        #access
+        #modify
+        
+   
+class RORowRefTestCase(unittest.TestCase):
+    def setUp(self):
+        self.setUpView()
+        self.v = self.v.unique()
+    def setUpView(self):
+        self.s = s = Mk4py.storage()
+        self.v = v = s.getas('test[i:I,l:L,f:F,d:D,s:S,v[s:S],b:B,m:M]')
+        v.append()
+    def testProperties(self):
+        plist = self.v.structure()
+        pdict = self.v.properties()
+        for prop in plist:
+            self.assertEqual(prop, pdict[prop.name])
+            self.assertEqual(prop, getattr(self.v, prop.name))
+    def testType(self):
+        self.assertEqual(type(self.v[0]), Mk4py.RORowRefType)
+    def testGetAttr(self):
+        r = self.v[0]
+        attrs = r.__attrs__
+        self.assertEqual(len(attrs), 8)
+        self.assertEqual(attrs[0].name, 'i')
+        self.assertEqual(attrs[0].type, 'I')
+        self.assertEqual(attrs[0].id, Mk4py.property('I','i').id)
+        self.assertEqual(attrs[7].name, 'm')
+        self.assertEqual(attrs[7].type, 'B')
+        self.assertEqual(attrs[7].id, Mk4py.property('M','m').id)
+        #self.assertEqual(r.__view__, v)    what's r.__view__ good for??
+        self.assertEqual(r.__index__, 0)
+        self.assertEqual(r.i, 0)
+        self.assertEqual(r.l, 0)
+        self.assertEqual(r.f, 0.0)
+        self.assertEqual(r.d, 0.0)
+        self.assertEqual(r.s, '')
+        self.assertEqual(len(r.v, ), 0)
+        self.assertEqual(type(r.v), Mk4py.ViewType)
+        self.assertEqual(r.b, '')
+        self.assertEqual(r.m, '')
+    def testSetAttr(self):
+        v = self.v.unique()
+        r = v[0]
+        self.assertRaises(TypeError, setattr, (r, 'i', 1))
+
+class RowRefTestCase(RORowRefTestCase):
+    def setUp(self):
+        self.setUpView()
+    def testType(self):
+        self.assertEqual(type(self.v[0]), Mk4py.RowRefType)
+    def testSetAttr(self):
+        r = self.v[0]
+        
+        #setattr I - int, castable to int
+        r.i = 3
+        self.assertEqual(r.i, 3)
+        self.assertEqual(type(r.i), int)
+        try:
+            r.i = True
+        except NameError:
+            pass
+        else:
+            self.assertEqual(r.i, 1)
+            self.assertEqual(type(r.i), int)
+        r.i = 8.0
+        self.assertEqual(r.i, 8)
+        self.assertEqual(type(r.i), int)
+        r.i = 8.9
+        self.assertEqual(r.i, 8)
+        self.assertEqual(type(r.i), int)
+        self.assertRaises(TypeError, setattr, (r, 'i', '1'))
+            
+        #        L - int, long, castable to long
+        r.l = 3L
+        self.assertEqual(r.l, 3)
+        self.assertEqual(type(r.l), long)
+        try:
+            r.l = True
+        except NameError:
+            pass
+        else:
+            self.assertEqual(r.l, 1)
+            self.assertEqual(type(r.l), long)
+        r.l = 8.0
+        self.assertEqual(r.l, 8)
+        self.assertEqual(type(r.l), long)
+        r.l = 8.9
+        self.assertEqual(r.l, 8)
+        self.assertEqual(type(r.l), long)
+        try:
+            bignum = sys.maxint + 1
+        except OverflowError:
+            pass
+        else:
+            r.l = bignum
+            self.assertEqual(r.l, bignum)
+        self.assertRaises(TypeError, setattr, (r, 'l', '1'))
+            
+        #        F - float, castable to double
+        r.f = 1.0
+        self.assertEqual(r.f, 1.0)
+        r.f = 1
+        self.assertEqual(r.f, 1.0)
+        self.assertEqual(type(r.f), float)
+        self.assertRaises(TypeError, setattr, (r, 'f', '1.0'))
+        
+        #        D - float, castable to double
+        r.d = 1.0
+        self.assertEqual(r.d, 1.0)
+        r.d = 1
+        self.assertEqual(r.d, 1.0)
+        self.assertEqual(type(r.d), float)
+        self.assertRaises(TypeError, setattr, (r, 'd', '1.0'))
+        
+        #        S - string
+        s = 'a string'
+        r.s = s
+        self.assertEqual(r.s, s)
+        r.s = s*50
+        self.assertEqual(r.s, s*50)
+        self.assertRaises(TypeError, setattr, (r, 's', 1.0))
+        
+        #        V - view, sequence
+        r.v = []
+        self.assertEqual(len(r.v), 0)
+        r.v = [('a',),('b',)]
+        self.assertEqual(len(r.v), 2)
+        self.assertEqual(r.v[0].s, 'a')
+        self.assertEqual(r.v[1].s, 'b')
+        #special case where subview has only one property
+        r.v = ['a','b']
+        self.assertEqual(len(r.v), 2)
+        self.assertEqual(r.v[0].s, 'a')
+        self.assertEqual(r.v[1].s, 'b')
+        r.v = [{'s':'a'},{'s':'b'}]
+        self.assertEqual(len(r.v), 2)
+        self.assertEqual(r.v[0].s, 'a')
+        self.assertEqual(r.v[1].s, 'b')
+        r.v = [Dummy(s='a'),Dummy(s='b')]
+        self.assertEqual(len(r.v), 2)
+        self.assertEqual(r.v[0].s, 'a')
+        self.assertEqual(r.v[1].s, 'b')
+        
+        #        B,M - string
+        s = '\0a\0binary\1string'
+        r.b = s
+        self.assertEqual(r.b, s)
+        r.b = s*50
+        self.assertEqual(r.b, s*50)
+        self.assertRaises(TypeError, setattr, (r, 'b', 1.0))
+        r.m = s
+        self.assertEqual(r.m, s)
+        r.m = s*50
+        self.assertEqual(r.m, s*50)
+        self.assertRaises(TypeError, setattr, (r, 'm', 1.0))
+
+def test_main():
+    l = [ unittest.makeSuite(RORowRefTestCase),
+          unittest.makeSuite(RowRefTestCase),
+          unittest.makeSuite(ViewerTestCase),
+          unittest.makeSuite(ViewTestCase), ]
+    suite = unittest.TestSuite(l)
+    test_support.run_suite(suite)
+
+if __name__ == '__main__':
+    test_main()
diff --git a/8.x/mk/src/borc.h b/8.x/mk/src/borc.h
new file mode 100755 (executable)
index 0000000..eed03a9
--- /dev/null
@@ -0,0 +1,33 @@
+// borc.h --
+// $Id: borc.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Configuration header for Borland C++
+ */
+
+#define q4_BORC 1
+
+// get rid of several common warning messages
+#if !q4_STRICT
+#pragma warn -aus // 'identifier' is assigned a value that is never used
+#pragma warn -par // Parameter 'parameter' is never used.
+#pragma warn -sig // Conversion may lose significant digits
+#pragma warn -use // 'identifier' declared but never used
+#endif 
+
+#if __BORLANDC__ >= 0x500
+#define q4_BOOL 1     // supports the bool datatype
+// undo previous defaults, because q4_BOOL is not set early enough
+#undef false
+#undef true
+#undef bool
+#endif 
+
+#if !defined (q4_EXPORT)
+#define q4_EXPORT 1     // requires export/import specifiers
+#endif 
+
+#if defined (__MT__)
+#define q4_MULTI 1      // uses multi-threading
+#endif
diff --git a/8.x/mk/src/column.cpp b/8.x/mk/src/column.cpp
new file mode 100755 (executable)
index 0000000..066cb01
--- /dev/null
@@ -0,0 +1,1499 @@
+// column.cpp --
+// $Id: column.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Implements c4_Column, c4_ColOfInts, and c4_ColIter
+ */
+
+#include "header.h"
+#include "column.h"
+#include "persist.h"
+
+#if !q4_INLINE
+#include "column.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if !HAVE_MEMMOVE && !HAVE_BCOPY
+// in case we have no library memmove, or one that can't handle overlap
+
+void f4_memmove(void *to_, const void *from_, int n_) {
+  char *to = (char*)to_;
+  const char *from = (const char*)from_;
+
+  if (to + n_ <= from || from + n_ <= to)
+    memcpy(to, from, n_);
+  else if (to < from)
+    while (--n_ >= 0)
+      *to++ =  *from++;
+    else if (to > from)
+      while (--n_ >= 0)
+        to[n_] = from[n_];
+}
+
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Column
+
+c4_Column::c4_Column(c4_Persist *persist_): _position(0), _size(0), _persist
+  (persist_), _gap(0), _slack(0), _dirty(false){}
+
+#if q4_CHECK
+
+// debugging version to verify that the internal data is consistent
+void c4_Column::Validate()const {
+  d4_assert(0 <= _slack && _slack < kSegMax);
+
+  if (_segments.GetSize() == 0)
+    return ;
+  // ok, not initialized
+
+  d4_assert(_gap <= _size);
+
+  int n = fSegIndex(_size + _slack);
+  d4_assert(n == _segments.GetSize() - 1);
+
+  t4_byte *p = (t4_byte*)_segments.GetAt(n);
+
+  if (fSegRest(_size + _slack) == 0)
+    d4_assert(p == 0);
+  else
+    d4_assert(p != 0);
+
+  while (--n >= 0) {
+    t4_byte *p = (t4_byte*)_segments.GetAt(n);
+    d4_assert(p != 0);
+  }
+}
+
+#else 
+
+// nothing, so inline this thing to avoid even the calling overhead
+d4_inline void c4_Column::Validate()const{}
+
+#endif 
+
+c4_Column::~c4_Column() {
+  Validate();
+  ReleaseAllSegments();
+
+  // this is needed to remove this column from the cache
+  d4_assert(_slack == 0);
+  FinishSlack();
+
+  _slack =  - 1; // bad value in case we try to set up again (!)
+}
+
+c4_Strategy &c4_Column::Strategy()const {
+  d4_assert(_persist != 0);
+
+  return _persist->Strategy();
+}
+
+bool c4_Column::IsMapped()const {
+  return _position > 1 && _persist != 0 && Strategy()._mapStart != 0;
+}
+
+bool c4_Column::UsesMap(const t4_byte *ptr_)const {
+  // the most common falsifying case is checked first
+  return _persist != 0 &&
+    ptr_ >= Strategy()._mapStart &&
+    Strategy()._dataSize != 0 &&
+    ptr_ < Strategy()._mapStart + Strategy()._dataSize;
+}
+
+bool c4_Column::RequiresMap()const {
+  if (_persist != 0 && Strategy()._mapStart != 0)
+    for (int i = _segments.GetSize(); --i >= 0;)
+      if (UsesMap((t4_byte*)_segments.GetAt(i)))
+        return true;
+  return false;
+}
+
+void c4_Column::ReleaseSegment(int index_) {
+  t4_byte *p = (t4_byte*)_segments.GetAt(index_);
+  if (!UsesMap(p))
+    delete [] p;
+}
+
+void c4_Column::ReleaseAllSegments() {
+  //for (int i = 0; i < _segments.GetSize(); ++i)
+  for (int i = _segments.GetSize(); --i >= 0;)
+    ReleaseSegment(i);
+  // last one might be a null pointer
+
+  _segments.SetSize(0);
+
+  _gap = 0;
+  _slack = 0;
+
+  if (_size == 0)
+    _position = 0;
+
+  _dirty = false;
+}
+
+//@func Define where data is on file, or setup buffers (opt cleared).
+void c4_Column::SetLocation(t4_i32 pos_, t4_i32 size_) {
+  d4_assert(size_ > 0 || pos_ == 0);
+
+  ReleaseAllSegments();
+
+  _position = pos_;
+  _size = size_;
+
+  //  There are two position settings:
+  //
+  //     0 = raw buffer, no file access
+  //    >1 = file position from where data can be loaded on demand
+
+  _dirty = pos_ == 0;
+}
+
+void c4_Column::PullLocation(const t4_byte * &ptr_) {
+  d4_assert(_segments.GetSize() == 0);
+
+  _size = PullValue(ptr_);
+  _position = 0;
+  if (_size > 0) {
+    _position = PullValue(ptr_);
+    if (_position > 0) {
+      d4_assert(_persist != 0);
+      _persist->OccupySpace(_position, _size);
+    }
+  }
+
+  _dirty = false;
+}
+
+//@func How many contiguous bytes are there at a specified position.
+int c4_Column::AvailAt(t4_i32 offset_)const {
+  d4_assert(offset_ <= _size);
+  d4_assert(_gap <= _size);
+
+  t4_i32 limit = _gap;
+
+  if (offset_ >= _gap) {
+    offset_ += _slack;
+    limit = _size + _slack;
+  }
+
+  int count = kSegMax - fSegRest(offset_);
+  if (offset_ + count > limit)
+    count = (int)(limit - offset_);
+
+  // either some real data or it must be at the very end of all data
+  d4_assert(0 < count && count <= kSegMax || count == 0 && offset_ == _size +
+    _slack);
+  return count;
+}
+
+void c4_Column::SetupSegments() {
+  d4_assert(_segments.GetSize() == 0);
+  d4_assert(_gap == 0);
+  d4_assert(_slack == 0);
+
+  //  The last entry in the _segments array is either a partial block
+  //  or a null pointer, so calling "fSegIndex(_size)" is always allowed.
+
+  int n = fSegIndex(_size) + 1;
+  _segments.SetSize(n);
+
+  // treat last block differently if it is a partial entry
+  int last = n;
+  if (fSegRest(_size))
+    --last;
+  // this block is partial, size is 1 .. kSegMax-1
+  else
+    --n;
+  // the last block is left as a null pointer
+
+  int id =  - 1;
+  if (_position < 0) {
+    // special aside id, figure out the real position
+    d4_assert(_persist != 0);
+    id = ~_position;
+    _position = _persist->LookupAside(id);
+    d4_assert(_position >= 0);
+  }
+
+  if (IsMapped()) {
+    // setup for mapped files is quick, just fill in the pointers
+    d4_assert(_position > 1);
+    d4_assert(_position + (n - 1) *kSegMax <= Strategy()._dataSize);
+    const t4_byte *map = Strategy()._mapStart + _position;
+
+    for (int i = 0; i < n; ++i) {
+      _segments.SetAt(i, (t4_byte*)map); // loses const
+      map += kSegMax;
+    }
+  } else {
+    int chunk = kSegMax;
+    t4_i32 pos = _position;
+
+    // allocate buffers, load them if necessary
+    for (int i = 0; i < n; ++i) {
+      if (i == last)
+        chunk = fSegRest(_size);
+
+      t4_byte *p = d4_new t4_byte[chunk];
+      _segments.SetAt(i, p);
+
+      if (_position > 0) {
+        d4_dbgdef(int n = )Strategy().DataRead(pos, p, chunk);
+        d4_assert(n == chunk);
+        pos += chunk;
+      }
+    }
+  }
+
+  if (id >= 0) {
+    d4_assert(_persist != 0);
+    _persist->ApplyAside(id,  *this);
+  }
+
+  Validate();
+}
+
+//@func Makes sure the requested data is in a modifiable buffer.
+t4_byte *c4_Column::CopyNow(t4_i32 offset_) {
+  d4_assert(offset_ <= _size);
+
+  _dirty = true;
+
+  const t4_byte *ptr = LoadNow(offset_);
+  if (UsesMap(ptr)) {
+    if (offset_ >= _gap)
+      offset_ += _slack;
+
+    // this will only force creation of a buffer
+    ptr = CopyData(offset_, offset_, 0);
+    d4_assert(!UsesMap(ptr));
+  }
+
+  return (t4_byte*)ptr;
+}
+
+//@func Copies data, creating a buffer if needed.  Must be in single segment.
+t4_byte *c4_Column::CopyData(t4_i32 to_, t4_i32 from_, int count_) {
+  int i = fSegIndex(to_);
+  t4_byte *p = (t4_byte*)_segments.GetAt(i);
+
+  if (UsesMap(p)) {
+    int n = kSegMax;
+    if (fSegOffset(i) + n > _size + _slack)
+      n = (int)(_size + _slack - fSegOffset(i));
+
+    d4_assert(n > 0);
+
+    t4_byte *q = d4_new t4_byte[n];
+    memcpy(q, p, n); // some copying can be avoided, overwritten below...
+    _segments.SetAt(i, q);
+
+    p = q;
+  }
+
+  p += fSegRest(to_);
+
+  if (count_ > 0) {
+    d4_assert(fSegIndex(to_ + count_ - 1) == i);
+
+    const t4_byte *src = (const t4_byte*)_segments.GetAt(fSegIndex(from_));
+    d4_memmove(p, src + fSegRest(from_), count_);
+  }
+
+  return p;
+}
+
+/*
+ *  Resizing a segmented vector can be a complicated operation.
+ *  For now, simply making it work in all cases is the first priority.
+ *
+ *  A major simplification - and good performance improvement - is caused
+ *  by the trick of maintaining a "gap" in the data, which can be "moved"
+ *  around to allow fast insertion as well as simple (delayed) deletion.
+ *  
+ *  The only complexity comes from the fact that the gap must end up being 
+ *  less than one full segment in size.  Therefore, insertion and removal
+ *  across segment boundaries needs to handle a variety of situations.
+ *
+ *  Since complete segments can be inserted quickly, this approach avoids
+ *  lots of copying when consecutive insertions/deletions are clustered.
+ *  Even random changes move half as much (on average) as without a gap.
+ *
+ *  The price is the overhead of up to one segment of empty space, and the
+ *  complexity of this code (all the magic is within this c4_Column class).
+ */
+
+void c4_Column::MoveGapUp(t4_i32 dest_) {
+  d4_assert(dest_ <= _size);
+  d4_assert(_gap < dest_);
+  d4_assert(_slack > 0);
+
+  // forward loop to copy contents down, in little pieces if need be
+  while (_gap < dest_) {
+    int n = kSegMax - fSegRest(_gap);
+    t4_i32 curr = _gap + n;
+    if (curr > dest_)
+      curr = dest_;
+
+    // copy to [_gap..curr), which is inside one segment
+    d4_assert(_gap < curr);
+    d4_assert(fSegIndex(_gap) == fSegIndex(curr - 1));
+
+    // copy from [_gap + _slack .. curr + _slack), of the same size
+    t4_i32 fromBeg = _gap + _slack;
+    t4_i32 fromEnd = curr + _slack;
+
+    while (fromBeg < fromEnd) {
+      int k = kSegMax - fSegRest(fromBeg);
+      if (fromBeg + k > fromEnd)
+        k = (int)(fromEnd - fromBeg);
+
+      d4_assert(k > 0);
+
+      CopyData(_gap, fromBeg, k);
+
+      _gap += k;
+      fromBeg += k;
+    }
+
+    _gap = curr;
+  }
+
+  d4_assert(_gap == dest_);
+}
+
+void c4_Column::MoveGapDown(t4_i32 dest_) {
+  d4_assert(dest_ <= _size);
+  d4_assert(_gap > dest_);
+  d4_assert(_slack > 0);
+
+  // reverse loop to copy contents up, in little pieces if need be
+  t4_i32 toEnd = _gap + _slack;
+  t4_i32 toBeg = dest_ + _slack;
+
+  while (toEnd > toBeg) {
+    int n = fSegRest(toEnd);
+    t4_i32 curr = toEnd - (n ? n : kSegMax);
+    if (curr < toBeg)
+      curr = toBeg;
+
+    // copy to [curr..toEnd), which is inside one segment
+    d4_assert(curr < toEnd);
+    d4_assert(fSegIndex(curr) == fSegIndex(toEnd - 1));
+
+    // copy from [fromBeg .. _gap), which has the same size
+    t4_i32 fromBeg = _gap - (toEnd - curr);
+
+    while (_gap > fromBeg) {
+      int k = fSegRest(_gap);
+      if (k == 0)
+        k = kSegMax;
+      if (_gap - k < fromBeg)
+        k = (int)(_gap - fromBeg);
+
+      d4_assert(k > 0);
+
+      toEnd -= k;
+      _gap -= k;
+
+      CopyData(toEnd, _gap, k);
+    }
+  }
+
+  d4_assert(_gap == dest_);
+}
+
+void c4_Column::MoveGapTo(t4_i32 pos_) {
+  d4_assert(pos_ <= _size);
+
+  if (_slack == 0)
+  // if there is no real gap, then just move it
+    _gap = pos_;
+  else if (_gap < pos_)
+  // move the gap up, ie. some bytes down
+    MoveGapUp(pos_);
+  else if (_gap > pos_)
+  // move the gap down, ie. some bytes up
+  if (_gap - pos_ > _size - _gap + fSegRest(pos_)) {
+    RemoveGap(); // it's faster to get rid of the gap instead
+    _gap = pos_;
+  } else
+  // normal case, move some bytes up
+    MoveGapDown(pos_);
+
+  d4_assert(_gap == pos_);
+
+  Validate();
+}
+
+void c4_Column::RemoveGap() {
+  if (_slack > 0) {
+    if (_gap < _size)
+      MoveGapUp(_size);
+
+    d4_assert(_gap == _size); // the gap is now at the end
+    d4_assert(_slack < kSegMax);
+
+    //  Case 1: gap is at start of segment
+    //  ==================================
+    //
+    //    G G+S 
+    //
+    //    |  |
+    //    :----+xx:
+    //    |   |
+    //
+    //    i    i+1 (limit)
+    //
+    //  Case 2: gap is inside segment
+    //  =============================
+    //
+    //       G G+S
+    //
+    //       |  |
+    //    :--+--+x:
+    //    |   |
+    //
+    //    i    i+1 (limit)
+    //
+    //  Case 3: gap runs to end of segment
+    //  ==================================
+    //
+    //       G   G+S
+    //
+    //       |  |
+    //    :--+----:0000000:
+    //    |   |   |
+    //
+    //    i    i+1     i+2 (limit)
+    //
+    //  Case 4: gap is across two segments
+    //  ==================================
+    //
+    //       G   G+S
+    //
+    //       |    |
+    //    :--+----:-+xxxxx:
+    //    |   |   |
+    //
+    //    i    i+1     i+2 (limit)
+
+    int i = fSegIndex(_gap);
+    int n = fSegRest(_gap);
+
+    if (n == 0) {
+      // case 1
+      ReleaseSegment(i);
+      _segments.SetAt(i, 0);
+    } else {
+      if (n + _slack > kSegMax)
+      // case 4
+        ReleaseSegment(i + 1);
+
+      // truncate rest of segment
+      t4_byte *p = d4_new t4_byte[n];
+      memcpy(p, _segments.GetAt(i), n);
+
+      ReleaseSegment(i);
+      _segments.SetAt(i, p);
+      _segments.SetSize(i + 1);
+    }
+
+    _slack = 0;
+  }
+
+  Validate();
+}
+
+void c4_Column::Grow(t4_i32 off_, t4_i32 diff_) {
+  d4_assert(off_ <= _size);
+  d4_assert(diff_ > 0);
+
+  if (_segments.GetSize() == 0)
+    SetupSegments();
+
+  Validate();
+
+  _dirty = true;
+
+  // move the gap so it starts where we want to insert
+  MoveGapTo(off_);
+
+  t4_i32 bigSlack = _slack;
+  if (bigSlack < diff_) {
+    // only do more if this isn't good enough
+    // number of segments to insert
+    int n = fSegIndex(diff_ - _slack + kSegMax - 1);
+    d4_assert(n > 0);
+
+    int i1 = fSegIndex(_gap);
+    int i2 = fSegIndex(_gap + _slack);
+
+    bool moveBack = false;
+
+    if (i2 > i1)
+    // cases 3 and 4
+      ++i1;
+    else if (fSegRest(_gap))
+    // case 2
+      moveBack = true;
+
+    _segments.InsertAt(i1, 0, n);
+    for (int i = 0; i < n; ++i)
+      _segments.SetAt(i1 + i, d4_new t4_byte[(int)kSegMax]);
+
+    bigSlack += fSegOffset(n);
+
+    if (moveBack) {
+      d4_assert(i1 == fSegIndex(_gap));
+
+      //  we have inserted too low, move bytes in front of gap back
+      CopyData(fSegOffset(i1), fSegOffset(i1 + n), fSegRest(_gap));
+    }
+  }
+
+  d4_assert(diff_ <= bigSlack && bigSlack < diff_ + kSegMax);
+
+  _gap += diff_;
+  _slack = (int)(bigSlack - diff_);
+  _size += diff_;
+
+  FinishSlack();
+}
+
+void c4_Column::Shrink(t4_i32 off_, t4_i32 diff_) {
+  d4_assert(off_ <= _size);
+  d4_assert(diff_ > 0);
+
+  if (_segments.GetSize() == 0)
+    SetupSegments();
+
+  Validate();
+
+  _dirty = true;
+
+  // the simplification here is that we have in fact simply *two*
+  // gaps and we must merge them together and end up with just one
+
+  if (_slack > 0) {
+    if (_gap < off_)
+    // if too low, move the gap up
+      MoveGapTo(off_);
+    else if (off_ + diff_ < _gap)
+    // if too high, move down to end
+      MoveGapTo(off_ + diff_);
+
+    // the gap is now inside, or adjacent to, the deleted area
+    d4_assert(off_ <= _gap && _gap <= off_ + diff_);
+  }
+
+  _gap = off_;
+
+  // check whether the merged gap would cross a segment boundary
+  int i1 = fSegIndex(_gap);
+  int i2 = fSegIndex(_gap + _slack + diff_);
+
+  // drop complete segments, not a partially filled boundary
+  if (fSegRest(_gap))
+    ++i1;
+
+  // moved up (was after the next if in the 1.7 May 28 build)
+  _slack += diff_;
+  _size -= diff_;
+
+  int n = i2 - i1;
+  if (n > 0) {
+    for (int i = i1; i < i2; ++i)
+      ReleaseSegment(i);
+
+    _segments.RemoveAt(i1, n);
+
+    // the logic in 1.7 of May 28 was warped (the assert "fix" was wrong)
+    d4_assert(_slack >= fSegOffset(n));
+    _slack -= fSegOffset(n);
+  }
+
+  d4_assert(0 <= _slack && _slack < 2 *kSegMax);
+
+  // if the gap is at the end, get rid of a partial segment after it
+  if (_gap == _size) {
+    int i = fSegIndex(_size + _slack);
+    if (i != fSegIndex(_gap)) {
+      d4_assert(i == fSegIndex(_gap) + 1);
+      d4_assert(i == _segments.GetSize() - 1);
+
+      ReleaseSegment(i);
+      _segments.SetAt(i, 0);
+
+      _slack -= fSegRest(_size + _slack);
+
+      d4_assert(_slack < kSegMax);
+      d4_assert(fSegRest(_gap + _slack) == 0);
+    }
+  }
+
+  // the slack may still be too large to leave as is
+  if (_slack >= kSegMax) {
+    // move the bytes just after the end of the gap one segment down
+    int x = fSegRest(_gap + _slack);
+    int r = kSegMax - x;
+    if (_gap + r > _size)
+      r = (int)(_size - _gap);
+
+    CopyData(_gap, _gap + _slack, r);
+
+    int i = fSegIndex(_gap + kSegMax - 1);
+    ReleaseSegment(i);
+
+    if (r + x < kSegMax)
+      _segments.SetAt(i, 0);
+    else
+      _segments.RemoveAt(i);
+
+    _slack -= r + x;
+    _gap += r;
+  }
+
+  // if we have no data anymore, make sure not to use the file map either
+  if (_size == 0 && _slack > 0)
+    CopyNow(0);
+
+  FinishSlack();
+}
+
+void c4_Column::FinishSlack() {
+  Validate();
+
+  // optimization: if partial end segment easily fits in slack, move it down
+  t4_i32 gapEnd = _gap + _slack;
+  if (!fSegRest(gapEnd) && gapEnd >= _size + 500) {
+    // slack is at least 500 bytes more than the partial end segment
+    // also, the gap must end exactly on a segment boundary
+    int i = fSegIndex(gapEnd);
+    d4_assert(i == _segments.GetSize() - 1);
+
+    int n = _size - _gap;
+    CopyData(gapEnd - n, gapEnd, n);
+
+    ReleaseSegment(i);
+    _segments.SetAt(i, 0);
+
+    _slack -= n;
+    d4_assert(_slack >= 500);
+
+    Validate();
+  }
+}
+
+void c4_Column::SaveNow(c4_Strategy &strategy_, t4_i32 pos_) {
+  if (_segments.GetSize() == 0)
+    SetupSegments();
+
+  // write all segments
+  c4_ColIter iter(*this, 0, _size);
+  while (iter.Next(kSegMax)) {
+    int n = iter.BufLen();
+    strategy_.DataWrite(pos_, iter.BufLoad(), n);
+    if (strategy_._failure != 0)
+      break;
+    pos_ += n;
+  }
+}
+
+const t4_byte *c4_Column::FetchBytes(t4_i32 pos_, int len_, c4_Bytes &buffer_,
+  bool forceCopy_) {
+  d4_assert(len_ > 0);
+  d4_assert(pos_ + len_ <= ColSize());
+  d4_assert(0 <= _slack && _slack < kSegMax);
+
+  c4_ColIter iter(*this, pos_, pos_ + len_);
+  iter.Next();
+
+  // most common case, all bytes are inside the same segment
+  if (!forceCopy_ && iter.BufLen() == len_)
+    return iter.BufLoad();
+
+  t4_byte *p = buffer_.SetBuffer(len_);
+  do {
+    d4_assert(iter.BufLen() > 0);
+    memcpy(p, iter.BufLoad(), iter.BufLen());
+    p += iter.BufLen();
+  } while (iter.Next());
+  d4_assert(p == buffer_.Contents() + len_);
+
+  return buffer_.Contents();
+}
+
+void c4_Column::StoreBytes(t4_i32 pos_, const c4_Bytes &buffer_) {
+  int n = buffer_.Size();
+  if (n > 0) {
+    d4_assert(pos_ + n <= ColSize());
+
+    c4_ColIter iter(*this, pos_, pos_ + n);
+
+    const t4_byte *p = buffer_.Contents();
+    while (iter.Next(n)) {
+      d4_assert(iter.BufLen() > 0);
+      memcpy(iter.BufSave(), p, iter.BufLen());
+      p += iter.BufLen();
+    }
+    d4_assert(p == buffer_.Contents() + n);
+  }
+}
+
+/*
+PushValue and PullValue deal with variable-sized storage of
+one unsigned integer value of up to 32 bits. Depending on the
+magnitude of the integer, 1..6 bytes are used to represent it.
+Each byte holds 7 significant bits and one continuation bit.
+This saves storage, but it is also byte order independent.
+Negative values are stored as a zero byte plus positive value.
+ */
+
+t4_i32 c4_Column::PullValue(const t4_byte * &ptr_) {
+  t4_i32 mask =  *ptr_ ? 0 : ~0;
+
+  t4_i32 v = 0;
+  for (;;) {
+    v = (v << 7) +  *ptr_;
+    if (*ptr_++ &0x80)
+      break;
+  }
+
+  return mask ^ (v - 0x80); // oops, last byte had bit 7 set
+}
+
+void c4_Column::PushValue(t4_byte * &ptr_, t4_i32 v_) {
+  if (v_ < 0) {
+    v_ = ~v_;
+    *ptr_++ = 0;
+  }
+
+  int n = 0;
+  do {
+    n += 7;
+  } while ((v_ >> n) && n < 32);
+
+  while (n) {
+    n -= 7;
+    t4_byte b = (t4_byte)((v_ >> n) &0x7F);
+    if (!n)
+      b |= 0x80;
+    // set bit 7 on the last byte
+    *ptr_++ = b;
+  }
+}
+
+void c4_Column::InsertData(t4_i32 index_, t4_i32 count_, bool clear_) {
+  d4_assert(index_ <= ColSize());
+
+  if (count_ > 0) {
+    Grow(index_, count_);
+
+    // clear the contents, in separate chunks if necessary
+    if (clear_) {
+      c4_ColIter iter(*this, index_, index_ + count_);
+      while (iter.Next())
+        memset(iter.BufSave(), 0, iter.BufLen());
+    }
+  }
+}
+
+void c4_Column::RemoveData(t4_i32 index_, t4_i32 count_) {
+  d4_assert(index_ + count_ <= ColSize());
+
+  if (count_ > 0)
+    Shrink(index_, count_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void c4_ColOfInts::Get_0b(int) {
+  *(t4_i32*)_item = 0;
+}
+
+void c4_ColOfInts::Get_1b(int index_) {
+  t4_i32 off = index_ >> 3;
+  d4_assert(off < ColSize());
+
+  *(t4_i32*)_item = (*LoadNow(off) >> (index_ &7)) &0x01;
+}
+
+void c4_ColOfInts::Get_2b(int index_) {
+  t4_i32 off = index_ >> 2;
+  d4_assert(off < ColSize());
+
+  *(t4_i32*)_item = (*LoadNow(off) >> ((index_ &3) << 1)) &0x03;
+}
+
+void c4_ColOfInts::Get_4b(int index_) {
+  t4_i32 off = index_ >> 1;
+  d4_assert(off < ColSize());
+
+  *(t4_i32*)_item = (*LoadNow(off) >> ((index_ &1) << 2)) &0x0F;
+}
+
+void c4_ColOfInts::Get_8i(int index_) {
+  t4_i32 off = index_;
+  d4_assert(off < ColSize());
+
+  *(t4_i32*)_item = *(const signed char*)LoadNow(off);
+}
+
+void c4_ColOfInts::Get_16i(int index_) {
+  t4_i32 off = index_ *(t4_i32)2;
+  d4_assert(off + 2 <= ColSize());
+
+  const t4_byte *vec = LoadNow(off);
+
+  _item[0] = vec[0];
+  _item[1] = vec[1];
+
+  *(t4_i32*)_item = *(const short*)_item;
+}
+
+void c4_ColOfInts::Get_16r(int index_) {
+  t4_i32 off = index_ *(t4_i32)2;
+  d4_assert(off + 2 <= ColSize());
+
+  const t4_byte *vec = LoadNow(off);
+
+  // 2003-02-02 - gcc 3.2.1 on linux (!) fails to compile this
+  // sign-extension trick properly, use a temp buffer instead:
+  //*(t4_i32*) _item = *(const short*) _item;
+
+  t4_byte temp[2];
+  temp[1] = vec[0];
+  temp[0] = vec[1];
+  *(t4_i32*)_item = *(const short*)temp;
+}
+
+void c4_ColOfInts::Get_32i(int index_) {
+  t4_i32 off = index_ *(t4_i32)4;
+  d4_assert(off + 4 <= ColSize());
+
+  const t4_byte *vec = LoadNow(off);
+
+  _item[0] = vec[0];
+  _item[1] = vec[1];
+  _item[2] = vec[2];
+  _item[3] = vec[3];
+}
+
+void c4_ColOfInts::Get_32r(int index_) {
+  t4_i32 off = index_ *(t4_i32)4;
+  d4_assert(off + 4 <= ColSize());
+
+  const t4_byte *vec = LoadNow(off);
+
+  _item[3] = vec[0];
+  _item[2] = vec[1];
+  _item[1] = vec[2];
+  _item[0] = vec[3];
+}
+
+void c4_ColOfInts::Get_64i(int index_) {
+  t4_i32 off = index_ *(t4_i32)8;
+  d4_assert(off + 8 <= ColSize());
+
+  const t4_byte *vec = LoadNow(off);
+
+  for (int i = 0; i < 8; ++i)
+    _item[i] = vec[i];
+}
+
+void c4_ColOfInts::Get_64r(int index_) {
+  t4_i32 off = index_ *(t4_i32)8;
+  d4_assert(off + 8 <= ColSize());
+
+  const t4_byte *vec = LoadNow(off);
+
+  for (int i = 0; i < 8; ++i)
+    _item[7-i] = vec[i];
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+static int fBitsNeeded(t4_i32 v) {
+  if ((v >> 4) == 0) {
+    static int bits[] =  {
+      0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
+    };
+    return bits[(int)v];
+  }
+
+  if (v < 0)
+  // first flip all bits if bit 31 is set
+    v = ~v;
+  // ... bit 31 is now always zero
+
+  // then check if bits 15-31 used (32b), 7-31 used (16b), else (8b)
+  return v >> 15 ? 32 : v >> 7 ? 16 : 8;
+}
+
+bool c4_ColOfInts::Set_0b(int, const t4_byte *item_) {
+  t4_i32 v = *(const t4_i32*)item_;
+  return v == 0;
+}
+
+bool c4_ColOfInts::Set_1b(int index_, const t4_byte *item_) {
+  t4_i32 v = *(const t4_i32*)item_;
+
+  t4_i32 off = index_ >> 3;
+  d4_assert(off < ColSize());
+
+  index_ &= 7;
+
+  t4_byte *p = CopyNow(off);
+  *p = (*p &~(1 << index_)) | (((t4_byte)v &1) << index_);
+
+  return (v >> 1) == 0;
+}
+
+bool c4_ColOfInts::Set_2b(int index_, const t4_byte *item_) {
+  t4_i32 v = *(const t4_i32*)item_;
+
+  t4_i32 off = index_ >> 2;
+  d4_assert(off < ColSize());
+
+  const int n = (index_ &3) << 1;
+
+  t4_byte *p = CopyNow(off);
+  *p = (*p &~(0x03 << n)) | (((t4_byte)v &0x03) << n);
+
+  return (v >> 2) == 0;
+}
+
+bool c4_ColOfInts::Set_4b(int index_, const t4_byte *item_) {
+  t4_i32 v = *(const t4_i32*)item_;
+
+  t4_i32 off = index_ >> 1;
+  d4_assert(off < ColSize());
+
+  const int n = (index_ &1) << 2;
+
+  t4_byte *p = CopyNow(off);
+  *p = (*p &~(0x0F << n)) | (((t4_byte)v &0x0F) << n);
+
+  return (v >> 4) == 0;
+}
+
+// avoid a bug in MS EVC 3.0's code gen for ARM (i.e. WinCE)
+#ifdef _ARM_
+#pragma optimize("g",off)
+#endif 
+
+bool c4_ColOfInts::Set_8i(int index_, const t4_byte *item_) {
+  t4_i32 v = *(const t4_i32*)item_;
+
+  t4_i32 off = index_;
+  d4_assert(off < ColSize());
+
+  *(char*)CopyNow(off) = (char)v;
+
+  return v == (signed char)v;
+}
+
+#ifdef _ARM_
+#pragma optimize("",on)
+#endif 
+
+bool c4_ColOfInts::Set_16i(int index_, const t4_byte *item_) {
+  t4_i32 v = *(const t4_i32*)item_;
+
+  t4_i32 off = index_ *(t4_i32)2;
+  d4_assert(off + 2 <= ColSize());
+
+  *(short*)CopyNow(off) = (short)v;
+
+  return v == (short)v;
+}
+
+bool c4_ColOfInts::Set_16r(int index_, const t4_byte *item_) {
+  t4_i32 v = *(const t4_i32*)item_;
+
+  t4_byte buf[2];
+  *(short*)buf = (short)v;
+
+  t4_i32 off = index_ *(t4_i32)2;
+  d4_assert(off + 2 <= ColSize());
+
+  t4_byte *vec = CopyNow(off);
+
+  vec[1] = buf[0];
+  vec[0] = buf[1];
+
+  return v == (short)v;
+}
+
+bool c4_ColOfInts::Set_32i(int index_, const t4_byte *item_) {
+  t4_i32 v = *(const t4_i32*)item_;
+
+  t4_i32 off = index_ *(t4_i32)4;
+  d4_assert(off + 4 <= ColSize());
+
+  *(t4_i32*)CopyNow(off) = (t4_i32)v;
+
+  return true;
+}
+
+bool c4_ColOfInts::Set_32r(int index_, const t4_byte *item_) {
+  t4_i32 off = index_ *(t4_i32)4;
+  d4_assert(off + 4 <= ColSize());
+
+  t4_byte *vec = CopyNow(off);
+
+  vec[3] = item_[0];
+  vec[2] = item_[1];
+  vec[1] = item_[2];
+  vec[0] = item_[3];
+
+  return true;
+}
+
+bool c4_ColOfInts::Set_64i(int index_, const t4_byte *item_) {
+  t4_i32 off = index_ *(t4_i32)8;
+  d4_assert(off + 8 <= ColSize());
+
+  t4_byte *vec = CopyNow(off);
+
+  for (int i = 0; i < 8; ++i)
+    vec[i] = item_[i];
+
+  return true;
+}
+
+bool c4_ColOfInts::Set_64r(int index_, const t4_byte *item_) {
+  t4_i32 off = index_ *(t4_i32)8;
+  d4_assert(off + 8 <= ColSize());
+
+  t4_byte *vec = CopyNow(off);
+
+  for (int i = 0; i < 8; ++i)
+    vec[7-i] = item_[i];
+
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_ColOfInts::c4_ColOfInts(c4_Persist *persist_, int width_): c4_Column
+  (persist_), _getter(&c4_ColOfInts::Get_0b), _setter(&c4_ColOfInts::Set_0b),
+  _currWidth(0), _dataWidth(width_), _numRows(0), _mustFlip(false){}
+
+void c4_ColOfInts::ForceFlip() {
+  _mustFlip = true;
+}
+
+int c4_ColOfInts::RowCount()const {
+  d4_assert(_numRows >= 0);
+
+  return _numRows;
+}
+
+int c4_ColOfInts::CalcAccessWidth(int numRows_, t4_i32 colSize_) {
+  d4_assert(numRows_ > 0);
+
+  int w = (int)((colSize_ << 3) / numRows_);
+
+  // deduce sub-byte sizes for small vectors, see c4_ColOfInts::Set
+  if (numRows_ <= 7 && 0 < colSize_ && colSize_ <= 6) {
+    static t4_byte realWidth[][6] =  {
+      // sz =  1:  2:  3:  4:  5:  6:
+       {
+        8, 16, 1, 32, 2, 4
+      }
+      ,  { //  n = 1
+        4, 8, 1, 16, 2, 0
+      }
+      ,  { //  n = 2
+        2, 4, 8, 1, 0, 16
+      }
+      ,  { //  n = 3
+        2, 4, 0, 8, 1, 0
+      }
+      ,  { //  n = 4
+        1, 2, 4, 0, 8, 0
+      }
+      ,  { //  n = 5
+        1, 2, 4, 0, 0, 8
+      }
+      ,  { //  n = 6
+        1, 2, 0, 4, 0, 0
+      }
+      ,  //  n = 7
+    };
+
+    w = realWidth[numRows_ - 1][(int)colSize_ - 1];
+    d4_assert(w > 0);
+  }
+
+  return (w &(w - 1)) == 0 ? w :  - 1;
+}
+
+void c4_ColOfInts::SetRowCount(int numRows_) {
+  _numRows = numRows_;
+  if (numRows_ > 0) {
+    int w = CalcAccessWidth(numRows_, ColSize());
+    d4_assert(w >= 0);
+    SetAccessWidth(w);
+  }
+}
+
+void c4_ColOfInts::FlipBytes() {
+  if (_currWidth > 8) {
+    int step = _currWidth >> 3;
+
+    c4_ColIter iter(*this, 0, ColSize());
+    while (iter.Next(step)) {
+      t4_byte *data = iter.BufSave();
+      d4_assert(data != 0);
+
+      for (int j = 0; j < step; ++j) {
+        t4_byte c = data[j];
+        data[j] = data[step - j - 1];
+        data[step - j - 1] = c;
+      }
+    }
+  }
+}
+
+void c4_ColOfInts::SetAccessWidth(int bits_) {
+  d4_assert((bits_ &(bits_ - 1)) == 0);
+
+  int l2bp1 = 0; // "log2 bits plus one" needed to represent value
+  while (bits_) {
+    ++l2bp1;
+    bits_ >>= 1;
+  }
+  d4_assert(0 <= l2bp1 && l2bp1 < 8);
+
+  _currWidth = (1 << l2bp1) >> 1;
+
+  if (l2bp1 > 4 && (_mustFlip || Persist() != 0 && Strategy()._bytesFlipped))
+    l2bp1 += 3;
+  // switch to the trailing entries for byte flipping
+
+  // Metrowerks Codewarrior 11 is dumb, it requires the "&c4_ColOfInts::"
+
+  static tGetter gTab[] =  {
+     &c4_ColOfInts::Get_0b,  //  0:  0 bits/entry
+     &c4_ColOfInts::Get_1b,  //  1:  1 bits/entry
+     &c4_ColOfInts::Get_2b,  //  2:  2 bits/entry
+     &c4_ColOfInts::Get_4b,  //  3:  4 bits/entry
+
+     &c4_ColOfInts::Get_8i,  //  4:  8 bits/entry
+     &c4_ColOfInts::Get_16i,  //  5: 16 bits/entry
+     &c4_ColOfInts::Get_32i,  //  6: 32 bits/entry
+     &c4_ColOfInts::Get_64i,  //  7: 64 bits/entry
+
+     &c4_ColOfInts::Get_16r,  //  8: 16 bits/entry, reversed
+     &c4_ColOfInts::Get_32r,  //  9: 32 bits/entry, reversed
+     &c4_ColOfInts::Get_64r,  // 10: 64 bits/entry, reversed
+  };
+
+  static tSetter sTab[] =  {
+     &c4_ColOfInts::Set_0b,  //  0:  0 bits/entry
+     &c4_ColOfInts::Set_1b,  //  1:  1 bits/entry
+     &c4_ColOfInts::Set_2b,  //  2:  2 bits/entry
+     &c4_ColOfInts::Set_4b,  //  3:  4 bits/entry
+
+     &c4_ColOfInts::Set_8i,  //  4:  8 bits/entry
+     &c4_ColOfInts::Set_16i,  //  5: 16 bits/entry
+     &c4_ColOfInts::Set_32i,  //  6: 32 bits/entry
+     &c4_ColOfInts::Set_64i,  //  7: 64 bits/entry
+
+     &c4_ColOfInts::Set_16r,  //  8: 16 bits/entry, reversed
+     &c4_ColOfInts::Set_32r,  //  9: 32 bits/entry, reversed
+     &c4_ColOfInts::Set_64r,  // 10: 64 bits/entry, reversed
+  };
+
+  d4_assert(l2bp1 < sizeof gTab / sizeof * gTab);
+
+  _getter = gTab[l2bp1];
+  _setter = sTab[l2bp1];
+
+  d4_assert(_getter != 0 && _setter != 0);
+}
+
+int c4_ColOfInts::ItemSize(int) {
+  return _currWidth >= 8 ? _currWidth >> 3:  - _currWidth;
+}
+
+const void *c4_ColOfInts::Get(int index_, int &length_) {
+  d4_assert(sizeof _item >= _dataWidth);
+
+  (this->*_getter)(index_);
+
+  length_ = _dataWidth;
+  return _item;
+}
+
+void c4_ColOfInts::Set(int index_, const c4_Bytes &buf_) {
+  d4_assert(buf_.Size() == _dataWidth);
+
+  if ((this->*_setter)(index_, buf_.Contents()))
+    return ;
+
+  d4_assert(buf_.Size() == sizeof(t4_i32));
+
+  int n = fBitsNeeded(*(const t4_i32*)buf_.Contents());
+  if (n > _currWidth) {
+    int k = RowCount();
+
+    t4_i32 oldEnd = ColSize();
+    t4_i32 newEnd = ((t4_i32)k *n + 7) >> 3;
+
+    if (newEnd > oldEnd) {
+      InsertData(oldEnd, newEnd - oldEnd, _currWidth == 0);
+
+      // 14-5-2002: need to get rid of gap in case it risks not being a
+      //  multiple of the increased size (bug, see s46 regression test)
+      //
+      // Example scenario: gap size is odd, data gets resized to 2/4-byte
+      // ints, data at end fits without moving gap to end, then we end
+      // up with a vector that has an int split *across* the gap - this
+      // commits just fine, but access to that split int is now bad.
+      //
+      // Lesson: need stricter/simpler consistency, it's way too complex!
+      if (n > 8)
+        RemoveGap();
+    }
+
+    // data value exceeds width, expand to new size and repeat
+    if (_currWidth > 0) {
+      d4_assert(n % _currWidth == 0); // must be expanding by a multiple
+
+      // To expand, we start by inserting a new appropriate chunk
+      // at the end, and expand the entries in place (last to first).
+
+      tGetter oldGetter = _getter;
+      SetAccessWidth(n);
+
+      d4_assert(sizeof _item >= _dataWidth);
+
+      // this expansion in place works because it runs backwards
+      while (--k >= 0) {
+        (this->*oldGetter)(k);
+        (this->*_setter)(k, _item);
+      }
+    } else {
+      if (_dataWidth > (int)sizeof(t4_i32))
+        n = _dataWidth << 3;
+      // don't trust setter result, use max instead
+
+      SetAccessWidth(n);
+    }
+
+    // now repeat the failed call to _setter
+     /* bool f = */(this->*_setter)(index_, buf_.Contents());
+    //? d4_assert(f);
+  }
+}
+
+t4_i32 c4_ColOfInts::GetInt(int index_) {
+  int n;
+  const void *p = Get(index_, n);
+  d4_assert(n == sizeof(t4_i32));
+  return *(const t4_i32*)p;
+}
+
+void c4_ColOfInts::SetInt(int index_, t4_i32 value_) {
+  Set(index_, c4_Bytes(&value_, sizeof value_));
+}
+
+int c4_ColOfInts::DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  d4_assert(b1_.Size() == sizeof(t4_i32));
+  d4_assert(b2_.Size() == sizeof(t4_i32));
+
+  t4_i32 v1 = *(const t4_i32*)b1_.Contents();
+  t4_i32 v2 = *(const t4_i32*)b2_.Contents();
+
+  return v1 == v2 ? 0 : v1 < v2 ?  - 1:  + 1;
+}
+
+void c4_ColOfInts::Insert(int index_, const c4_Bytes &buf_, int count_) {
+  d4_assert(buf_.Size() == _dataWidth);
+  d4_assert(count_ > 0);
+
+  bool clear = true;
+  const t4_byte *ptr = buf_.Contents();
+
+  for (int i = 0; i < _dataWidth; ++i)
+  if (*ptr++) {
+    clear = false;
+    break;
+  }
+
+  ResizeData(index_, count_, clear);
+
+  if (!clear)
+    while (--count_ >= 0)
+      Set(index_++, buf_);
+}
+
+void c4_ColOfInts::Remove(int index_, int count_) {
+  d4_assert(count_ > 0);
+
+  ResizeData(index_,  - count_);
+}
+
+void c4_ColOfInts::ResizeData(int index_, int count_, bool clear_) {
+  _numRows += count_;
+
+  if (!(_currWidth &7)) {
+    // not 1, 2, or 4
+    const t4_i32 w = (t4_i32)(_currWidth >> 3);
+    if (count_ > 0)
+      InsertData(index_ *w, count_ *w, clear_);
+    else
+      RemoveData(index_ *w,  - count_ * w);
+    return ;
+  }
+
+  d4_assert(_currWidth == 1 || _currWidth == 2 || _currWidth == 4);
+
+  /*  _currwidth    1:  2:  4:
+   *    shiftPos     3   2   1    shift the offset right this much
+   *    maskPos      7   3   1    mask the offset with this
+   */
+
+  const int shiftPos = _currWidth == 4 ? 1 : 4-_currWidth;
+  const int maskPos = (1 << shiftPos) - 1;
+
+  // the following code is similar to c4_Column::Resize, but at bit level
+
+  // turn insertion into deletion by inserting entire bytes
+  if (count_ > 0) {
+    unsigned off = (unsigned)index_ >> shiftPos;
+    int gapBytes = (count_ + maskPos) >> shiftPos;
+
+    InsertData(off, gapBytes, clear_);
+
+    // oops, we might have inserted too low by a few entries
+    const int bits = (index_ &maskPos) *_currWidth;
+    if (bits) {
+      const int maskLow = (1 << bits) - 1;
+
+      // move the first few bits to start of inserted range
+      t4_byte *p = CopyNow(off + gapBytes);
+      t4_byte one =  *p &maskLow;
+      *p &= ~maskLow;
+
+      *CopyNow(off) = one;
+    }
+
+    index_ += count_;
+    count_ -= gapBytes << shiftPos;
+    d4_assert(count_ <= 0);
+  }
+
+  // now perform a deletion using a forward loop to copy down
+  if (count_ < 0) {
+    c4_Bytes temp;
+
+    while (index_ < _numRows) {
+      int length;
+      const void *ptr = Get(index_ - count_, length);
+      Set(index_++, c4_Bytes(ptr, length));
+    }
+  } else
+    d4_assert(count_ == 0);
+
+  FixSize(false);
+}
+
+void c4_ColOfInts::FixSize(bool fudge_) {
+  int n = RowCount();
+  t4_i32 needBytes = ((t4_i32)n *_currWidth + 7) >> 3;
+
+  // use a special trick to mark sizes less than 1 byte in storage
+  if (fudge_ && 1 <= n && n <= 4 && (_currWidth &7)) {
+    const int shiftPos = _currWidth == 4 ? 1 : 4-_currWidth;
+
+    static t4_byte fakeSizes[3][4] =  {
+       { //  n:  1:  2:  3:  4:
+        6, 1, 2, 2
+      }
+      ,  { //  4-bit entries:   4b  8b 12b 16b
+        5, 5, 1, 1
+      }
+      ,  { //  2-bit entries:   2b  4b  6b  8b
+        3, 3, 4, 5
+      }
+      ,  //  1-bit entries:   1b  2b  3b  4b
+    };
+
+    // The idea is to use an "impossible" size (ie. 5, for n = 2)
+    // to give information about the current bit packing density.
+    d4_assert(needBytes <= 2);
+    needBytes = fakeSizes[shiftPos - 1][n - 1];
+  }
+
+  t4_i32 currSize = ColSize();
+
+  if (needBytes < currSize)
+    RemoveData(needBytes, currSize - needBytes);
+  else if (needBytes > currSize)
+    InsertData(currSize, needBytes - currSize, true);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool c4_ColIter::Next() {
+  _pos += _len;
+
+  _len = _column.AvailAt(_pos);
+  _ptr = _column.LoadNow(_pos);
+
+  if (!_ptr)
+    _len = 0;
+  else if (_pos + _len >= _limit)
+    _len = _limit - _pos;
+  else {
+    // 19990831 - optimization to avoid most copying
+    // while the end is adjacent to the next segment, extend it
+    while (_ptr + _len == _column.LoadNow(_pos + _len)) {
+      int n = _column.AvailAt(_pos + _len);
+      if (n == 0)
+        break;
+      // may be a short column (strings)
+
+      _len += n;
+
+      if (_pos + _len >= _limit) {
+        _len = _limit - _pos;
+        break;
+      }
+    }
+  }
+
+  return _len > 0;
+}
+
+bool c4_ColIter::Next(int max_) {
+  _pos += _len;
+
+  _len = _column.AvailAt(_pos);
+  _ptr = _column.LoadNow(_pos);
+
+  if (!_ptr)
+    _len = 0;
+  else if (_pos + _len > _limit)
+    _len = _limit - _pos;
+
+  if (_len <= 0)
+    return false;
+
+  if (_len > max_)
+    _len = max_;
+
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/column.h b/8.x/mk/src/column.h
new file mode 100755 (executable)
index 0000000..4241faf
--- /dev/null
@@ -0,0 +1,212 @@
+// column.h --
+// $Id: column.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Definition of the column classes
+ */
+
+#ifndef __COLUMN_H__
+#define __COLUMN_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+class c4_Column; // a column in a table
+class c4_ColIter; // an iterator over column data
+class c4_ColCache; // manages a cache for columns
+
+class c4_Persist; // not defined here
+class c4_Strategy; // not defined here
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Column {
+    c4_PtrArray _segments;
+    t4_i32 _position;
+    t4_i32 _size;
+    c4_Persist *_persist;
+    t4_i32 _gap;
+    int _slack;
+    bool _dirty;
+
+  public:
+    c4_Column(c4_Persist *persist_);
+    //: Constructs a column using the specified persistence manager.
+    ~c4_Column();
+
+    void SetBuffer(t4_i32);
+    //: Allocate a new buffer of the specified size.
+
+    c4_Persist *Persist()const;
+    //: Returns persistence manager for this column, or zero.
+    c4_Strategy &Strategy()const;
+    //: Returns the associated strategy pointer.
+    t4_i32 Position()const;
+    //: Special access for the DUMP program.
+    t4_i32 ColSize()const;
+    //: Returns the number of bytes as stored on disk.
+    bool IsDirty()const;
+    //: Returns true if contents needs to be saved.
+
+    void SetLocation(t4_i32, t4_i32);
+    //: Sets the position and size of this column on file.
+    void PullLocation(const t4_byte * &ptr_);
+    //: Extract position and size of this column.
+
+    int AvailAt(t4_i32 offset_)const;
+    //: Returns number of bytes we can access at once.
+    const t4_byte *LoadNow(t4_i32);
+    //: Makes sure the data is loaded into memory.
+    t4_byte *CopyNow(t4_i32);
+    //: Makes sure a copy of the data is in memory.
+    void Grow(t4_i32, t4_i32);
+    //: Grows the buffer by inserting space.
+    void Shrink(t4_i32, t4_i32);
+    //: Shrinks the buffer by removing space.
+    void SaveNow(c4_Strategy &, t4_i32 pos_);
+    //: Save the buffer to file.
+
+    const t4_byte *FetchBytes(t4_i32 pos_, int len_, c4_Bytes &buffer_, bool
+      forceCopy_);
+    //: Returns pointer to data, use buffer only if non-contiguous.
+    void StoreBytes(t4_i32 pos_, const c4_Bytes &buffer_);
+    //: Stores a copy of the buffer in the column.
+
+    bool RequiresMap()const;
+    void ReleaseAllSegments();
+
+    static t4_i32 PullValue(const t4_byte * &ptr_);
+    static void PushValue(t4_byte * &ptr_, t4_i32 v_);
+
+    void InsertData(t4_i32 index_, t4_i32 count_, bool clear_);
+    void RemoveData(t4_i32 index_, t4_i32 count_);
+    void RemoveGap();
+
+    enum {
+        kSegBits = 12, kSegMax = 1 << kSegBits, kSegMask = kSegMax - 1
+    };
+
+  private:
+    static int fSegIndex(t4_i32 offset_);
+    static t4_i32 fSegOffset(int index_);
+    static int fSegRest(t4_i32 offset_);
+
+    bool UsesMap(const t4_byte*)const;
+    bool IsMapped()const;
+
+    void ReleaseSegment(int);
+    void SetupSegments();
+    void Validate()const;
+    void FinishSlack();
+
+    void MoveGapUp(t4_i32 pos_);
+    void MoveGapDown(t4_i32 pos_);
+    void MoveGapTo(t4_i32 pos_);
+
+    t4_byte *CopyData(t4_i32, t4_i32, int);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ColOfInts: public c4_Column {
+  public:
+    c4_ColOfInts(c4_Persist *persist_, int width_ = sizeof(t4_i32));
+
+    int RowCount()const;
+    void SetRowCount(int numRows_);
+
+    void FlipBytes();
+
+    int ItemSize(int index_);
+    const void *Get(int index_, int &length_);
+    void Set(int index_, const c4_Bytes &buf_);
+
+    t4_i32 GetInt(int index_);
+    void SetInt(int index_, t4_i32 value_);
+
+    void Insert(int index_, const c4_Bytes &buf_, int count_);
+    void Remove(int index_, int count_);
+
+    static int CalcAccessWidth(int numRows_, t4_i32 colSize_);
+
+    void SetAccessWidth(int bits_);
+    void FixSize(bool fudge_);
+    void ForceFlip();
+
+    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
+
+  private:
+    typedef void(c4_ColOfInts:: *tGetter)(int);
+    typedef bool(c4_ColOfInts:: *tSetter)(int, const t4_byte*);
+
+    void Get_0b(int index_);
+    void Get_1b(int index_);
+    void Get_2b(int index_);
+    void Get_4b(int index_);
+    void Get_8i(int index_);
+    void Get_16i(int index_);
+    void Get_16r(int index_);
+    void Get_32i(int index_);
+    void Get_32r(int index_);
+    void Get_64i(int index_);
+    void Get_64r(int index_);
+
+    bool Set_0b(int index_, const t4_byte *item_);
+    bool Set_1b(int index_, const t4_byte *item_);
+    bool Set_2b(int index_, const t4_byte *item_);
+    bool Set_4b(int index_, const t4_byte *item_);
+    bool Set_8i(int index_, const t4_byte *item_);
+    bool Set_16i(int index_, const t4_byte *item_);
+    bool Set_16r(int index_, const t4_byte *item_);
+    bool Set_32i(int index_, const t4_byte *item_);
+    bool Set_32r(int index_, const t4_byte *item_);
+    bool Set_64i(int index_, const t4_byte *item_);
+    bool Set_64r(int index_, const t4_byte *item_);
+
+    void ResizeData(int index_, int count_, bool clear_ = false);
+
+    tGetter _getter;
+    tSetter _setter;
+
+    union {
+        t4_byte _item[8]; // holds temp result (careful with alignment!)
+        double _aligner; // needed for SPARC
+    };
+
+    int _currWidth; // number of bits used for one entry (0..64)
+    int _dataWidth; // number of bytes used for passing a value along
+    int _numRows;
+    bool _mustFlip;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ColIter {
+    c4_Column &_column;
+    t4_i32 _limit;
+    t4_i32 _pos;
+    int _len;
+    const t4_byte *_ptr;
+
+  public:
+    c4_ColIter(c4_Column &col_, t4_i32 offset_, t4_i32 limit_);
+    //  ~c4_ColIter ();
+
+    bool Next();
+    bool Next(int max_);
+
+    const t4_byte *BufLoad()const;
+    t4_byte *BufSave();
+    int BufLen()const;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "column.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/column.inl b/8.x/mk/src/column.inl
new file mode 100755 (executable)
index 0000000..9c75cee
--- /dev/null
@@ -0,0 +1,89 @@
+// column.inl --
+// $Id: column.inl 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Inlined members of the column classes
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Column
+
+d4_inline int c4_Column::fSegIndex(t4_i32 offset_)
+{
+    // limited by max array: 1 << (kSegBits + 15) with 16-bit ints
+  return (int) (offset_ >> kSegBits);
+}
+
+d4_inline t4_i32 c4_Column::fSegOffset(int index_)
+{
+  return (t4_i32) index_ << kSegBits;
+}
+
+d4_inline int c4_Column::fSegRest(t4_i32 offset_)
+{
+  return ((int) offset_ & kSegMask);
+}
+
+d4_inline c4_Persist* c4_Column::Persist() const
+{
+  return _persist;
+}
+
+d4_inline t4_i32 c4_Column::Position() const
+{
+  return _position;
+}
+
+d4_inline t4_i32 c4_Column::ColSize() const
+{
+  return _size;
+}
+
+d4_inline bool c4_Column::IsDirty() const
+{
+  return _dirty;
+}
+
+d4_inline void c4_Column::SetBuffer(t4_i32 length_)
+{
+  SetLocation(0, length_);
+  _dirty = true;
+}
+
+d4_inline const t4_byte* c4_Column::LoadNow(t4_i32 offset_)
+{
+  if (_segments.GetSize() == 0)
+    SetupSegments();
+
+  if (offset_ >= _gap)
+    offset_ += _slack;
+
+  t4_byte* ptr = (t4_byte*) _segments.GetAt(fSegIndex(offset_));
+  return ptr + fSegRest(offset_); 
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_ColIter
+
+d4_inline c4_ColIter::c4_ColIter (c4_Column& col_, t4_i32 offset_, t4_i32 limit_)
+  : _column (col_), _limit (limit_), _pos (offset_), _len (0), _ptr (0)
+{
+}
+
+d4_inline const t4_byte* c4_ColIter::BufLoad() const
+{
+  return _ptr;
+}
+
+d4_inline t4_byte* c4_ColIter::BufSave()
+{
+  return _column.CopyNow(_pos);
+}
+
+d4_inline int c4_ColIter::BufLen() const
+{
+  return _len;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/custom.cpp b/8.x/mk/src/custom.cpp
new file mode 100755 (executable)
index 0000000..c0e9b38
--- /dev/null
@@ -0,0 +1,925 @@
+// custom.cpp --
+// $Id: custom.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Implementation of many custom viewer classes
+ */
+
+#include "header.h"
+
+#include "custom.h"
+#include "format.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_CustomHandler: public c4_Handler {
+    c4_CustomSeq *_seq;
+
+  public:
+    c4_CustomHandler(const c4_Property &prop_, c4_CustomSeq *seq_);
+    virtual ~c4_CustomHandler();
+
+    virtual int ItemSize(int index_);
+    virtual const void *Get(int index_, int &length_);
+    virtual void Set(int index_, const c4_Bytes &buf_);
+
+    virtual void Insert(int index_, const c4_Bytes &buf_, int count_);
+    virtual void Remove(int index_, int count_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_CustomHandler::c4_CustomHandler(const c4_Property &prop_, c4_CustomSeq *seq_)
+  : c4_Handler(prop_), _seq(seq_) {
+  d4_assert(_seq != 0);
+}
+
+c4_CustomHandler::~c4_CustomHandler(){}
+
+int c4_CustomHandler::ItemSize(int index_) {
+  c4_Bytes &buf = _seq->Buffer();
+
+  int colnum = _seq->PropIndex(Property().GetId());
+  d4_assert(colnum >= 0);
+
+  if (!_seq->DoGet(index_, colnum, buf))
+    return 0;
+
+  return buf.Size();
+}
+
+const void *c4_CustomHandler::Get(int index_, int &length_) {
+  c4_Bytes &buf = _seq->Buffer();
+
+  int colnum = _seq->PropIndex(Property().GetId());
+  d4_assert(colnum >= 0);
+
+  if (!_seq->DoGet(index_, colnum, buf))
+    ClearBytes(buf);
+
+  length_ = buf.Size();
+  return buf.Contents();
+}
+
+void c4_CustomHandler::Set(int index_, const c4_Bytes &buf_) {
+  int colnum = _seq->PropIndex(Property().GetId());
+  d4_assert(colnum >= 0);
+
+  _seq->DoSet(index_, colnum, buf_);
+}
+
+void c4_CustomHandler::Insert(int, const c4_Bytes &, int) {
+  d4_assert(0); //! not yet
+}
+
+void c4_CustomHandler::Remove(int, int) {
+  d4_assert(0); //! not yet
+}
+
+c4_Handler *c4_CustomSeq::CreateHandler(const c4_Property &prop_) {
+  return d4_new c4_CustomHandler(prop_, this);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_CustomSeq::c4_CustomSeq(c4_CustomViewer *viewer_): c4_HandlerSeq(0), _viewer
+  (viewer_), _inited(false) {
+  d4_assert(_viewer != 0);
+
+  // set up handlers to match a template obtained from the viewer
+  c4_View v = viewer_->GetTemplate();
+
+  for (int i = 0; i < v.NumProperties(); ++i)
+    PropIndex(v.NthProperty(i));
+
+  _inited = true;
+}
+
+c4_CustomSeq::~c4_CustomSeq() {
+  delete _viewer;
+}
+
+int c4_CustomSeq::NumRows()const {
+  return _inited ? _viewer->GetSize(): 0;
+}
+
+bool c4_CustomSeq::RestrictSearch(c4_Cursor cursor_, int &pos_, int &count_) {
+  if (count_ > 0) {
+    int n;
+    int o = _viewer->Lookup(cursor_, n);
+    // a -1 result means: "don't know, please scan all"
+    if (o < 0)
+      return count_ > 0;
+
+    if (n > 0) {
+      if (pos_ < o) {
+        count_ -= o - pos_;
+        pos_ = o;
+      }
+
+      if (pos_ + count_ > o + n)
+        count_ = o + n - pos_;
+
+      if (count_ > 0)
+        return true;
+    }
+  }
+
+  count_ = 0;
+  return false;
+}
+
+void c4_CustomSeq::InsertAt(int p_, c4_Cursor c_, int n_) {
+  _viewer->InsertRows(p_, c_, n_);
+}
+
+void c4_CustomSeq::RemoveAt(int p_, int n_) {
+  _viewer->RemoveRows(p_, n_);
+}
+
+void c4_CustomSeq::Move(int, int) {
+  d4_assert(false); //! not yet
+}
+
+bool c4_CustomSeq::DoGet(int row_, int col_, c4_Bytes &buf_)const {
+  d4_assert(_inited);
+
+  return _viewer->GetItem(row_, col_, buf_);
+}
+
+void c4_CustomSeq::DoSet(int row_, int col_, const c4_Bytes &buf_) {
+  d4_assert(_inited);
+
+  d4_dbgdef(const bool f = )_viewer->SetItem(row_, col_, buf_);
+  d4_assert(f);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_CustomViewer
+ *
+ *  Abstract base class for definition of custom views.
+ *
+ *  A custom view is a view which can be accessed like any other view, using
+ *  row and property operations, but which is fully managed by a customized
+ *  "viewer" class.  The viewer will eventually handle all requests for the
+ *  view, such as defining its structure and size, as well as providing the
+ *  actual data values when requested.
+ *
+ *  Custom views cannot propagate changes.
+ *
+ *  To implement a custom view, you must derive your viewer from this base
+ *  class and define each of the virtual members.  Then create a new object
+ *  of this type on the heap and pass it to the c4_View constructor.  Your
+ *  viewer will automatically be destroyed when the last reference to its
+ *  view goes away.  See the DBF2MK sample code for an example of a viewer.
+ */
+
+c4_CustomViewer::~c4_CustomViewer(){}
+
+/// Locate a row in this view, try to use native searches
+int c4_CustomViewer::Lookup(c4_Cursor, int &count_) {
+  count_ = GetSize();
+  return 0; // not implemented, return entire view range
+}
+
+/// Store one data item, supplied as a generic data value
+bool c4_CustomViewer::SetItem(int, int, const c4_Bytes &) {
+  return false; // default is not modifiable
+}
+
+/// Insert one or more copies of a row (if possible)
+bool c4_CustomViewer::InsertRows(int, c4_Cursor, int) {
+  return false; // default is not modifiable
+}
+
+/// Remove one or more rows (this is not always possible)
+bool c4_CustomViewer::RemoveRows(int, int) {
+  return false; // default is not modifiable
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_SliceViewer: public c4_CustomViewer {
+    c4_View _parent;
+    int _first, _limit, _step;
+
+  public:
+    c4_SliceViewer(c4_Sequence &seq_, int first_, int limit_, int step_);
+    virtual ~c4_SliceViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+    virtual bool InsertRows(int pos_, c4_Cursor value_, int count_ = 1);
+    virtual bool RemoveRows(int pos_, int count_ = 1);
+};
+
+c4_SliceViewer::c4_SliceViewer(c4_Sequence &seq_, int first_, int limit_, int
+  step_): _parent(&seq_), _first(first_), _limit(limit_), _step(step_) {
+  d4_assert(_step != 0);
+}
+
+c4_SliceViewer::~c4_SliceViewer(){}
+
+c4_View c4_SliceViewer::GetTemplate() {
+  return _parent.Clone(); // could probably return _parent just as well
+}
+
+int c4_SliceViewer::GetSize() {
+  int n = _limit >= 0 ? _limit : _parent.GetSize();
+  if (n < _first)
+    n = _first;
+
+  int k = _step < 0 ?  - _step: _step;
+  return (n - _first + k - 1) / k;
+}
+
+bool c4_SliceViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  row_ = _first + _step *(_step > 0 ? row_ : row_ - GetSize() + 1);
+
+  return _parent.GetItem(row_, col_, buf_);
+}
+
+bool c4_SliceViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  row_ = _first + _step *(_step > 0 ? row_ : row_ - GetSize() + 1);
+
+  _parent.SetItem(row_, col_, buf_);
+  return true;
+}
+
+bool c4_SliceViewer::InsertRows(int pos_, c4_Cursor value_, int count_) {
+  if (_step != 1)
+    return false;
+
+  pos_ = _first + _step *(_step > 0 ? pos_ : pos_ - GetSize() + 1);
+  if (_limit >= 0)
+    _limit += count_;
+
+  _parent.InsertAt(pos_,  *value_, count_);
+  return true;
+}
+
+bool c4_SliceViewer::RemoveRows(int pos_, int count_) {
+  if (_step != 1)
+    return false;
+
+  pos_ = _first + _step *(_step > 0 ? pos_ : pos_ - GetSize() + 1);
+  if (_limit >= 0)
+    _limit -= count_;
+
+  _parent.RemoveAt(pos_, count_);
+  return true;
+}
+
+c4_CustomViewer *f4_CustSlice(c4_Sequence &seq_, int first_, int limit_, int
+  step_) {
+  return d4_new c4_SliceViewer(seq_, first_, limit_, step_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ProductViewer: public c4_CustomViewer {
+    c4_View _parent, _argView, _template;
+
+  public:
+    c4_ProductViewer(c4_Sequence &seq_, const c4_View &view_);
+    virtual ~c4_ProductViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+};
+
+c4_ProductViewer::c4_ProductViewer(c4_Sequence &seq_, const c4_View &view_):
+  _parent(&seq_), _argView(view_), _template(_parent.Clone()) {
+  for (int i = 0; i < _argView.NumProperties(); ++i)
+    _template.AddProperty(_argView.NthProperty(i));
+}
+
+c4_ProductViewer::~c4_ProductViewer(){}
+
+c4_View c4_ProductViewer::GetTemplate() {
+  return _template;
+}
+
+int c4_ProductViewer::GetSize() {
+  return _parent.GetSize() *_argView.GetSize();
+}
+
+bool c4_ProductViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  c4_View v = _parent;
+
+  if (col_ < v.NumProperties()) {
+    row_ /= _argView.GetSize();
+  } else {
+    v = _argView;
+    row_ %= _argView.GetSize();
+    col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+
+    d4_assert(col_ >= 0);
+  }
+
+  return v.GetItem(row_, col_, buf_);
+}
+
+c4_CustomViewer *f4_CustProduct(c4_Sequence &seq_, const c4_View &view_) {
+  return d4_new c4_ProductViewer(seq_, view_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_RemapWithViewer: public c4_CustomViewer {
+    c4_View _parent, _argView;
+
+  public:
+    c4_RemapWithViewer(c4_Sequence &seq_, const c4_View &view_);
+    virtual ~c4_RemapWithViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+};
+
+c4_RemapWithViewer::c4_RemapWithViewer(c4_Sequence &seq_, const c4_View &view_)
+  : _parent(&seq_), _argView(view_){}
+
+c4_RemapWithViewer::~c4_RemapWithViewer(){}
+
+c4_View c4_RemapWithViewer::GetTemplate() {
+  return _parent.Clone(); // could probably return _parent just as well
+}
+
+int c4_RemapWithViewer::GetSize() {
+  return _argView.GetSize();
+}
+
+bool c4_RemapWithViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  const c4_Property &map = _argView.NthProperty(0);
+  d4_assert(map.Type() == 'I');
+
+  row_ = ((const c4_IntProp &)map)(_argView[row_]);
+
+  return _parent.GetItem(row_, col_, buf_);
+}
+
+bool c4_RemapWithViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  const c4_Property &map = _argView.NthProperty(0);
+  d4_assert(map.Type() == 'I');
+
+  row_ = ((const c4_IntProp &)map)(_argView[row_]);
+
+  _parent.SetItem(row_, col_, buf_);
+  return true;
+}
+
+c4_CustomViewer *f4_CustRemapWith(c4_Sequence &seq_, const c4_View &view_) {
+  return d4_new c4_RemapWithViewer(seq_, view_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_PairViewer: public c4_CustomViewer {
+    c4_View _parent, _argView, _template;
+
+  public:
+    c4_PairViewer(c4_Sequence &seq_, const c4_View &view_);
+    virtual ~c4_PairViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+    virtual bool InsertRows(int pos_, c4_Cursor value_, int count_ = 1);
+    virtual bool RemoveRows(int pos_, int count_ = 1);
+};
+
+c4_PairViewer::c4_PairViewer(c4_Sequence &seq_, const c4_View &view_): _parent
+  (&seq_), _argView(view_), _template(_parent.Clone()) {
+  for (int i = 0; i < _argView.NumProperties(); ++i)
+    _template.AddProperty(_argView.NthProperty(i));
+}
+
+c4_PairViewer::~c4_PairViewer(){}
+
+c4_View c4_PairViewer::GetTemplate() {
+  return _template;
+}
+
+int c4_PairViewer::GetSize() {
+  return _parent.GetSize();
+}
+
+bool c4_PairViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  c4_View v = _parent;
+
+  if (col_ >= v.NumProperties()) {
+    v = _argView;
+    col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+    d4_assert(col_ >= 0);
+  }
+
+  return v.GetItem(row_, col_, buf_);
+}
+
+bool c4_PairViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  c4_View v = _parent;
+
+  if (col_ >= v.NumProperties()) {
+    v = _argView;
+    col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+    d4_assert(col_ >= 0);
+  }
+
+  v.SetItem(row_, col_, buf_);
+  return true;
+}
+
+bool c4_PairViewer::InsertRows(int pos_, c4_Cursor value_, int count_) {
+  _parent.InsertAt(pos_,  *value_, count_);
+  _argView.InsertAt(pos_,  *value_, count_);
+  return true;
+}
+
+bool c4_PairViewer::RemoveRows(int pos_, int count_) {
+  _parent.RemoveAt(pos_, count_);
+  _argView.RemoveAt(pos_, count_);
+  return true;
+}
+
+c4_CustomViewer *f4_CustPair(c4_Sequence &seq_, const c4_View &view_) {
+  return d4_new c4_PairViewer(seq_, view_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ConcatViewer: public c4_CustomViewer {
+    c4_View _parent, _argView;
+
+  public:
+    c4_ConcatViewer(c4_Sequence &seq_, const c4_View &view_);
+    virtual ~c4_ConcatViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+};
+
+c4_ConcatViewer::c4_ConcatViewer(c4_Sequence &seq_, const c4_View &view_):
+  _parent(&seq_), _argView(view_){}
+
+c4_ConcatViewer::~c4_ConcatViewer(){}
+
+c4_View c4_ConcatViewer::GetTemplate() {
+  return _parent.Clone(); // could probably return _parent just as well
+}
+
+int c4_ConcatViewer::GetSize() {
+  return _parent.GetSize() + _argView.GetSize();
+}
+
+bool c4_ConcatViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  c4_View v = _parent;
+
+  if (row_ >= _parent.GetSize()) {
+    v = _argView;
+    row_ -= _parent.GetSize();
+    col_ = v.FindProperty(_parent.NthProperty(col_).GetId());
+
+    if (col_ < 0)
+      return false;
+  }
+
+  return v.GetItem(row_, col_, buf_);
+}
+
+bool c4_ConcatViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  c4_View v = _parent;
+
+  if (row_ >= _parent.GetSize()) {
+    v = _argView;
+    row_ -= _parent.GetSize();
+    col_ = v.FindProperty(_parent.NthProperty(col_).GetId());
+    d4_assert(col_ >= 0);
+  }
+
+  v.SetItem(row_, col_, buf_);
+  return true;
+}
+
+c4_CustomViewer *f4_CustConcat(c4_Sequence &seq_, const c4_View &view_) {
+  return d4_new c4_ConcatViewer(seq_, view_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_RenameViewer: public c4_CustomViewer {
+    c4_View _parent, _template;
+
+  public:
+    c4_RenameViewer(c4_Sequence &seq_, const c4_Property &old_, const
+      c4_Property &new_);
+    virtual ~c4_RenameViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    virtual bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+    //virtual bool InsertRows(int pos_, c4_Cursor value_, int count_=1);
+    //virtual bool RemoveRows(int pos_, int count_=1);
+};
+
+c4_RenameViewer::c4_RenameViewer(c4_Sequence &seq_, const c4_Property &old_,
+  const c4_Property &new_): _parent(&seq_) {
+  for (int i = 0; i < _parent.NumProperties(); ++i) {
+    const c4_Property &prop = _parent.NthProperty(i);
+    _template.AddProperty(prop.GetId() == old_.GetId() ? new_ : prop);
+  }
+}
+
+c4_RenameViewer::~c4_RenameViewer(){}
+
+c4_View c4_RenameViewer::GetTemplate() {
+  return _template;
+}
+
+int c4_RenameViewer::GetSize() {
+  return _parent.GetSize();
+}
+
+bool c4_RenameViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  return _parent.GetItem(row_, col_, buf_);
+}
+
+bool c4_RenameViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  _parent.SetItem(row_, col_, buf_);
+  return true;
+}
+
+c4_CustomViewer *f4_CustRename(c4_Sequence &seq_, const c4_Property &old_,
+  const c4_Property &new_) {
+  return d4_new c4_RenameViewer(seq_, old_, new_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_GroupByViewer: public c4_CustomViewer {
+    c4_View _parent, _keys, _sorted, _temp;
+    c4_Property _result;
+    c4_DWordArray _map;
+
+    int ScanTransitions(int lo_, int hi_, t4_byte *flags_, const c4_View
+      &match_)const;
+
+  public:
+    c4_GroupByViewer(c4_Sequence &seq_, const c4_View &keys_, const c4_Property
+      &result_);
+    virtual ~c4_GroupByViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+};
+
+c4_GroupByViewer::c4_GroupByViewer(c4_Sequence &seq_, const c4_View &keys_,
+  const c4_Property &result_): _parent(&seq_), _keys(keys_), _result(result_) {
+  _sorted = _parent.SortOn(_keys);
+  int n = _sorted.GetSize();
+
+  c4_Bytes temp;
+  t4_byte *buf = temp.SetBufferClear(n);
+
+  int groups = 0;
+  if (n > 0) {
+    ++buf[0]; // the first entry is always a transition
+    groups = 1+ScanTransitions(1, n, buf, _sorted.Project(_keys));
+  }
+
+  // set up a map pointing to each transition
+  _map.SetSize(groups + 1);
+  int j = 0;
+
+  for (int i = 0; i < n; ++i)
+    if (buf[i])
+      _map.SetAt(j++, i);
+
+  // also append an entry to point just past the end
+  _map.SetAt(j, n);
+
+  d4_assert(_map.GetAt(0) == 0);
+  d4_assert(j == groups);
+}
+
+c4_GroupByViewer::~c4_GroupByViewer(){}
+
+int c4_GroupByViewer::ScanTransitions(int lo_, int hi_, t4_byte *flags_, const
+  c4_View &match_)const {
+  d4_assert(lo_ > 0);
+
+  int m = hi_ - lo_;
+  d4_assert(m >= 0);
+
+  // done if nothing left or if entire range is identical
+  if (m == 0 || match_[lo_ - 1] == match_[hi_ - 1])
+    return 0;
+
+  // range has a transition, done if it is exactly of size one
+  if (m == 1) {
+    ++(flags_[lo_]);
+    return 1;
+  }
+
+  // use binary splitting if the range has enough entries
+  if (m >= 5)
+    return ScanTransitions(lo_, lo_ + m / 2, flags_, match_) + ScanTransitions
+      (lo_ + m / 2, hi_, flags_, match_);
+
+  // else use a normal linear scan
+  int n = 0;
+
+  for (int i = lo_; i < hi_; ++i)
+  if (match_[i] != match_[i - 1]) {
+    ++(flags_[i]);
+    ++n;
+  }
+
+  return n;
+}
+
+c4_View c4_GroupByViewer::GetTemplate() {
+  c4_View v = _keys.Clone();
+  v.AddProperty(_result);
+
+  return v;
+}
+
+int c4_GroupByViewer::GetSize() {
+  d4_assert(_map.GetSize() > 0);
+
+  return _map.GetSize() - 1;
+}
+
+bool c4_GroupByViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  if (col_ < _keys.NumProperties())
+    return _sorted.GetItem(_map.GetAt(row_), col_, buf_);
+
+  d4_assert(col_ == _keys.NumProperties());
+
+  t4_i32 count;
+  switch (_result.Type()) {
+    case 'I':
+      count = _map.GetAt(row_ + 1) - _map.GetAt(row_);
+      buf_ = c4_Bytes(&count, sizeof count, true);
+      break;
+    case 'V':
+      _temp = _sorted.Slice(_map.GetAt(row_), _map.GetAt(row_ + 1))
+        .ProjectWithout(_keys);
+      buf_ = c4_Bytes(&_temp, sizeof _temp, true);
+      break;
+    default:
+      d4_assert(0);
+  }
+
+  return true;
+}
+
+c4_CustomViewer *f4_CustGroupBy(c4_Sequence &seq_, const c4_View &template_,
+  const c4_Property &result_) {
+  return d4_new c4_GroupByViewer(seq_, template_, result_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_JoinPropViewer: public c4_CustomViewer {
+    c4_View _parent, _template;
+    c4_ViewProp _sub;
+    int _subPos, _subWidth;
+    c4_DWordArray _base, _offset;
+
+  public:
+    c4_JoinPropViewer(c4_Sequence &seq_, const c4_ViewProp &sub_, bool outer_);
+    virtual ~c4_JoinPropViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+};
+
+c4_JoinPropViewer::c4_JoinPropViewer(c4_Sequence &seq_, const c4_ViewProp &sub_,
+  bool outer_): _parent(&seq_), _sub(sub_), _subPos(_parent.FindProperty
+  (sub_.GetId())), _subWidth(0) {
+  d4_assert(_subPos >= 0);
+
+  for (int k = 0; k < _parent.NumProperties(); ++k) {
+    if (k != _subPos)
+      _template.AddProperty(_parent.NthProperty(k));
+    else
+    // if there are no rows, then this join does very little anyway
+    //! OOPS: if this is an unattached view, then the subviews can differ
+    if (_parent.GetSize() > 0) {
+      c4_View view = sub_(_parent[0]);
+      for (int l = 0; l < view.NumProperties(); ++l) {
+        _template.AddProperty(view.NthProperty(l));
+        ++_subWidth;
+      }
+    }
+  }
+
+  _base.SetSize(0, 5);
+  _offset.SetSize(0, 5);
+
+  for (int i = 0; i < _parent.GetSize(); ++i) {
+    c4_View v = _sub(_parent[i]);
+
+    int n = v.GetSize();
+    if (n == 0 && outer_) {
+      _base.Add(i);
+      _offset.Add(~(t4_i32)0); // special null entry for outer joins
+    } else
+    for (int j = 0; j < n; ++j) {
+      _base.Add(i);
+      _offset.Add(j);
+    }
+  }
+}
+
+c4_JoinPropViewer::~c4_JoinPropViewer(){}
+
+c4_View c4_JoinPropViewer::GetTemplate() {
+  return _template;
+}
+
+int c4_JoinPropViewer::GetSize() {
+  return _base.GetSize();
+}
+
+bool c4_JoinPropViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  c4_View v = _parent;
+  int r = _base.GetAt(row_);
+
+  if (col_ >= _subPos)
+  if (col_ >= _subPos + _subWidth) {
+    col_ -= _subWidth - 1;
+  } else {
+    v = _sub(_parent[r]);
+    r = _offset.GetAt(row_);
+    if (r < 0)
+      return false;
+    // if this is a null row in an outer join
+
+    col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+    if (col_ < 0)
+      return false;
+    // if subview doesn't have all properties
+  }
+
+  return v.GetItem(r, col_, buf_);
+}
+
+c4_CustomViewer *f4_CustJoinProp(c4_Sequence &seq_, const c4_ViewProp &sub_,
+  bool outer_) {
+  return d4_new c4_JoinPropViewer(seq_, sub_, outer_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_JoinViewer: public c4_CustomViewer {
+    c4_View _parent, _argView, _template;
+    c4_DWordArray _base, _offset;
+
+  public:
+    c4_JoinViewer(c4_Sequence &seq_, const c4_View &keys_, const c4_View &view_,
+      bool outer_);
+    virtual ~c4_JoinViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+};
+
+c4_JoinViewer::c4_JoinViewer(c4_Sequence &seq_, const c4_View &keys_, const
+  c4_View &view_, bool outer_): _parent(&seq_), _argView(view_.SortOn(keys_)) {
+  // why not in GetTemplate, since we don't need to know this...
+  _template = _parent.Clone();
+  for (int l = 0; l < _argView.NumProperties(); ++l)
+    _template.AddProperty(_argView.NthProperty(l));
+
+  c4_View sorted = _parent.SortOn(keys_).Project(keys_);
+  c4_View temp = _argView.Project(keys_);
+
+  _base.SetSize(0, 5);
+  _offset.SetSize(0, 5);
+
+  int j = 0, n = 0;
+
+  for (int i = 0; i < sorted.GetSize(); ++i) {
+    int orig = _parent.GetIndexOf(sorted[i]);
+    d4_assert(orig >= 0);
+
+    if (i > 0 && sorted[i] == sorted[i - 1]) {
+      // if last key was same, repeat the same join
+      int last = _offset.GetSize() - n;
+      for (int k = 0; k < n; ++k) {
+        _base.Add(orig);
+        _offset.Add(_offset.GetAt(last + k));
+      }
+    } else
+     { // no, this is a new combination
+      bool match = false;
+
+      // advance until the temp view entry is >= this sorted entry
+      while (j < temp.GetSize())
+      if (sorted[i] <= temp[j]) {
+        match = sorted[i] == temp[j];
+        break;
+      } else
+        ++j;
+
+      n = 0;
+
+      if (match) {
+        do {
+          _base.Add(orig);
+          _offset.Add(j);
+          ++n;
+        } while (++j < temp.GetSize() && temp[j] == temp[j - 1]);
+      } else if (outer_) {
+        // no match, add an entry anyway if this is an outer join
+        _base.Add(orig);
+        _offset.Add(~(t4_i32)0); // special null entry
+        ++n;
+      }
+    }
+  }
+}
+
+c4_JoinViewer::~c4_JoinViewer(){}
+
+c4_View c4_JoinViewer::GetTemplate() {
+  return _template;
+}
+
+int c4_JoinViewer::GetSize() {
+  return _base.GetSize();
+}
+
+bool c4_JoinViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  c4_View v = _parent;
+  int r = _base.GetAt(row_);
+
+  if (col_ >= v.NumProperties()) {
+    v = _argView;
+    r = _offset.GetAt(row_);
+    if (r < 0)
+      return false;
+    // if this is a null row in an outer join
+
+    col_ = v.FindProperty(_template.NthProperty(col_).GetId());
+    if (col_ < 0)
+      return false;
+    // if second view doesn't have all properties
+  }
+
+  return v.GetItem(r, col_, buf_);
+}
+
+#if 0
+bool c4_JoinViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  c4_View v = _parent;
+
+  int o = 0;
+  int r = _offset.GetAt(row_);
+
+  if (r < 0) {
+    o = ~r;
+    if (o == 0)
+      return false;
+    // if this is a null row in an outer join
+    r -= o;
+  }
+
+  if (col_ >= v.NumProperties()) {
+    v = _argView;
+    r = _o;
+
+    col_ = v.FindProperty(_template.NthProperty(col_));
+    if (col_ < 0)
+      return false;
+    // if second view doesn't have all properties
+  }
+
+  return v.GetItem(r, col_, buf_);
+}
+
+#endif 
+
+c4_CustomViewer *f4_CustJoin(c4_Sequence &seq_, const c4_View &keys_, const
+  c4_View &view_, bool outer_) {
+  return d4_new c4_JoinViewer(seq_, keys_, view_, outer_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/custom.h b/8.x/mk/src/custom.h
new file mode 100755 (executable)
index 0000000..12de5bf
--- /dev/null
@@ -0,0 +1,63 @@
+// custom.h --
+// $Id: custom.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Encapsulation of many custom viewer classes
+ */
+
+#ifndef __CUSTOM_H__
+#define __CUSTOM_H__
+
+#ifndef __FIELD_H__
+#include "field.h"
+#endif 
+#ifndef __STORE_H__
+#include "handler.h"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_CustomSeq: public c4_HandlerSeq {
+    c4_CustomViewer *_viewer;
+    bool _inited;
+
+  public:
+    c4_CustomSeq(c4_CustomViewer *viewer_);
+    virtual ~c4_CustomSeq();
+
+    virtual int NumRows()const;
+
+    virtual bool RestrictSearch(c4_Cursor, int &, int &);
+
+    virtual void InsertAt(int, c4_Cursor, int = 1);
+    virtual void RemoveAt(int, int = 1);
+    virtual void Move(int from_, int);
+
+    bool DoGet(int row_, int col_, c4_Bytes &buf_)const;
+    void DoSet(int row_, int col_, const c4_Bytes &buf_);
+
+  private:
+    // this *is* used, as override
+    virtual c4_Handler *CreateHandler(const c4_Property &);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+extern c4_CustomViewer *f4_CustSlice(c4_Sequence &, int, int, int);
+extern c4_CustomViewer *f4_CustProduct(c4_Sequence &, const c4_View &);
+extern c4_CustomViewer *f4_CustRemapWith(c4_Sequence &, const c4_View &);
+extern c4_CustomViewer *f4_CustPair(c4_Sequence &, const c4_View &);
+extern c4_CustomViewer *f4_CustConcat(c4_Sequence &, const c4_View &);
+extern c4_CustomViewer *f4_CustRename(c4_Sequence &, const c4_Property &, const
+  c4_Property &);
+extern c4_CustomViewer *f4_CustGroupBy(c4_Sequence &, const c4_View &, const
+  c4_Property &);
+extern c4_CustomViewer *f4_CustJoinProp(c4_Sequence &, const c4_ViewProp &,
+  bool);
+extern c4_CustomViewer *f4_CustJoin(c4_Sequence &, const c4_View &, const
+  c4_View &, bool);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/derived.cpp b/8.x/mk/src/derived.cpp
new file mode 100755 (executable)
index 0000000..33fe4b8
--- /dev/null
@@ -0,0 +1,899 @@
+// derived.cpp --
+// $Id: derived.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Derived views are virtual views which track changes
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "store.h"
+#include "derived.h"
+
+#include <stdlib.h>   // qsort
+
+/////////////////////////////////////////////////////////////////////////////
+// Implemented in this file
+
+//  class c4_Sequence;
+class c4_DerivedSeq;
+class c4_FilterSeq;
+class c4_SortSeq;
+class c4_ProjectSeq;
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FilterSeq: public c4_DerivedSeq {
+  protected:
+    c4_DWordArray _rowMap;
+    c4_DWordArray _revMap;
+    c4_Row _lowRow;
+    c4_Row _highRow;
+    c4_Bytes _rowIds;
+
+  protected:
+    c4_FilterSeq(c4_Sequence &seq_);
+    virtual ~c4_FilterSeq();
+
+    void FixupReverseMap();
+    int PosInMap(int index_)const;
+    bool Match(int index_, c4_Sequence &seq_, const int * = 0, const int * = 0)
+      const;
+    bool MatchOne(int prop_, const c4_Bytes &data_)const;
+
+  public:
+    c4_FilterSeq(c4_Sequence &seq_, c4_Cursor low_, c4_Cursor high_);
+
+    virtual int RemapIndex(int, const c4_Sequence*)const;
+
+    virtual int NumRows()const;
+
+    virtual int Compare(int, c4_Cursor)const;
+    virtual bool Get(int, int, c4_Bytes &);
+
+    virtual void InsertAt(int, c4_Cursor, int = 1);
+    virtual void RemoveAt(int, int = 1);
+    virtual void Set(int, const c4_Property &, const c4_Bytes &);
+    virtual void SetSize(int);
+
+    virtual c4_Notifier *PreChange(c4_Notifier &nf_);
+    virtual void PostChange(c4_Notifier &nf_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FilterSeq::c4_FilterSeq(c4_Sequence &seq_): c4_DerivedSeq(seq_) {
+  _rowMap.SetSize(_seq.NumRows());
+  _revMap.SetSize(_seq.NumRows());
+  d4_assert(NumRows() == _seq.NumRows());
+
+  for (int i = 0; i < NumRows(); ++i) {
+    _rowMap.SetAt(i, i);
+    _revMap.SetAt(i, i);
+  }
+}
+
+c4_FilterSeq::c4_FilterSeq(c4_Sequence &seq_, c4_Cursor low_, c4_Cursor high_):
+  c4_DerivedSeq(seq_), _lowRow(*low_), _highRow(*high_) {
+  d4_assert((&_lowRow)._index == 0);
+  d4_assert((&_highRow)._index == 0);
+
+  // use a sneaky way to obtain the sequence pointers and indices
+  c4_Sequence *lowSeq = (&_lowRow)._seq;
+  c4_Sequence *highSeq = (&_highRow)._seq;
+  d4_assert(lowSeq && highSeq);
+
+  // prepare column numbers to avoid looking them up on every row
+  // lowCols is a vector of column numbers to use for the low limits
+  // highCols is a vector of column numbers to use for the high limits
+  int nl = lowSeq->NumHandlers(), nh = highSeq->NumHandlers();
+  c4_Bytes lowVec, highVec;
+  int *lowCols = (int*)lowVec.SetBufferClear(nl *sizeof(int));
+  int *highCols = (int*)highVec.SetBufferClear(nh *sizeof(int));
+
+  for (int il = 0; il < nl; ++il)
+    lowCols[il] = seq_.PropIndex(lowSeq->NthPropId(il));
+  for (int ih = 0; ih < nh; ++ih)
+    highCols[ih] = seq_.PropIndex(highSeq->NthPropId(ih));
+
+  // set _rowIds flag buffer for fast matching
+   {
+    int max =  - 1;
+
+     {
+      for (int i1 = 0; i1 < nl; ++i1) {
+        int n = lowSeq->NthPropId(i1);
+        if (max < n)
+          max = n;
+      }
+      for (int i2 = 0; i2 < nh; ++i2) {
+        int n = highSeq->NthPropId(i2);
+        if (max < n)
+          max = n;
+      }
+    }
+
+    t4_byte *p = _rowIds.SetBufferClear(max + 1);
+
+     {
+      for (int i1 = 0; i1 < nl; ++i1)
+        p[lowSeq->NthPropId(i1)] |= 1;
+      for (int i2 = 0; i2 < nh; ++i2)
+        p[highSeq->NthPropId(i2)] |= 2;
+    }
+  }
+
+  // now go through all rows and select the ones that are in range
+
+  _rowMap.SetSize(_seq.NumRows()); // avoid growing, use safe upper bound
+
+  int n = 0;
+
+  for (int i = 0; i < _seq.NumRows(); ++i)
+    if (Match(i, _seq, lowCols, highCols))
+      _rowMap.SetAt(n++, i);
+
+  _rowMap.SetSize(n);
+
+  FixupReverseMap();
+}
+
+c4_FilterSeq::~c4_FilterSeq(){}
+
+void c4_FilterSeq::FixupReverseMap() {
+  int n = _seq.NumRows();
+
+  _revMap.SetSize(0);
+
+  if (n > 0) {
+    _revMap.InsertAt(0, ~(t4_i32)0, n); //!
+
+    for (int i = 0; i < _rowMap.GetSize(); ++i)
+      _revMap.SetAt((int)_rowMap.GetAt(i), i);
+  }
+}
+
+bool c4_FilterSeq::MatchOne(int prop_, const c4_Bytes &data_)const {
+  d4_assert(prop_ < _rowIds.Size());
+
+  t4_byte flag = _rowIds.Contents()[prop_];
+  d4_assert(flag);
+
+  if (flag &1) {
+    c4_Sequence *lowSeq = (&_lowRow)._seq;
+
+    c4_Handler &h = lowSeq->NthHandler(lowSeq->PropIndex(prop_));
+    if (h.Compare(0, data_) > 0)
+      return false;
+  }
+
+  if (flag &2) {
+    c4_Sequence *highSeq = (&_highRow)._seq;
+
+    c4_Handler &h = highSeq->NthHandler(highSeq->PropIndex(prop_));
+    if (h.Compare(0, data_) < 0)
+      return false;
+  }
+
+  return true;
+}
+
+bool c4_FilterSeq::Match(int index_, c4_Sequence &seq_, const int *lowCols_,
+  const int *highCols_)const {
+  // use a sneaky way to obtain the sequence pointers and indices
+  c4_Sequence *lowSeq = (&_lowRow)._seq;
+  c4_Sequence *highSeq = (&_highRow)._seq;
+  d4_assert(lowSeq && highSeq);
+
+  int nl = lowSeq->NumHandlers(), nh = highSeq->NumHandlers();
+
+  c4_Bytes data;
+
+  // check each of the lower limits
+  for (int cl = 0; cl < nl; ++cl) {
+    c4_Handler &hl = lowSeq->NthHandler(cl);
+
+    int n = lowCols_ ? lowCols_[cl]: seq_.PropIndex(lowSeq->NthPropId(cl));
+    if (n >= 0) {
+      c4_Handler &h = seq_.NthHandler(n);
+      const c4_Sequence *hc = seq_.HandlerContext(n);
+      int i = seq_.RemapIndex(index_, hc);
+
+      h.GetBytes(i, data);
+    } else
+      hl.ClearBytes(data);
+
+    if (hl.Compare(0, data) > 0)
+      return false;
+  }
+
+  // check each of the upper limits
+  for (int ch = 0; ch < nh; ++ch) {
+    c4_Handler &hh = highSeq->NthHandler(ch);
+
+    int n = highCols_ ? highCols_[ch]: seq_.PropIndex(highSeq->NthPropId(ch));
+    if (n >= 0) {
+      c4_Handler &h = seq_.NthHandler(n);
+      const c4_Sequence *hc = seq_.HandlerContext(n);
+      int i = seq_.RemapIndex(index_, hc);
+
+      h.GetBytes(i, data);
+    } else
+      hh.ClearBytes(data);
+
+    if (hh.Compare(0, data) < 0)
+      return false;
+  }
+
+  return true;
+}
+
+int c4_FilterSeq::RemapIndex(int index_, const c4_Sequence *seq_)const {
+  return seq_ == this ? index_: _seq.RemapIndex((int)_rowMap.GetAt(index_),
+    seq_);
+}
+
+int c4_FilterSeq::NumRows()const {
+  return _rowMap.GetSize();
+}
+
+int c4_FilterSeq::Compare(int index_, c4_Cursor cursor_)const {
+  return _seq.Compare((int)_rowMap.GetAt(index_), cursor_);
+}
+
+bool c4_FilterSeq::Get(int index_, int propId_, c4_Bytes &bytes_) {
+  return _seq.Get((int)_rowMap.GetAt(index_), propId_, bytes_);
+}
+
+void c4_FilterSeq::InsertAt(int, c4_Cursor, int) {
+  d4_assert(0);
+}
+
+void c4_FilterSeq::RemoveAt(int, int) {
+  d4_assert(0);
+}
+
+void c4_FilterSeq::Set(int, const c4_Property &, const c4_Bytes &) {
+  d4_assert(0);
+}
+
+void c4_FilterSeq::SetSize(int) {
+  d4_assert(0);
+}
+
+int c4_FilterSeq::PosInMap(int index_)const {
+  int i = 0;
+
+  while (i < NumRows())
+    if ((int)_rowMap.GetAt(i) >= index_)
+      break;
+    else
+      ++i;
+
+  return i;
+}
+
+c4_Notifier *c4_FilterSeq::PreChange(c4_Notifier &nf_) {
+  if (!GetDependencies())
+    return 0;
+
+  c4_Notifier *chg = d4_new c4_Notifier(this);
+
+  bool pass = false;
+
+  switch (nf_._type) {
+    case c4_Notifier::kSet: pass = nf_._propId >= _rowIds.Size() ||
+      _rowIds.Contents()[nf_._propId] == 0;
+    // fall through...
+
+    case c4_Notifier::kSetAt:  {
+      int r = (int)_revMap.GetAt(nf_._index);
+
+      bool includeRow = r >= 0;
+      if (!pass)
+      if (nf_._type == c4_Notifier::kSetAt) {
+        d4_assert(nf_._cursor != 0);
+        includeRow = Match(nf_._cursor->_index, *nf_._cursor->_seq);
+      }
+       else
+      // set just one property, and it's not in a row yet
+        includeRow = MatchOne(nf_._propId,  *nf_._bytes);
+
+      if (r >= 0 && !includeRow)
+        chg->StartRemoveAt(r, 1);
+      else if (r < 0 && includeRow)
+        chg->StartInsertAt(PosInMap(nf_._index),  *nf_._cursor, 1);
+      else if (includeRow) {
+        d4_assert(r >= 0);
+
+        if (nf_._type == c4_Notifier::kSetAt)
+          chg->StartSetAt(r,  *nf_._cursor);
+        else
+          chg->StartSet(r, nf_._propId,  *nf_._bytes);
+      }
+    }
+    break;
+
+    case c4_Notifier::kInsertAt:  {
+      int i = PosInMap(nf_._index);
+
+      d4_assert(nf_._cursor != 0);
+      if (Match(nf_._cursor->_index,  *nf_._cursor->_seq))
+        chg->StartInsertAt(i,  *nf_._cursor, nf_._count);
+    }
+    break;
+
+    case c4_Notifier::kRemoveAt:  {
+      int i = PosInMap(nf_._index);
+      int j = PosInMap(nf_._index + nf_._count);
+      d4_assert(j >= i);
+
+      if (j > i)
+        chg->StartRemoveAt(i, j - i);
+    }
+    break;
+
+    case c4_Notifier::kMove:  {
+      int i = PosInMap(nf_._index);
+      bool inMap = i < NumRows() && (int)_rowMap.GetAt(i) == nf_._index;
+
+      if (inMap && nf_._index != nf_._count)
+        chg->StartMove(i, PosInMap(nf_._count));
+    }
+    break;
+  }
+
+  return chg;
+}
+
+void c4_FilterSeq::PostChange(c4_Notifier &nf_) {
+  bool pass = false;
+
+  switch (nf_._type) {
+    case c4_Notifier::kSet: pass = nf_._propId >= _rowIds.Size() ||
+      _rowIds.Contents()[nf_._propId] == 0;
+    // fall through...
+
+    case c4_Notifier::kSetAt:  {
+      int r = (int)_revMap.GetAt(nf_._index);
+
+      bool includeRow = r >= 0;
+      if (!pass)
+      if (nf_._type == c4_Notifier::kSetAt) {
+        d4_assert(nf_._cursor != 0);
+        includeRow = Match(nf_._cursor->_index, *nf_._cursor->_seq);
+      }
+       else
+      // set just one property, and it's not in a row yet
+        includeRow = MatchOne(nf_._propId,  *nf_._bytes);
+
+      if (r >= 0 && !includeRow)
+        _rowMap.RemoveAt(r);
+      else if (r < 0 && includeRow)
+        _rowMap.InsertAt(PosInMap(nf_._index), nf_._index);
+      else
+        break;
+
+      FixupReverseMap();
+    }
+    break;
+
+    case c4_Notifier::kInsertAt:  {
+      int i = PosInMap(nf_._index);
+
+      if (Match(nf_._index, _seq)) {
+        _rowMap.InsertAt(i, 0, nf_._count);
+
+        for (int j = 0; j < nf_._count; ++j)
+          _rowMap.SetAt(i++, nf_._index + j);
+      }
+
+      while (i < NumRows())
+        _rowMap.ElementAt(i++) += nf_._count;
+
+      FixupReverseMap();
+    }
+    break;
+
+    case c4_Notifier::kRemoveAt:  {
+      int i = PosInMap(nf_._index);
+      int j = PosInMap(nf_._index + nf_._count);
+      d4_assert(j >= i);
+
+      if (j > i)
+        _rowMap.RemoveAt(i, j - i);
+
+      while (i < NumRows())
+        _rowMap.ElementAt(i++) -= nf_._count;
+
+      FixupReverseMap();
+    }
+    break;
+
+    case c4_Notifier::kMove:  {
+      int i = PosInMap(nf_._index);
+      bool inMap = i < NumRows() && (int)_rowMap.GetAt(i) == nf_._index;
+
+      if (inMap && nf_._index != nf_._count) {
+        int j = PosInMap(nf_._count);
+
+        _rowMap.RemoveAt(i);
+
+        if (j > i)
+          --j;
+
+        _rowMap.InsertAt(j, nf_._count);
+
+        FixupReverseMap();
+      }
+    }
+    break;
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_SortSeq: public c4_FilterSeq {
+  public:
+    typedef t4_i32 T;
+
+    c4_SortSeq(c4_Sequence &seq_, c4_Sequence *down_);
+    virtual ~c4_SortSeq();
+
+    virtual c4_Notifier *PreChange(c4_Notifier &nf_);
+    virtual void PostChange(c4_Notifier &nf_);
+
+  private:
+    struct c4_SortInfo {
+        c4_Handler *_handler;
+        const c4_Sequence *_context;
+        c4_Bytes _buffer;
+
+        int CompareOne(c4_Sequence &seq_, T a, T b) {
+            _handler->GetBytes(seq_.RemapIndex((int)b, _context), _buffer, true)
+              ;
+            return _handler->Compare(seq_.RemapIndex((int)a, _context), _buffer)
+              ;
+        } 
+    };
+
+    bool LessThan(T a, T b);
+    bool TestSwap(T &first, T &second);
+    void MergeSortThis(T *ar, int size, T scratch[]);
+    void MergeSort(T ar[], int size);
+
+    virtual int Compare(int, c4_Cursor)const;
+    int PosInMap(c4_Cursor cursor_)const;
+
+    c4_SortInfo *_info;
+    c4_Bytes _down;
+    int _width;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool c4_SortSeq::LessThan(T a, T b) {
+  if (a == b)
+    return false;
+
+  // go through each of the columns and compare values, but since
+  // handler access is used, we must be careful to remap indices
+
+  c4_SortInfo *info;
+
+  for (info = _info; info->_handler; ++info) {
+    int f = info->CompareOne(_seq, a, b);
+    if (f) {
+      int n = info - _info;
+      if (_width < n)
+        _width = n;
+
+      return (_down.Contents()[n] ?  - f: f) < 0;
+    }
+  }
+
+  _width = info - _info;
+  return a < b;
+}
+
+inline bool c4_SortSeq::TestSwap(T &first, T &second) {
+  if (LessThan(second, first)) {
+    T temp = first;
+    first = second;
+    second = temp;
+    return true;
+  }
+
+  return false;
+}
+
+void c4_SortSeq::MergeSortThis(T *ar, int size, T scratch[]) {
+  switch (size) {
+    //Handle the special cases for speed:
+    case 2:
+      TestSwap(ar[0], ar[1]);
+      break;
+
+    case 3:
+      TestSwap(ar[0], ar[1]);
+      if (TestSwap(ar[1], ar[2]))
+        TestSwap(ar[0], ar[1]);
+      break;
+
+    case 4:
+      //Gotta optimize this....
+      TestSwap(ar[0], ar[1]);
+      TestSwap(ar[2], ar[3]);
+      TestSwap(ar[0], ar[2]);
+      TestSwap(ar[1], ar[3]);
+      TestSwap(ar[1], ar[2]);
+      break;
+
+      //Gotta do special case for list of five.
+
+    default:
+      //Subdivide the list, recurse, and merge
+       {
+        int s1 = size / 2;
+        int s2 = size - s1;
+        T *from1_ = scratch;
+        T *from2_ = scratch + s1;
+        MergeSortThis(from1_, s1, ar);
+        MergeSortThis(from2_, s2, ar + s1);
+
+        T *to1_ = from1_ + s1;
+        T *to2_ = from2_ + s2;
+
+        for (;;) {
+          if (LessThan(*from1_,  *from2_)) {
+            *ar++ =  *from1_++;
+
+            if (from1_ >= to1_) {
+              while (from2_ < to2_)
+                *ar++ =  *from2_++;
+              break;
+            }
+          }
+           else {
+            *ar++ =  *from2_++;
+
+            if (from2_ >= to2_) {
+              while (from1_ < to1_)
+                *ar++ =  *from1_++;
+              break;
+            }
+          }
+        }
+      }
+  }
+}
+
+void c4_SortSeq::MergeSort(T ar[], int size) {
+  if (size > 1) {
+    T *scratch = d4_new T[size];
+    memcpy(scratch, ar, size *sizeof(T));
+    MergeSortThis(ar, size, scratch);
+    delete [] scratch;
+  }
+}
+
+c4_SortSeq::c4_SortSeq(c4_Sequence &seq_, c4_Sequence *down_): c4_FilterSeq
+  (seq_), _info(0), _width( - 1) {
+  d4_assert(NumRows() == seq_.NumRows());
+
+  if (NumRows() > 0) {
+    // down is a vector of flags, true to sort in reverse order
+    char *down = (char*)_down.SetBufferClear(NumHandlers());
+
+    // set the down flag for all properties to be sorted in reverse
+    if (down_)
+      for (int i = 0; i < NumHandlers(); ++i)
+        if (down_->PropIndex(NthPropId(i)) >= 0)
+          down[i] = 1;
+
+    _width =  - 1;
+    int n = NumHandlers() + 1;
+    _info = d4_new c4_SortInfo[n];
+
+    int j;
+
+    for (j = 0; j < NumHandlers(); ++j) {
+      _info[j]._handler = &_seq.NthHandler(j);
+      _info[j]._context = _seq.HandlerContext(j);
+    }
+
+    _info[j]._handler = 0;
+
+    // everything is ready, go sort the row index vector
+    MergeSort((T*) &_rowMap.ElementAt(0), NumRows());
+
+    delete [] _info;
+    _info = 0;
+
+    FixupReverseMap();
+  }
+}
+
+c4_SortSeq::~c4_SortSeq() {
+  d4_assert(!_info);
+}
+
+int c4_SortSeq::Compare(int index_, c4_Cursor cursor_)const {
+  d4_assert(cursor_._seq != 0);
+
+  const char *down = (const char*)_down.Contents();
+  d4_assert(_down.Size() <= NumHandlers());
+
+  c4_Bytes data;
+
+  for (int colNum = 0; colNum < NumHandlers(); ++colNum) {
+    c4_Handler &h = NthHandler(colNum);
+    const c4_Sequence *hc = HandlerContext(colNum);
+
+    if (!cursor_._seq->Get(cursor_._index, h.PropId(), data))
+      h.ClearBytes(data);
+
+    int f = h.Compare(RemapIndex(index_, hc), data);
+    if (f != 0)
+      return colNum < _down.Size() && down[colNum] ?  - f:  + f;
+  }
+
+  return 0;
+}
+
+int c4_SortSeq::PosInMap(c4_Cursor cursor_)const {
+  int i = 0;
+
+  while (i < NumRows())
+    if (Compare(i, cursor_) >= 0)
+      break;
+    else
+      ++i;
+
+  d4_assert(i == NumRows() || Compare(i, cursor_) >= 0);
+  return i;
+}
+
+c4_Notifier *c4_SortSeq::PreChange(c4_Notifier & /*nf_*/) {
+  if (!GetDependencies())
+    return 0;
+
+#if 0
+  c4_Notifier *chg = d4_new c4_Notifier(this);
+
+  switch (nf_._type) {
+    case c4_Notifier::kSetAt: case c4_Notifier::kSet:  {
+      d4_assert(0); // also needs nested propagation
+
+      /*
+      change can require a move *and* a change of contents
+       */
+    }
+    break;
+
+    case c4_Notifier::kInsertAt:  {
+      d4_assert(0); // this case isn't really difficult
+    }
+    break;
+
+    case c4_Notifier::kRemoveAt:  {
+      d4_assert(0); // nested propagation is too difficult for now
+      // i.e. can only use sort as last derived view
+      /*
+      possible solution:
+
+      if 1 row, simple
+      else if contig in map, also simple
+      else propagate reorder first, then delete contig
+
+      it can be done here, as multiple notifications,
+      by simulating n-1 SetAt's of first row in others
+      needs some map juggling, allow temp dup entries?
+
+      or perhaps more consistent with n separate removes
+       */
+    }
+    break;
+
+    case c4_Notifier::kMove:  {
+      // incorrect: may need to move if recnum matters (recs same)
+    }
+    break;
+  }
+
+  return chg;
+#endif 
+
+  //  d4_assert(0); // fail, cannot handle a view dependent on this one yet
+  return 0;
+}
+
+void c4_SortSeq::PostChange(c4_Notifier &nf_) {
+  switch (nf_._type) {
+    case c4_Notifier::kSet: if (_seq.PropIndex(nf_._propId) > _width)
+      break;
+    // cannot affect sort order, valuable optimization
+
+    case c4_Notifier::kSetAt:  {
+      int oi = (int)_revMap.GetAt(nf_._index);
+      d4_assert(oi >= 0);
+
+      c4_Cursor cursor(_seq, nf_._index);
+
+      // move the entry if the sort order has been disrupted
+      if ((oi > 0 && Compare(oi - 1, cursor) > 0) || (oi + 1 < NumRows() &&
+        Compare(oi + 1, cursor) < 0)) {
+        _rowMap.RemoveAt(oi);
+        _rowMap.InsertAt(PosInMap(cursor), nf_._index);
+
+        FixupReverseMap();
+      }
+
+      _width = NumHandlers(); // sorry, no more optimization
+    }
+    break;
+
+    case c4_Notifier::kInsertAt:  {
+      // if cursor was not set, it started out as a single Set
+      c4_Cursor cursor(_seq, nf_._index);
+      if (nf_._cursor)
+        cursor =  *nf_._cursor;
+
+      for (int n = 0; n < NumRows(); ++n)
+        if ((int)_rowMap.GetAt(n) >= nf_._index)
+          _rowMap.ElementAt(n) += nf_._count;
+
+      int i = PosInMap(cursor);
+      _rowMap.InsertAt(i, 0, nf_._count);
+
+      for (int j = 0; j < nf_._count; ++j)
+        _rowMap.SetAt(i++, nf_._index + j);
+
+      FixupReverseMap();
+
+      _width = NumHandlers(); // sorry, no more optimization
+    }
+    break;
+
+    case c4_Notifier::kRemoveAt:  {
+      int lo = nf_._index;
+      int hi = nf_._index + nf_._count;
+
+      int j = 0;
+      for (int i = 0; i < NumRows(); ++i) {
+        int n = (int)_rowMap.GetAt(i);
+
+        if (n >= hi)
+          _rowMap.ElementAt(i) -= nf_._count;
+
+        if (!(lo <= n && n < hi))
+          _rowMap.SetAt(j++, _rowMap.GetAt(i));
+      }
+
+      d4_assert(j + nf_._count == NumRows());
+      _rowMap.SetSize(j);
+
+      FixupReverseMap();
+
+      _width = NumHandlers(); // sorry, no more optimization
+    }
+    break;
+
+    case c4_Notifier::kMove:  {
+      // incorrect: may need to move if recnum matters (recs same)
+    }
+    break;
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ProjectSeq: public c4_DerivedSeq {
+    c4_DWordArray _colMap; // a bit large, but bytes would be too small
+    bool _frozen;
+    int _omitCount; // if > 0 then this is a dynamic "project without"
+
+  public:
+    c4_ProjectSeq(c4_Sequence &seq_, c4_Sequence &in_, bool, c4_Sequence *out_);
+    virtual ~c4_ProjectSeq();
+
+    virtual int NumHandlers()const;
+    virtual c4_Handler &NthHandler(int)const;
+    virtual const c4_Sequence *HandlerContext(int)const;
+    virtual int AddHandler(c4_Handler*);
+
+    virtual bool Get(int, int, c4_Bytes &);
+    virtual void Set(int, const c4_Property &, const c4_Bytes &);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_ProjectSeq::c4_ProjectSeq(c4_Sequence &seq_, c4_Sequence &in_, bool reorder_,
+  c4_Sequence *out_): c4_DerivedSeq(seq_), _frozen(!reorder_ && !out_),
+  _omitCount(0) {
+  // build the array with column indexes
+  for (int j = 0; j < in_.NumHandlers(); ++j) {
+    int propId = in_.NthPropId(j);
+    int idx = _seq.PropIndex(propId);
+
+    // if the j'th property is in the sequence, add it
+    if (idx >= 0) {
+      // but only if it's not in the out_ view
+      if (out_ && out_->PropIndex(propId) >= 0)
+        ++_omitCount;
+      else
+        _colMap.Add(idx);
+    }
+  }
+
+  // if only reordering, append remaining columns from original view
+  if (reorder_) {
+    for (int i = 0; i < _seq.NumHandlers(); ++i) {
+      int propId = _seq.NthPropId(i);
+
+      // only consider properties we did not deal with before
+      if (in_.PropIndex(propId) < 0)
+        _colMap.Add(i);
+    }
+
+    d4_assert(_colMap.GetSize() == _seq.NumHandlers());
+  }
+}
+
+c4_ProjectSeq::~c4_ProjectSeq(){}
+
+int c4_ProjectSeq::NumHandlers()const {
+  return _frozen ? _colMap.GetSize(): _seq.NumHandlers() - _omitCount;
+}
+
+c4_Handler &c4_ProjectSeq::NthHandler(int colNum_)const {
+  int n = colNum_ < _colMap.GetSize() ? _colMap.GetAt(colNum_): colNum_;
+  return _seq.NthHandler(n);
+}
+
+const c4_Sequence *c4_ProjectSeq::HandlerContext(int colNum_)const {
+  int n = colNum_ < _colMap.GetSize() ? _colMap.GetAt(colNum_): colNum_;
+  return _seq.HandlerContext(n);
+}
+
+int c4_ProjectSeq::AddHandler(c4_Handler *handler_) {
+  int n = _seq.AddHandler(handler_);
+  return _frozen ? _colMap.Add(n): n - _omitCount;
+}
+
+bool c4_ProjectSeq::Get(int index_, int propId_, c4_Bytes &buf_) {
+  // fixed in 1.8: check that the property is visible
+  return PropIndex(propId_) >= 0 && _seq.Get(index_, propId_, buf_);
+}
+
+void c4_ProjectSeq::Set(int index_, const c4_Property &prop_, const c4_Bytes
+  &bytes_) {
+  int n = _seq.NumHandlers();
+  _seq.Set(index_, prop_, bytes_);
+
+  // if the number of handlers changed, then one must have been added
+  if (n != _seq.NumHandlers()) {
+    d4_assert(n == _seq.NumHandlers() - 1);
+
+    if (_frozen)
+      _colMap.Add(n);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Sequence *f4_CreateFilter(c4_Sequence &seq_, c4_Cursor l_, c4_Cursor h_) {
+  return d4_new c4_FilterSeq(seq_, l_, h_);
+}
+
+c4_Sequence *f4_CreateSort(c4_Sequence &seq_, c4_Sequence *down_) {
+  return d4_new c4_SortSeq(seq_, down_);
+}
+
+c4_Sequence *f4_CreateProject(c4_Sequence &seq_, c4_Sequence &in_, bool
+  reorder_, c4_Sequence *out_) {
+  return d4_new c4_ProjectSeq(seq_, in_, reorder_, out_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/derived.h b/8.x/mk/src/derived.h
new file mode 100755 (executable)
index 0000000..49dc524
--- /dev/null
@@ -0,0 +1,25 @@
+// derived.h --
+// $Id: derived.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Encapsulation of derived view classes
+ */
+
+#ifndef __DERIVED_H__
+#define __DERIVED_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+class c4_Cursor; // not defined here
+class c4_Sequence; // not defined here
+
+extern c4_Sequence *f4_CreateFilter(c4_Sequence &, c4_Cursor, c4_Cursor);
+extern c4_Sequence *f4_CreateSort(c4_Sequence &, c4_Sequence * = 0);
+extern c4_Sequence *f4_CreateProject(c4_Sequence &, c4_Sequence &, bool,
+  c4_Sequence * = 0);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/doxy.h b/8.x/mk/src/doxy.h
new file mode 100644 (file)
index 0000000..cadf03c
--- /dev/null
@@ -0,0 +1,28 @@
+// doxy.h --
+// $Id: doxy.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @mainpage Metakit API Reference
+
+The is the reference documentation for the public C++ API of Metakit.
+
+- For the documentation of Metakit, see http://www.equi4.com/mkdocs.html
+- To use Metakit from Python, see http://www.equi4.com/metakit/python.html
+- To use Metakit from Tcl, see http://www.equi4.com/metakit/tcl.html
+
+@section install Installation
+
+- Windows: open "win/msvc60/mksrc.dsw" with Microsoft Visual C++ 6.0
+- Unix: "cd builds; ../unix/configure; make; make test; make install"
+
+@section using Using the library
+
+- There are some examples in the "demo/" and "examples/" directories.
+- The "tests/" directory contains a test suite with 140+ small samples.
+
+@section news News, releases, discussions
+
+- See the Metakit homepage at http://www.equi4.com/metakit.html
+ */
+
+// vim:wm=5
diff --git a/8.x/mk/src/field.cpp b/8.x/mk/src/field.cpp
new file mode 100755 (executable)
index 0000000..f592855
--- /dev/null
@@ -0,0 +1,115 @@
+// field.cpp --
+// $Id: field.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Implementation of the field structure tree
+ */
+
+#include "header.h"
+#include "field.h"
+
+#include <stdlib.h>   // strtol
+
+#if !q4_INLINE
+#include "field.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Implemented in this file
+
+class c4_Field;
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Field
+
+c4_Field::c4_Field(const char * &description_, c4_Field *parent_): _type(0) {
+    _indirect = this;
+
+    size_t n = strcspn(description_, ",[]");
+    const char *p = strchr(description_, ':');
+
+    if (p != 0 && p < description_ + n) {
+        _name = c4_String(description_, p - description_);
+        _type = p[1] &~0x20; // force to upper case
+    } else {
+        _name = c4_String(description_, n);
+        _type = 'S';
+    }
+
+    description_ += n;
+
+    if (*description_ == '[') {
+        ++description_;
+        _type = 'V';
+
+        if (*description_ == '^') {
+            ++description_;
+            _indirect = parent_;
+            d4_assert(*description_ == ']');
+        }
+
+        if (*description_ == ']')
+          ++description_;
+        else
+        do {
+            // 2004-01-20 ignore duplicate property names
+            // (since there is no good way to report errors at this point)
+            c4_Field *sf = d4_new c4_Field(description_, this);
+            for (int i = 0; i < NumSubFields(); ++i)
+            if (SubField(i).Name().CompareNoCase(sf->Name()) == 0) {
+                delete sf;
+                sf = 0;
+                break;
+            }
+            if (sf != 0)
+              _subFields.Add(sf);
+        } while (*description_++ == ',');
+    }
+}
+
+c4_Field::~c4_Field() {
+  if (_indirect == this) {
+    //better? for (int i = NumSubFields(); --i >= 0 ;)
+    for (int i = 0; i < NumSubFields(); ++i) {
+      c4_Field *sf = &SubField(i);
+      if (sf != this)
+      // careful with recursive subfields
+        delete sf;
+    }
+  }
+}
+
+c4_String c4_Field::Description(bool anonymous_)const {
+  c4_String s = anonymous_ ? "?" : (const char*)Name();
+
+  if (Type() == 'V')
+    s += "[" + DescribeSubFields(anonymous_) + "]";
+  else {
+    s += ":";
+    s += (c4_String)Type();
+  }
+
+  return s;
+}
+
+c4_String c4_Field::DescribeSubFields(bool)const {
+  d4_assert(Type() == 'V');
+
+  if (_indirect != this)
+    return "^";
+
+  c4_String s;
+  char c = 0;
+
+  for (int i = 0; i < NumSubFields(); ++i) {
+    if (c != 0)
+      s += (c4_String)c;
+    s += SubField(i).Description();
+    c = ',';
+  }
+
+  return s;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/field.h b/8.x/mk/src/field.h
new file mode 100755 (executable)
index 0000000..d7ad6cd
--- /dev/null
@@ -0,0 +1,63 @@
+// field.h --
+// $Id: field.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Core class to represent fields
+ */
+
+#ifndef __FIELD_H__
+#define __FIELD_H__
+
+#ifndef __K4CONF_H__
+#error Please include "k4conf.h" before this header file
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Field {
+    c4_PtrArray _subFields;
+    c4_String _name;
+    char _type;
+    c4_Field *_indirect;
+
+  public:
+    /* Construction / destruction */
+    c4_Field(const char * &, c4_Field * = 0);
+    //: Constructs a new field.
+    ~c4_Field();
+
+    /* Repeating and compound fields */
+    int NumSubFields()const;
+    //: Returns the number of subfields.
+    c4_Field &SubField(int)const;
+    //: Returns the description of each subfield.
+    bool IsRepeating()const;
+    //: Returns true if this field contains subtables.
+
+    /* Field name and description */
+    const c4_String &Name()const;
+    //: Returns name of this field.
+    char Type()const;
+    //: Returns the type description of this field, if any.
+    char OrigType()const;
+    //: Similar, but report types which were originall 'M' as well.
+    c4_String Description(bool anonymous_ = false)const;
+    //: Describes the structure, omit names if anonymous.
+    c4_String DescribeSubFields(bool anonymous_ = false)const;
+    //: Describes just the subfields, omit names if anonymous.
+
+  private:
+    c4_Field(const c4_Field &); // not implemented
+    void operator = (const c4_Field &); // not implemented
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "field.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/field.inl b/8.x/mk/src/field.inl
new file mode 100755 (executable)
index 0000000..e23ffef
--- /dev/null
@@ -0,0 +1,37 @@
+// field.inl --
+// $Id: field.inl 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Inlined members of the field class
+ */
+
+d4_inline bool c4_Field::IsRepeating() const
+{
+  return _type == 'V';
+}
+
+d4_inline int c4_Field::NumSubFields() const
+{
+  return _indirect->_subFields.GetSize();
+}
+
+d4_inline c4_Field& c4_Field::SubField(int index_) const
+{
+  return *(c4_Field*) _indirect->_subFields.GetAt(index_);
+}
+
+d4_inline const c4_String& c4_Field::Name() const
+{
+  return _name;
+}
+  
+d4_inline char c4_Field::OrigType() const
+{
+  return _type;
+}
+  
+d4_inline char c4_Field::Type() const
+{
+  return _type == 'M' ? 'B' : _type;
+}
diff --git a/8.x/mk/src/fileio.cpp b/8.x/mk/src/fileio.cpp
new file mode 100755 (executable)
index 0000000..90b113e
--- /dev/null
@@ -0,0 +1,437 @@
+// fileio.cpp --
+// $Id: fileio.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Implementation of c4_FileStrategy and c4_FileStream
+ */
+
+#include "header.h"
+#include "mk4io.h"
+
+#if q4_WIN32
+#if q4_MSVC && !q4_STRICT
+#pragma warning(disable: 4201) // nonstandard extension used : ...
+#endif 
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <io.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#endif 
+
+#if q4_UNIX && HAVE_MMAP
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif 
+
+#if q4_UNIX
+#include <unistd.h>
+#include <fcntl.h>
+#endif 
+
+#if q4_WINCE
+#define _get_osfhandle(x) x
+#endif 
+
+#ifndef _O_NOINHERIT
+#define _O_NOINHERIT 0
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//  The "Carbon" version of a build on Macintosh supports running under
+//  either MacOS 7..9 (which has no mmap), or MacOS X (which has mmap).
+//  The logic below was adapted from a contribution by Paul Snively, it
+//  decides at run time which case it is, and switches I/O calls to match.
+
+#if defined (q4_CARBON) && q4_CARBON
+//#if q4_MAC && !defined (__MACH__) && (!q4_MWCW || __MWERKS__ >= 0x3000)
+#undef HAVE_MMAP
+#define HAVE_MMAP 1
+
+#include <CFBundle.h>
+#include <Folders.h>
+
+#define PROT_NONE        0x00
+#define PROT_READ        0x01
+#define PROT_WRITE       0x02
+#define PROT_EXEC        0x04
+
+#define MAP_SHARED       0x0001
+#define MAP_PRIVATE      0x0002
+
+#define MAP_FIXED        0x0010
+#define MAP_RENAME       0x0020
+#define MAP_NORESERVE    0x0040
+#define MAP_INHERIT      0x0080
+#define MAP_NOEXTEND     0x0100
+#define MAP_HASSEMAPHORE 0x0200
+
+typedef unsigned long t4_u32;
+
+static t4_u32 sfwRefCount = 0;
+static CFBundleRef systemFramework = NULL;
+
+static char *fake_mmap(char *, t4_u32, int, int, int, long long) {
+  return (char*) - 1L;
+}
+
+static int fake_munmap(char *, t4_u32) {
+  return 0;
+}
+
+static FILE *(*my_fopen)(const char *, const char*) = fopen;
+static int(*my_fclose)(FILE*) = fclose;
+static long(*my_ftell)(FILE*) = ftell;
+static int(*my_fseek)(FILE *, long, int) = fseek;
+static t4_u32(*my_fread)(void *ptr, t4_u32, t4_u32, FILE*) = fread;
+static t4_u32(*my_fwrite)(const void *ptr, t4_u32, t4_u32, FILE*) = fwrite;
+static int(*my_ferror)(FILE*) = ferror;
+static int(*my_fflush)(FILE*) = fflush;
+static int(*my_fileno)(FILE*) = fileno;
+static char *(*my_mmap)(char *, t4_u32, int, int, int, long long) = fake_mmap;
+static int(*my_munmap)(char *, t4_u32) = fake_munmap;
+
+static void InitializeIO() {
+  if (sfwRefCount++)
+    return ;
+  // race condition, infinitesimal risk
+
+  FSRef theRef;
+  if (FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, false, &theRef) 
+    == noErr) {
+    CFURLRef fw = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &theRef);
+    if (fw) {
+      CFURLRef bd = CFURLCreateCopyAppendingPathComponent
+        (kCFAllocatorSystemDefault, fw, CFSTR("System.framework"), false);
+      CFRelease(fw);
+      if (bd) {
+        systemFramework = CFBundleCreate(kCFAllocatorSystemDefault, bd);
+        CFRelease(bd);
+      }
+    }
+    if (!systemFramework || !CFBundleLoadExecutable(systemFramework))
+      return ;
+#define F(x) CFBundleGetFunctionPointerForName(systemFramework, CFSTR(#x))
+    my_fopen = (FILE *(*)(const char *, const char*))F(fopen);
+    my_fclose = (int(*)(FILE*))F(fclose);
+    my_ftell = (long(*)(FILE*))F(ftell);
+    my_fseek = (int(*)(FILE *, long, int))F(fseek);
+    my_fread = (t4_u32(*)(void *ptr, t4_u32, t4_u32, FILE*))F(fread);
+    my_fwrite = (t4_u32(*)(const void *ptr, t4_u32, t4_u32, FILE*))F(fwrite);
+    my_ferror = (int(*)(FILE*))F(ferror);
+    my_fflush = (int(*)(FILE*))F(fflush);
+    my_fileno = (int(*)(FILE*))F(fileno);
+    my_mmap = (char *(*)(char *, t4_u32, int, int, int, long long))F(mmap);
+    my_munmap = (int(*)(char *, t4_u32))F(munmap);
+#undef F
+    d4_assert(my_fopen && my_fclose && my_ftell && my_fseek && my_fread &&
+      my_fwrite && my_ferror && my_fflush && my_fileno && my_mmap && my_munmap);
+  }
+}
+
+static void FinalizeIO() {
+  if (--sfwRefCount)
+    return ;
+  // race condition, infinitesimal risk
+
+  if (systemFramework) {
+    CFBundleUnloadExecutable(systemFramework);
+    CFRelease(systemFramework);
+    systemFramework = 0;
+  }
+}
+
+#define fopen my_fopen
+#define fclose  my_fclose
+#define ftell my_ftell
+#define fseek my_fseek
+#define fread my_fread
+#define fwrite  my_fwrite
+#define ferror  my_ferror
+#define fflush  my_fflush
+#define fileno  my_fileno
+#define mmap  my_mmap
+#define munmap  my_munmap
+
+#else 
+
+#define InitializeIO()
+#define FinalizeIO()
+
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_CHECK
+#include <stdlib.h>
+
+void f4_AssertionFailed(const char *cond_, const char *file_, int line_) {
+  fprintf(stderr, "Assertion failed: %s (file %s, line %d)\n", cond_, file_,
+    line_);
+  abort();
+}
+
+#endif //q4_CHECK
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FileStream
+
+c4_FileStream::c4_FileStream(FILE *stream_, bool owned_): _stream(stream_),
+  _owned(owned_){}
+
+c4_FileStream::~c4_FileStream() {
+  if (_owned)
+    fclose(_stream);
+}
+
+int c4_FileStream::Read(void *buffer_, int length_) {
+  d4_assert(_stream != 0);
+
+  return (int)fread(buffer_, 1, length_, _stream);
+}
+
+bool c4_FileStream::Write(const void *buffer_, int length_) {
+  d4_assert(_stream != 0);
+
+  return (int)fwrite(buffer_, 1, length_, _stream) == length_;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FileStrategy
+
+c4_FileStrategy::c4_FileStrategy(FILE *file_): _file(file_), _cleanup(0) {
+  InitializeIO();
+  ResetFileMapping();
+}
+
+c4_FileStrategy::~c4_FileStrategy() {
+  _file = 0;
+  ResetFileMapping();
+
+  if (_cleanup)
+    fclose(_cleanup);
+
+  d4_assert(_mapStart == 0);
+  FinalizeIO();
+}
+
+bool c4_FileStrategy::IsValid()const {
+  return _file != 0;
+}
+
+t4_i32 c4_FileStrategy::FileSize() {
+  d4_assert(_file != 0);
+
+  long size =  - 1;
+
+  long old = ftell(_file);
+  if (old >= 0 && fseek(_file, 0, 2) == 0) {
+    long pos = ftell(_file);
+    if (fseek(_file, old, 0) == 0)
+      size = pos;
+  }
+
+  if (size < 0)
+    _failure = ferror(_file);
+
+  return size;
+}
+
+t4_i32 c4_FileStrategy::FreshGeneration() {
+  d4_assert(false);
+  return 0;
+}
+
+void c4_FileStrategy::ResetFileMapping() {
+#if q4_WIN32
+  if (_mapStart != 0) {
+    _mapStart -= _baseOffset;
+    d4_dbgdef(BOOL g = )::UnmapViewOfFile((char*)_mapStart);
+    d4_assert(g);
+    _mapStart = 0;
+    _dataSize = 0;
+  }
+
+  if (_file != 0) {
+    t4_i32 len = FileSize();
+
+    if (len > 0) {
+      FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(_file)));
+      HANDLE h = ::CreateFileMapping((HANDLE)_get_osfhandle(_fileno(_file)), 0,
+        PAGE_READONLY, 0, len, 0);
+
+      if (h) {
+        _mapStart = (t4_byte*)::MapViewOfFile(h, FILE_MAP_READ, 0, 0, len);
+
+        if (_mapStart != 0) {
+          _mapStart += _baseOffset;
+          _dataSize = len - _baseOffset;
+        }
+
+        d4_dbgdef(BOOL f = )::CloseHandle(h);
+        d4_assert(f);
+      }
+    }
+  }
+#elif HAVE_MMAP && !NO_MMAP
+  if (_mapStart != 0) {
+    _mapStart -= _baseOffset;
+    munmap((char*)_mapStart, _baseOffset + _dataSize); // also loses const
+    _mapStart = 0;
+    _dataSize = 0;
+  }
+
+  if (_file != 0) {
+    t4_i32 len = FileSize();
+
+    if (len > 0) {
+      _mapStart = (const t4_byte*)mmap(0, len, PROT_READ, MAP_SHARED, fileno
+        (_file), 0);
+      if (_mapStart != (void*) - 1L) {
+        _mapStart += _baseOffset;
+        _dataSize = len - _baseOffset;
+      } else
+        _mapStart = 0;
+    }
+  }
+#endif 
+}
+
+#if q4_WIN32 && !q4_BORC && !q4_WINCE
+static DWORD GetPlatformId() {
+  static OSVERSIONINFO os;
+  if (os.dwPlatformId == 0) {
+    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    GetVersionEx(&os);
+  }
+  return os.dwPlatformId;
+}
+
+#endif 
+
+bool c4_FileStrategy::DataOpen(const char *fname_, int mode_) {
+  d4_assert(!_file);
+
+#if q4_WIN32 && !q4_BORC && !q4_WINCE
+  int flags = _O_BINARY | _O_NOINHERIT | (mode_ > 0 ? _O_RDWR : _O_RDONLY);
+  int fd =  - 1;
+
+  if (GetPlatformId() != VER_PLATFORM_WIN32_NT)
+    fd = _open(fname_, flags);
+  if (fd ==  - 1) {
+    WCHAR wName[MAX_PATH];
+    MultiByteToWideChar(CP_UTF8, 0, fname_,  - 1, wName, MAX_PATH);
+    fd = _wopen(wName, flags);
+  }
+  if (fd !=  - 1)
+    _cleanup = _file = _fdopen(fd, mode_ > 0 ? "r+b" : "rb");
+#else 
+  _cleanup = _file = fopen(fname_, mode_ > 0 ? "r+b" : "rb");
+#if q4_UNIX
+  if (_file != 0)
+    fcntl(fileno(_file), F_SETFD, FD_CLOEXEC);
+#endif //q4_UNIX
+#endif //q4_WIN32 && !q4_BORC && !q4_WINCE
+
+  if (_file != 0) {
+    ResetFileMapping();
+    return true;
+  }
+
+  if (mode_ > 0) {
+#if q4_WIN32 && !q4_BORC && !q4_WINCE
+    WCHAR wName[MAX_PATH];
+    MultiByteToWideChar(CP_UTF8, 0, fname_,  - 1, wName, MAX_PATH);
+    fd = _wopen(wName, flags | _O_CREAT, _S_IREAD | _S_IWRITE);
+    if (fd !=  - 1)
+      _cleanup = _file = _fdopen(fd, "w+b");
+#else 
+    _cleanup = _file = fopen(fname_, "w+b");
+#if q4_UNIX
+    if (_file != 0)
+      fcntl(fileno(_file), F_SETFD, FD_CLOEXEC);
+#endif //q4_UNIX
+#endif //q4_WIN32 && !q4_BORC && !q4_WINCE
+  }
+
+  //d4_assert(_file != 0);
+  return false;
+}
+
+int c4_FileStrategy::DataRead(t4_i32 pos_, void *buf_, int len_) {
+  d4_assert(_baseOffset + pos_ >= 0);
+  d4_assert(_file != 0);
+
+  //printf("DataRead at %d len %d\n", pos_, len_);
+  return fseek(_file, _baseOffset + pos_, 0) != 0 ?  - 1: (int)fread(buf_, 1,
+    len_, _file);
+}
+
+void c4_FileStrategy::DataWrite(t4_i32 pos_, const void *buf_, int len_) {
+  d4_assert(_baseOffset + pos_ >= 0);
+  d4_assert(_file != 0);
+#if 0
+  if (_mapStart <= buf_ && buf_ < _mapStart + _dataSize) {
+    printf("DataWrite %08x at %d len %d (map %d)\n", buf_, pos_, len_, (const
+      t4_byte*)buf_ - _mapStart + _baseOffset);
+  } else {
+    printf("DataWrite %08x at %d len %d\n", buf_, pos_, len_);
+  }
+  fprintf(stderr, 
+    "  _mapStart %08x _dataSize %d buf_ %08x len_ %d _baseOffset %d\n",
+    _mapStart, _dataSize, buf_, len_, _baseOffset);
+  printf("  _mapStart %08x _dataSize %d buf_ %08x len_ %d _baseOffset %d\n",
+    _mapStart, _dataSize, buf_, len_, _baseOffset);
+  fflush(stdout);
+#endif 
+
+#if q4_WIN32 || __hpux || __MACH__ 
+  // if (buf_ >= _mapStart && buf_ <= _mapLimit - len_)
+
+  // a horrendous hack to allow file mapping for Win95 on network drive
+  // must use a temp buf to avoid write from mapped file to same file
+  // 
+  //  6-Feb-1999  --  this workaround is not thread safe
+  // 30-Nov-2001  --  changed to use the stack so now it is
+  // 28-Oct-2002  --  added HP/UX to the mix, to avoid hard lockup
+  char tempBuf[4096];
+  d4_assert(len_ <= sizeof tempBuf);
+  buf_ = memcpy(tempBuf, buf_, len_);
+#endif 
+
+  if (fseek(_file, _baseOffset + pos_, 0) != 0 || (int)fwrite(buf_, 1, len_,
+    _file) != len_) {
+    _failure = ferror(_file);
+    d4_assert(_failure != 0);
+    d4_assert(true); // always force an assertion failure in debug mode
+  }
+}
+
+void c4_FileStrategy::DataCommit(t4_i32 limit_) {
+  d4_assert(_file != 0);
+
+  if (fflush(_file) < 0) {
+    _failure = ferror(_file);
+    d4_assert(_failure != 0);
+    d4_assert(true); // always force an assertion failure in debug mode
+    return ;
+  }
+
+  if (limit_ > 0) {
+#if 0 // can't truncate file in a portable way!
+    // unmap the file first, WinNT is more picky about this than Win95
+    FILE *save = _file;
+
+    _file = 0;
+    ResetFileMapping();
+    _file = save;
+
+    _file->SetLength(limit_); // now we can resize the file
+#endif 
+    ResetFileMapping(); // remap, since file length may have changed
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/format.cpp b/8.x/mk/src/format.cpp
new file mode 100755 (executable)
index 0000000..af1d306
--- /dev/null
@@ -0,0 +1,1280 @@
+// format.cpp --
+// $Id: format.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Format handlers deal with the representation of data
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "column.h"
+#include "format.h"
+#include "persist.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatHandler: public c4_Handler {
+    c4_HandlerSeq &_owner;
+
+  public:
+    c4_FormatHandler(const c4_Property &prop_, c4_HandlerSeq &owner_);
+    virtual ~c4_FormatHandler();
+
+    virtual bool IsPersistent()const;
+
+  protected:
+    c4_HandlerSeq &Owner()const;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_FormatHandler
+
+c4_FormatHandler::c4_FormatHandler(const c4_Property &prop_, c4_HandlerSeq
+  &owner_): c4_Handler(prop_), _owner(owner_){}
+
+c4_FormatHandler::~c4_FormatHandler(){}
+
+d4_inline c4_HandlerSeq &c4_FormatHandler::Owner()const {
+  return _owner;
+}
+
+bool c4_FormatHandler::IsPersistent()const {
+  return _owner.Persist() != 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatX: public c4_FormatHandler {
+  public:
+    c4_FormatX(const c4_Property &prop_, c4_HandlerSeq &seq_, int width_ =
+      sizeof(t4_i32));
+
+    virtual void Define(int, const t4_byte **);
+    virtual void OldDefine(char type_, c4_Persist &);
+    virtual void FlipBytes();
+
+    virtual int ItemSize(int index_);
+    virtual const void *Get(int index_, int &length_);
+    virtual void Set(int index_, const c4_Bytes &buf_);
+
+    virtual void Insert(int index_, const c4_Bytes &buf_, int count_);
+    virtual void Remove(int index_, int count_);
+
+    virtual void Commit(c4_SaveContext &ar_);
+
+    virtual void Unmapped();
+
+    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
+
+  protected:
+    c4_ColOfInts _data;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatX::c4_FormatX(const c4_Property &p_, c4_HandlerSeq &s_, int w_):
+  c4_FormatHandler(p_, s_), _data(s_.Persist(), w_){}
+
+int c4_FormatX::DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  return c4_ColOfInts::DoCompare(b1_, b2_);
+}
+
+void c4_FormatX::Commit(c4_SaveContext &ar_) {
+  _data.FixSize(true);
+  ar_.CommitColumn(_data);
+  //_data.FixSize(false);
+}
+
+void c4_FormatX::Define(int rows_, const t4_byte **ptr_) {
+  if (ptr_ != 0)
+    _data.PullLocation(*ptr_);
+
+  _data.SetRowCount(rows_);
+}
+
+void c4_FormatX::OldDefine(char, c4_Persist &pers_) {
+  pers_.FetchOldLocation(_data);
+  _data.SetRowCount(Owner().NumRows());
+}
+
+void c4_FormatX::FlipBytes() {
+  _data.FlipBytes();
+}
+
+int c4_FormatX::ItemSize(int index_) {
+  return _data.ItemSize(index_);
+}
+
+const void *c4_FormatX::Get(int index_, int &length_) {
+  return _data.Get(index_, length_);
+}
+
+void c4_FormatX::Set(int index_, const c4_Bytes &buf_) {
+  _data.Set(index_, buf_);
+}
+
+void c4_FormatX::Insert(int index_, const c4_Bytes &buf_, int count_) {
+  _data.Insert(index_, buf_, count_);
+}
+
+void c4_FormatX::Remove(int index_, int count_) {
+  _data.Remove(index_, count_);
+}
+
+void c4_FormatX::Unmapped() {
+  _data.ReleaseAllSegments();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#if !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatL: public c4_FormatX {
+  public:
+    c4_FormatL(const c4_Property &prop_, c4_HandlerSeq &seq_);
+
+    virtual void Define(int, const t4_byte **);
+
+    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatL::c4_FormatL(const c4_Property &prop_, c4_HandlerSeq &seq_):
+  c4_FormatX(prop_, seq_, sizeof(t4_i64)) {
+  // force maximum size, autosizing more than 32 bits won't work
+  _data.SetAccessWidth(8 *sizeof(t4_i64));
+}
+
+int c4_FormatL::DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  d4_assert(b1_.Size() == sizeof(t4_i64));
+  d4_assert(b2_.Size() == sizeof(t4_i64));
+
+  t4_i64 v1 = *(const t4_i64*)b1_.Contents();
+  t4_i64 v2 = *(const t4_i64*)b2_.Contents();
+
+  return v1 == v2 ? 0 : v1 < v2 ?  - 1:  + 1;
+}
+
+void c4_FormatL::Define(int rows_, const t4_byte **ptr_) {
+  if (ptr_ == 0 && rows_ > 0) {
+    d4_assert(_data.ColSize() == 0);
+    _data.InsertData(0, rows_ *sizeof(t4_i64), true);
+  }
+
+  c4_FormatX::Define(rows_, ptr_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatF: public c4_FormatX {
+  public:
+    c4_FormatF(const c4_Property &prop_, c4_HandlerSeq &seq_);
+
+    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatF::c4_FormatF(const c4_Property &prop_, c4_HandlerSeq &seq_):
+  c4_FormatX(prop_, seq_, sizeof(float)){}
+
+int c4_FormatF::DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  d4_assert(b1_.Size() == sizeof(float));
+  d4_assert(b2_.Size() == sizeof(float));
+
+  float v1 = *(const float*)b1_.Contents();
+  float v2 = *(const float*)b2_.Contents();
+
+  return v1 == v2 ? 0 : v1 < v2 ?  - 1:  + 1;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatD: public c4_FormatX {
+  public:
+    c4_FormatD(const c4_Property &prop_, c4_HandlerSeq &seq_);
+
+    virtual void Define(int, const t4_byte **);
+
+    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatD::c4_FormatD(const c4_Property &prop_, c4_HandlerSeq &seq_):
+  c4_FormatX(prop_, seq_, sizeof(double)) {
+  // force maximum size, autosizing more than 32 bits won't work
+  _data.SetAccessWidth(8 *sizeof(double));
+}
+
+int c4_FormatD::DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  d4_assert(b1_.Size() == sizeof(double));
+  d4_assert(b2_.Size() == sizeof(double));
+
+  double v1 = *(const double*)b1_.Contents();
+  double v2 = *(const double*)b2_.Contents();
+
+  return v1 == v2 ? 0 : v1 < v2 ?  - 1:  + 1;
+}
+
+void c4_FormatD::Define(int rows_, const t4_byte **ptr_) {
+  if (ptr_ == 0 && rows_ > 0) {
+    d4_assert(_data.ColSize() == 0);
+    _data.InsertData(0, rows_ *sizeof(double), true);
+  }
+
+  c4_FormatX::Define(rows_, ptr_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+
+/*
+Byte properties are used for raw bytes and for indirect (memo) data.
+
+There are two columns: the actual data and the item sizes.  If the data
+is indirect, then the size is stored as a negative value.
+
+In addition, there is an in-memory-only vector of columns (_memos).
+Columns are created when asked for, and stay around until released with
+a commit call.  If the column object exists and is not dirty, then it
+is either a real column (size < 0), or simply a duplicate of the data
+stored inline as bytes.
+ */
+
+class c4_FormatB: public c4_FormatHandler {
+  public:
+    c4_FormatB(const c4_Property &prop_, c4_HandlerSeq &seq_);
+    virtual ~c4_FormatB();
+
+    virtual void Define(int, const t4_byte **);
+    virtual void OldDefine(char type_, c4_Persist &);
+    virtual void Commit(c4_SaveContext &ar_);
+
+    virtual int ItemSize(int index_);
+    virtual const void *Get(int index_, int &length_);
+    virtual void Set(int index_, const c4_Bytes &buf_);
+
+    virtual void Insert(int index_, const c4_Bytes &buf_, int count_);
+    virtual void Remove(int index_, int count_);
+
+    virtual c4_Column *GetNthMemoCol(int index_, bool alloc_);
+
+    virtual void Unmapped();
+
+    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
+
+  protected:
+    const void *GetOne(int index_, int &length_);
+    void SetOne(int index_, const c4_Bytes &buf_, bool ignoreMemos_ = false);
+
+  private:
+    t4_i32 Offset(int index_)const;
+    bool ShouldBeMemo(int length_)const;
+    int ItemLenOffCol(int index_, t4_i32 &off_, c4_Column * &col_);
+    bool CommitItem(c4_SaveContext &ar_, int index_);
+    void InitOffsets(c4_ColOfInts &sizes_);
+
+    c4_Column _data;
+    c4_ColOfInts _sizeCol; // 2001-11-27: keep, to track position on disk
+    c4_Column _memoCol; // 2001-11-27: keep, to track position on disk
+    c4_DWordArray _offsets;
+    c4_PtrArray _memos;
+    bool _recalc; // 2001-11-27: remember when to redo _{size,memo}Col
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatB::c4_FormatB(const c4_Property &prop_, c4_HandlerSeq &seq_):
+  c4_FormatHandler(prop_, seq_), _data(seq_.Persist()), _sizeCol(seq_.Persist())
+  , _memoCol(seq_.Persist()), _recalc(false) {
+  _offsets.SetSize(1, 100);
+  _offsets.SetAt(0, 0);
+}
+
+c4_FormatB::~c4_FormatB() {
+  // cleanup allocated columns
+  //better? for (int i = _memos.GetSize(); --i >= 0 ;)
+  for (int i = 0; i < _memos.GetSize(); ++i)
+    delete (c4_Column*)_memos.GetAt(i);
+}
+
+d4_inline t4_i32 c4_FormatB::Offset(int index_)const {
+  d4_assert((t4_i32)_offsets.GetAt(_offsets.GetSize() - 1) == _data.ColSize());
+  d4_assert(_offsets.GetSize() == _memos.GetSize() + 1);
+  d4_assert(index_ < _offsets.GetSize());
+
+  // extend offset vectors for missing empty entries at end 
+  int n = _offsets.GetSize();
+  d4_assert(n > 0);
+
+  if (index_ >= n)
+    index_ = n - 1;
+
+  return _offsets.GetAt(index_);
+}
+
+d4_inline bool c4_FormatB::ShouldBeMemo(int length_)const {
+  // items over 10000 bytes are always memos
+  // items up to 100 bytes are never memos
+  //
+  // else, memo only if the column would be under 1 Mb
+  // (assuming all items had the same size as this one)
+  //
+  // the effect is that as the number of rows increases,
+  // smaller and smaller items get turned into memos
+  //
+  // note that items which are no memo right now stay
+  // as is, and so do memos which have not been modified
+
+  int rows = _memos.GetSize() + 1; // avoids divide by zero
+  return length_ > 10000 || length_ > 100 && length_ > 1000000 / rows;
+}
+
+int c4_FormatB::ItemLenOffCol(int index_, t4_i32 &off_, c4_Column * &col_) {
+  col_ = (c4_Column*)_memos.GetAt(index_);
+  if (col_ != 0) {
+    off_ = 0;
+    return col_->ColSize();
+  }
+
+  col_ = &_data;
+  off_ = Offset(index_);
+  return Offset(index_ + 1) - off_;
+}
+
+c4_Column *c4_FormatB::GetNthMemoCol(int index_, bool alloc_) {
+  t4_i32 start;
+  c4_Column *col;
+  int n = ItemLenOffCol(index_, start, col);
+
+  if (col ==  &_data && alloc_) {
+    col = d4_new c4_Column(_data.Persist());
+    _memos.SetAt(index_, col);
+
+    if (n > 0)
+    if (_data.IsDirty()) {
+      c4_Bytes temp;
+      _data.FetchBytes(start, n, temp, true);
+      col->SetBuffer(n);
+      col->StoreBytes(0, temp);
+    } else
+      col->SetLocation(_data.Position() + start, n);
+  }
+
+  return col;
+}
+
+void c4_FormatB::Unmapped() {
+  _data.ReleaseAllSegments();
+  _sizeCol.ReleaseAllSegments();
+  _memoCol.ReleaseAllSegments();
+
+  for (int i = 0; i < _memos.GetSize(); ++i) {
+    c4_Column *cp = (c4_Column*)_memos.GetAt(i);
+    if (cp != 0)
+      cp->ReleaseAllSegments();
+  }
+}
+
+void c4_FormatB::Define(int, const t4_byte **ptr_) {
+  d4_assert(_memos.GetSize() == 0);
+
+  if (ptr_ != 0) {
+    _data.PullLocation(*ptr_);
+    if (_data.ColSize() > 0)
+      _sizeCol.PullLocation(*ptr_);
+    _memoCol.PullLocation(*ptr_);
+  }
+
+  // everything below this point could be delayed until use
+  // in that case, watch out that column space use is properly tracked
+
+  InitOffsets(_sizeCol);
+
+  if (_memoCol.ColSize() > 0) {
+    c4_Bytes walk;
+    _memoCol.FetchBytes(0, _memoCol.ColSize(), walk, true);
+
+    const t4_byte *p = walk.Contents();
+
+    for (int row = 0; p < walk.Contents() + walk.Size(); ++row) {
+      row += c4_Column::PullValue(p);
+      d4_assert(row < _memos.GetSize());
+
+      c4_Column *mc = d4_new c4_Column(_data.Persist());
+      d4_assert(mc != 0);
+      _memos.SetAt(row, mc);
+
+      mc->PullLocation(p);
+    }
+
+    d4_assert(p == walk.Contents() + walk.Size());
+  }
+}
+
+void c4_FormatB::OldDefine(char type_, c4_Persist &pers_) {
+  int rows = Owner().NumRows();
+
+  c4_ColOfInts sizes(_data.Persist());
+
+  if (type_ == 'M') {
+    InitOffsets(sizes);
+
+    c4_ColOfInts szVec(_data.Persist());
+    pers_.FetchOldLocation(szVec);
+    szVec.SetRowCount(rows);
+
+    c4_ColOfInts posVec(_data.Persist());
+    pers_.FetchOldLocation(posVec);
+    posVec.SetRowCount(rows);
+
+    for (int r = 0; r < rows; ++r) {
+      t4_i32 sz = szVec.GetInt(r);
+      if (sz > 0) {
+        c4_Column *mc = d4_new c4_Column(_data.Persist());
+        d4_assert(mc != 0);
+        _memos.SetAt(r, mc);
+
+        mc->SetLocation(posVec.GetInt(r), sz);
+      }
+    }
+  } else {
+    pers_.FetchOldLocation(_data);
+
+    if (type_ == 'B') {
+      pers_.FetchOldLocation(sizes);
+
+#if !q4_OLD_IS_ALWAYS_V2
+
+      // WARNING - HUGE HACK AHEAD - THIS IS NOT 100% FULLPROOF!
+      //
+      // The above is correct for MK versions 2.0 and up, but *NOT*
+      // for MK 1.8.6 datafiles, which store sizes first (OUCH!!!).
+      // This means that there is not a 100% safe way to auto-convert
+      // both 1.8.6 and 2.0 files - since there is no way to detect
+      // unambiguously which version a datafile is.  All we can do,
+      // is to carefully check both vectors, and *hope* that only one
+      // of them is valid as sizes vector.  This problem applies to
+      // the 'B' (bytes) property type only, and only pre 2.0 files.
+      //
+      // To build a version which *always* converts assuming 1.8.6,
+      // add flag "-Dq4_OLD_IS_PRE_V2" to the compiler command line.
+      // Conversely, "-Dq4_OLD_IS_ALWAYS_V2" forces 2.0 conversion.
+
+      if (rows > 0) {
+        t4_i32 s1 = sizes.ColSize();
+        t4_i32 s2 = _data.ColSize();
+
+#if !q4_OLD_IS_PRE_V2
+        // if the size vector is clearly impossible, swap vectors
+        bool fix = c4_ColOfInts::CalcAccessWidth(rows, s1) < 0;
+
+        // if the other vector might be valid as well, check further
+        if (!fix && c4_ColOfInts::CalcAccessWidth(rows, s2) >= 0) {
+          sizes.SetRowCount(rows);
+          t4_i32 total = 0;
+          for (int i = 0; i < rows; ++i) {
+            t4_i32 w = sizes.GetInt(i);
+            if (w < 0 || total > s2) {
+              total =  - 1;
+              break;
+            }
+            total += w;
+          }
+
+          // if the sizes don't add up, swap vectors
+          fix = total != s2;
+        }
+
+        if (fix)
+#endif 
+         {
+          t4_i32 p1 = sizes.Position();
+          t4_i32 p2 = _data.Position();
+          _data.SetLocation(p1, s1);
+          sizes.SetLocation(p2, s2);
+        }
+      }
+#endif 
+      InitOffsets(sizes);
+    } else {
+      d4_assert(type_ == 'S');
+
+      sizes.SetRowCount(rows);
+
+      t4_i32 pos = 0;
+      t4_i32 lastEnd = 0;
+      int k = 0;
+
+      c4_ColIter iter(_data, 0, _data.ColSize());
+      while (iter.Next()) {
+        const t4_byte *p = iter.BufLoad();
+        for (int j = 0; j < iter.BufLen(); ++j)
+        if (!p[j]) {
+          sizes.SetInt(k++, pos + j + 1-lastEnd);
+          lastEnd = pos + j + 1;
+        }
+
+        pos += iter.BufLen();
+      }
+
+      d4_assert(pos == _data.ColSize());
+
+      if (lastEnd < pos) {
+        // last entry had no zero byte
+        _data.InsertData(pos++, 1, true);
+        sizes.SetInt(k, pos - lastEnd);
+      }
+
+      InitOffsets(sizes);
+
+      // get rid of entries with just a null byte
+      for (int r = 0; r < rows; ++r)
+        if (c4_FormatB::ItemSize(r) == 1)
+          SetOne(r, c4_Bytes());
+    }
+  }
+}
+
+void c4_FormatB::InitOffsets(c4_ColOfInts &sizes_) {
+  int rows = Owner().NumRows();
+
+  if (sizes_.RowCount() != rows) {
+    sizes_.SetRowCount(rows);
+  }
+
+  _memos.SetSize(rows);
+  _offsets.SetSize(rows + 1);
+
+  if (_data.ColSize() > 0) {
+    t4_i32 total = 0;
+
+    for (int r = 0; r < rows; ++r) {
+      int n = sizes_.GetInt(r);
+      d4_assert(n >= 0);
+      total += n;
+      _offsets.SetAt(r + 1, total);
+    }
+
+    d4_assert(total == _data.ColSize());
+  }
+
+}
+
+int c4_FormatB::ItemSize(int index_) {
+  t4_i32 start;
+  c4_Column *col;
+  return ItemLenOffCol(index_, start, col);
+}
+
+const void *c4_FormatB::GetOne(int index_, int &length_) {
+  t4_i32 start;
+  c4_Column *cp;
+  length_ = ItemLenOffCol(index_, start, cp);
+  d4_assert(length_ >= 0);
+
+  if (length_ == 0)
+    return "";
+
+  return cp->FetchBytes(start, length_, Owner().Buffer(), false);
+}
+
+const void *c4_FormatB::Get(int index_, int &length_) {
+  return GetOne(index_, length_);
+}
+
+void c4_FormatB::SetOne(int index_, const c4_Bytes &xbuf_, bool ignoreMemos_) {
+  // this fixes bug in 2.4.0 when copying string from higher row
+  // TODO: this fix is very conservative, figure out when to copy
+  // (can probably look at pointer to see whether it's from us)
+  int sz = xbuf_.Size();
+  c4_Bytes buf_(xbuf_.Contents(), sz, 0 < sz && sz <= c4_Column::kSegMax);
+
+  c4_Column *cp = &_data;
+  t4_i32 start = Offset(index_);
+  int len = Offset(index_ + 1) - start;
+
+  if (!ignoreMemos_ && _memos.GetAt(index_) != 0)
+    len = ItemLenOffCol(index_, start, cp);
+
+  int m = buf_.Size();
+  int n = m - len;
+
+  if (n > 0)
+    cp->Grow(start, n);
+  else if (n < 0)
+    cp->Shrink(start,  - n);
+  else if (m == 0)
+    return ;
+  // no size change and no contents
+
+  _recalc = true;
+
+  cp->StoreBytes(start, buf_);
+
+  if (n && cp ==  &_data) {
+    // if size has changed
+    int k = _offsets.GetSize() - 1;
+
+    // if filling in an empty entry at end: extend offsets first
+    if (m > 0 && index_ >= k) {
+      _offsets.InsertAt(k, _offsets.GetAt(k), index_ - k + 1);
+
+      k = index_ + 1;
+      d4_assert(k == _offsets.GetSize() - 1);
+    }
+
+    // adjust following entry offsets
+    while (++index_ <= k)
+      _offsets.ElementAt(index_) += n;
+  }
+
+  d4_assert((t4_i32)_offsets.GetAt(_offsets.GetSize() - 1) == _data.ColSize());
+}
+
+void c4_FormatB::Set(int index_, const c4_Bytes &buf_) {
+  SetOne(index_, buf_);
+}
+
+int c4_FormatB::DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  int n = b1_.Size();
+  if (n > b2_.Size())
+    n = b2_.Size();
+
+  int f = memcmp(b1_.Contents(), b2_.Contents(), n);
+  return f ? f : b1_.Size() - b2_.Size();
+}
+
+void c4_FormatB::Insert(int index_, const c4_Bytes &buf_, int count_) {
+  d4_assert(count_ > 0);
+
+  _recalc = true;
+
+  int m = buf_.Size();
+  t4_i32 off = Offset(index_);
+
+  _memos.InsertAt(index_, 0, count_);
+
+  // insert the appropriate number of bytes
+  t4_i32 n = count_ *(t4_i32)m;
+  if (n > 0) {
+    _data.Grow(off, n);
+
+    // store as many copies as needed, but may have to do it in chunks
+    int spos = 0;
+
+    c4_ColIter iter(_data, off, off + n);
+    while (iter.Next(m - spos)) {
+      memcpy(iter.BufSave(), buf_.Contents() + spos, iter.BufLen());
+
+      spos += iter.BufLen();
+      if (spos >= m)
+        spos = 0;
+    }
+
+    d4_assert(spos == 0); // must have copied an exact multiple of the data
+  }
+
+  // define offsets of the new entries
+  _offsets.InsertAt(index_, 0, count_);
+  d4_assert(_offsets.GetSize() <= _memos.GetSize() + 1);
+
+  while (--count_ >= 0) {
+    _offsets.SetAt(index_++, off);
+    off += m;
+  }
+
+  d4_assert(index_ < _offsets.GetSize());
+
+  // adjust all following entries
+  while (index_ < _offsets.GetSize())
+    _offsets.ElementAt(index_++) += n;
+
+  d4_assert((t4_i32)_offsets.GetAt(index_ - 1) == _data.ColSize());
+  d4_assert(index_ <= _memos.GetSize() + 1);
+}
+
+void c4_FormatB::Remove(int index_, int count_) {
+  _recalc = true;
+
+  t4_i32 off = Offset(index_);
+  t4_i32 n = Offset(index_ + count_) - off;
+  d4_assert(n >= 0);
+
+  // remove the columns, if present
+  for (int i = 0; i < count_; ++i)
+    delete (c4_Column*)_memos.GetAt(index_ + i);
+  _memos.RemoveAt(index_, count_);
+
+  if (n > 0)
+    _data.Shrink(off, n);
+
+  _offsets.RemoveAt(index_, count_);
+
+  d4_assert(index_ < _offsets.GetSize());
+
+  // adjust all following entries
+  while (index_ < _offsets.GetSize())
+    _offsets.ElementAt(index_++) -= n;
+
+  d4_assert((t4_i32)_offsets.GetAt(index_ - 1) == _data.ColSize());
+  d4_assert(index_ <= _memos.GetSize() + 1);
+}
+
+void c4_FormatB::Commit(c4_SaveContext &ar_) {
+  int rows = _memos.GetSize();
+  d4_assert(rows > 0);
+
+  bool full = _recalc || ar_.Serializing();
+
+  if (!full)
+  for (int i = 0; i < rows; ++i) {
+    c4_Column *col = (c4_Column*)_memos.GetAt(i);
+    if (col != 0) {
+      full = true;
+      break;
+    }
+  }
+  d4_assert(_recalc || _sizeCol.RowCount() == rows);
+
+  if (full) {
+    _memoCol.SetBuffer(0);
+    _sizeCol.SetBuffer(0);
+    _sizeCol.SetAccessWidth(0);
+    _sizeCol.SetRowCount(rows);
+
+    int skip = 0;
+
+    c4_Column *saved = ar_.SetWalkBuffer(&_memoCol);
+
+    for (int r = 0; r < rows; ++r) {
+      ++skip;
+
+      t4_i32 start;
+      c4_Column *col;
+      int len = ItemLenOffCol(r, start, col);
+
+      bool oldMemo = col !=  &_data;
+      bool newMemo = ShouldBeMemo(len);
+
+      if (!oldMemo && newMemo) {
+        col = GetNthMemoCol(r, true);
+        d4_assert(col !=  &_data);
+        //? start = 0;
+      }
+
+      c4_Bytes temp;
+
+      if (newMemo) {
+        // it now is a memo, inlined data will be empty
+        ar_.StoreValue(skip - 1);
+        skip = 0;
+        ar_.CommitColumn(*col);
+      } else if (!oldMemo) {
+        // it was no memo, done if it hasn't become one
+        _sizeCol.SetInt(r, len);
+        continue;
+      } else {
+        // it was a memo, but it no longer is
+        d4_assert(start == 0);
+        if (len > 0) {
+          _sizeCol.SetInt(r, len);
+          col->FetchBytes(start, len, temp, true);
+          delete (c4_Column*)_memos.GetAt(r); // 28-11-2001: fix mem leak
+          _memos.SetAt(r, 0); // 02-11-2001: fix for use after commit
+        }
+      }
+
+      SetOne(r, temp, true); // bypass current memo pointer
+    }
+
+    ar_.SetWalkBuffer(saved);
+  }
+
+  ar_.CommitColumn(_data);
+
+  if (_data.ColSize() > 0) {
+    _sizeCol.FixSize(true);
+    ar_.CommitColumn(_sizeCol);
+    //_sizeCol.FixSize(false);
+  }
+
+  ar_.CommitColumn(_memoCol);
+
+  // need a way to find out when the data has been committed (on 2nd pass)
+  // both _sizeCol and _memoCol will be clean again when it has
+  // but be careful because dirty flag is only useful if size is nonzero
+  if (_recalc && !ar_.Serializing())
+    _recalc = _sizeCol.ColSize() > 0 && _sizeCol.IsDirty() || _memoCol.ColSize()
+      > 0 && _memoCol.IsDirty();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatS: public c4_FormatB {
+  public:
+    c4_FormatS(const c4_Property &prop_, c4_HandlerSeq &seq_);
+
+    virtual int ItemSize(int index_);
+    virtual const void *Get(int index_, int &length_);
+    virtual void Set(int index_, const c4_Bytes &buf_);
+
+    virtual void Insert(int index_, const c4_Bytes &buf_, int count_);
+
+    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatS::c4_FormatS(const c4_Property &prop_, c4_HandlerSeq &seq_):
+  c4_FormatB(prop_, seq_){}
+
+int c4_FormatS::ItemSize(int index_) {
+  int n = c4_FormatB::ItemSize(index_) - 1;
+  return n >= 0 ? n : 0;
+}
+
+const void *c4_FormatS::Get(int index_, int &length_) {
+  const void *ptr = GetOne(index_, length_);
+
+  if (length_ == 0) {
+    length_ = 1;
+    ptr = "";
+  }
+
+  d4_assert(((const char*)ptr)[length_ - 1] == 0);
+  return ptr;
+}
+
+void c4_FormatS::Set(int index_, const c4_Bytes &buf_) {
+  int m = buf_.Size();
+  if (--m >= 0) {
+    d4_assert(buf_.Contents()[m] == 0);
+    if (m == 0) {
+      SetOne(index_, c4_Bytes()); // don't store data for empty strings
+      return ;
+    }
+  }
+
+  SetOne(index_, buf_);
+}
+
+int c4_FormatS::DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  c4_String v1((const char*)b1_.Contents(), b1_.Size());
+  c4_String v2((const char*)b2_.Contents(), b2_.Size());
+
+  return v1.CompareNoCase(v2);
+}
+
+void c4_FormatS::Insert(int index_, const c4_Bytes &buf_, int count_) {
+  d4_assert(count_ > 0);
+
+  int m = buf_.Size();
+  if (--m >= 0) {
+    d4_assert(buf_.Contents()[m] == 0);
+    if (m == 0) {
+      c4_FormatB::Insert(index_, c4_Bytes(), count_);
+      return ;
+    }
+  }
+
+  c4_FormatB::Insert(index_, buf_, count_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FormatV: public c4_FormatHandler {
+  public:
+    c4_FormatV(const c4_Property &prop_, c4_HandlerSeq &seq_);
+    virtual ~c4_FormatV();
+
+    virtual void Define(int rows_, const t4_byte **ptr_);
+    virtual void OldDefine(char type_, c4_Persist &);
+    virtual void Commit(c4_SaveContext &ar_);
+
+    virtual void FlipBytes();
+
+    virtual int ItemSize(int index_);
+    virtual const void *Get(int index_, int &length_);
+    virtual void Set(int index_, const c4_Bytes &buf_);
+
+    virtual void Insert(int index_, const c4_Bytes &buf_, int count_);
+    virtual void Remove(int index_, int count_);
+
+    virtual void Unmapped();
+    virtual bool HasSubview(int index_);
+
+    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
+
+  private:
+    c4_HandlerSeq &At(int index_);
+    void Replace(int index_, c4_HandlerSeq *seq_);
+    void SetupAllSubviews();
+    void ForgetSubview(int index_);
+
+    c4_Column _data;
+    c4_PtrArray _subSeqs;
+    bool _inited;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FormatV::c4_FormatV(const c4_Property &prop_, c4_HandlerSeq &seq_):
+  c4_FormatHandler(prop_, seq_), _data(seq_.Persist()), _inited(false){}
+
+c4_FormatV::~c4_FormatV() {
+  for (int i = 0; i < _subSeqs.GetSize(); ++i)
+    ForgetSubview(i);
+}
+
+c4_HandlerSeq &c4_FormatV::At(int index_) {
+  d4_assert(_inited);
+
+  c4_HandlerSeq * &hs = (c4_HandlerSeq * &)_subSeqs.ElementAt(index_);
+  if (hs == 0) {
+    hs = d4_new c4_HandlerSeq(Owner(), this);
+    hs->IncRef();
+  }
+
+  return  *hs;
+}
+
+void c4_FormatV::SetupAllSubviews() {
+  d4_assert(!_inited);
+  _inited = true;
+
+  if (_data.ColSize() > 0) {
+    c4_Bytes temp;
+    _data.FetchBytes(0, _data.ColSize(), temp, true);
+    const t4_byte *ptr = temp.Contents();
+
+    for (int r = 0; r < _subSeqs.GetSize(); ++r) {
+      // don't materialize subview if it is empty
+      // duplicates code which is in c4_HandlerSeq::Prepare
+      const t4_byte *p2 = ptr;
+      d4_dbgdef(t4_i32 sias = )c4_Column::PullValue(p2);
+      d4_assert(sias == 0); // not yet
+
+      if (c4_Column::PullValue(p2) > 0)
+        At(r).Prepare(&ptr, false);
+      else
+        ptr = p2;
+    }
+
+    d4_assert(ptr == temp.Contents() + temp.Size());
+  }
+}
+
+void c4_FormatV::Define(int rows_, const t4_byte **ptr_) {
+  if (_inited) {
+    // big oops: a root handler already contains data
+
+    for (int i = 0; i < _subSeqs.GetSize(); ++i)
+      ForgetSubview(i);
+
+    _inited = false;
+  }
+
+  _subSeqs.SetSize(rows_);
+  if (ptr_ != 0)
+    _data.PullLocation(*ptr_);
+}
+
+void c4_FormatV::OldDefine(char, c4_Persist &pers_) {
+  int rows = Owner().NumRows();
+  _subSeqs.SetSize(rows);
+
+  for (int i = 0; i < rows; ++i) {
+    int n = pers_.FetchOldValue();
+    if (n) {
+      // 14-11-2000: do not create again (this causes a mem leak)
+      // 04-12-2000: but do create if absent (fixes occasional crash)
+      c4_HandlerSeq *hs = (c4_HandlerSeq*)_subSeqs.GetAt(i);
+      if (hs == 0) {
+        hs = d4_new c4_HandlerSeq(Owner(), this);
+        _subSeqs.SetAt(i, hs);
+        hs->IncRef();
+      }
+      hs->SetNumRows(n);
+      hs->OldPrepare();
+    }
+  }
+}
+
+void c4_FormatV::FlipBytes() {
+  if (!_inited)
+    SetupAllSubviews();
+
+  for (int i = 0; i < _subSeqs.GetSize(); ++i)
+    At(i).FlipAllBytes();
+}
+
+int c4_FormatV::ItemSize(int index_) {
+  if (!_inited)
+    SetupAllSubviews();
+
+  // 06-02-2002: avoid creating empty subview
+  c4_HandlerSeq *hs = (c4_HandlerSeq * &)_subSeqs.ElementAt(index_);
+  return hs == 0 ? 0 : hs->NumRows();
+}
+
+const void *c4_FormatV::Get(int index_, int &length_) {
+  if (!_inited)
+    SetupAllSubviews();
+
+  At(index_); // forces existence of a real entry
+  c4_HandlerSeq * &e = (c4_HandlerSeq * &)_subSeqs.ElementAt(index_);
+
+  length_ = sizeof(c4_HandlerSeq **);
+  return  &e;
+}
+
+void c4_FormatV::Set(int index_, const c4_Bytes &buf_) {
+  d4_assert(buf_.Size() == sizeof(c4_Sequence*));
+
+  if (!_inited)
+    SetupAllSubviews();
+
+  c4_HandlerSeq *value = *(c4_HandlerSeq *const*)buf_.Contents();
+
+  if (value !=  &At(index_))
+    Replace(index_, value);
+}
+
+void c4_FormatV::Replace(int index_, c4_HandlerSeq *seq_) {
+  if (!_inited)
+    SetupAllSubviews();
+
+  c4_HandlerSeq * &curr = (c4_HandlerSeq * &)_subSeqs.ElementAt(index_);
+  if (seq_ == curr)
+    return ;
+
+  if (curr != 0) {
+    d4_assert(&curr->Parent() ==  &Owner());
+    curr->DetachFromParent();
+    curr->DetachFromStorage(true);
+
+    curr->DecRef();
+    curr = 0;
+  }
+
+  if (seq_) {
+    int n = seq_->NumRows();
+
+    c4_HandlerSeq &t = At(index_);
+    d4_assert(t.NumRows() == 0);
+
+    t.Resize(n);
+
+    c4_Bytes data;
+
+    // this dest seq has only the persistent handlers
+    // and maybe in a different order
+    // create any others we need as temporary properties
+    for (int i = 0; i < seq_->NumHandlers(); ++i) {
+      c4_Handler &h1 = seq_->NthHandler(i);
+
+      int j = t.PropIndex(h1.Property());
+      d4_assert(j >= 0);
+
+      c4_Handler &h2 = t.NthHandler(j);
+
+      for (int k = 0; k < n; ++k)
+        if (seq_->Get(k, h1.PropId(), data))
+          h2.Set(k, data);
+    }
+  }
+}
+
+int c4_FormatV::DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  d4_assert(b1_.Size() == sizeof(c4_Sequence*));
+  d4_assert(b2_.Size() == sizeof(c4_Sequence*));
+
+  c4_View v1 = *(c4_Sequence *const*)b1_.Contents();
+  c4_View v2 = *(c4_Sequence *const*)b2_.Contents();
+
+  return v1.Compare(v2);
+}
+
+void c4_FormatV::Insert(int index_, const c4_Bytes &buf_, int count_) {
+  d4_assert(buf_.Size() == sizeof(c4_Sequence*));
+  d4_assert(count_ > 0);
+
+  // can only insert an empty entry!
+  d4_assert(*(c4_Sequence *const*)buf_.Contents() == 0);
+
+  if (!_inited)
+    SetupAllSubviews();
+
+  _subSeqs.InsertAt(index_, 0, count_);
+  _data.SetBuffer(0); // 2004-01-18 force dirty
+}
+
+void c4_FormatV::Remove(int index_, int count_) {
+  d4_assert(count_ > 0);
+
+  if (!_inited)
+    SetupAllSubviews();
+
+  for (int i = 0; i < count_; ++i)
+    ForgetSubview(index_ + i);
+
+  _subSeqs.RemoveAt(index_, count_);
+  _data.SetBuffer(0); // 2004-01-18 force dirty
+}
+
+void c4_FormatV::Unmapped() {
+  if (_inited)
+    for (int i = 0; i < _subSeqs.GetSize(); ++i)
+  if (HasSubview(i)) {
+    c4_HandlerSeq &hs = At(i);
+    hs.UnmappedAll();
+    if (hs.NumRefs() == 1 && hs.NumRows() == 0)
+        ForgetSubview(i);
+  }
+
+  _data.ReleaseAllSegments();
+}
+
+bool c4_FormatV::HasSubview(int index_) {
+  if (!_inited)
+    SetupAllSubviews();
+
+  return _subSeqs.ElementAt(index_) != 0;
+}
+
+void c4_FormatV::ForgetSubview(int index_) {
+  c4_HandlerSeq * &seq = (c4_HandlerSeq * &)_subSeqs.ElementAt(index_);
+  if (seq != 0) {
+    d4_assert(&seq->Parent() ==  &Owner());
+    seq->DetachFromParent();
+    seq->DetachFromStorage(true);
+    seq->UnmappedAll();
+    seq->DecRef();
+    seq = 0;
+  }
+}
+
+void c4_FormatV::Commit(c4_SaveContext &ar_) {
+  if (!_inited)
+    SetupAllSubviews();
+
+  int rows = _subSeqs.GetSize();
+  d4_assert(rows > 0);
+
+  c4_Column temp(0);
+  c4_Column *saved = ar_.SetWalkBuffer(&temp);
+
+  for (int r = 0; r < rows; ++r)
+  if (HasSubview(r)) {
+    c4_HandlerSeq &hs = At(r);
+    ar_.CommitSequence(hs, false);
+    if (hs.NumRefs() == 1 && hs.NumRows() == 0)
+      ForgetSubview(r);
+  } else {
+    ar_.StoreValue(0); // sias
+    ar_.StoreValue(0); // row count
+  }
+
+  ar_.SetWalkBuffer(saved);
+
+  c4_Bytes buf;
+  temp.FetchBytes(0, temp.ColSize(), buf, true);
+
+  bool changed = temp.ColSize() != _data.ColSize();
+
+  if (!changed) {
+    c4_Bytes buf2;
+    _data.FetchBytes(0, _data.ColSize(), buf2, true);
+    changed = buf != buf2;
+  }
+
+  if (changed) {
+    _data.SetBuffer(buf.Size());
+    _data.StoreBytes(0, buf);
+  }
+
+  ar_.CommitColumn(_data);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Handler *f4_CreateFormat(const c4_Property &prop_, c4_HandlerSeq &seq_) {
+  switch (prop_.Type()) {
+    case 'I':
+      return d4_new c4_FormatX(prop_, seq_);
+#if !q4_TINY
+    case 'L':
+      return d4_new c4_FormatL(prop_, seq_);
+    case 'F':
+      return d4_new c4_FormatF(prop_, seq_);
+    case 'D':
+      return d4_new c4_FormatD(prop_, seq_);
+#endif 
+    case 'B':
+      return d4_new c4_FormatB(prop_, seq_);
+    case 'S':
+      return d4_new c4_FormatS(prop_, seq_);
+    case 'V':
+      return d4_new c4_FormatV(prop_, seq_);
+  }
+
+  d4_assert(0);
+  // 2004-01-16 turn bad definition type into an int property to avoid crash
+  return d4_new c4_FormatX(c4_IntProp(prop_.Name()), seq_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int f4_ClearFormat(char type_) {
+  switch (type_) {
+    case 'I':
+      return sizeof(t4_i32);
+#if !q4_TINY
+    case 'L':
+      return sizeof(t4_i64);
+    case 'F':
+      return sizeof(float);
+    case 'D':
+      return sizeof(double);
+#endif 
+    case 'S':
+      return 1;
+    case 'V':
+      return sizeof(c4_Sequence*);
+  }
+
+  return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int f4_CompareFormat(char type_, const c4_Bytes &b1_, const c4_Bytes &b2_) {
+  switch (type_) {
+    case 'I':
+      return c4_FormatX::DoCompare(b1_, b2_);
+#if !q4_TINY
+    case 'L':
+      return c4_FormatL::DoCompare(b1_, b2_);
+    case 'F':
+      return c4_FormatF::DoCompare(b1_, b2_);
+    case 'D':
+      return c4_FormatD::DoCompare(b1_, b2_);
+#endif 
+    case 'B':
+      return c4_FormatB::DoCompare(b1_, b2_);
+    case 'S':
+      return c4_FormatS::DoCompare(b1_, b2_);
+    case 'V':
+      return c4_FormatV::DoCompare(b1_, b2_);
+  }
+
+  d4_assert(0);
+  return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/format.h b/8.x/mk/src/format.h
new file mode 100755 (executable)
index 0000000..cda7793
--- /dev/null
@@ -0,0 +1,23 @@
+// format.h --
+// $Id: format.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Encapsulation of all format handlers
+ */
+
+#ifndef __FORMAT_H__
+#define __FORMAT_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+class c4_Handler; // not defined here
+
+extern c4_Handler *f4_CreateFormat(const c4_Property &, c4_HandlerSeq &);
+extern int f4_ClearFormat(char);
+extern int f4_CompareFormat(char, const c4_Bytes &, const c4_Bytes &);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/gnuc.h b/8.x/mk/src/gnuc.h
new file mode 100755 (executable)
index 0000000..739b8ed
--- /dev/null
@@ -0,0 +1,13 @@
+// gnuc.h --
+// $Id: gnuc.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Configuration header for GNU C++
+ */
+
+#define q4_GNUC 1
+
+#if !defined (q4_BOOL)
+#define q4_BOOL 1
+#endif
diff --git a/8.x/mk/src/handler.cpp b/8.x/mk/src/handler.cpp
new file mode 100755 (executable)
index 0000000..2416bd6
--- /dev/null
@@ -0,0 +1,463 @@
+// handler.cpp --
+// $Id: handler.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Handlers store data in column-wise format
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "format.h"
+#include "field.h"
+#include "column.h"
+#include "persist.h"
+
+#if !q4_INLINE
+#include "handler.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Handler
+
+void c4_Handler::ClearBytes(c4_Bytes &buf_)const {
+  static char zeros[8];
+
+  int n = f4_ClearFormat(Property().Type());
+  d4_assert(n <= sizeof zeros);
+
+  buf_ = c4_Bytes(zeros, n);
+}
+
+int c4_Handler::Compare(int index_, const c4_Bytes &buf_) {
+  // create a copy for small data, since ints use a common _item buffer
+  c4_Bytes copy(buf_.Contents(), buf_.Size(), buf_.Size() <= 8);
+
+  c4_Bytes data;
+  GetBytes(index_, data);
+
+  return f4_CompareFormat(Property().Type(), data, copy);
+}
+
+void c4_Handler::Commit(c4_SaveContext &) {
+  d4_assert(0);
+}
+
+void c4_Handler::OldDefine(char, c4_Persist &) {
+  d4_assert(0);
+}
+
+// this is how the old "Get" was, keep it until no longer needed
+void c4_Handler::GetBytes(int index_, c4_Bytes &buf_, bool copySmall_) {
+  int n;
+  const void *p = Get(index_, n);
+  buf_ = c4_Bytes(p, n, copySmall_ && n <= 8);
+}
+
+void c4_Handler::Move(int from_, int to_) {
+  if (from_ != to_) {
+    c4_Bytes data;
+    GetBytes(from_, data);
+
+    Remove(from_, 1);
+
+    if (to_ > from_)
+      --to_;
+
+    Insert(to_, data, 1);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_HandlerSeq
+
+c4_HandlerSeq::c4_HandlerSeq(c4_Persist *persist_): _persist(persist_), _field
+  (0), _parent(0), _numRows(0){}
+
+c4_HandlerSeq::c4_HandlerSeq(c4_HandlerSeq &owner_, c4_Handler *handler_):
+  _persist(owner_.Persist()), _field(owner_.FindField(handler_)), _parent
+  (&owner_), _numRows(0) {
+  for (int i = 0; i < NumFields(); ++i) {
+    c4_Field &field = Field(i);
+    c4_Property prop(field.Type(), field.Name());
+
+    d4_dbgdef(int n = )AddHandler(f4_CreateFormat(prop,  *this));
+    d4_assert(n == i);
+  }
+}
+
+c4_HandlerSeq::~c4_HandlerSeq() {
+  const bool rootLevel = _parent == this;
+  c4_Persist *pers = _persist;
+
+  if (rootLevel && pers != 0)
+    pers->DoAutoCommit();
+
+  DetachFromParent();
+  DetachFromStorage(true);
+
+  for (int i = 0; i < NumHandlers(); ++i)
+    delete  &NthHandler(i);
+  _handlers.SetSize(0);
+
+  ClearCache();
+
+  if (rootLevel) {
+    delete _field;
+
+    d4_assert(pers != 0);
+    delete pers;
+  }
+}
+
+c4_Persist *c4_HandlerSeq::Persist()const {
+  return _persist;
+}
+
+void c4_HandlerSeq::DefineRoot() {
+  d4_assert(_field == 0);
+  d4_assert(_parent == 0);
+
+  SetNumRows(1);
+
+  const char *desc = "[]";
+  _field = d4_new c4_Field(desc);
+  d4_assert(! *desc);
+
+  _parent = this;
+}
+
+c4_Handler *c4_HandlerSeq::CreateHandler(const c4_Property &prop_) {
+  return f4_CreateFormat(prop_,  *this);
+}
+
+c4_Field &c4_HandlerSeq::Definition()const {
+  d4_assert(_field != 0);
+
+  return  *_field;
+}
+
+void c4_HandlerSeq::DetachFromParent() {
+  if (_field != 0) {
+    const char *desc = "[]";
+    c4_Field f(desc);
+    d4_assert(! *desc);
+    Restructure(f, false);
+    _field = 0;
+  }
+
+  _parent = 0;
+}
+
+void c4_HandlerSeq::DetachFromStorage(bool full_) {
+  if (_persist != 0) {
+    int limit = full_ ? 0 : NumFields();
+
+    // get rid of all handlers which might do I/O
+    for (int c = NumHandlers(); --c >= 0;) {
+      c4_Handler &h = NthHandler(c);
+
+      // all nested fields are detached recursively
+      if (IsNested(c))
+        for (int r = 0; r < NumRows(); ++r)
+          if (h.HasSubview(r))
+            SubEntry(c, r).DetachFromStorage(full_);
+
+      if (c >= limit) {
+        if (h.IsPersistent()) {
+          delete  &h;
+          _handlers.RemoveAt(c);
+          ClearCache();
+        }
+      }
+    }
+
+    if (full_) {
+      //UnmappedAll();
+      _persist = 0;
+    }
+  }
+}
+
+void c4_HandlerSeq::DetermineSpaceUsage() {
+  for (int c = 0; c < NumFields(); ++c)
+  if (IsNested(c)) {
+    c4_Handler &h = NthHandler(c);
+    for (int r = 0; r < NumRows(); ++r)
+      if (h.HasSubview(r))
+        SubEntry(c, r).DetermineSpaceUsage();
+  }
+}
+
+void c4_HandlerSeq::SetNumRows(int numRows_) {
+  d4_assert(_numRows >= 0);
+
+  _numRows = numRows_;
+}
+
+int c4_HandlerSeq::AddHandler(c4_Handler *handler_) {
+  d4_assert(handler_ != 0);
+
+  return _handlers.Add(handler_);
+}
+
+const char *c4_HandlerSeq::Description() {
+  // 19-01-2003: avoid too dense code, since Sun CC seems to choke on it
+  //return _field != 0 ? UseTempBuffer(Definition().DescribeSubFields()) : 0;
+  if (_field == 0)
+    return 0;
+  c4_String s = _field->DescribeSubFields();
+  return UseTempBuffer(s);
+}
+
+void c4_HandlerSeq::Restructure(c4_Field &field_, bool remove_) {
+  //d4_assert(_field != 0);
+
+  // all nested fields must be set up, before we shuffle them around
+  for (int k = 0; k < NumHandlers(); ++k)
+  if (IsNested(k)) {
+    c4_Handler &h = NthHandler(k);
+    for (int n = 0; n < NumRows(); ++n)
+      if (h.HasSubview(n))
+        SubEntry(k, n);
+  }
+
+  for (int i = 0; i < field_.NumSubFields(); ++i) {
+    c4_Field &nf = field_.SubField(i);
+    c4_Property prop(nf.Type(), nf.Name());
+
+    int n = PropIndex(prop.GetId());
+    if (n == i)
+      continue;
+
+    if (n < 0) {
+      _handlers.InsertAt(i, f4_CreateFormat(prop,  *this));
+      NthHandler(i).Define(NumRows(), 0);
+    } else {
+      // move the handler to the front
+      d4_assert(n > i);
+      _handlers.InsertAt(i, _handlers.GetAt(n));
+      _handlers.RemoveAt(++n);
+    }
+
+    ClearCache(); // we mess with the order of handler, keep clearing it
+
+    d4_assert(PropIndex(prop.GetId()) == i);
+  }
+
+  c4_Field *ofld = _field;
+  // special case if we're "restructuring a view out of persistence", see below
+
+  _field = remove_ ? 0 : &field_;
+
+  // let handler do additional init once all have been prepared
+  //for (int n = 0; n < NumHandlers(); ++n)
+  //    NthHandler(n).Define(NumRows(), 0);
+
+  const char *desc = "[]";
+  c4_Field temp(desc);
+
+  // all nested fields are restructured recursively
+  for (int j = 0; j < NumHandlers(); ++j)
+  if (IsNested(j)) {
+    c4_Handler &h = NthHandler(j);
+    for (int n = 0; n < NumRows(); ++n)
+    if (h.HasSubview(n)) {
+      c4_HandlerSeq &seq = SubEntry(j, n);
+      if (j < NumFields())
+        seq.Restructure(field_.SubField(j), false);
+      else if (seq._field != 0)
+        seq.Restructure(temp, true);
+    }
+  }
+
+  if (_parent == this)
+    delete ofld;
+  // the root table owns its field structure tree
+}
+
+int c4_HandlerSeq::NumFields()const {
+  return _field != 0 ? _field->NumSubFields(): 0;
+}
+
+char c4_HandlerSeq::ColumnType(int index_)const {
+  return NthHandler(index_).Property().Type();
+}
+
+bool c4_HandlerSeq::IsNested(int index_)const {
+  return ColumnType(index_) == 'V';
+}
+
+c4_Field &c4_HandlerSeq::Field(int index_)const {
+  d4_assert(_field != 0);
+
+  return _field->SubField(index_);
+}
+
+void c4_HandlerSeq::Prepare(const t4_byte **ptr_, bool selfDesc_) {
+  if (ptr_ != 0) {
+    d4_dbgdef(t4_i32 sias = )c4_Column::PullValue(*ptr_);
+    d4_assert(sias == 0); // not yet
+
+    if (selfDesc_) {
+      t4_i32 n = c4_Column::PullValue(*ptr_);
+      if (n > 0) {
+        c4_String s = "[" + c4_String((const char*) * ptr_, n) + "]";
+        const char *desc = s;
+
+        c4_Field *f = d4_new c4_Field(desc);
+        d4_assert(! *desc);
+
+        Restructure(*f, false);
+        *ptr_ += n;
+      }
+    }
+
+    int rows = (int)c4_Column::PullValue(*ptr_);
+    if (rows > 0) {
+      SetNumRows(rows);
+
+      for (int i = 0; i < NumFields(); ++i)
+        NthHandler(i).Define(rows, ptr_);
+    }
+  }
+}
+
+void c4_HandlerSeq::OldPrepare() {
+  d4_assert(_persist != 0);
+
+  for (int i = 0; i < NumFields(); ++i) {
+    char origType = _field->SubField(i).OrigType();
+    NthHandler(i).OldDefine(origType,  *_persist);
+  }
+}
+
+void c4_HandlerSeq::FlipAllBytes() {
+  for (int i = 0; i < NumHandlers(); ++i) {
+    c4_Handler &h = NthHandler(i);
+    h.FlipBytes();
+  }
+}
+
+// New 19990903: swap rows in tables without touching the memo fields 
+// or subviews on disk.  This is used by the new c4_View::RelocateRows.
+
+void c4_HandlerSeq::ExchangeEntries(int srcPos_, c4_HandlerSeq &dst_, int
+  dstPos_) {
+  d4_assert(NumHandlers() == dst_.NumHandlers());
+
+  c4_Bytes t1, t2;
+
+  for (int col = 0; col < NumHandlers(); ++col) {
+    if (IsNested(col)) {
+      d4_assert(dst_.IsNested(col));
+
+      int n;
+      c4_HandlerSeq **e1 = (c4_HandlerSeq **)NthHandler(col).Get(srcPos_, n);
+      c4_HandlerSeq **e2 = (c4_HandlerSeq **)dst_.NthHandler(col).Get(dstPos_,
+        n);
+      d4_assert(*e1 != 0 &&  *e2 != 0);
+
+      // swap the two entries
+      c4_HandlerSeq *e =  *e1;
+      *e1 =  *e2;
+      *e2 = e;
+
+      // shorthand, *after* the swap
+      c4_HandlerSeq &t1 = SubEntry(col, srcPos_);
+      c4_HandlerSeq &t2 = dst_.SubEntry(col, dstPos_);
+
+      // adjust the parents
+      t1._parent = this;
+      t2._parent = &dst_;
+
+      // reattach the proper field structures
+      t1.Restructure(Field(col), false);
+      t2.Restructure(dst_.Field(col), false);
+    } else {
+      d4_assert(ColumnType(col) == dst_.ColumnType(col));
+
+      c4_Handler &h1 = NthHandler(col);
+      c4_Handler &h2 = dst_.NthHandler(col);
+
+#if 0 // memo's are 'B' now, but tricky to deal with, so copy them for now
+      if (ColumnType(col) == 'M') {
+        c4_Column *c1 = h1.GetNthMemoCol(srcPos_, true);
+        c4_Column *c2 = h2.GetNthMemoCol(dstPos_, true);
+
+        t4_i32 p1 = c1 ? c1->Position(): 0;
+        t4_i32 p2 = c2 ? c2->Position(): 0;
+
+        t4_i32 s1 = c1 ? c1->ColSize(): 0;
+        t4_i32 s2 = c2 ? c2->ColSize(): 0;
+
+        d4_assert(false); // broken
+        //!h1.SetNthMemoPos(srcPos_, p2, s2, c2);
+        //!h2.SetNthMemoPos(dstPos_, p1, s1, c1);
+      }
+#endif 
+      // 10-4-2002: Need to use copies in case either item points into
+      // memory that could move, or if access re-uses a shared buffer.
+      // The special cases are sufficiently tricky that it's NOT being
+      // optimized for now (temp bufs, mmap ptrs, c4_Bytes buffering).
+
+      int n1, n2;
+      const void *p1 = h1.Get(srcPos_, n1);
+      const void *p2 = h2.Get(dstPos_, n2);
+
+      c4_Bytes t1(p1, n1, true);
+      c4_Bytes t2(p2, n2, true);
+
+      h1.Set(srcPos_, t2);
+      h2.Set(dstPos_, t1);
+    }
+  }
+}
+
+c4_HandlerSeq &c4_HandlerSeq::SubEntry(int col_, int row_)const {
+  d4_assert(IsNested(col_));
+
+  c4_Bytes temp;
+  NthHandler(col_).GetBytes(row_, temp);
+
+  d4_assert(temp.Size() == sizeof(c4_HandlerSeq **));
+  c4_HandlerSeq **p = (c4_HandlerSeq **)temp.Contents(); // loses const
+
+  d4_assert(p != 0 &&  *p != 0);
+
+  return  **p;
+}
+
+c4_Field *c4_HandlerSeq::FindField(const c4_Handler *handler_) {
+  for (int i = 0; i < NumFields(); ++i)
+    if (handler_ ==  &NthHandler(i))
+      return  &Field(i);
+  return 0;
+}
+
+void c4_HandlerSeq::UnmappedAll() {
+  for (int i = 0; i < NumFields(); ++i)
+    NthHandler(i).Unmapped();
+}
+
+// construct meta view from a pre-parsed field tree structure
+// this will one day be converted to directly parse the description string
+void c4_HandlerSeq::BuildMeta(int parent_, int colnum_, c4_View &meta_, const
+  c4_Field &field_) {
+  c4_IntProp pP("P"), pC("C");
+  c4_ViewProp pF("F");
+  c4_StringProp pN("N"), pT("T");
+
+  int n = meta_.Add(pP[parent_] + pC[colnum_]);
+  c4_View fields = pF(meta_[n]);
+
+  for (int i = 0; i < field_.NumSubFields(); ++i) {
+    const c4_Field &f = field_.SubField(i);
+    char type = f.Type();
+    fields.Add(pN[f.Name()] + pT[c4_String(&type, 1)]);
+    if (type == 'V')
+      BuildMeta(n, i, meta_, f);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/handler.h b/8.x/mk/src/handler.h
new file mode 100755 (executable)
index 0000000..5b0cf61
--- /dev/null
@@ -0,0 +1,148 @@
+// handler.h --
+// $Id: handler.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Definition of the main handler classes
+ */
+
+#ifndef __HANDLER_H__
+#define __HANDLER_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+class c4_Handler; // data representation handler
+
+//  class c4_Sequence;
+class c4_HandlerSeq; // a sequence built from handlers
+
+class c4_Column; // not defined here
+class c4_Field; // not defined here
+class c4_Persist; // not defined here
+class c4_SaveContext; // not defined here
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Handler {
+    c4_Property _property;
+
+  public:
+    c4_Handler(const c4_Property &_prop);
+    //: Constructor (this is an abstract base class).
+    virtual ~c4_Handler();
+
+    virtual void Define(int, const t4_byte **);
+    //: Called when the corresponding table has been fully defined.
+    virtual void FlipBytes();
+    //: Called to reverse the internal byte order of foreign data.
+    virtual void Commit(c4_SaveContext &ar_);
+    //: Commit the associated column(s) to file.
+    virtual void OldDefine(char, c4_Persist &);
+
+    const c4_Property &Property()const;
+    //: Returns the property associated with this handler.
+    int PropId()const;
+    //: Returns the id of the property associated with this handler.
+
+    void ClearBytes(c4_Bytes &buf_)const;
+    //: Returns the default value for items of this type.
+
+    virtual int ItemSize(int index_) = 0;
+    //: Return width of specified data item.
+    void GetBytes(int index_, c4_Bytes &buf_, bool copySmall_ = false);
+    //: Used for backward compatibility, should probably be replaced.
+    virtual const void *Get(int index_, int &length_) = 0;
+    //: Retrieves the data item at the specified index.
+    virtual void Set(int index_, const c4_Bytes &buf_) = 0;
+    //: Stores a new data item at the specified index.
+
+    int Compare(int index_, const c4_Bytes &buf_);
+    //: Compares an entry with a specified data item.
+
+    virtual void Insert(int index_, const c4_Bytes &buf_, int count_) = 0;
+    //: Inserts 1 or more data items at the specified index.
+    virtual void Remove(int index_, int count_) = 0;
+    //: Removes 1 or more data items at the specified index.
+    void Move(int from_, int to_);
+    //: Move a data item to another position.
+
+    virtual c4_Column *GetNthMemoCol(int index_, bool alloc_ = false);
+    //: Special access to underlying data of memo entries
+
+    virtual bool IsPersistent()const;
+    //: True if this handler might do I/O to satisfy fetches
+
+    virtual void Unmapped();
+    //: Make sure this handler stops using file mappings
+
+    virtual bool HasSubview(int index_);
+    //: True if this subview has materialized into an object
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_HandlerSeq: public c4_Sequence {
+    c4_PtrArray _handlers;
+    c4_Persist *_persist;
+    c4_Field *_field;
+    c4_HandlerSeq *_parent;
+    int _numRows;
+
+  public:
+    c4_HandlerSeq(c4_Persist*);
+    c4_HandlerSeq(c4_HandlerSeq &owner_, c4_Handler *handler_);
+
+    virtual int NumRows()const;
+    virtual void SetNumRows(int);
+
+    virtual int NumHandlers()const;
+    virtual c4_Handler &NthHandler(int)const;
+    virtual const c4_Sequence *HandlerContext(int)const;
+    virtual int AddHandler(c4_Handler*);
+
+    void DefineRoot();
+    void Restructure(c4_Field &, bool remove_);
+    void DetachFromParent();
+    void DetachFromStorage(bool full_);
+    void DetermineSpaceUsage();
+
+    c4_Field &Definition()const;
+    const char *Description();
+    c4_HandlerSeq &Parent()const;
+    virtual c4_Persist *Persist()const;
+
+    c4_Field &Field(int)const;
+    int NumFields()const;
+    char ColumnType(int index_)const;
+    bool IsNested(int)const;
+
+    void Prepare(const t4_byte **ptr_, bool selfDesc_);
+    void OldPrepare();
+
+    void FlipAllBytes();
+    void ExchangeEntries(int srcPos_, c4_HandlerSeq &dst_, int dstPos_);
+
+    c4_HandlerSeq &SubEntry(int, int)const;
+
+    c4_Field *FindField(const c4_Handler *handler_);
+
+    void UnmappedAll();
+
+    static void BuildMeta(int, int, c4_View &, const c4_Field &);
+
+  protected:
+    virtual c4_Handler *CreateHandler(const c4_Property &);
+
+    virtual ~c4_HandlerSeq();
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "handler.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/handler.inl b/8.x/mk/src/handler.inl
new file mode 100755 (executable)
index 0000000..a15da45
--- /dev/null
@@ -0,0 +1,90 @@
+// handler.inl --
+// $Id: handler.inl 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Inlined members of the handler classes
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Handler
+
+d4_inline c4_Handler::c4_Handler (const c4_Property& prop_)
+  : _property (prop_)
+{
+}
+
+d4_inline c4_Handler::~c4_Handler ()
+{
+}
+
+d4_inline void c4_Handler::Define(int, const t4_byte**)
+{
+}
+
+d4_inline void c4_Handler::FlipBytes()
+{
+}
+
+d4_inline const c4_Property& c4_Handler::Property() const
+{
+  return _property;
+}
+
+d4_inline int c4_Handler::PropId() const
+{
+  return _property.GetId();
+}
+
+d4_inline c4_Column* c4_Handler::GetNthMemoCol(int, bool alloc_)
+{
+  return 0;
+}
+
+d4_inline bool c4_Handler::IsPersistent() const
+{
+  return false;
+}
+
+d4_inline void c4_Handler::Unmapped()
+{
+}
+
+d4_inline bool c4_Handler::HasSubview(int)
+{
+  return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_HandlerSeq
+
+d4_inline int c4_HandlerSeq::NumRows() const
+{
+  d4_assert(_numRows >= 0);
+
+  return _numRows;
+}
+  
+d4_inline int c4_HandlerSeq::NumHandlers() const
+{
+  return _handlers.GetSize();
+}
+
+d4_inline c4_Handler& c4_HandlerSeq::NthHandler(int index_) const
+{
+  d4_assert(_handlers.GetAt(index_) != 0);
+  
+  return *(c4_Handler*) _handlers.GetAt(index_);
+}
+
+d4_inline const c4_Sequence* c4_HandlerSeq::HandlerContext(int) const
+{
+  return this;
+}
+
+d4_inline c4_HandlerSeq& c4_HandlerSeq::Parent() const
+{
+  return *_parent;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/header.h b/8.x/mk/src/header.h
new file mode 100755 (executable)
index 0000000..7d06d5a
--- /dev/null
@@ -0,0 +1,221 @@
+// header.h --
+// $Id: header.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * The internal header included in all source files
+ */
+
+#ifndef __HEADER_H__
+#define __HEADER_H__
+
+/////////////////////////////////////////////////////////////////////////////
+
+#include "config.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// A number of preprocessor options are used in the source code
+//
+//  q4_DOS      MS-DOS real-mode OS
+//  q4_MAC      Apple Macintosh OS
+//  q4_UNIX     Unix, any flavor
+//  q4_VMS      DEC OpenVMS OS
+//  q4_WIN      Microsoft Windows OS, any flavor
+//  q4_WIN32    Microsoft Windows OS, 32-bit
+//  q4_WINCE    Microsoft Windows OS, embedded
+//
+//  q4_MFC      Microsoft MFC framework
+//  q4_STD      Standard STL version
+//  q4_UNIV     Universal version
+//
+//  q4_BOOL     compiler supports bool datatype
+//  q4_CHECK    enable assertion checks
+//  q4_FIX      manual header fix (see above)
+//  q4_INLINE   enable inline expansion
+//  q4_KITDLL   compile as DLL (shared library)
+//  q4_MULTI    compile for multi-threading
+//  q4_NOLIB    do not add automatic lib linkage (MSVC5)
+//  q4_NO_NS    don't use namespaces for STL
+//  q4_OK       assume all software is perfect
+//  q4_STRICT   do not disable any compiler warnings
+//  q4_TINY     small version, no floating point
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#define __K4CONF_H__    // skip section in "mk4.h", since we use "header.h"
+
+// if neither MFC nor STD are specified, default to Universal version
+#if !q4_MFC && !q4_STD && !defined (q4_UNIV)
+#define q4_UNIV 1
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// You can either use '#define q4_xxx 1' to flag the choice of an OS, or
+// use a '#define d4_OS_H "file.h"' to force inclusion of a header later.
+
+#if defined (__MINGW32__)
+#define d4_OS_H "win.h"
+#elif defined (MSDOS) && defined (__GNUC__)
+#define q4_DOS 1
+#elif defined(unix) || defined(__unix__) || defined(__GNUC__) || \
+defined(_AIX) || defined(__hpux)
+#define q4_UNIX 1
+#elif defined (__VMS)
+#define q4_VMS 1
+#elif defined (macintosh)
+#define q4_MAC 1
+#elif !defined (d4_OS_H)
+#define d4_OS_H "win.h"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Use '#define q4_xxx 1' to flag the choice of a CPU.
+
+#if defined (_M_I86) || defined (_M_IX86) || defined (i386)
+#define q4_I86 1
+#if defined (_M_I86SM)
+#define q4_TINY 1
+#endif 
+#elif defined (__powerc)
+#define q4_PPC 1
+#elif defined (__alpha)
+#define q4_AXP 1
+#define q4_LONG64 1
+#elif defined (__VMS)
+#define q4_VAX 1
+#else 
+#define q4_M68K 1
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Use '#define q4_xxx 1' to flag the choice of an IDE, and optionally also
+// add '#include "file.h"' to force inclusion of a header file right here.
+
+#if defined (__BORLANDC__)                  // Borland C++
+#include "borc.h"
+#elif defined (__DECCXX)                    // DEC C++
+#define q4_DECC 1
+#elif defined (__GNUC__)                    // GNU C++
+#include "gnuc.h"
+#elif defined (__MWERKS__)                  // Metrowerks CodeWarrior C++
+#include "mwcw.h"
+#elif defined (_MSC_VER)                    // Microsoft Visual C++
+#include "msvc.h"
+#elif defined (__SC__)                      // Symantec C++
+#define q4_SYMC 1
+#elif defined (__WATCOMC__)                 // Watcom C++
+#define q4_WATC 1
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Some of the options take precedence over others
+
+#if !q4_BOOL && !q4_STD         // define a bool datatype
+#define false 0
+#define true 1
+#define bool int
+#endif 
+
+#if !q4_CHECK                   // disable assertions
+#undef d4_assert
+#define d4_dbgdef(x)
+#define d4_assert(x)
+#endif 
+
+#if q4_NO_NS                    // don't use namespaces
+#define d4_std
+#else 
+#define d4_std std
+#endif 
+
+#if HAVE_MEMMOVE
+#define d4_memmove(d,s,n)   memmove(d,s,n)
+#elif HAVE_BCOPY
+#define d4_memmove(d,s,n)   bcopy(s,d,n)
+#else 
+#define d4_memmove f4_memmove
+extern void f4_memmove(void *d, const void *s, int n);
+#endif 
+
+typedef unsigned char t4_byte; // create typedefs for t4_byte, etc.
+
+#if SIZEOF_LONG == 8
+typedef int t4_i32; // longs are 64b, so int must be 32b
+#else 
+typedef long t4_i32; // longs aren't 64b, so they are 32b
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Include header files which contain additional os/cpu/ide/fw specifics
+
+#ifdef d4_OS_H                  // operating system dependencies
+#include d4_OS_H
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Several defines should always be set
+
+#ifndef d4_assert               // assertion macro
+#include <assert.h>
+#define d4_assert assert
+#endif 
+
+#ifndef d4_dbgdef               // conditionally compiled
+#ifdef NDEBUG
+#define d4_dbgdef(x)
+#else 
+#define d4_dbgdef(x) x
+#endif 
+#endif 
+
+#ifndef d4_new                  // heap allocator
+#define d4_new new
+#endif 
+
+#ifndef d4_reentrant            // thread-local storage
+#define d4_reentrant
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Debug logging option, called internally where properties are modified
+
+#if q4_LOGPROPMODS
+void f4_DoLogProp(const c4_Handler *, int, const char *, int);
+#else 
+#define f4_LogPropMods(a,b) 0
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Public definitions, plus a few more framework-specific ones
+
+#include "mk4.h"
+
+#if q4_MFC
+#include "mfc.h"
+#elif q4_STD
+#include "std.h"
+#elif q4_UNIV
+#include "univ.h"
+#endif 
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4100 4127 4135 4244 4511 4512 4514)
+#endif 
+
+#include <string.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// Report unexpected combinations of settings
+
+#if !q4_FIX
+#if (q4_DOS+q4_MAC+q4_UNIX+q4_VMS+q4_WIN) != 1
+#error Exactly one operating system should have been defined
+#endif 
+#if (q4_MFC+q4_STD+q4_UNIV) != 1
+#error Exactly one container library should have been defined
+#endif 
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/mfc.h b/8.x/mk/src/mfc.h
new file mode 100755 (executable)
index 0000000..47e9324
--- /dev/null
@@ -0,0 +1,34 @@
+// mfc.h --
+// $Id: mfc.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Configuration header for MFC-based builds
+ */
+
+#define q4_MFC 1
+
+#if q4_WIN && !q4_WIN32
+#include <afxwin.h>
+#else 
+#include <afxcoll.h>
+#endif 
+
+#undef d4_assert
+#define d4_assert ASSERT
+
+#undef d4_assertThis
+#define d4_assertThis d4_assert(AfxIsValidAddress(this, sizeof *this, FALSE))
+
+#undef d4_new
+#define d4_new DEBUG_NEW
+
+typedef class CString c4_String;
+typedef class CPtrArray c4_PtrArray;
+typedef class CDWordArray c4_DWordArray;
+typedef class CStringArray c4_StringArray;
+
+// MSVC 1.52 thinks a typedef has no constructor, so use a define instead
+#if !q4_OK && q4_MSVC && _MSC_VER == 800
+#define c4_String CString
+#endif
diff --git a/8.x/mk/src/msvc.h b/8.x/mk/src/msvc.h
new file mode 100755 (executable)
index 0000000..2b340da
--- /dev/null
@@ -0,0 +1,39 @@
+// msvc.h --
+// $Id: msvc.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Configuration header for Microsoft Visual C++
+ */
+
+#define q4_MSVC 1
+
+// get rid of several common warning messages
+#if !q4_STRICT
+//#pragma warning(disable: 4244) // conversion ..., possible loss of data
+//#pragma warning(disable: 4135) // conversion between diff. integral types
+//#pragma warning(disable: 4511) // copy constructor could not be generated
+//#pragma warning(disable: 4512) // assignment op could not be generated
+//#pragma warning(disable: 4514) // unreferenced inline removed
+#pragma warning(disable: 4710) // function ... not inlined
+#pragma warning(disable: 4711) // ... selected for automatic inline expansion
+#pragma warning(disable: 4100) // unreferenced formal parameter
+#endif 
+
+#if _MSC_VER >= 1100
+#define q4_BOOL 1     // 5.0 supports the bool datatype
+#else 
+#define q4_NO_NS 1      // 4.x doesn't use namespaces for STL
+#endif 
+
+#if defined (_MT)
+#define q4_MULTI 1      // uses multi-threading
+#endif 
+
+#if defined (_DEBUG) && !defined (q4_CHECK) // use assertions in debug build
+#define q4_CHECK 1
+#endif 
+
+#if !q4_STD && !q4_UNIV && !defined (q4_MFC)
+#define d4_FW_H "mfc.h"   // default for MSVC is to use MFC
+#endif
diff --git a/8.x/mk/src/mwcw.h b/8.x/mk/src/mwcw.h
new file mode 100755 (executable)
index 0000000..87cbc05
--- /dev/null
@@ -0,0 +1,31 @@
+// mwcw.h --
+// $Id: mwcw.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Configuration header for Metrowerks CodeWarrior
+ */
+
+#define q4_MWCW 1
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_68K
+#if !__option(IEEEdoubles)
+#error Cannot build Metakit with 10-byte doubles
+#endif 
+#endif 
+
+#if __option(bool)
+#define q4_BOOL 1
+// undo previous defaults, because q4_BOOL is not set early enough
+#undef false
+#undef true
+#undef bool
+#endif 
+
+#undef _MSC_VER
+
+#pragma export on
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/persist.cpp b/8.x/mk/src/persist.cpp
new file mode 100755 (executable)
index 0000000..4df6418
--- /dev/null
@@ -0,0 +1,1165 @@
+// persist.cpp --
+// $Id: persist.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Implementation of the main file management classes
+ */
+
+#include "header.h"
+#include "column.h"
+#include "persist.h"
+#include "handler.h"
+#include "store.h"
+#include "field.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_FileMark {
+    enum {
+        kStorageFormat = 0x4C4A,  // b0 = 'J', b1 = <4C> (on Intel)
+        kReverseFormat = 0x4A4C  // b0 = <4C>, b1 = 'J'
+    };
+
+    t4_byte _data[8];
+
+  public:
+    c4_FileMark();
+    c4_FileMark(t4_i32 pos_, bool flipped_, bool extend_);
+    c4_FileMark(t4_i32 pos_, int len_);
+
+    t4_i32 Offset()const;
+    t4_i32 OldOffset()const;
+
+    bool IsHeader()const;
+    bool IsOldHeader()const;
+    bool IsFlipped()const;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FileMark::c4_FileMark() {
+  d4_assert(sizeof *this == 8);
+}
+
+c4_FileMark::c4_FileMark(t4_i32 pos_, bool flipped_, bool extend_) {
+  d4_assert(sizeof *this == 8);
+  *(short*)_data = flipped_ ? kReverseFormat : kStorageFormat;
+  _data[2] = extend_ ? 0x0A : 0x1A;
+  _data[3] = 0;
+  t4_byte *p = _data + 4;
+  for (int i = 24; i >= 0; i -= 8)
+    *p++ = (t4_byte)(pos_ >> i);
+  d4_assert(p == _data + sizeof _data);
+}
+
+c4_FileMark::c4_FileMark(t4_i32 pos_, int len_) {
+  d4_assert(sizeof *this == 8);
+  t4_byte *p = _data;
+  *p++ = 0x80;
+  for (int j = 16; j >= 0; j -= 8)
+    *p++ = (t4_byte)(len_ >> j);
+  for (int i = 24; i >= 0; i -= 8)
+    *p++ = (t4_byte)(pos_ >> i);
+  d4_assert(p == _data + sizeof _data);
+}
+
+t4_i32 c4_FileMark::Offset()const {
+  t4_i32 v = 0;
+  for (int i = 4; i < 8; ++i)
+    v = (v << 8) + _data[i];
+  return v;
+}
+
+t4_i32 c4_FileMark::OldOffset()const {
+  t4_i32 v = 0;
+  for (int i = 8; --i >= 4;)
+    v = (v << 8) + _data[i];
+  return v;
+}
+
+bool c4_FileMark::IsHeader()const {
+  return (_data[0] == 'J' || _data[0] == 'L') && (_data[0] ^ _data[1]) == ('J'
+    ^ 'L') && _data[2] == 0x1A;
+}
+
+bool c4_FileMark::IsOldHeader()const {
+  return IsHeader() && _data[3] == 0x80;
+}
+
+bool c4_FileMark::IsFlipped()const {
+  return *(short*)_data == kReverseFormat;
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Allocator: public c4_DWordArray {
+  public:
+    c4_Allocator();
+
+    void Initialize(t4_i32 first_ = 1);
+
+    t4_i32 AllocationLimit()const;
+
+    t4_i32 Allocate(t4_i32 len_);
+    void Occupy(t4_i32 pos_, t4_i32 len_);
+    void Release(t4_i32 pos_, t4_i32 len_);
+    void Dump(const char *str_);
+    t4_i32 FreeCounts(t4_i32 *bytes_ = 0);
+
+  private:
+    int Locate(t4_i32 pos_)const;
+    void InsertPair(int i_, t4_i32 from_, t4_i32 to_);
+    t4_i32 ReduceFrags(int goal_, int sHi_, int sLo_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//  Allocation of blocks is maintained in a separate data structure.
+//  There is no allocation overhead in the allocation arena itself.
+//  
+//  A single vector of "walls" is maintained, sorted by position:
+//  
+//    * Each transition between free and allocated is a single entry.
+//      The number of entries is <num-free-ranges> + <num-used-ranges>.
+//    * By definition, free areas start at the positions indicated
+//      by the entries on even indices. Allocated ones use odd entries.
+//    * There is an extra <0,0> free slot at the very beginning. This
+//      simplifies boundary conditions at the start of the arena.
+//    * Position zero cannot be allocated, first slot starts at 1.
+//
+//  Properties of this approach:
+//
+//    * No allocation overhead for adjacent allocated areas. On the
+//      other hand, the allocator does not know the size of used slots.
+//    * Alternate function allows marking a specific range as occupied.
+//    * Allocator can be initialized as either all free or all in-use.
+//    * Allocation info contains only integers, it could be stored.
+//    * To extend allocated slots: "occupy" extra bytes at the end.
+//    * Generic: can be used for memory, disk files, and array entries.
+
+c4_Allocator::c4_Allocator() {
+  Initialize();
+}
+
+void c4_Allocator::Initialize(t4_i32 first_) {
+  SetSize(0, 1000); // empty, and growing in large chunks 
+  Add(0); // fake block at start
+  Add(0); // ... only used to avoid merging
+
+  // if occupied, add a tiny free slot at the end, else add entire range
+  const t4_i32 kMaxInt = 0x7fffffff;
+  if (first_ == 0)
+    first_ = kMaxInt;
+
+  Add(first_); // start at a nicely aligned position
+  Add(kMaxInt); // ... there is no limit on file size
+}
+
+t4_i32 c4_Allocator::Allocate(t4_i32 len_) {
+  // zero arg is ok, it simply returns first allocatable position   
+  for (int i = 2; i < GetSize(); i += 2)
+  if (GetAt(i + 1) >= GetAt(i) + len_) {
+    t4_i32 pos = GetAt(i);
+    if ((t4_i32)GetAt(i + 1) > pos + len_)
+      ElementAt(i) += len_;
+    else
+      RemoveAt(i, 2);
+    return pos;
+  }
+
+  d4_assert(0);
+  return 0; // not reached
+}
+
+void c4_Allocator::Occupy(t4_i32 pos_, t4_i32 len_) {
+  d4_assert(pos_ > 0);
+  // note that zero size simply checks if there is any space to extend
+
+  int i = Locate(pos_);
+  d4_assert(0 < i && i < GetSize());
+
+  if (i % 2) {
+    // allocation is not at start of free block
+    d4_assert((t4_i32)GetAt(i - 1) < pos_);
+
+    if ((t4_i32)GetAt(i) == pos_ + len_)
+    // allocate from end of free block
+      SetAt(i, pos_);
+    else
+    // split free block in two
+      InsertPair(i, pos_, pos_ + len_);
+  } else if ((t4_i32)GetAt(i) == pos_)
+  /*
+  This side of the if used to be unconditional, but that was
+  incorrect if ReduceFrags gets called (which only happens with
+  severely fragmented files) - there are cases when allocation
+  leads to an occupy request of which the free space list knows
+  nothing about because it dropped small segments.  The solution
+  is to silently "allow" such allocations - fixed 29-02-2000
+  Thanks to Andrew Kuchling for his help in chasing this bug.
+   */
+   {
+    // else extend tail of allocated area
+    if ((t4_i32)GetAt(i + 1) > pos_ + len_)
+      ElementAt(i) += len_;
+    // move start of next free up
+    else
+      RemoveAt(i, 2);
+    // remove this slot
+  }
+}
+
+void c4_Allocator::Release(t4_i32 pos, t4_i32 len) {
+  int i = Locate(pos + len);
+  d4_assert(0 < i && i < GetSize());
+  d4_assert(i % 2 == 0); // don't release inside a free block
+
+  if ((t4_i32)GetAt(i) == pos)
+  // move start of next free down 
+    ElementAt(i) -= len;
+  else if ((t4_i32)GetAt(i - 1) == pos)
+  // move end of previous free up
+    ElementAt(i - 1) += len;
+  else
+  // insert a new entry
+    InsertPair(i, pos, pos + len);
+
+  if (GetAt(i - 1) == GetAt(i))
+  // merge if adjacent free
+    RemoveAt(i - 1, 2);
+}
+
+t4_i32 c4_Allocator::AllocationLimit()const {
+  d4_assert(GetSize() >= 2);
+
+  return GetAt(GetSize() - 2);
+}
+
+int c4_Allocator::Locate(t4_i32 pos)const {
+  int lo = 0, hi = GetSize() - 1;
+
+  while (lo < hi) {
+    int i = (lo + hi) / 2;
+    if (pos < (t4_i32)GetAt(i))
+      hi = i - 1;
+    else if (pos > (t4_i32)GetAt(i))
+      lo = i + 1;
+    else
+      return i;
+  }
+
+  return lo < GetSize() && pos > (t4_i32)GetAt(lo) ? lo + 1: lo;
+}
+
+void c4_Allocator::InsertPair(int i_, t4_i32 from_, t4_i32 to_) {
+  d4_assert(0 < i_);
+  d4_assert(i_ < GetSize());
+
+  d4_assert(from_ < to_);
+  d4_assert((t4_i32)GetAt(i_ - 1) < from_);
+  //!d4_assert(to_ < GetAt(i_));
+
+  if (to_ >= (t4_i32)GetAt(i_))
+    return ;
+  // ignore 2nd allocation of used area
+
+  InsertAt(i_, from_, 2);
+  SetAt(i_ + 1, to_);
+
+  // it's ok to have arrays up to some 30000 bytes
+  if (GetSize() > 7500)
+    ReduceFrags(5000, 12, 6);
+}
+
+t4_i32 c4_Allocator::ReduceFrags(int goal_, int sHi_, int sLo_) {
+  // drastic fail-safe measure: remove small gaps if vec gets too long
+  // this will cause some lost free space but avoids array overflow
+  // the lost space will most probably be re-used after the next commit
+
+  int limit = GetSize() - 2;
+  t4_i32 loss = 0;
+
+  // go through all entries and remove gaps under the given threshold
+  for (int shift = sHi_; shift >= sLo_; --shift) {
+    // the threshold is a fraction of the current size of the arena
+    t4_i32 threshold = AllocationLimit() >> shift;
+    if (threshold == 0)
+      continue;
+
+    int n = 2;
+    for (int i = n; i < limit; i += 2)
+    if ((t4_i32)GetAt(i + 1) - (t4_i32)GetAt(i) > threshold) {
+      SetAt(n++, GetAt(i));
+      SetAt(n++, GetAt(i + 1));
+    } else
+      loss += GetAt(i + 1) - GetAt(i);
+
+    limit = n;
+
+    // if (GetSize() < goal_) - suboptimal, fixed 29-02-2000
+    if (limit < goal_)
+      break;
+    // got rid of enough entries, that's enough
+  }
+
+  int n = GetSize() - 2;
+  SetAt(limit++, GetAt(n++));
+  SetAt(limit++, GetAt(n));
+  SetSize(limit);
+
+  return loss;
+}
+
+#if q4_CHECK
+#include <stdio.h>
+
+void c4_Allocator::Dump(const char *str_) {
+  fprintf(stderr, "c4_Allocator::Dump, %d entries <%s>\n", GetSize(), str_);
+  for (int i = 2; i < GetSize(); i += 2)
+    fprintf(stderr, "  %10ld .. %ld\n", GetAt(i - 1), GetAt(i));
+  fprintf(stderr, "END\n");
+}
+
+#else 
+
+void c4_Allocator::Dump(const char *str_){}
+
+#endif 
+
+t4_i32 c4_Allocator::FreeCounts(t4_i32 *bytes_) {
+  if (bytes_ != 0) {
+    t4_i32 total = 0;
+    for (int i = 2; i < GetSize() - 2; i += 2)
+      total += GetAt(i + 1) - GetAt(i);
+    *bytes_ = total;
+  }
+  return GetSize() / 2-2;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Differ {
+  public:
+    c4_Differ(c4_Storage &storage_);
+    ~c4_Differ();
+
+    int NewDiffID();
+    void CreateDiff(int id_, c4_Column &col_);
+    t4_i32 BaseOfDiff(int id_);
+    void ApplyDiff(int id_, c4_Column &col_)const;
+
+    void GetRoot(c4_Bytes &buffer_);
+
+    c4_Storage _storage;
+    c4_View _diffs;
+    c4_View _temp;
+
+  private:
+    void AddEntry(t4_i32, t4_i32, const c4_Bytes &);
+
+    c4_ViewProp pCols; //  column info:
+    c4_IntProp pOrig; //    original position
+    c4_ViewProp pDiff; //    difference chunks:
+    c4_IntProp pKeep; //      offset
+    c4_IntProp pResize; //      length
+    c4_BytesProp pBytes; //      data
+};
+
+c4_Differ::c4_Differ(c4_Storage &storage_): _storage(storage_), pCols("_C"),
+  pOrig("_O"), pDiff("_D"), pKeep("_K"), pResize("_R"), pBytes("_B") {
+  // weird names, to avoid clashing with existing ones (capitalization!)
+  _diffs = _storage.GetAs("_C[_O:I,_D[_K:I,_R:I,_B:B]]");
+}
+
+c4_Differ::~c4_Differ() {
+  _diffs = c4_View();
+}
+
+void c4_Differ::AddEntry(t4_i32 off_, t4_i32 len_, const c4_Bytes &data_) {
+  int n = _temp.GetSize();
+  _temp.SetSize(n + 1);
+  c4_RowRef r = _temp[n];
+
+  pKeep(r) = (t4_i32)off_;
+  pResize(r) = (t4_i32)len_;
+  pBytes(r).SetData(data_);
+}
+
+int c4_Differ::NewDiffID() {
+  int n = _diffs.GetSize();
+  _diffs.SetSize(n + 1);
+  return n;
+}
+
+void c4_Differ::CreateDiff(int id_, c4_Column &col_) {
+  _temp.SetSize(0);
+#if 0
+  t4_i32 offset = 0;
+  t4_i32 savedOff = 0;
+  t4_i32 savedLen = 0;
+
+  c4_Strategy *strat = col_.Persist() != 0 ? &col_.Strategy(): 0;
+
+  c4_ColIter iter(col_, 0, col_.ColSize());
+  while (iter.Next()) {
+    const t4_byte *p = iter.BufLoad();
+    if (strat != 0 && strat->_mapStart != 0 && p >= strat->_mapStart && p -
+      strat->_mapStart < strat->_dataSize) {
+      t4_i32 nextOff = p - strat->_mapStart;
+      if (savedLen == 0)
+        savedOff = nextOff;
+      if (nextOff == savedOff + savedLen) {
+        savedLen += iter.BufLen();
+        continue;
+      }
+
+      if (savedLen > 0)
+        AddEntry(savedOff, savedLen, c4_Bytes());
+
+      savedOff = nextOff;
+      savedLen = iter.BufLen();
+    } else {
+      AddEntry(savedOff, savedLen, c4_Bytes(p, iter.BufLen()));
+      savedLen = 0;
+    }
+
+    offset += iter.BufLen();
+  }
+
+  c4_View diff = pDiff(_diffs[id_]);
+  if (_temp.GetSize() != diff.GetSize() || _temp != diff)
+#else 
+    c4_Bytes t1;
+  const t4_byte *p = col_.FetchBytes(0, col_.ColSize(), t1, false);
+  AddEntry(0, 0, c4_Bytes(p, col_.ColSize()));
+#endif 
+  pDiff(_diffs[id_]) = _temp;
+
+  pOrig(_diffs[id_]) = col_.Position();
+}
+
+t4_i32 c4_Differ::BaseOfDiff(int id_) {
+  d4_assert(0 <= id_ && id_ < _diffs.GetSize());
+
+  return pOrig(_diffs[id_]);
+}
+
+void c4_Differ::ApplyDiff(int id_, c4_Column &col_)const {
+  d4_assert(0 <= id_ && id_ < _diffs.GetSize());
+
+  c4_View diff = pDiff(_diffs[id_]);
+  t4_i32 offset = 0;
+
+  for (int n = 0; n < diff.GetSize(); ++n) {
+    c4_RowRef row(diff[n]);
+    offset += pKeep(row);
+
+    c4_Bytes data;
+    pBytes(row).GetData(data);
+
+    // the following code is a lot like c4_MemoRef::Modify
+    const t4_i32 change = pResize(row);
+    if (change < 0)
+      col_.Shrink(offset,  - change);
+    else if (change > 0)
+      col_.Grow(offset, change);
+
+    col_.StoreBytes(offset, data);
+    offset += data.Size();
+  }
+
+  if (offset > col_.ColSize())
+    col_.Shrink(offset, offset - col_.ColSize());
+}
+
+void c4_Differ::GetRoot(c4_Bytes &buffer_) {
+  int last = _diffs.GetSize() - 1;
+  if (last >= 0) {
+    c4_Bytes temp;
+    c4_View diff = pDiff(_diffs[last]);
+    if (diff.GetSize() > 0)
+      pBytes(diff[0]).GetData(buffer_);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_SaveContext::c4_SaveContext(c4_Strategy &strategy_, bool fullScan_, int
+  mode_, c4_Differ *differ_, c4_Allocator *space_): _strategy(strategy_), _walk
+  (0), _differ(differ_), _space(space_), _cleanup(0), _nextSpace(0), _preflight
+  (true), _fullScan(fullScan_), _mode(mode_), _nextPosIndex(0), _bufPtr(_buffer)
+  , _curr(_buffer), _limit(_buffer) {
+  if (_space == 0)
+    _space = _cleanup = d4_new c4_Allocator;
+
+  _nextSpace = _mode == 1 ? d4_new c4_Allocator: _space;
+}
+
+c4_SaveContext::~c4_SaveContext() {
+  delete _cleanup;
+  if (_nextSpace != _space)
+    delete _nextSpace;
+}
+
+bool c4_SaveContext::IsFlipped()const {
+  return _strategy._bytesFlipped;
+}
+
+bool c4_SaveContext::Serializing()const {
+  return _fullScan;
+}
+
+void c4_SaveContext::AllocDump(const char *str_, bool next_) {
+  c4_Allocator *ap = next_ ? _nextSpace : _space;
+  if (ap != 0)
+    ap->Dump(str_);
+}
+
+void c4_SaveContext::FlushBuffer() {
+  int n = _curr - _bufPtr;
+  if (_walk != 0 && n > 0) {
+    t4_i32 end = _walk->ColSize();
+    _walk->Grow(end, n);
+    _walk->StoreBytes(end, c4_Bytes(_bufPtr, n));
+  }
+
+  _curr = _bufPtr = _buffer;
+  _limit = _buffer + sizeof _buffer;
+}
+
+c4_Column *c4_SaveContext::SetWalkBuffer(c4_Column *col_) {
+  FlushBuffer();
+
+  c4_Column *prev = _walk;
+  _walk = col_;
+  return prev;
+}
+
+void c4_SaveContext::Write(const void *buf_, int len_) {
+  // use buffering if possible
+  if (_curr + len_ <= _limit) {
+    memcpy(_curr, buf_, len_);
+    _curr += len_;
+  } else {
+    FlushBuffer();
+    _bufPtr = (t4_byte*)buf_; // also loses const
+    _curr = _limit = _bufPtr + len_;
+    FlushBuffer();
+  }
+}
+
+void c4_SaveContext::StoreValue(t4_i32 v_) {
+  if (_walk == 0)
+    return ;
+
+  if (_curr + 10 >= _limit)
+    FlushBuffer();
+
+  d4_assert(_curr + 10 < _limit);
+  c4_Column::PushValue(_curr, v_);
+}
+
+void c4_SaveContext::SaveIt(c4_HandlerSeq &root_, c4_Allocator **spacePtr_,
+  c4_Bytes &rootWalk_) {
+  d4_assert(_space != 0);
+
+  const t4_i32 size = _strategy.FileSize();
+  if (_strategy._failure != 0)
+    return ;
+
+  const t4_i32 end = _fullScan ? 0 : size - _strategy._baseOffset;
+
+  if (_differ == 0) {
+    if (_mode != 1)
+      _space->Initialize();
+
+    // don't allocate anything inside the file in extend mode
+    if (_mode == 2 && end > 0) {
+      _space->Occupy(1, end - 1);
+      _nextSpace->Occupy(1, end - 1);
+    }
+
+    // the header is always reserved
+    _space->Occupy(1, 7);
+    _nextSpace->Occupy(1, 7);
+
+    if (end > 0) {
+      d4_assert(end >= 16);
+      _space->Occupy(end - 16, 16);
+      _nextSpace->Occupy(end - 16, 16);
+      _space->Occupy(end, 8);
+      _nextSpace->Occupy(end, 8);
+    }
+  }
+
+  //AllocDump("a1", false);
+  //AllocDump("a2", true);
+
+  // first pass allocates columns and constructs shallow walks
+  c4_Column walk(root_.Persist());
+  SetWalkBuffer(&walk);
+  CommitSequence(root_, true);
+  SetWalkBuffer(0);
+  CommitColumn(walk);
+
+  c4_Bytes tempWalk;
+  walk.FetchBytes(0, walk.ColSize(), tempWalk, true);
+
+  t4_i32 limit = _nextSpace->AllocationLimit();
+  d4_assert(limit >= 8 || _differ != 0);
+
+  if (limit < 0) {
+    // 2006-01-12 #2: catch file size exceeding 2 Gb
+    _strategy._failure =  - 1; // unusual non-zero value flags this case
+    return ;
+  }
+
+  bool changed = _fullScan || tempWalk != rootWalk_;
+
+  rootWalk_ = c4_Bytes(tempWalk.Contents(), tempWalk.Size(), true);
+
+  _preflight = false;
+
+  // special-case to avoid saving data if file is logically empty
+  // in that case, the data is 0x80 0x81 0x80 (plus the header)
+  if (!_fullScan && limit <= 11 && _differ == 0) {
+    _space->Initialize();
+    _nextSpace->Initialize();
+    changed = false;
+  }
+
+  if (!changed)
+    return ;
+
+  //AllocDump("b1", false);
+  //AllocDump("b2", true);
+
+  if (_differ != 0) {
+    int n = _differ->NewDiffID();
+    _differ->CreateDiff(n, walk);
+    return ;
+  }
+
+  d4_assert(_mode != 0 || _fullScan);
+
+  // this is the place where writing may start
+
+  // figure out where the new file ends and write a skip tail there
+  t4_i32 end0 = end;
+
+  // true if the file need not be extended due to internal free space
+  bool inPlace = end0 == limit - 8;
+  if (inPlace) {
+    d4_assert(!_fullScan);
+    _space->Release(end0, 8);
+    _nextSpace->Release(end0, 8);
+    end0 -= 16; // overwrite existing tail markers
+  } else {
+    /* 18-11-2005 write new end marker and flush it before *anything* else! */
+    if (!_fullScan && end0 < limit) {
+      c4_FileMark mark1(limit, 0);
+      _strategy.DataWrite(limit, &mark1, sizeof mark1);
+      _strategy.DataCommit(0);
+      if (_strategy._failure != 0)
+        return ;
+    }
+
+    c4_FileMark head(limit + 16-end, _strategy._bytesFlipped, end > 0);
+    _strategy.DataWrite(end, &head, sizeof head);
+
+    if (end0 < limit)
+      end0 = limit;
+    // create a gap
+  }
+
+  t4_i32 end1 = end0 + 8;
+  t4_i32 end2 = end1 + 8;
+
+  if (!_fullScan && !inPlace) {
+    c4_FileMark mark1(end0, 0);
+    _strategy.DataWrite(end0, &mark1, sizeof mark1);
+#if q4_WIN32
+    /* March 8, 2002
+     * On at least NT4 with NTFS, extending a file can cause it to be
+     * rounded up further than expected.  To prevent creating a bad
+     * file (since the file does then not end with a marker), the
+     * workaround it so simply accept the new end instead and rewrite.
+     * Note that between these two writes, the file is in a bad state.
+     */
+    t4_i32 realend = _strategy.FileSize() - _strategy._baseOffset;
+    if (realend > end1) {
+      end0 = limit = realend - 8;
+      end1 = realend;
+      end2 = realend + 8;
+      c4_FileMark mark1a(end0, 0);
+      _strategy.DataWrite(end0, &mark1a, sizeof mark1a);
+    }
+#endif 
+    d4_assert(_strategy.FileSize() == _strategy._baseOffset + end1);
+  }
+
+  _space->Occupy(end0, 16);
+  _nextSpace->Occupy(end0, 16);
+
+  // strategy.DataCommit(0); // may be needed, need more info on how FS's work
+  // but this would need more work, since we can't adjust file-mapping here
+
+  // second pass saves the columns and structure to disk
+  CommitSequence(root_, true); // writes changed columns
+  CommitColumn(walk);
+
+  //! d4_assert(_curr == 0);
+  d4_assert(_nextPosIndex == _newPositions.GetSize());
+
+  if (_fullScan) {
+    c4_FileMark mark1(limit, 0);
+    _strategy.DataWrite(_strategy.FileSize() - _strategy._baseOffset,  &mark1,
+      sizeof mark1);
+
+    c4_FileMark mark2(limit - walk.ColSize(), walk.ColSize());
+    _strategy.DataWrite(_strategy.FileSize() - _strategy._baseOffset,  &mark2,
+      sizeof mark2);
+
+    return ;
+  }
+
+  if (inPlace)
+    d4_assert(_strategy.FileSize() == _strategy._baseOffset + end2);
+  else {
+    // make sure the allocated size hasn't changed
+    d4_assert(_nextSpace->AllocationLimit() == limit + 16);
+    d4_assert(end0 >= limit);
+    d4_assert(_strategy.FileSize() - _strategy._baseOffset == end1);
+  }
+
+  if (walk.Position() == 0 || _strategy._failure != 0)
+    return ;
+
+  _strategy.DataCommit(0);
+
+  c4_FileMark mark2(walk.Position(), walk.ColSize());
+  _strategy.DataWrite(end1, &mark2, sizeof mark2);
+  d4_assert(_strategy.FileSize() - _strategy._baseOffset == end2);
+
+  // do not alter the file header in extend mode, unless it is new
+  if (!_fullScan && (_mode == 1 || end == 0)) {
+    _strategy.DataCommit(0);
+
+    c4_FileMark head(end2, _strategy._bytesFlipped, false);
+    d4_assert(head.IsHeader());
+    _strategy.DataWrite(0, &head, sizeof head);
+
+    // if the file became smaller, we could shrink it
+    if (limit + 16 < end0) {
+      /*
+      Not yet, this depends on the strategy class being able to truncate, but
+      there is no way to find out whether it does (the solution is to write tail
+      markers in such a way that the file won't grow unnecessarily if it doesn't).
+
+      The logic will probably be:
+
+       * write new skip + commit "tails" at limit (no visible effect on file)
+       * overwrite commit tail at end  with a skip to this new one (equivalent)
+       * replace header with one pointing to that internal new one (equivalent)
+       * flush (now the file is valid both truncated and not-yet-truncated
+
+      end = limit;
+       */
+    }
+  }
+
+  // if using memory mapped files, make sure the map is no longer in use
+  if (_strategy._mapStart != 0)
+    root_.UnmappedAll();
+
+  // commit and tell strategy object what the new file size is, this
+  // may be smaller now, if old data at the end is no longer referenced
+  _strategy.DataCommit(end2);
+
+  d4_assert(_strategy.FileSize() - _strategy._baseOffset == end2);
+
+  if (spacePtr_ != 0 && _space != _nextSpace) {
+    d4_assert(*spacePtr_ == _space);
+    delete  *spacePtr_;
+    *spacePtr_ = _nextSpace;
+    _nextSpace = 0;
+  }
+}
+
+bool c4_SaveContext::CommitColumn(c4_Column &col_) {
+  bool changed = col_.IsDirty() || _fullScan;
+
+  t4_i32 sz = col_.ColSize();
+  StoreValue(sz);
+  if (sz > 0) {
+    t4_i32 pos = col_.Position();
+
+    if (_differ) {
+      if (changed) {
+        int n = pos < 0 ? ~pos: _differ->NewDiffID();
+        _differ->CreateDiff(n, col_);
+
+        d4_assert(n >= 0);
+        pos = ~n;
+      }
+    } else if (_preflight) {
+      if (changed)
+        pos = _space->Allocate(sz);
+
+      _nextSpace->Occupy(pos, sz);
+      _newPositions.Add(pos);
+    } else {
+      pos = _newPositions.GetAt(_nextPosIndex++);
+
+      if (changed)
+        col_.SaveNow(_strategy, pos);
+
+      if (!_fullScan)
+        col_.SetLocation(pos, sz);
+    }
+
+    StoreValue(pos);
+  }
+
+  return changed;
+}
+
+void c4_SaveContext::CommitSequence(c4_HandlerSeq &seq_, bool selfDesc_) {
+  StoreValue(0); // sias prefix
+
+  if (selfDesc_) {
+    c4_String desc = seq_.Description();
+    int k = desc.GetLength();
+    StoreValue(k);
+    Write((const char*)desc, k);
+  }
+
+  StoreValue(seq_.NumRows());
+  if (seq_.NumRows() > 0)
+    for (int i = 0; i < seq_.NumFields(); ++i)
+      seq_.NthHandler(i).Commit(*this);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+// used for on-the-fly conversion of old-format datafiles
+t4_byte *_oldBuf;
+const t4_byte *_oldCurr;
+const t4_byte *_oldLimit;
+t4_i32 _oldSeek;
+
+
+c4_Persist::c4_Persist(c4_Strategy &strategy_, bool owned_, int mode_): _space
+  (0), _strategy(strategy_), _root(0), _differ(0), _fCommit(0), _mode(mode_),
+  _owned(owned_), _oldBuf(0), _oldCurr(0), _oldLimit(0), _oldSeek( - 1) {
+  if (_mode == 1)
+    _space = d4_new c4_Allocator;
+}
+
+c4_Persist::~c4_Persist() {
+  delete _differ;
+
+  if (_owned) {
+    if (_root != 0)
+      _root->UnmappedAll();
+    delete  &_strategy;
+  }
+
+  delete _space;
+
+  if (_oldBuf != 0)
+    delete [] _oldBuf;
+}
+
+c4_HandlerSeq &c4_Persist::Root()const {
+  d4_assert(_root != 0);
+  return  *_root;
+}
+
+void c4_Persist::SetRoot(c4_HandlerSeq *root_) {
+  d4_assert(_root == 0);
+  _root = root_;
+}
+
+c4_Strategy &c4_Persist::Strategy()const {
+  return _strategy;
+}
+
+bool c4_Persist::AutoCommit(bool flag_) {
+  bool prev = _fCommit != 0;
+  if (flag_)
+    _fCommit = &c4_Persist::Commit;
+  else
+    _fCommit = 0;
+  return prev;
+}
+
+void c4_Persist::DoAutoCommit() {
+  if (_fCommit != 0)
+    (this->*_fCommit)(false);
+}
+
+bool c4_Persist::SetAside(c4_Storage &aside_) {
+  delete _differ;
+  _differ = d4_new c4_Differ(aside_);
+  Rollback(false);
+  return true; //! true if the generation matches
+}
+
+c4_Storage *c4_Persist::GetAside()const {
+  return _differ != 0 ? &_differ->_storage: 0;
+}
+
+bool c4_Persist::Commit(bool full_) {
+  // 1-Mar-1999, new semantics! return success status of commits
+  _strategy._failure = 0;
+
+  if (!_strategy.IsValid())
+    return false;
+
+  if (_mode == 0 && (_differ == 0 || full_))
+  // can't commit to r/o file
+    return false;
+  // note that _strategy._failure is *zero* in this case
+
+  c4_SaveContext ar(_strategy, false, _mode, full_ ? 0 : _differ, _space);
+
+  // get rid of temp properties which still use the datafile
+  if (_mode == 1)
+    _root->DetachFromStorage(false);
+
+  // 30-3-2001: moved down, fixes "crash every 2nd call of mkdemo/dbg"
+  ar.SaveIt(*_root, &_space, _rootWalk);
+  return _strategy._failure == 0;
+}
+
+bool c4_Persist::Rollback(bool full_) {
+  _root->DetachFromParent();
+  _root->DetachFromStorage(true);
+  _root = 0;
+
+  if (_space != 0)
+    _space->Initialize();
+
+  c4_HandlerSeq *seq = d4_new c4_HandlerSeq(this);
+  seq->DefineRoot();
+  SetRoot(seq);
+
+  if (full_) {
+    delete _differ;
+    _differ = 0;
+  }
+
+  LoadAll();
+
+  return _strategy._failure == 0;
+}
+
+bool c4_Persist::LoadIt(c4_Column &walk_) {
+  t4_i32 limit = _strategy.FileSize();
+  if (_strategy._failure != 0)
+    return false;
+
+  if (_strategy.EndOfData(limit) < 0) {
+    _strategy.SetBase(limit);
+    d4_assert(_strategy._failure == 0); // file is ok, but empty
+    return false;
+  }
+
+  if (_strategy._rootLen > 0)
+    walk_.SetLocation(_strategy._rootPos, _strategy._rootLen);
+
+  // if the file size has increased, we must remap
+  if (_strategy._mapStart != 0 && _strategy.FileSize() > _strategy._baseOffset 
+    + _strategy._dataSize)
+    _strategy.ResetFileMapping();
+
+  return true;
+}
+
+void c4_Persist::LoadAll() {
+  c4_Column walk(this);
+  if (!LoadIt(walk))
+    return ;
+
+  if (_strategy._rootLen < 0) {
+    _oldSeek = _strategy._rootPos;
+    _oldBuf = d4_new t4_byte[512];
+    _oldCurr = _oldLimit = _oldBuf;
+
+    t4_i32 n = FetchOldValue();
+    d4_assert(n == 0);
+    n = FetchOldValue();
+    d4_assert(n > 0);
+
+    c4_Bytes temp;
+    t4_byte *buf = temp.SetBuffer(n);
+    d4_dbgdef(int n2 = )OldRead(buf, n);
+    d4_assert(n2 == n);
+
+    c4_String s = "[" + c4_String((const char*)buf, n) + "]";
+    const char *desc = s;
+
+    c4_Field *f = d4_new c4_Field(desc);
+    d4_assert(! *desc);
+
+    //?_root->DefineRoot();
+    _root->Restructure(*f, false);
+
+    _root->OldPrepare();
+
+    // don't touch data inside while converting the file
+    if (_strategy.FileSize() >= 0)
+      OccupySpace(1, _strategy.FileSize());
+  } else {
+    walk.FetchBytes(0, walk.ColSize(), _rootWalk, true);
+    if (_differ)
+      _differ->GetRoot(_rootWalk);
+
+    // 2006-08-01: maintain stable-storage space usage on re-open
+    OccupySpace(_strategy._rootPos, _strategy._rootLen);
+
+    // define and fill the root table 
+    const t4_byte *ptr = _rootWalk.Contents();
+    _root->Prepare(&ptr, true);
+    d4_assert(ptr == _rootWalk.Contents() + _rootWalk.Size());
+  }
+}
+
+t4_i32 c4_Persist::FetchOldValue() {
+  d4_assert(_oldSeek >= 0);
+
+  if (_oldCurr == _oldLimit) {
+    int n = OldRead(_oldBuf, 500);
+    _oldLimit = _oldCurr + n;
+    _oldBuf[n] = 0x80; // to force end
+  }
+
+  const t4_byte *p = _oldCurr;
+  t4_i32 value = c4_Column::PullValue(p);
+
+  if (p > _oldLimit) {
+    int k = _oldLimit - _oldCurr;
+    d4_assert(0 < k && k < 10);
+    memcpy(_oldBuf, _oldCurr, k);
+
+    int n = OldRead(_oldBuf + k, 500);
+    _oldCurr = _oldBuf + k;
+    _oldLimit = _oldCurr + n;
+    _oldBuf[n + k] = 0x80; // to force end
+
+    p = _oldCurr;
+    value = c4_Column::PullValue(p);
+    d4_assert(p <= _oldLimit);
+  }
+
+  _oldCurr = p;
+  return value;
+}
+
+void c4_Persist::FetchOldLocation(c4_Column &col_) {
+  d4_assert(_oldSeek >= 0);
+
+  t4_i32 sz = FetchOldValue();
+  if (sz > 0)
+    col_.SetLocation(FetchOldValue(), sz);
+}
+
+t4_i32 c4_Persist::FreeBytes(t4_i32 *bytes_) {
+  return _space == 0 ?  - 1: _space->FreeCounts(bytes_);
+}
+
+int c4_Persist::OldRead(t4_byte *buf_, int len_) {
+  d4_assert(_oldSeek >= 0);
+
+  t4_i32 newSeek = _oldSeek + _oldCurr - _oldLimit;
+  int n = _strategy.DataRead(newSeek, buf_, len_);
+  d4_assert(n > 0);
+  _oldSeek = newSeek + n;
+  _oldCurr = _oldLimit = _oldBuf;
+  return n;
+}
+
+c4_HandlerSeq *c4_Persist::Load(c4_Stream *stream_) {
+  d4_assert(stream_ != 0);
+
+  c4_FileMark head;
+  if (stream_->Read(&head, sizeof head) != sizeof head || !head.IsHeader())
+    return 0;
+  // no data in file
+
+  //_oldStyle = head._data[3] == 0x80;
+  d4_assert(!head.IsOldHeader());
+
+  t4_i32 limit = head.Offset();
+
+  c4_StreamStrategy *strat = d4_new c4_StreamStrategy(limit);
+  strat->_bytesFlipped = head.IsFlipped();
+  strat->DataWrite(strat->FileSize() - strat->_baseOffset, &head, sizeof head);
+
+  while (strat->FileSize() - strat->_baseOffset < limit) {
+    char buffer[4096];
+    int n = stream_->Read(buffer, sizeof buffer);
+    d4_assert(n > 0);
+    strat->DataWrite(strat->FileSize() - strat->_baseOffset, buffer, n);
+  }
+
+  c4_Persist *pers = d4_new c4_Persist(*strat, true, 0);
+  c4_HandlerSeq *seq = d4_new c4_HandlerSeq(pers);
+  seq->DefineRoot();
+  pers->SetRoot(seq);
+
+  c4_Column walk(pers);
+  if (!pers->LoadIt(walk)) {
+    seq->IncRef();
+    seq->DecRef(); // a funny way to delete
+    return 0;
+  }
+
+  c4_Bytes tempWalk;
+  walk.FetchBytes(0, walk.ColSize(), tempWalk, true);
+
+  const t4_byte *ptr = tempWalk.Contents();
+  seq->Prepare(&ptr, true);
+  d4_assert(ptr == tempWalk.Contents() + tempWalk.Size());
+
+  return seq;
+}
+
+void c4_Persist::Save(c4_Stream *stream_, c4_HandlerSeq &root_) {
+  d4_assert(stream_ != 0);
+
+  c4_StreamStrategy strat(stream_);
+
+  // 31-01-2002: streaming must adopt byte order of origin datafile
+  c4_Persist *p = root_.Persist();
+  if (p != 0)
+    strat._bytesFlipped = p->Strategy()._bytesFlipped;
+
+  c4_SaveContext ar(strat, true, 0, 0, 0);
+  c4_Bytes tempWalk;
+  ar.SaveIt(root_, 0, tempWalk);
+}
+
+t4_i32 c4_Persist::LookupAside(int id_) {
+  d4_assert(_differ != 0);
+
+  return _differ->BaseOfDiff(id_);
+}
+
+void c4_Persist::ApplyAside(int id_, c4_Column &col_) {
+  d4_assert(_differ != 0);
+
+  _differ->ApplyDiff(id_, col_);
+}
+
+void c4_Persist::OccupySpace(t4_i32 pos_, t4_i32 len_) {
+  d4_assert(_mode != 1 || _space != 0);
+
+  if (_space != 0)
+    _space->Occupy(pos_, len_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/persist.h b/8.x/mk/src/persist.h
new file mode 100755 (executable)
index 0000000..6087d85
--- /dev/null
@@ -0,0 +1,127 @@
+// persist.h --
+// $Id: persist.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Definition of the core file management classes
+ */
+
+#ifndef __PERSIST_H__
+#define __PERSIST_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+class c4_SaveContext; // wraps file commits
+class c4_Persist; // persistent table storage
+
+class c4_Allocator; // not defined here
+class c4_Column; // not defined here
+class c4_Differ; // not defined here
+class c4_FileMark; // not defined here
+class c4_Strategy; // not defined here
+class c4_HandlerSeq; // not defined here
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_SaveContext {
+    c4_Strategy &_strategy;
+    c4_Column *_walk;
+    c4_Differ *_differ;
+
+    c4_Allocator *_space;
+    c4_Allocator *_cleanup;
+    c4_Allocator *_nextSpace;
+
+    bool _preflight;
+    bool _fullScan;
+    int _mode;
+
+    c4_DWordArray _newPositions;
+    int _nextPosIndex;
+
+    t4_byte *_bufPtr;
+    t4_byte *_curr;
+    t4_byte *_limit;
+    t4_byte _buffer[512];
+
+  public:
+    c4_SaveContext(c4_Strategy &strategy_, bool fullScan_, int mode_, c4_Differ
+      *differ_, c4_Allocator *space_);
+    ~c4_SaveContext();
+
+    void SaveIt(c4_HandlerSeq &root_, c4_Allocator **spacePtr_, c4_Bytes
+      &rootWalk_);
+
+    void StoreValue(t4_i32 v_);
+    bool CommitColumn(c4_Column &col_);
+    void CommitSequence(c4_HandlerSeq &seq_, bool selfDesc_);
+
+    c4_Column *SetWalkBuffer(c4_Column *walk_);
+    bool IsFlipped()const;
+
+    bool Serializing()const;
+    void AllocDump(const char *, bool = false);
+
+  private:
+    void FlushBuffer();
+    void Write(const void *buf_, int len_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Persist {
+    c4_Allocator *_space;
+    c4_Strategy &_strategy;
+    c4_HandlerSeq *_root;
+    c4_Differ *_differ;
+    c4_Bytes _rootWalk;
+    bool(c4_Persist:: *_fCommit)(bool);
+    int _mode;
+    bool _owned;
+
+    // used for on-the-fly conversion of old-format datafiles
+    t4_byte *_oldBuf;
+    const t4_byte *_oldCurr;
+    const t4_byte *_oldLimit;
+    t4_i32 _oldSeek;
+
+    int OldRead(t4_byte *buf_, int len_);
+
+  public:
+    c4_Persist(c4_Strategy &, bool owned_, int mode_);
+    ~c4_Persist();
+
+    c4_HandlerSeq &Root()const;
+    void SetRoot(c4_HandlerSeq *root_);
+    c4_Strategy &Strategy()const;
+
+    bool AutoCommit(bool = true);
+    void DoAutoCommit();
+
+    bool SetAside(c4_Storage &aside_);
+    c4_Storage *GetAside()const;
+
+    bool Commit(bool full_);
+    bool Rollback(bool full_);
+
+    bool LoadIt(c4_Column &walk_);
+    void LoadAll();
+
+    t4_i32 LookupAside(int id_);
+    void ApplyAside(int id_, c4_Column &col_);
+
+    void OccupySpace(t4_i32 pos_, t4_i32 len_);
+
+    t4_i32 FetchOldValue();
+    void FetchOldLocation(c4_Column &col_);
+
+    t4_i32 FreeBytes(t4_i32 *bytes_ = 0);
+
+    static c4_HandlerSeq *Load(c4_Stream*);
+    static void Save(c4_Stream *, c4_HandlerSeq &root_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/remap.cpp b/8.x/mk/src/remap.cpp
new file mode 100755 (executable)
index 0000000..452a230
--- /dev/null
@@ -0,0 +1,1089 @@
+// remap.cpp --
+// $Id: remap.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Mapping and remapping custom viewers
+ */
+
+#include "header.h"
+#include "remap.h"
+#include "handler.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_ReadOnlyViewer: public c4_CustomViewer {
+    c4_View _base;
+
+  public:
+    c4_ReadOnlyViewer(c4_Sequence &seq_): _base(&seq_){}
+    virtual ~c4_ReadOnlyViewer(){}
+
+    virtual c4_View GetTemplate() {
+        return _base.Clone();
+    }
+    virtual int GetSize() {
+        return _base.GetSize();
+    }
+
+    virtual int Lookup(c4_Cursor key_, int &count_) {
+        int pos = 0;
+        count_ = _base.GetSize();
+        return _base.RestrictSearch(*key_, pos, count_);
+    }
+
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_) {
+        return _base.GetItem(row_, col_, buf_);
+    }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_HashViewer: public c4_CustomViewer {
+    c4_View _base;
+    c4_View _map;
+    int _numKeys;
+
+    c4_IntProp _pHash;
+    c4_IntProp _pRow;
+
+    bool KeySame(int row_, c4_Cursor cursor_)const;
+    t4_i32 CalcHash(c4_Cursor cursor_)const;
+    int LookDict(t4_i32 hash_, c4_Cursor cursor_)const;
+    void InsertDict(int row_);
+    void RemoveDict(int pos_);
+    bool DictResize(int minused);
+
+    int Row(int i_)const {
+        return _pRow(_map[i_]);
+    }
+    int Hash(int i_)const {
+        return _pHash(_map[i_]);
+    }
+
+    void SetRow(int i_, int v_) {
+        _pRow(_map[i_]) = v_;
+    }
+    void SetHash(int i_, int v_) {
+        _pHash(_map[i_]) = v_;
+    }
+
+    bool IsUnused(int)const;
+    bool IsDummy(int)const;
+    bool IsActive(int i_)const {
+        return Row(i_) >= 0;
+    }
+
+    int GetPoly()const;
+    void SetPoly(int v_);
+    int GetSpare()const;
+    void SetSpare(int v_);
+
+  public:
+    c4_HashViewer(c4_Sequence &seq_, int numKeys_, c4_Sequence *map_ = 0);
+    virtual ~c4_HashViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual int Lookup(c4_Cursor key_, int &count_);
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    virtual bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+    virtual bool InsertRows(int pos_, c4_Cursor value_, int count_ = 1);
+    virtual bool RemoveRows(int pos_, int count_ = 1);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// The following contains code derived froms Python's dictionaries, hence:
+//  Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+//  The Netherlands.
+// Reduced and turned into a fast C++ class by Christian Tismer, hence:
+//  Copyright 1999 by Christian Tismer.
+// Vectorized and reorganized further by Jean-Claude Wippler.
+/////////////////////////////////////////////////////////////////////////////
+
+//  Table of irreducible polynomials to efficiently cycle through
+//  GF(2^n)-{0}, 2<=n<=30.
+
+static long s_polys[] =  {
+  4+3, 8+3, 16+3, 32+5, 64+3, 128+3, 256+29, 512+17, 1024+9, 2048+5, 4096+83,
+    8192+27, 16384+43, 32768+3, 65536+45, 131072+9, 262144+39, 524288+39,
+    1048576+9, 2097152+5, 4194304+3, 8388608+33, 16777216+27, 33554432+9,
+    67108864+71, 134217728+39, 268435456+9, 536870912+5, 1073741824+83, 0
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_HashViewer::c4_HashViewer(c4_Sequence &seq_, int numKeys_, c4_Sequence *map_)
+  : _base(&seq_), _map(map_), _numKeys(numKeys_), _pHash("_H"), _pRow("_R") {
+  if (_map.GetSize() == 0)
+    _map.SetSize(1);
+
+  int poly = GetPoly();
+  if (poly == 0 || _map.GetSize() <= _base.GetSize())
+    DictResize(_base.GetSize());
+}
+
+c4_HashViewer::~c4_HashViewer(){}
+
+bool c4_HashViewer::IsUnused(int row_)const {
+  c4_RowRef r = _map[row_];
+  return _pRow(r) < 0 && _pHash(r) == 0;
+}
+
+bool c4_HashViewer::IsDummy(int row_)const {
+  c4_RowRef r = _map[row_];
+  return _pRow(r) < 0 && _pHash(r) < 0;
+}
+
+int c4_HashViewer::GetPoly()const {
+  return Hash(_map.GetSize() - 1);
+}
+
+void c4_HashViewer::SetPoly(int v_) {
+  SetHash(_map.GetSize() - 1, v_);
+}
+
+int c4_HashViewer::GetSpare()const {
+  return Row(_map.GetSize() - 1);
+}
+
+void c4_HashViewer::SetSpare(int v_) {
+  SetRow(_map.GetSize() - 1, v_);
+}
+
+bool c4_HashViewer::KeySame(int row_, c4_Cursor cursor_)const {
+  for (int i = 0; i < _numKeys; ++i) {
+    c4_Bytes buffer;
+    _base.GetItem(row_, i, buffer);
+
+    c4_Handler &h = cursor_._seq->NthHandler(i);
+    if (h.Compare(cursor_._index, buffer) != 0)
+      return false;
+  }
+
+  return true;
+}
+
+/// Create mapped view which is uses a second view for hashing
+t4_i32 c4_HashViewer::CalcHash(c4_Cursor cursor_)const {
+  c4_Bytes buffer, buf2;
+  const t4_i32 endian = 0x03020100;
+  t4_i32 hash = 0;
+
+  for (int i = 0; i < _numKeys; ++i) {
+    c4_Handler &h = cursor_._seq->NthHandler(i);
+    cursor_._seq->Get(cursor_._index, h.PropId(), buffer);
+
+    // this code borrows from Python's stringobject.c/string_hash()
+    int len = buffer.Size();
+    if (len > 0) {
+      const t4_byte *p = buffer.Contents();
+
+      // 20030218: careful to avoid endian-ness sensitivity
+      if (*(const t4_byte*) &endian)
+      // true on big-endian systems
+      switch (h.Property().Type()) {
+        case 'I':
+        case 'L':
+        case 'F':
+        case 'D':
+           {
+            t4_byte *q = buf2.SetBuffer(len);
+            for (int j = 0; j < len; ++j)
+              q[len - j - 1] = p[j];
+            p = q;
+          }
+      }
+
+      long x =  *p << 7;
+
+      // modifications are risky, this code avoid scanning huge blobs
+      if (len > 200)
+        len = 100;
+
+      while (--len >= 0)
+        x = (1000003 *x) ^  *p++;
+
+      if (buffer.Size() > 200) {
+        len = 100;
+        p += buffer.Size() - 200;
+        while (--len >= 0)
+          x = (1000003 *x) ^  *p++;
+      }
+
+      x ^= buffer.Size();
+      hash ^= x ^ i;
+    }
+  }
+
+  if (hash == 0)
+    hash =  - 1;
+
+  return hash;
+}
+
+/*
+ * Types of slots:
+ *  Unused: row = -1, hash = 0
+ *  Dummy:  row = -1, hash = -1
+ *  Active: row >= 0
+ * There must be at least one Unused slot at all times.
+ */
+
+int c4_HashViewer::LookDict(t4_i32 hash_, c4_Cursor cursor_)const {
+  const unsigned int mask = _map.GetSize() - 2;
+  /* We must come up with (i, incr) such that 0 <= i < _size
+  and 0 < incr < _size and both are a function of hash */
+  int i = mask &~hash_;
+  /* We use ~hash_ instead of hash_, as degenerate hash functions, such
+  as for ints <sigh>, can have lots of leading zeros. It's not
+  really a performance risk, but better safe than sorry. */
+  if (IsUnused(i) || Hash(i) == hash_ && KeySame(Row(i), cursor_))
+    return i;
+
+  int freeslot = IsDummy(i) ? i :  - 1;
+
+  /* Derive incr from hash_, just to make it more arbitrary. Note that
+  incr must not be 0, or we will get into an infinite loop.*/
+  unsigned incr = (hash_ ^ ((unsigned long)hash_ >> 3)) &mask;
+  if (!incr)
+    incr = mask;
+
+  int poly = GetPoly();
+  for (;;) {
+    i = (i + incr) &mask;
+    if (IsUnused(i))
+      break;
+    if (Hash(i) == hash_ && KeySame(Row(i), cursor_))
+      return i;
+    if (freeslot ==  - 1 && IsDummy(i))
+      freeslot = i;
+    /* Cycle through GF(2^n)-{0} */
+    incr = incr << 1;
+    if (incr > mask)
+      incr ^= poly;
+     /* This will implicitely clear the highest bit */
+  }
+
+  return freeslot !=  - 1 ? freeslot : i;
+}
+
+void c4_HashViewer::InsertDict(int row_) {
+  c4_Cursor cursor = &_base[row_];
+
+  t4_i32 hash = CalcHash(cursor);
+  int i = LookDict(hash, cursor);
+
+  if (IsDummy(i)) {
+    int n = GetSpare();
+    d4_assert(n > 0);
+    SetSpare(n - 1);
+  }
+
+  SetHash(i, hash);
+  SetRow(i, row_);
+}
+
+void c4_HashViewer::RemoveDict(int pos_) {
+  c4_Cursor key = &_base[pos_];
+  t4_i32 hash = CalcHash(key);
+  int i = LookDict(hash, key);
+  d4_assert(i >= 0);
+
+  d4_assert(Row(i) == pos_);
+
+  SetHash(i,  - 1);
+  SetRow(i,  - 1);
+
+  SetSpare(GetSpare() + 1);
+}
+
+bool c4_HashViewer::DictResize(int minused) {
+  int i, newsize, newpoly;
+  for (i = 0, newsize = 4;; i++, newsize <<= 1) {
+    if (s_polys[i] == 0)
+      return false;
+    else if (newsize > minused) {
+      newpoly = s_polys[i];
+      break;
+    }
+  }
+
+  _map.SetSize(0);
+
+  c4_Row empty;
+  _pRow(empty) =  - 1;
+  _map.InsertAt(0, empty, newsize + 1);
+
+  SetPoly(newpoly);
+  SetSpare(0);
+
+  for (int j = 0; j < _base.GetSize(); ++j)
+    InsertDict(j);
+
+  return true;
+}
+
+c4_View c4_HashViewer::GetTemplate() {
+  return _base.Clone();
+}
+
+int c4_HashViewer::GetSize() {
+  return _base.GetSize();
+}
+
+int c4_HashViewer::Lookup(c4_Cursor key_, int &count_) {
+  // can only use hashing if the properties match the query
+  // XXX it appears that this loop takes some 300 uS!
+  c4_View kv = (*key_).Container();
+  for (int k = 0; k < _numKeys; ++k)
+    if (kv.FindProperty(_base.NthProperty(k).GetId()) < 0)
+      return  - 1;
+
+  t4_i32 hash = CalcHash(key_); // TODO should combine with above loop
+  int i = LookDict(hash, key_);
+
+  int row = Row(i);
+  count_ = row >= 0 && KeySame(row, key_) ? 1 : 0;
+  return count_ ? row : 0; // don't return -1, we *know* it's not there
+}
+
+bool c4_HashViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  return _base.GetItem(row_, col_, buf_);
+}
+
+bool c4_HashViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  if (col_ < _numKeys) {
+    c4_Bytes temp;
+    _base.GetItem(row_, col_, temp);
+    if (buf_ == temp)
+      return true;
+    // this call will have no effect, just ignore it
+
+    RemoveDict(row_);
+  }
+
+  _base.SetItem(row_, col_, buf_);
+
+  if (col_ < _numKeys) {
+    // careful if changing a key to one which is already present:
+    // in that case, delete the other row to preserve uniqueness
+    //
+    // Note: this is a tricky and confusing issue, because now the
+    // mere act of *setting* a property value can *delete* a row!
+    //
+    // The big problem here is that setting the rest of the values
+    // in a loop can end up *wrong*, if the row has moved down!!!
+    int n;
+    int i = Lookup(&_base[row_], n);
+    if (i >= 0 && n > 0) {
+      RemoveRows(i, 1);
+      if (i < row_)
+        --row_;
+    }
+
+    InsertDict(row_);
+  }
+
+  return true;
+}
+
+bool c4_HashViewer::InsertRows(int pos_, c4_Cursor value_, int count_) {
+  d4_assert(count_ > 0);
+
+  int n;
+  int i = Lookup(value_, n);
+  if (i >= 0 && n > 0) {
+    _base.SetAt(i,  *value_); // replace existing
+    return true;
+  }
+
+  // adjust row numbers if the insertion is not at the end
+  //
+  // TODO this could be optimized to go through the rows which
+  // were moved up, and then adjusting the map through a lookup
+  // (probably better than full scan if pos_ is relatively high)
+  if (pos_ < _base.GetSize()) {
+    for (int r = 0; r < _map.GetSize() - 1; ++r) {
+      int n2 = Row(r);
+      if (n2 >= pos_)
+        SetRow(r, n2 + 1);
+    }
+  }
+
+  _base.InsertAt(pos_,  *value_);
+  InsertDict(pos_);
+
+  int used = _base.GetSize();
+  int fill = used + GetSpare();
+  if (fill *3 >= (_map.GetSize() - 1) *2 && !DictResize(used *2))
+    return false;
+  // bail out
+
+  d4_assert(_base.GetSize() + GetSpare() < _map.GetSize() - 1);
+  return true;
+}
+
+bool c4_HashViewer::RemoveRows(int pos_, int count_) {
+  while (--count_ >= 0) {
+    // since the map persists, be somewhat more aggressive than the
+    // original code in resizing down when the map is getting empty
+    if (_base.GetSize() *3 < _map.GetSize() - 1 && !DictResize(_base.GetSize()))
+      return false;
+    // bail out
+
+    RemoveDict(pos_);
+
+    // move rows down for now
+    //
+    // optionally: consider replacing with last entry (much faster)
+    for (int r = 0; r < _map.GetSize() - 1; ++r) {
+      int n = Row(r);
+      if (n > pos_)
+        SetRow(r, n - 1);
+    }
+
+    _base.RemoveAt(pos_, 1);
+  }
+
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_BlockedViewer: public c4_CustomViewer {
+    enum {
+        kLimit = 1000
+    };
+
+    c4_View _base;
+
+    c4_ViewProp _pBlock;
+    c4_DWordArray _offsets;
+
+    int _last_base, _last_limit, _last_slot;
+    c4_View _last_view;
+
+    int Slot(int &pos_);
+    void Split(int block_, int row_);
+    void Merge(int block_);
+    void Validate()const;
+
+    // 2004-04-27 new cache logic, thx MB
+    void SetLast(int row_);
+    void ClearLast(int slot_) {
+        if (_last_slot >= slot_) {
+            _last_limit = _last_slot =  - 1;
+            _last_view = c4_View();
+        }
+    }
+
+  public:
+    c4_BlockedViewer(c4_Sequence &seq_);
+    virtual ~c4_BlockedViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    virtual bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+    virtual bool InsertRows(int pos_, c4_Cursor value_, int count_ = 1);
+    virtual bool RemoveRows(int pos_, int count_ = 1);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_CHECK
+
+// debugging version to verify that the internal data is consistent
+void c4_BlockedViewer::Validate()const {
+  d4_assert(_base.GetSize() >= 2);
+
+  int n = _base.GetSize() - 1;
+  d4_assert(_offsets.GetSize() == n);
+
+  int total = 0;
+  for (int i = 0; i < n; i++) {
+    c4_View bv = _pBlock(_base[i]);
+    d4_assert(bv.GetSize() > 0 || i == 0);
+    total += bv.GetSize();
+    d4_assert((int)_offsets.GetAt(i) == total++);
+  }
+
+  c4_View be = _pBlock(_base[n]);
+  d4_assert(be.GetSize() == n - 1);
+}
+
+#else 
+
+// nothing, so inline this thing to avoid even the calling overhead
+d4_inline void c4_BlockedViewer::Validate()const{}
+
+#endif 
+
+c4_BlockedViewer::c4_BlockedViewer(c4_Sequence &seq_): _base(&seq_), _pBlock(
+  "_B"), _last_base( - 1), _last_limit( - 1), _last_slot( - 1) {
+  if (_base.GetSize() < 2)
+    _base.SetSize(2);
+
+  int n = _base.GetSize() - 1;
+  _offsets.SetSize(n);
+
+  int total = 0;
+  for (int i = 0; i < n; i++) {
+    c4_View bv = _pBlock(_base[i]);
+    total += bv.GetSize();
+    _offsets.SetAt(i, total++);
+  }
+  Validate();
+}
+
+c4_BlockedViewer::~c4_BlockedViewer(){}
+
+int c4_BlockedViewer::Slot(int &pos_) {
+  const int n = _offsets.GetSize();
+
+  d4_assert(n > 0);
+  d4_assert(pos_ <= (int)_offsets.GetAt(n - 1));
+
+#if 0
+  // not sure the following adds any performance (the logic looks ok)
+  // reason: won't work if inserts/removes always invalidate the cache
+  if (_last_base <= pos_ && pos_ < _last_limit) {
+    pos_ -= _last_base;
+    return _last_slot;
+  }
+#endif 
+
+#if 0
+  int h;
+  for (h = 0; h < n; ++h)
+    if (pos_ <= (t4_i32)_offsets.GetAt(h))
+      break;
+#else 
+  // switch to binary search, adapted from code by Zhang Dehua, 28-3-2002
+  // slows down some 5%, but said to be much better with 5 million rows
+  int l = 0, h = n - 1;
+  while (l < h) {
+    int m = l + (h - l) / 2;
+    if ((t4_i32)_offsets.GetAt(m) < pos_)
+      l = m + 1;
+    else
+      h = m;
+  }
+#endif 
+
+  if (h > 0)
+    pos_ -= _offsets.GetAt(h - 1) + 1;
+
+  return h;
+}
+
+void c4_BlockedViewer::Split(int bno_, int row_) {
+  ClearLast(bno_);
+
+  int z = _offsets.GetSize();
+  d4_assert(bno_ < z);
+  c4_View bz = _pBlock(_base[z]);
+  c4_View bv = _pBlock(_base[bno_]);
+  d4_assert(row_ < bv.GetSize());
+
+  _offsets.InsertAt(bno_, _offsets.GetAt(bno_) - bv.GetSize() + row_);
+
+  _base.InsertAt(bno_ + 1, c4_Row());
+  c4_View bn = _pBlock(_base[bno_ + 1]);
+
+  bv.RelocateRows(row_ + 1,  - 1, bn, 0);
+  bv.RelocateRows(row_, 1, bz, bno_);
+
+  Validate();
+}
+
+void c4_BlockedViewer::Merge(int bno_) {
+  ClearLast(bno_);
+
+  int z = _offsets.GetSize();
+  c4_View bz = _pBlock(_base[z]);
+  c4_View bv1 = _pBlock(_base[bno_]);
+  c4_View bv2 = _pBlock(_base[bno_ + 1]);
+
+  _offsets.RemoveAt(bno_);
+
+  bz.RelocateRows(bno_, 1, bv1,  - 1);
+  bv2.RelocateRows(0,  - 1, bv1,  - 1);
+
+  _base.RemoveAt(bno_ + 1);
+
+  Validate();
+}
+
+c4_View c4_BlockedViewer::GetTemplate() {
+  c4_View bv = _pBlock(_base[0]);
+  return bv.Clone();
+}
+
+int c4_BlockedViewer::GetSize() {
+  int n = _offsets.GetAt(_offsets.GetSize() - 1);
+  d4_assert(n >= 0);
+  return n;
+}
+
+void c4_BlockedViewer::SetLast(int row_) {
+  int orig = row_;
+
+  int i = Slot(row_);
+  d4_assert(0 <= i && i < _offsets.GetSize());
+
+  _last_limit = _offsets.GetAt(i);
+
+  if (_last_limit == orig) {
+    row_ = i;
+    i = _offsets.GetSize();
+    _last_limit = 0; // force miss next time, but view is still cached
+  }
+
+  if (i != _last_slot) {
+    _last_slot = i;
+    _last_view = _pBlock(_base[i]);
+  }
+
+  _last_base = orig - row_;
+}
+
+bool c4_BlockedViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  if (row_ < _last_base || row_ >= _last_limit)
+    SetLast(row_);
+  return _last_view.GetItem(row_ - _last_base, col_, buf_);
+}
+
+bool c4_BlockedViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  if (row_ < _last_base || row_ >= _last_limit)
+    SetLast(row_);
+  _last_view.SetItem(row_ - _last_base, col_, buf_);
+  return true;
+}
+
+bool c4_BlockedViewer::InsertRows(int pos_, c4_Cursor value_, int count_) {
+  d4_assert(count_ > 0);
+
+  bool atEnd = pos_ == GetSize();
+
+  int z = _offsets.GetSize();
+  int i = Slot(pos_);
+  d4_assert(0 <= i && i < z);
+
+  ClearLast(i);
+
+  c4_View bv = _pBlock(_base[i]);
+  d4_assert(0 <= pos_ && pos_ <= bv.GetSize());
+
+  bv.InsertAt(pos_,  *value_, count_);
+  for (int j = i; j < z; ++j)
+    _offsets.SetAt(j, _offsets.GetAt(j) + count_);
+
+  // massive insertions are first split off
+  while (bv.GetSize() >= 2 *kLimit)
+    Split(i, bv.GetSize() - kLimit - 2);
+
+  if (bv.GetSize() > kLimit)
+    Split(i, atEnd ? kLimit - 1: bv.GetSize() / 2);
+  // 23-3-2002, from MB
+
+  Validate();
+
+  return true;
+}
+
+bool c4_BlockedViewer::RemoveRows(int pos_, int count_) {
+  d4_assert(count_ > 0);
+  d4_assert(pos_ + count_ <= GetSize());
+
+  int z = _offsets.GetSize();
+  int i = Slot(pos_);
+  d4_assert(0 <= i && i < z);
+
+  ClearLast(i);
+
+  c4_View bv = _pBlock(_base[i]);
+  d4_assert(0 <= pos_ && pos_ <= bv.GetSize());
+
+  int todo = count_;
+
+  // optimize if the deletion goes past the end of this block...
+  int overshoot = pos_ + count_ - bv.GetSize();
+  if (overshoot > 0) {
+
+    // first, delete blocks which are going away completely
+    while (i + 1 < _offsets.GetSize()) {
+      int nextsize = _offsets.GetAt(i + 1) - _offsets.GetAt(i);
+      if (overshoot < nextsize)
+        break;
+      todo -= nextsize;
+      overshoot -= nextsize;
+
+      // drop the block and forget it ever existed
+      for (int j = i + 1; j < z; ++j)
+        _offsets.SetAt(j, _offsets.GetAt(j) - nextsize);
+      _offsets.RemoveAt(i + 1);
+
+      _base.RemoveAt(i + 1);
+      --z;
+      c4_View bz = _pBlock(_base[z]);
+      bz.RemoveAt(i);
+
+      Validate();
+    }
+
+    // delete before merging, to avoid useless copying
+    if (overshoot > 1) {
+      c4_View bv2 = _pBlock(_base[i + 1]);
+      bv2.RemoveAt(0, overshoot - 1);
+      todo -= overshoot - 1;
+
+      for (int j = i + 1; j < z; ++j)
+        _offsets.SetAt(j, _offsets.GetAt(j) - (overshoot - 1));
+
+      // if the next block is filled enough, rotate the separator
+      // this avoids an expensive and unnecessary merge + split
+      if (bv2.GetSize() > kLimit / 2) {
+        c4_View bz = _pBlock(_base[z]);
+        bz[i] = bv2[0];
+        bv2.RemoveAt(0);
+        --todo;
+        d4_assert(pos_ + todo <= bv.GetSize());
+        d4_assert(i < _offsets.GetSize());
+
+        for (int j = i + 1; j < z; ++j)
+          _offsets.SetAt(j, _offsets.GetAt(j) - 1);
+      }
+    }
+
+    // merge into one block
+    if (pos_ + todo > bv.GetSize()) {
+      d4_assert(i < z - 1);
+      Merge(i);
+      --z;
+    }
+  }
+  d4_assert(pos_ + todo <= bv.GetSize());
+
+  // now remove the rows and adjust offsets
+  if (todo > 0)
+    bv.RemoveAt(pos_, todo);
+
+  for (int j = i; j < z; ++j)
+    _offsets.SetAt(j, _offsets.GetAt(j) - todo);
+
+  // if the block underflows, merge it
+  if (bv.GetSize() < kLimit / 2) {
+    if (i > 0)
+    // merge with predecessor, preferably
+      bv = _pBlock(_base[--i]);
+    if (i >= z - 1)
+    // unless there is no successor to merge with
+      return true;
+    Merge(i);
+  }
+
+  // if the block overflows, split it
+  if (bv.GetSize() > kLimit)
+    Split(i, bv.GetSize() / 2);
+
+  Validate();
+
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_OrderedViewer: public c4_CustomViewer {
+    c4_View _base;
+    int _numKeys;
+
+    int KeyCompare(int row_, c4_Cursor cursor_)const;
+
+  public:
+    c4_OrderedViewer(c4_Sequence &seq_, int numKeys_);
+    virtual ~c4_OrderedViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual int Lookup(c4_Cursor key_, int &count_);
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    virtual bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+    virtual bool InsertRows(int pos_, c4_Cursor value_, int count_ = 1);
+    virtual bool RemoveRows(int pos_, int count_ = 1);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_OrderedViewer::c4_OrderedViewer(c4_Sequence &seq_, int numKeys_): _base
+  (&seq_), _numKeys(numKeys_){}
+
+c4_OrderedViewer::~c4_OrderedViewer(){}
+
+int c4_OrderedViewer::KeyCompare(int row_, c4_Cursor cursor_)const {
+  for (int i = 0; i < _numKeys; ++i) {
+    c4_Bytes buffer;
+    _base.GetItem(row_, i, buffer);
+
+    c4_Handler &h = cursor_._seq->NthHandler(i);
+    int f = h.Compare(cursor_._index, buffer);
+    if (f != 0)
+      return f;
+  }
+
+  return 0;
+}
+
+c4_View c4_OrderedViewer::GetTemplate() {
+  return _base.Clone();
+}
+
+int c4_OrderedViewer::GetSize() {
+  return _base.GetSize();
+}
+
+int c4_OrderedViewer::Lookup(c4_Cursor key_, int &count_) {
+  // can only use bsearch if the properties match the query
+  // XXX with ord1.tcl (dict words), this loop takes 300 uS!
+  c4_View kv = (*key_).Container();
+  for (int k = 0; k < _numKeys; ++k)
+    if (kv.FindProperty(_base.NthProperty(k).GetId()) < 0)
+      return  - 1;
+
+#if 0 // Locate gets the count wrong, it seems 2000-06-15
+  int pos;
+  count_ = _base.Locate(*key_, &pos);
+#else 
+  int pos = _base.Search(*key_);
+  count_ = pos < _base.GetSize() && KeyCompare(pos, key_) == 0 ? 1 : 0;
+#endif 
+  return pos;
+}
+
+bool c4_OrderedViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  return _base.GetItem(row_, col_, buf_);
+}
+
+bool c4_OrderedViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  if (col_ < _numKeys) {
+    c4_Bytes temp;
+    _base.GetItem(row_, col_, temp);
+    if (buf_ == temp)
+      return true;
+    // this call will have no effect, just ignore it
+  }
+
+  _base.SetItem(row_, col_, buf_);
+
+  if (col_ < _numKeys) {
+    c4_Row copy = _base[row_];
+    // have to remove the row because it messes up searching
+    // it would be more efficient to search *around* this row
+    // or perhaps figure out new pos before changing any data
+    RemoveRows(row_);
+    InsertRows(0, &copy); // position is ignored
+  }
+
+  return true;
+}
+
+bool c4_OrderedViewer::InsertRows(int, c4_Cursor value_, int count_) {
+  d4_assert(count_ > 0);
+
+  int n;
+  int i = Lookup(value_, n);
+
+  // XXX if the lookup does not work, then insert as first element (!?)
+  d4_assert(i >= 0);
+  if (i < 0)
+    i = 0;
+
+  if (n == 0)
+    _base.InsertAt(i,  *value_);
+  else {
+    d4_assert(i < _base.GetSize());
+    _base.SetAt(i,  *value_); // replace existing
+  }
+
+  return true;
+}
+
+bool c4_OrderedViewer::RemoveRows(int pos_, int count_) {
+  _base.RemoveAt(pos_, count_);
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_IndexedViewer: public c4_CustomViewer {
+    c4_View _base;
+    c4_View _map;
+    c4_View _props;
+    bool _unique;
+    c4_IntProp _mapProp;
+
+    int KeyCompare(int row_, c4_Cursor cursor_)const;
+
+  public:
+    c4_IndexedViewer(c4_Sequence &seq_, c4_Sequence &map_, const c4_View
+      &props_, bool unique_);
+    virtual ~c4_IndexedViewer();
+
+    virtual c4_View GetTemplate();
+    virtual int GetSize();
+    virtual int Lookup(c4_Cursor key_, int &count_);
+    virtual bool GetItem(int row_, int col_, c4_Bytes &buf_);
+    virtual bool SetItem(int row_, int col_, const c4_Bytes &buf_);
+    virtual bool InsertRows(int pos_, c4_Cursor value_, int count_ = 1);
+    virtual bool RemoveRows(int pos_, int count_ = 1);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_IndexedViewer::c4_IndexedViewer(c4_Sequence &seq_, c4_Sequence &map_, const
+  c4_View &props_, bool unique_): _base(&seq_), _map(&map_), _props(props_),
+  _unique(unique_), _mapProp((const c4_IntProp &)_map.NthProperty(0)) {
+  int n = _base.GetSize();
+  if (_map.GetSize() != n) {
+    c4_View sorted = _base.SortOn(_props);
+
+    _map.SetSize(n);
+    for (int i = 0; i < n; ++i)
+      _mapProp(_map[i]) = _base.GetIndexOf(sorted[i]);
+  }
+}
+
+c4_IndexedViewer::~c4_IndexedViewer(){}
+
+int c4_IndexedViewer::KeyCompare(int row_, c4_Cursor cursor_)const {
+  int n = _props.NumProperties();
+  for (int i = 0; i < n; ++i) {
+    c4_Bytes buffer;
+    _base.GetItem(row_, i, buffer);
+
+    c4_Handler &h = cursor_._seq->NthHandler(i);
+    int f = h.Compare(cursor_._index, buffer);
+    if (f != 0)
+      return f;
+  }
+
+  return 0;
+}
+
+c4_View c4_IndexedViewer::GetTemplate() {
+  return _base.Clone();
+}
+
+int c4_IndexedViewer::GetSize() {
+  return _base.GetSize();
+}
+
+int c4_IndexedViewer::Lookup(c4_Cursor key_, int &count_) {
+  // can only use bsearch if the properties match the query
+  // XXX with ord1.tcl (dict words), this loop takes 300 uS!
+  c4_View kv = (*key_).Container();
+  int n = _props.NumProperties();
+  for (int k = 0; k < n; ++k)
+    if (kv.FindProperty(_props.NthProperty(k).GetId()) < 0)
+      return  - 1;
+
+#if 0 // Locate gets the count wrong, it seems 2000-06-15
+  int pos;
+  count_ = _base.Locate(*key_, &pos);
+#else 
+  int pos = _base.Search(*key_);
+  count_ = pos < _base.GetSize() && KeyCompare(pos, key_) == 0 ? 1 : 0;
+#endif 
+  return pos;
+}
+
+bool c4_IndexedViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
+  return _base.GetItem(row_, col_, buf_);
+}
+
+bool c4_IndexedViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
+  const int id = _base.NthProperty(col_).GetId();
+  const bool keyMod = _props.FindProperty(id) >= 0;
+
+  if (keyMod) {
+    c4_Bytes temp;
+    _base.GetItem(row_, col_, temp);
+    if (buf_ == temp)
+      return true;
+    // this call will have no effect, just ignore it
+  }
+
+  _base.SetItem(row_, col_, buf_);
+
+  if (keyMod) {
+    // TODO adjust index
+  }
+
+  return true;
+}
+
+bool c4_IndexedViewer::InsertRows(int, c4_Cursor value_, int count_) {
+  d4_assert(count_ > 0);
+
+  if (_unique)
+    count_ = 1;
+
+  int n;
+  int i = Lookup(value_, n);
+
+  // XXX if the lookup does not work, then insert as first element (!?)
+  d4_assert(i >= 0);
+  if (i < 0)
+    i = 0;
+
+  if (n == 0)
+    _base.InsertAt(i,  *value_);
+  else {
+    d4_assert(i < _base.GetSize());
+    _base.SetAt(i,  *value_); // replace existing
+  }
+
+  return true;
+}
+
+bool c4_IndexedViewer::RemoveRows(int pos_, int count_) {
+  _base.RemoveAt(pos_, count_);
+
+  int n = _map.GetSize();
+  while (--n >= 0) {
+    int v = _mapProp(_map[n]);
+    if (v >= pos_)
+      if (v < pos_ + count_)
+        _map.RemoveAt(n);
+      else
+        _mapProp(_map[n]) = v - count_;
+  }
+
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_CustomViewer *f4_CreateReadOnly(c4_Sequence &seq_) {
+  return d4_new c4_ReadOnlyViewer(seq_);
+}
+
+c4_CustomViewer *f4_CreateHash(c4_Sequence &seq_, int nk_, c4_Sequence *map_) {
+  return d4_new c4_HashViewer(seq_, nk_, map_);
+}
+
+c4_CustomViewer *f4_CreateBlocked(c4_Sequence &seq_) {
+  return d4_new c4_BlockedViewer(seq_);
+}
+
+c4_CustomViewer *f4_CreateOrdered(c4_Sequence &seq_, int nk_) {
+  return d4_new c4_OrderedViewer(seq_, nk_);
+}
+
+c4_CustomViewer *f4_CreateIndexed(c4_Sequence &seq_, c4_Sequence &map_, const
+  c4_View &props_, bool unique_) {
+  return d4_new c4_IndexedViewer(seq_, map_, props_, unique_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/remap.h b/8.x/mk/src/remap.h
new file mode 100644 (file)
index 0000000..0eac577
--- /dev/null
@@ -0,0 +1,26 @@
+// remap.h --
+// $Id: remap.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Encapsulation of the (re)mapping viewers
+ */
+
+#ifndef __REMAP_H__
+#define __REMAP_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// Declarations in this file
+
+class c4_Sequence; // not defined here
+
+extern c4_CustomViewer *f4_CreateReadOnly(c4_Sequence &);
+extern c4_CustomViewer *f4_CreateHash(c4_Sequence &, int, c4_Sequence * = 0);
+extern c4_CustomViewer *f4_CreateBlocked(c4_Sequence &);
+extern c4_CustomViewer *f4_CreateOrdered(c4_Sequence &, int);
+extern c4_CustomViewer *f4_CreateIndexed(c4_Sequence &, c4_Sequence &, const
+  c4_View &, bool = false);
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/std.cpp b/8.x/mk/src/std.cpp
new file mode 100755 (executable)
index 0000000..3e5166e
--- /dev/null
@@ -0,0 +1,79 @@
+// std.cpp --
+// $Id: std.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Implementation of STL-based strings and containers
+ */
+
+#include "header.h"
+
+#if q4_STD // until end of source
+/////////////////////////////////////////////////////////////////////////////
+
+#include "column.h"   // c4_ColCache
+
+#if !q4_INLINE
+static char _mk4stdInl[] = "mk4str.inl";
+#include "mk4str.inl"
+#endif 
+
+#if !q4_NO_NS
+using namespace std;
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// Implemented in this file
+
+class c4_String;
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if !q4_MSVC && !q4_WATC
+
+// MS C/C++ has this handy stricmp: a case-insensitive version of strcmp
+// This version only works with 7-bit ASCII characters 0x00 through 0x7F
+
+static int stricmp(const char *p1, const char *p2) {
+    int c1, c2;
+
+#ifdef d4_USE_UNOPTIMIZED_CODE
+    do {
+        c1 = tolower(*p1++);
+        c2 = tolower(*p2++);
+    } while (c1 != 0 && c1 == c2);
+#else 
+    do {
+        c1 =  *p1++;
+        c2 =  *p2++;
+    } while (c1 != 0 && (c1 == c2 || tolower(c1) == tolower(c2)));
+
+    c1 = tolower(c1);
+    c2 = tolower(c2);
+#endif 
+
+    return c1 - c2;
+}
+
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_String
+
+c4_String c4_String::Mid(int nFirst_, int nCount_)const {
+  int n = length();
+  if (nFirst_ > n)
+    nFirst_ = n;
+  if (nFirst_ + nCount_ > n)
+    nCount_ = n - nFirst_;
+
+  return substr(nFirst_, nCount_);
+}
+
+int c4_String::CompareNoCase(const char *str_)const {
+  // this is not very "standard library-ish" ...
+  return *(const string*)this == str_ ? 0 : stricmp(c_str(), str_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // q4_STD
diff --git a/8.x/mk/src/std.h b/8.x/mk/src/std.h
new file mode 100755 (executable)
index 0000000..d286237
--- /dev/null
@@ -0,0 +1,65 @@
+// std.h --
+// $Id: std.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Configuration header for STL-based builds
+ */
+
+#define q4_STD 1
+
+#include "mk4str.h"
+
+#include <vector>
+
+/////////////////////////////////////////////////////////////////////////////
+
+template <class T> class c4_ArrayT {
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+    d4_std::vector<T, d4_std::allocator<T> > _vector;
+#else 
+    d4_std::vector<T, d4_std::alloc> _vector;
+#endif 
+
+  public:
+    c4_ArrayT(){}
+    ~c4_ArrayT(){}
+
+    int GetSize()const {
+        return _vector.size();
+    }
+    void SetSize(int nNewSize, int =  - 1) {
+        _vector.resize(nNewSize);
+    }
+
+    T GetAt(int nIndex)const {
+        return _vector[nIndex];
+    }
+    T &ElementAt(int nIndex) {
+        return _vector[nIndex];
+    }
+
+    void SetAt(int nIndex, const T &newElement) {
+        _vector[nIndex] = newElement;
+    }
+
+    int Add(const T &newElement) {
+        int n = _vector.size();
+        _vector.push_back(newElement);
+        return n;
+    }
+
+    void InsertAt(int nIndex, const T &newElement, int nCount = 1) {
+        _vector.insert(&_vector[nIndex], nCount, newElement);
+    }
+
+    void RemoveAt(int nIndex, int nCount = 1) {
+        _vector.erase(&_vector[nIndex], &_vector[nIndex + nCount]);
+    }
+};
+
+typedef c4_ArrayT < t4_i32 > c4_DWordArray;
+typedef c4_ArrayT < void * > c4_PtrArray;
+typedef c4_ArrayT < c4_String > c4_StringArray;
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/store.cpp b/8.x/mk/src/store.cpp
new file mode 100755 (executable)
index 0000000..b700e86
--- /dev/null
@@ -0,0 +1,543 @@
+// store.cpp --
+// $Id: store.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Storage management and several other loose ends
+ */
+
+#include "header.h"
+#include "handler.h"  // 19990906
+#include "store.h"
+#include "field.h"
+#include "persist.h"
+#include "format.h"   // 19990906
+
+#include "mk4io.h"    // 19991104
+
+#if !q4_INLINE
+#include "store.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Dependencies::c4_Dependencies() {
+  _refs.SetSize(0, 3); // a little optimization
+}
+
+c4_Dependencies::~c4_Dependencies(){}
+
+void c4_Dependencies::Add(c4_Sequence *seq_) {
+  for (int i = 0; i < _refs.GetSize(); ++i)
+    d4_assert(_refs.GetAt(i) != seq_);
+
+  _refs.Add(seq_);
+}
+
+bool c4_Dependencies::Remove(c4_Sequence *seq_) {
+  int n = _refs.GetSize() - 1;
+  d4_assert(n >= 0);
+
+  for (int i = 0; i <= n; ++i)
+  if (_refs.GetAt(i) == seq_) {
+    _refs.SetAt(i, _refs.GetAt(n));
+    _refs.SetSize(n);
+    return n > 0;
+  }
+
+  d4_assert(0); // dependency not found
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Notifier::~c4_Notifier() {
+  if (_type > kNone && _origin->GetDependencies()) {
+    c4_PtrArray &refs = _origin->GetDependencies()->_refs;
+
+    for (int i = 0; i < refs.GetSize(); ++i) {
+      c4_Sequence *seq = (c4_Sequence*)refs.GetAt(i);
+      d4_assert(seq != 0);
+
+      seq->PostChange(*this);
+
+      if (_chain && _chain->_origin == seq) {
+        c4_Notifier *next = _chain->_next;
+        _chain->_next = 0;
+
+        delete _chain;
+
+        _chain = next;
+      }
+    }
+  }
+
+  d4_assert(!_chain);
+  d4_assert(!_next);
+}
+
+void c4_Notifier::StartSetAt(int index_, c4_Cursor &cursor_) {
+  _type = kSetAt;
+  _index = index_;
+  _cursor = &cursor_;
+
+  Notify();
+}
+
+void c4_Notifier::StartInsertAt(int i_, c4_Cursor &cursor_, int n_) {
+  _type = kInsertAt;
+  _index = i_;
+  _cursor = &cursor_;
+  _count = n_;
+
+  Notify();
+}
+
+void c4_Notifier::StartRemoveAt(int index_, int count_) {
+  _type = kRemoveAt;
+  _index = index_;
+  _count = count_;
+
+  Notify();
+}
+
+void c4_Notifier::StartMove(int from_, int to_) {
+  _type = kMove;
+  _index = from_;
+  _count = to_;
+
+  Notify();
+}
+
+void c4_Notifier::StartSet(int i_, int propId_, const c4_Bytes &buf_) {
+  _type = kSet;
+  _index = i_;
+  _propId = propId_;
+  _bytes = &buf_;
+
+  Notify();
+}
+
+void c4_Notifier::Notify() {
+  d4_assert(_origin->GetDependencies() != 0);
+  c4_PtrArray &refs = _origin->GetDependencies()->_refs;
+
+  int n = refs.GetSize();
+  d4_assert(n > 0);
+
+  c4_Notifier **rover = &_chain;
+
+  for (int i = 0; i < n; ++i) {
+    c4_Sequence *seq = (c4_Sequence*)refs.GetAt(i);
+    d4_assert(seq != 0);
+
+    c4_Notifier *ptr = seq->PreChange(*this);
+    if (ptr) {
+      d4_assert(ptr->_origin == seq);
+
+      d4_assert(! *rover);
+      *rover = ptr;
+      rover = &ptr->_next;
+    }
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_Storage
+ *
+ *  Manager for persistent storage of view structures.
+ *
+ *  The storage class uses a view, with additional functionality to be able 
+ *  to store and reload the data it contains (including nested subviews).
+ *
+ *  By default, data is loaded on demand, i.e. whenever data which has
+ *  not yet been referenced is used for the first time.  Loading is limited
+ *  to the lifetime of this storage object, since the storage object carries
+ *  the file descriptor with it that is needed to access the data file.
+ *
+ *  To save changes, call the Commit member.  This is the only time
+ *  that data is written to file - when using a read-only file simply avoid
+ *  calling Commit.
+ *
+ *  The LoadFromStream and SaveToStream members can be used to
+ *  serialize the contents of this storage row using only sequential I/O
+ *  (no seeking, only read or write calls).
+ *
+ *  The data storage mechanism implementation provides fail-safe operation:
+ *  if anything prevents Commit from completing its task, the last
+ *  succesfully committed version of the saved data will be recovered on
+ *  the next open. This also includes changes made to the table structure. 
+ *
+ *  The following code creates a view with 1 row and stores it on file:
+ * @code
+ *    c4_StringProp pName ("Name");
+ *    c4_IntProp pAge ("Age");
+ *
+ *    c4_Storage storage ("myfile.dat", true);
+ *    c4_View myView = storage.GetAs("Musicians[Name:S,Age:I]");
+ *
+ *    myView.Add(pName ["John Williams"] + pAge [43]);
+ *
+ *    storage.Commit();
+ * @endcode
+ */
+
+c4_Storage::c4_Storage() {
+  // changed to r/o, now that commits don't crash on it anymore
+  Initialize(*d4_new c4_Strategy, true, 0);
+}
+
+c4_Storage::c4_Storage(c4_Strategy &strategy_, bool owned_, int mode_) {
+  Initialize(strategy_, owned_, mode_);
+  Persist()->LoadAll();
+}
+
+c4_Storage::c4_Storage(const char *fname_, int mode_) {
+  c4_FileStrategy *strat = d4_new c4_FileStrategy;
+  strat->DataOpen(fname_, mode_);
+
+  Initialize(*strat, true, mode_);
+  if (strat->IsValid())
+    Persist()->LoadAll();
+}
+
+c4_Storage::c4_Storage(const c4_View &root_) {
+  if (root_.Persist() != 0)
+  // only restore if view was indeed persistent
+    *(c4_View*)this = root_;
+  else
+  // if this was not possible, start with a fresh empty storage
+    Initialize(*d4_new c4_Strategy, true, 0);
+}
+
+c4_Storage::~c4_Storage() {
+  // cannot unmap here, because there may still be an autocommit pending
+  //((c4_HandlerSeq*) _seq)->UnmapAll();
+}
+
+void c4_Storage::Initialize(c4_Strategy &strategy_, bool owned_, int mode_) {
+  c4_Persist *pers = d4_new c4_Persist(strategy_, owned_, mode_);
+  c4_HandlerSeq *seq = d4_new c4_HandlerSeq(pers);
+  seq->DefineRoot();
+  *(c4_View*)this = seq;
+  pers->SetRoot(seq);
+}
+
+/// Get or set a named view in this storage object
+c4_ViewRef c4_Storage::View(const char *name_) {
+  /*
+  The easy solution would seem to be:
+
+  c4_ViewProp prop (name_);
+  return prop (Contents());
+
+  But this does not work, because the return value would point to
+  an object allocated on the stack.
+
+  Instead, make sure the view *has* such a property, and use the
+  one inside the c4_Handler for it (since this will stay around).
+   */
+
+  //  int n = _root->PropIndex(c4_ViewProp (name_));
+
+  c4_ViewProp prop(name_);
+  int n = AddProperty(prop);
+  d4_assert(n >= 0);
+
+  // the following is an expression of the form "property (rowref)"
+  return NthProperty(n)(GetAt(0));
+}
+
+/// Get a named view, redefining it to match the given structure
+c4_View c4_Storage::GetAs(const char *description_) {
+  d4_assert(description_ != 0);
+
+  // Dec 2001: now that GetAs is being used so much more frequently, 
+  // add a quick check to see whether restructuring is needed at all
+  const char *q = strchr(description_, '[');
+  if (q != 0) {
+    c4_String vname(description_, q - description_);
+    const char *d = Description(vname);
+    if (d != 0) {
+      c4_String desc(d);
+      if (("[" + desc + "]").CompareNoCase(q) == 0)
+        return View(vname);
+    }
+  }
+
+  c4_Field *field = d4_new c4_Field(description_);
+  d4_assert(field != 0);
+
+  d4_assert(! *description_);
+
+  c4_String name = field->Name();
+  d4_assert(!name.IsEmpty());
+
+  c4_Field &curr = Persist()->Root().Definition();
+
+  c4_String newField = "," + field->Description();
+  bool keep = newField.Find('[') >= 0;
+
+  c4_String newDef;
+
+  // go through all subfields
+  for (int i = 0; i < curr.NumSubFields(); ++i) {
+    c4_Field &of = curr.SubField(i);
+    if (of.Name().CompareNoCase(name) == 0) {
+      if (field->IsRepeating())
+        newDef += newField;
+      // else new is not a repeating entry, so drop this entire field
+
+      newField.Empty(); // don't append it later on
+      continue;
+    }
+
+    newDef += "," + of.Description(); // keep original field
+  }
+
+  if (keep)
+  // added 19990824 ignore if deletion
+    newDef += newField;
+  // appends new definition if not found earlier
+
+  delete field;
+
+  const char *p = newDef;
+  SetStructure(*p ? ++p: p); // skip the leading comma
+
+  if (!keep)
+  // 19990916: avoid adding an empty view again
+    return c4_View();
+
+  return View(name);
+}
+
+/// Define the complete view structure of the storage
+void c4_Storage::SetStructure(const char *description_) {
+  d4_assert(description_ != 0);
+
+  if (description_ != Description()) {
+    c4_String s = "[" + c4_String(description_) + "]";
+    description_ = s;
+
+    c4_Field *field = d4_new c4_Field(description_);
+    d4_assert(! *description_);
+
+    d4_assert(field != 0);
+    Persist()->Root().Restructure(*field, false);
+  }
+}
+
+/// Return the strategy object associated with this storage
+c4_Strategy &c4_Storage::Strategy()const {
+  return Persist()->Strategy();
+}
+
+/// Return a description of the view structure (default is all)
+const char *c4_Storage::Description(const char *name_) {
+  if (name_ == 0 ||  *name_ == 0)
+    return c4_View::Description();
+
+  c4_View v = View(name_);
+  return v.Description();
+}
+
+/// Define the storage to use for differential commits
+bool c4_Storage::SetAside(c4_Storage &aside_) {
+  c4_Persist *pers = Persist();
+  bool f = pers->SetAside(aside_);
+  // adjust our copy when the root view has been replaced
+  *(c4_View*)this = &pers->Root();
+  return f;
+}
+
+/// Return storage used for differential commits, or null
+c4_Storage *c4_Storage::GetAside()const {
+  return Persist()->GetAside();
+}
+
+/// Flush pending changes to file right now
+bool c4_Storage::Commit(bool full_) {
+  return Strategy().IsValid() && Persist()->Commit(full_);
+}
+
+/** (Re)initialize for on-demand loading
+ *
+ *  Calling Rollback will cancel all uncommitted changes.
+ */
+bool c4_Storage::Rollback(bool full_) {
+  c4_Persist *pers = Persist();
+  bool f = Strategy().IsValid() && pers->Rollback(full_);
+  // adjust our copy when the root view has been replaced
+  *(c4_View*)this = &pers->Root();
+  return f;
+}
+
+/// Set storage up to always call Commit in the destructor
+bool c4_Storage::AutoCommit(bool flag_) {
+  return Persist()->AutoCommit(flag_);
+}
+
+/// Load contents from the specified input stream
+bool c4_Storage::LoadFrom(c4_Stream &stream_) {
+  c4_HandlerSeq *newRoot = c4_Persist::Load(&stream_);
+  if (newRoot == 0)
+    return false;
+
+  // fix commit-after-load bug, by using a full view copy
+  // this is inefficient, but avoids mapping/strategy problems
+  c4_View temp(newRoot);
+
+  SetSize(0);
+  SetStructure(temp.Description());
+  InsertAt(0, temp);
+
+  return true;
+}
+
+/// Save contents to the specified output stream
+void c4_Storage::SaveTo(c4_Stream &stream_) {
+  c4_Persist::Save(&stream_, Persist()->Root());
+}
+
+t4_i32 c4_Storage::FreeSpace(t4_i32 *bytes_) {
+  return Persist()->FreeBytes(bytes_);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_DerivedSeq::c4_DerivedSeq(c4_Sequence &seq_): _seq(seq_) {
+  _seq.Attach(this);
+}
+
+c4_DerivedSeq::~c4_DerivedSeq() {
+  _seq.Detach(this);
+}
+
+int c4_DerivedSeq::RemapIndex(int index_, const c4_Sequence *seq_)const {
+  return seq_ == this ? index_ : _seq.RemapIndex(index_, seq_);
+}
+
+int c4_DerivedSeq::NumRows()const {
+  return _seq.NumRows();
+}
+
+int c4_DerivedSeq::NumHandlers()const {
+  return _seq.NumHandlers();
+}
+
+c4_Handler &c4_DerivedSeq::NthHandler(int colNum_)const {
+  return _seq.NthHandler(colNum_);
+}
+
+const c4_Sequence *c4_DerivedSeq::HandlerContext(int colNum_)const {
+  return _seq.HandlerContext(colNum_);
+}
+
+int c4_DerivedSeq::AddHandler(c4_Handler *handler_) {
+  return _seq.AddHandler(handler_);
+}
+
+c4_Handler *c4_DerivedSeq::CreateHandler(const c4_Property &prop_) {
+  return _seq.CreateHandler(prop_);
+}
+
+void c4_DerivedSeq::SetNumRows(int size_) {
+  _seq.SetNumRows(size_);
+}
+
+c4_Notifier *c4_DerivedSeq::PreChange(c4_Notifier &nf_) {
+  if (!GetDependencies())
+    return 0;
+
+  c4_Notifier *chg = d4_new c4_Notifier(this);
+
+  switch (nf_._type) {
+    case c4_Notifier::kSetAt: chg->StartSetAt(nf_._index,  *nf_._cursor);
+    break;
+
+    case c4_Notifier::kSet: chg->StartSet(nf_._index, nf_._propId,  *nf_._bytes)
+      ;
+    break;
+
+    case c4_Notifier::kInsertAt: chg->StartInsertAt(nf_._index,  *nf_._cursor,
+      nf_._count);
+    break;
+
+    case c4_Notifier::kRemoveAt: chg->StartRemoveAt(nf_._index, nf_._count);
+    break;
+
+    case c4_Notifier::kMove: chg->StartMove(nf_._index, nf_._count);
+    break;
+  }
+
+  return chg;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_StreamStrategy::c4_StreamStrategy(t4_i32 buflen_): _stream(0), _buffer
+  (d4_new t4_byte[buflen_]), _buflen(buflen_), _position(0) {
+  _mapStart = _buffer;
+  _dataSize = buflen_;
+}
+
+c4_StreamStrategy::c4_StreamStrategy(c4_Stream *stream_): _stream(stream_),
+  _buffer(0), _buflen(0), _position(0){}
+
+c4_StreamStrategy::~c4_StreamStrategy() {
+  _mapStart = 0;
+  _dataSize = 0;
+
+  if (_buffer != 0)
+    delete [] _buffer;
+}
+
+bool c4_StreamStrategy::IsValid()const {
+  return true;
+}
+
+int c4_StreamStrategy::DataRead(t4_i32 pos_, void *buffer_, int length_) {
+  if (_buffer != 0) {
+    d4_assert(pos_ <= _buflen);
+    _position = pos_ + _baseOffset;
+
+    if (length_ > _buflen - _position)
+      length_ = _buflen - _position;
+    if (length_ > 0)
+      memcpy(buffer_, _buffer + _position, length_);
+  } else {
+    d4_assert(_position == pos_ + _baseOffset);
+    length_ = _stream != 0 ? _stream->Read(buffer_, length_): 0;
+  }
+
+  _position += length_;
+  return length_;
+}
+
+void c4_StreamStrategy::DataWrite(t4_i32 pos_, const void *buffer_, int length_)
+  {
+  if (_buffer != 0) {
+    d4_assert(pos_ <= _buflen);
+    _position = pos_ + _baseOffset;
+
+    int n = length_;
+    if (n > _buflen - _position)
+      n = _buflen - _position;
+    if (n > 0)
+      memcpy(_buffer + _position, buffer_, n);
+  } else {
+    d4_assert(_position == pos_ + _baseOffset);
+    if (_stream != 0 && !_stream->Write(buffer_, length_))
+      ++_failure;
+  }
+
+  _position += length_;
+}
+
+t4_i32 c4_StreamStrategy::FileSize() {
+  return _position;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/store.h b/8.x/mk/src/store.h
new file mode 100755 (executable)
index 0000000..b7a70f7
--- /dev/null
@@ -0,0 +1,112 @@
+// store.h --
+// $Id: store.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Definition of auxiliary storage management classes
+ */
+
+#ifndef __STORE_H__
+#define __STORE_H__
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Dependencies {
+    c4_PtrArray _refs;
+
+  public:
+    c4_Dependencies();
+    ~c4_Dependencies();
+
+    void Add(c4_Sequence *seq_);
+    bool Remove(c4_Sequence *seq_);
+
+    friend class c4_Notifier;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_Notifier {
+    c4_Sequence *_origin;
+    c4_Notifier *_chain;
+    c4_Notifier *_next;
+
+  public:
+    enum {
+        kNone, kSetAt, kInsertAt, kRemoveAt, kMove, kSet, kLimit
+    };
+
+    c4_Notifier(c4_Sequence *origin_);
+    ~c4_Notifier();
+
+    bool HasDependents()const;
+
+    void StartSetAt(int index_, c4_Cursor &cursor_);
+    void StartInsertAt(int index_, c4_Cursor &cursor_, int count_);
+    void StartRemoveAt(int index_, int count_);
+    void StartMove(int from_, int to_);
+    void StartSet(int index_, int propId_, const c4_Bytes &buf_);
+
+    int _type;
+    int _index;
+    int _propId;
+    int _count;
+    c4_Cursor *_cursor;
+    const c4_Bytes *_bytes;
+
+  private:
+    void Notify();
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_DerivedSeq: public c4_Sequence {
+  protected:
+    c4_Sequence &_seq;
+
+  protected:
+    c4_DerivedSeq(c4_Sequence &seq_);
+    virtual ~c4_DerivedSeq();
+
+  public:
+    virtual int RemapIndex(int, const c4_Sequence*)const;
+
+    virtual int NumRows()const;
+    virtual void SetNumRows(int size_);
+
+    virtual int NumHandlers()const;
+    virtual c4_Handler &NthHandler(int)const;
+    virtual const c4_Sequence *HandlerContext(int)const;
+    virtual int AddHandler(c4_Handler*);
+    virtual c4_Handler *CreateHandler(const c4_Property &);
+
+    virtual c4_Notifier *PreChange(c4_Notifier &nf_);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_StreamStrategy: public c4_Strategy {
+    c4_Stream *_stream;
+    t4_byte *_buffer;
+    t4_i32 _buflen;
+    t4_i32 _position;
+  public:
+    c4_StreamStrategy(t4_i32 buflen_);
+    c4_StreamStrategy(c4_Stream *stream_);
+    virtual ~c4_StreamStrategy();
+
+    virtual bool IsValid()const;
+    virtual int DataRead(t4_i32 pos_, void *buffer_, int length_);
+    virtual void DataWrite(t4_i32 pos_, const void *buffer_, int length_);
+    virtual t4_i32 FileSize();
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "store.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/8.x/mk/src/store.inl b/8.x/mk/src/store.inl
new file mode 100755 (executable)
index 0000000..6bdd3d8
--- /dev/null
@@ -0,0 +1,20 @@
+// store.inl --
+// $Id: store.inl 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Inlined members of the storage management classes
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Notifier
+
+d4_inline c4_Notifier::c4_Notifier (c4_Sequence* origin_)
+  : _origin (origin_), _chain (0), _next (0),
+    _type (kNone), _index (0), _propId (0), _count (0), 
+    _cursor (0), _bytes (0)
+{
+  d4_assert(_origin != 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/string.cpp b/8.x/mk/src/string.cpp
new file mode 100755 (executable)
index 0000000..55c5c54
--- /dev/null
@@ -0,0 +1,274 @@
+// string.cpp --
+// $Id: string.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * yet another string implementation
+ */
+
+#include "header.h"
+
+/* these definitions could be used instead of header.h ...
+#define q4_UNIV 1
+#define d4_inline
+#include "mk4str.h"
+#define d4_reentrant
+#define d4_assert(x)
+ */
+
+#if q4_UNIV // until end of source
+/////////////////////////////////////////////////////////////////////////////
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef _AIX
+#include <strings.h>
+#endif 
+
+#if !q4_INLINE
+#include "mk4str.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_WINCE
+
+// MS C/C++ has this handy stricmp: a case-insensitive version of strcmp
+// This version only works with 7-bit ASCII characters 0x00 through 0x7F
+
+static int strcasecmp(const char *p1, const char *p2) {
+  int c1, c2;
+
+#ifdef d4_USE_UNOPTIMIZED_CODE
+  do {
+    c1 = tolower(*p1++);
+    c2 = tolower(*p2++);
+  } while (c1 != 0 && c1 == c2);
+#else 
+  do {
+    c1 =  *p1++;
+    c2 =  *p2++;
+  } while (c1 != 0 && (c1 == c2 || tolower(c1) == tolower(c2)));
+
+  c1 = tolower(c1);
+  c2 = tolower(c2);
+#endif 
+
+  return c1 - c2;
+}
+
+const char *strrchr(const char *p, char ch) {
+  const char *q = 0;
+  while (*p)
+    if (*p++ == ch)
+      q = p;
+  return q;
+}
+
+#elif q4_MSVC || q4_WATC || q4_BORC || (q4_MWCW && __MWERKS__ < 0x3000)
+#define strcasecmp stricmp
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//  This string class implement functionality which is very similar to that
+//  provided by the CString class of the Microsoft Framework Classes (MFC).
+//  
+//  There are also several major differences:
+//  
+//    1) This class uses reference counting to avoid massive copying.
+//       Consequently, function return as well as assignment is very fast.
+//    2) Strings of up to 255 bytes can contain any data, even null bytes.
+//       Longer strings can not contain any null bytes past position 255.
+//    3) This class can produce a "const char*" without overhead, but it
+//       can also cast to the byte-counted "const unsigned char*" used
+//       everywhere in Macintosh applications (as StringPtr, Str255, etc).
+//    4) This source code is not derived from Microsoft's code in any way.
+//    
+//  A good way to use this class, is to always use c4_String for function
+//  return values and "const [unsigned] char*" for all parameters. Together,
+//  these two choices will remove the need for nearly any messy casts.
+//
+//  Note: MFC 4.0 has now adopted refcounts, and is a good alternative to
+//      this code (but a bit bulkier, it also has Unicode support).
+
+// 2001-11-27, stop releasing nullvec, to allow MT use
+d4_reentrant static unsigned char *nullVec = 0;
+
+static int fInc(unsigned char *p) {
+  ++ *p;
+  if (*p)
+    return 1;
+
+  -- *p;
+  return 0;
+}
+
+inline static void fDec(unsigned char *p) {
+  -- *p;
+  if (! *p && p != nullVec)
+    delete [] p;
+}
+
+c4_String::c4_String(char ch, int n /* =1 */) {
+  if (n < 0)
+    n = 0;
+
+  _value = new unsigned char[n + 3];
+
+  _value[0] = 1; // see Init() member
+  memset(_value + 2, ch, n);
+  _value[1] = (unsigned char)(n <= 255 ? n : 255);
+  _value[n + 2] = 0;
+}
+
+c4_String::c4_String(const char *p) {
+  Init(p, p != 0 ? strlen(p): 0);
+}
+
+c4_String::c4_String(const c4_String &s) {
+  if (fInc(s._value))
+    _value = s._value;
+  else
+    Init(s.Data(), s.GetLength());
+}
+
+c4_String::~c4_String() {
+  fDec(_value);
+}
+
+const c4_String &c4_String::operator = (const c4_String &s) {
+  unsigned char *oldVal = _value;
+  if (fInc(s._value))
+    _value = s._value;
+  else
+    Init(s.Data(), s.GetLength());
+  fDec(oldVal);
+
+  return  *this;
+}
+
+c4_String operator + (const c4_String &a, const c4_String &b) {
+  const int aCnt = a.GetLength();
+  int sum = aCnt + b.GetLength();
+
+  c4_String result('\0', sum); // set up correct size, then fix contents
+  memcpy(result._value + 2, a.Data(), aCnt);
+  memcpy(result._value + 2+aCnt, b.Data(), sum - aCnt);
+
+  return result;
+}
+
+void c4_String::Init(const void *p, int n) {
+  if (p == NULL || n <= 0) {
+    //  Optimization to significantly speed-up init of empty strings:
+    //  share a common entry, which avoids *LOTS* of tiny mem allocs.
+    //  
+    //  Especially "new [...] c4_String" will benefit a lot, as well as:
+    //  
+    //    c4_String s;    // this would have caused a new allocation
+    //    s = ...     // then immediately drops the count back
+    //  
+    //  2001/11/27: changed to never release this empty vector, for MT use
+    //                 the new logic is to completely ignore its ref count
+
+    if (!nullVec) {
+      // obtain a valid new empty string buffer to keep around
+      unsigned char *nv = new unsigned char[3];
+      nv[0] = nv[1] = nv[2] = 0;
+      // only set static value after item is fully inited (avoid MT race)
+      nullVec = nv;
+    }
+
+    _value = nullVec; // use this buffer as our empty string
+    return ; // done... that was quick, wasn't it?
+  }
+
+  _value = new unsigned char[n + 3];
+
+  _value[0] = 1; // many assumptions here: set the reference count to 1
+
+  if (n > 0)
+    memcpy(_value + 2, p, n);
+  _value[1] = (unsigned char)(n <= 255 ? n : 255);
+  _value[n + 2] = 0;
+}
+
+int c4_String::FullLength()const {
+  int n = _value[1];
+  return n < 255 ? n : n + strlen((const char*)_value + 2+255);
+}
+
+c4_String c4_String::Mid(int nFirst, int nCount)const {
+  if (nFirst >= GetLength())
+    return c4_String();
+
+  if (nFirst + nCount > GetLength())
+    nCount = GetLength() - nFirst;
+
+  if (nFirst == 0 && nCount == GetLength())
+    return  *this;
+
+  return c4_String(Data() + nFirst, nCount);
+}
+
+c4_String c4_String::Left(int nCount)const {
+  if (nCount >= GetLength())
+    return  *this;
+
+  return c4_String(Data(), nCount);
+}
+
+c4_String c4_String::Right(int nCount)const {
+  if (nCount >= GetLength())
+    return  *this;
+
+  return c4_String(Data() + GetLength() - nCount, nCount);
+}
+
+bool operator == (const c4_String &a, const c4_String &b) {
+  return a._value == b._value || a.GetLength() == b.GetLength() && memcmp
+    (a.Data(), b.Data(), a.GetLength()) == 0;
+}
+
+int c4_String::Compare(const char *str)const {
+  return Data() == str ? 0 : strcmp(Data(), str);
+}
+
+int c4_String::CompareNoCase(const char *str)const {
+  return Data() == str ? 0 : strcasecmp(Data(), str);
+}
+
+int c4_String::Find(char ch)const {
+  const char *p = strchr(Data(), ch);
+  return p != 0 ? p - Data():  - 1;
+}
+
+int c4_String::ReverseFind(char ch)const {
+  const char *p = strrchr(Data(), ch);
+  return p != 0 ? p - Data():  - 1;
+}
+
+int c4_String::FindOneOf(const char *set)const {
+  const char *p = strpbrk(Data(), set);
+  return p != 0 ? p - Data():  - 1;
+}
+
+int c4_String::Find(const char *sub)const {
+  const char *p = strstr(Data(), sub);
+  return p != 0 ? p - Data():  - 1;
+}
+
+c4_String c4_String::SpanIncluding(const char *set)const {
+  return Left(strspn(Data(), set));
+}
+
+c4_String c4_String::SpanExcluding(const char *set)const {
+  return Left(strcspn(Data(), set));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // q4_UNIV
diff --git a/8.x/mk/src/table.cpp b/8.x/mk/src/table.cpp
new file mode 100755 (executable)
index 0000000..58b5475
--- /dev/null
@@ -0,0 +1,148 @@
+// table.cpp --
+// $Id: table.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Loose ends, these should be moved
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "store.h"
+#include "field.h"
+#include "format.h"
+#include "persist.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// Implemented in this file
+
+class c4_Bytes;
+class c4_HandlerSeq;
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_Bytes
+ *
+ *  Generic data buffer, with optional automatic clean up.
+ *
+ *  These objects are used to pass around untyped data without concern about
+ *  clean-up.  They know whether the bytes need to be de-allocated when these
+ *  objects go out of scope.  Small amounts of data are stored in the object.
+ *
+ *  Objects of this class are used a lot within Metakit to manipulate its own
+ *  data items generically.  The c4_BytesProp class allows storing binary
+ *  data explicitly in a file.  If such data files must be portable, then the 
+ *  application itself must define a generic format to deal with byte order.
+ *
+ *  How to store an object in binary form in a row (this is not portable):
+ * @code
+ *    struct MyStruct { ... };
+ *    MyStruct something;
+ *  
+ *    c4_BytesProp pData ("Data");
+ *    c4_Row row;
+ *  
+ *    pData (row) = c4_Bytes (&something, sizeof something);
+ * @endcode
+ */
+
+/// Construct an object with contents, optionally as a copy
+c4_Bytes::c4_Bytes(const void *buf_, int len_, bool copy_): _size(len_), _copy
+  (copy_) {
+    _contents = (t4_byte*)buf_; // moved out of intializers for DEC CXX 5.7
+    if (_copy)
+      _MakeCopy();
+}
+
+/// Copy constructor   
+c4_Bytes::c4_Bytes(const c4_Bytes &src_): _size(src_._size), _copy(src_._copy) {
+  _contents = src_._contents; // moved out of intializers for DEC CXX 5.7
+  if (_copy || _contents == src_._buffer)
+    _MakeCopy();
+}
+
+/// Assignment, this may make a private copy of contents
+c4_Bytes &c4_Bytes::operator = (const c4_Bytes &src_) {
+  if (&src_ != this) {
+    _LoseCopy();
+
+    _contents = src_._contents;
+    _size = src_._size;
+    _copy = src_._copy;
+
+    if (_copy || _contents == src_._buffer)
+      _MakeCopy();
+  }
+
+  return  *this;
+}
+
+/// Swap the contents and ownership of two byte objects
+void c4_Bytes::Swap(c4_Bytes &bytes_) {
+  t4_byte *p = _contents;
+  int s = _size;
+  bool c = _copy;
+
+  _contents = bytes_._contents;
+  _size = bytes_._size;
+  _copy = bytes_._copy;
+
+  bytes_._contents = p;
+  bytes_._size = s;
+  bytes_._copy = c;
+
+  // if either one is using its local buffer, swap those too
+  if (_contents == bytes_._buffer || p == _buffer) {
+    t4_byte t[sizeof _buffer];
+
+    memcpy(t, _buffer, sizeof _buffer);
+    memcpy(_buffer, bytes_._buffer, sizeof _buffer);
+    memcpy(bytes_._buffer, t, sizeof _buffer);
+
+    if (_contents == bytes_._buffer)
+      _contents = _buffer;
+
+    if (bytes_._contents == _buffer)
+      bytes_._contents = bytes_._buffer;
+  }
+}
+
+/// Define contents as a freshly allocated buffer of given size
+t4_byte *c4_Bytes::SetBuffer(int length_) {
+  /* No substantial improvement measured:
+  Perhaps keep a correctly sized c4_Bytes object in each property?
+  It means c4_...Ref objects would need to store a pointer, not an id.
+
+  if (length_ == _size)
+  return _contents; // no work needed, get out fast
+   */
+  _LoseCopy();
+
+  _size = length_;
+  _copy = _size > (int)sizeof _buffer;
+
+  return _contents = _copy ? d4_new t4_byte[_size]: _buffer;
+}
+
+/// Allocate a buffer and fills its contents with zero bytes
+t4_byte *c4_Bytes::SetBufferClear(int length_) {
+  return (t4_byte*)memset(SetBuffer(length_), 0, length_);
+}
+
+void c4_Bytes::_MakeCopy() {
+  d4_assert(_contents != 0);
+
+  _copy = _size > (int)sizeof _buffer;
+
+  if (_size > 0)
+    _contents = (t4_byte*)memcpy(_copy ? d4_new t4_byte[_size]: _buffer,
+      _contents, _size);
+}
+
+/// Return true if the contents of both objects are equal
+bool operator == (const c4_Bytes &a_, const c4_Bytes &b_) {
+  return a_._contents == b_._contents || (a_._size == b_._size && memcmp
+    (a_._contents, b_._contents, a_._size) == 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/univ.cpp b/8.x/mk/src/univ.cpp
new file mode 100755 (executable)
index 0000000..2fd3ebb
--- /dev/null
@@ -0,0 +1,202 @@
+// univ.cpp --
+// $Id: univ.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * A simple implementation of dynamic arrays
+ */
+
+#include "header.h"
+
+#if q4_UNIV // until end of source
+/////////////////////////////////////////////////////////////////////////////
+
+#include <stdlib.h>   // malloc
+
+#if !q4_INLINE
+#include "univ.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_UNIX || __MINGW32__
+#define _strdup strdup
+#elif !q4_BORC && !q4_MSVC && !q4_WATC && !(q4_MWCW && defined(_WIN32)) && \
+!(q4_MWCW && __MWERKS__ >= 0x3000)
+
+static char *_strdup(const char *p) {
+  if (!p)
+    return 0;
+
+  char *s = (char*)malloc(strlen(p) + 1);
+  return strcpy(s, p);
+}
+
+#endif 
+
+//  The Borland C++ RTL does not want file handle objects to cross
+//  DLL boundaries, so we add special fopen/fclose hooks to this DLL.
+
+#if q4_BORC
+#include <stdio.h>
+
+#if q4_WIN32
+__declspec(dllexport)FILE *
+#else 
+FILE *__export 
+#endif 
+f4_FileOpenInDLL(const char *name_, const char *mode_) {
+  return fopen(name_, mode_);
+}
+
+#if q4_WIN32
+__declspec(dllexport)
+#else 
+int __export 
+#endif 
+f4_FileCloseInDLL(FILE *file_) {
+  return fclose(file_);
+}
+
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_BaseArray
+
+c4_BaseArray::c4_BaseArray(): _data(0), _size(0){}
+
+c4_BaseArray::~c4_BaseArray() {
+  SetLength(0);
+}
+
+void c4_BaseArray::SetLength(int nNewSize) {
+  // 2001-11-25: use more granular allocation, as optimization
+  const int bits = 6;
+
+  if (((_size - 1) ^ (nNewSize - 1)) >> bits) {
+    const int n = (nNewSize + (1 << bits) - 1) & - (1 << bits);
+    _data = _data == 0 ? n == 0 ? (char*)0: (char*)malloc(n): n == 0 ? (free
+      (_data), (char*)0): (char*)realloc(_data, n);
+  }
+
+  d4_assert(_data != 0 || nNewSize == 0);
+
+  int n = _size;
+  _size = nNewSize;
+
+  if (nNewSize > n)
+    memset(GetData(n), 0, nNewSize - n);
+}
+
+void c4_BaseArray::Grow(int nIndex) {
+  if (nIndex > _size)
+    SetLength(nIndex);
+}
+
+void c4_BaseArray::InsertAt(int nIndex, int nCount) {
+  SetLength(_size + nCount);
+
+  int to = nIndex + nCount;
+  if (_size > to)
+    d4_memmove(GetData(to), GetData(nIndex), _size - to);
+}
+
+void c4_BaseArray::RemoveAt(int nIndex, int nCount) {
+  int from = nIndex + nCount;
+  if (_size > from)
+    d4_memmove(GetData(nIndex), GetData(from), _size - from);
+
+  SetLength(_size - nCount);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_DWordArray
+
+int c4_DWordArray::Add(t4_i32 newElement) {
+  int n = GetSize();
+  _vector.Grow(Off(n + 1));
+  SetAt(n, newElement);
+  return n;
+}
+
+void c4_DWordArray::InsertAt(int nIndex, t4_i32 newElement, int nCount) {
+  _vector.InsertAt(Off(nIndex), nCount *sizeof(t4_i32));
+
+  while (--nCount >= 0)
+    SetAt(nIndex++, newElement);
+}
+
+void c4_DWordArray::RemoveAt(int nIndex, int nCount) {
+  _vector.RemoveAt(Off(nIndex), nCount *sizeof(t4_i32));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_PtrArray
+
+int c4_PtrArray::Add(void *newElement) {
+  int n = GetSize();
+  _vector.Grow(Off(n + 1));
+  SetAt(n, newElement);
+  return n;
+}
+
+void c4_PtrArray::InsertAt(int nIndex, void *newElement, int nCount) {
+  _vector.InsertAt(Off(nIndex), nCount *sizeof(void*));
+
+  while (--nCount >= 0)
+    SetAt(nIndex++, newElement);
+}
+
+void c4_PtrArray::RemoveAt(int nIndex, int nCount) {
+  _vector.RemoveAt(Off(nIndex), nCount *sizeof(void*));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_StringArray
+
+c4_StringArray::~c4_StringArray() {
+  SetSize(0);
+}
+
+void c4_StringArray::SetSize(int nNewSize, int) {
+  int i = nNewSize;
+
+  while (i < GetSize())
+    SetAt(i++, 0);
+
+  _ptrs.SetSize(nNewSize);
+
+  while (i < GetSize())
+    _ptrs.SetAt(i++, "");
+}
+
+void c4_StringArray::SetAt(int nIndex, const char *newElement) {
+  char *s = (char*)_ptrs.GetAt(nIndex);
+  if (s &&  *s)
+    free(s);
+
+  _ptrs.SetAt(nIndex, newElement &&  *newElement ? _strdup(newElement): "");
+}
+
+int c4_StringArray::Add(const char *newElement) {
+  int n = _ptrs.Add(0);
+  SetAt(n, newElement);
+  return n;
+}
+
+void c4_StringArray::InsertAt(int nIndex, const char *newElement, int nCount) {
+  _ptrs.InsertAt(nIndex, 0, nCount);
+
+  while (--nCount >= 0)
+    SetAt(nIndex++, newElement);
+}
+
+void c4_StringArray::RemoveAt(int nIndex, int nCount) {
+  for (int i = 0; i < nCount; ++i)
+    SetAt(nIndex + i, 0);
+
+  _ptrs.RemoveAt(nIndex, nCount);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // q4_UNIV
diff --git a/8.x/mk/src/univ.h b/8.x/mk/src/univ.h
new file mode 100755 (executable)
index 0000000..45df0de
--- /dev/null
@@ -0,0 +1,110 @@
+// univ.h --
+// $Id: univ.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Definition of the container classes
+ */
+
+#define q4_UNIV 1
+
+#include "mk4str.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class c4_BaseArray {
+  public:
+    c4_BaseArray();
+    ~c4_BaseArray();
+
+    int GetLength()const;
+    void SetLength(int nNewSize);
+
+    const void *GetData(int nIndex)const;
+    void *GetData(int nIndex);
+
+    void Grow(int nIndex);
+
+    void InsertAt(int nIndex, int nCount);
+    void RemoveAt(int nIndex, int nCount);
+
+  private:
+    char *_data;
+    int _size;
+    //  char _buffer[4];
+};
+
+class c4_PtrArray {
+  public:
+    c4_PtrArray();
+    ~c4_PtrArray();
+
+    int GetSize()const;
+    void SetSize(int nNewSize, int nGrowBy =  - 1);
+
+    void *GetAt(int nIndex)const;
+    void SetAt(int nIndex, const void *newElement);
+    void * &ElementAt(int nIndex);
+
+    int Add(void *newElement);
+
+    void InsertAt(int nIndex, void *newElement, int nCount = 1);
+    void RemoveAt(int nIndex, int nCount = 1);
+
+  private:
+    static int Off(int n_);
+
+    c4_BaseArray _vector;
+};
+
+class c4_DWordArray {
+  public:
+    c4_DWordArray();
+    ~c4_DWordArray();
+
+    int GetSize()const;
+    void SetSize(int nNewSize, int nGrowBy =  - 1);
+
+    t4_i32 GetAt(int nIndex)const;
+    void SetAt(int nIndex, t4_i32 newElement);
+    t4_i32 &ElementAt(int nIndex);
+
+    int Add(t4_i32 newElement);
+
+    void InsertAt(int nIndex, t4_i32 newElement, int nCount = 1);
+    void RemoveAt(int nIndex, int nCount = 1);
+
+  private:
+    static int Off(int n_);
+
+    c4_BaseArray _vector;
+};
+
+class c4_StringArray {
+  public:
+    c4_StringArray();
+    ~c4_StringArray();
+
+    int GetSize()const;
+    void SetSize(int nNewSize, int nGrowBy =  - 1);
+
+    const char *GetAt(int nIndex)const;
+    void SetAt(int nIndex, const char *newElement);
+    //  c4_String& ElementAt(int nIndex);
+
+    int Add(const char *newElement);
+
+    void InsertAt(int nIndex, const char *newElement, int nCount = 1);
+    void RemoveAt(int nIndex, int nCount = 1);
+
+  private:
+    c4_PtrArray _ptrs;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_INLINE
+#include "univ.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/univ.inl b/8.x/mk/src/univ.inl
new file mode 100755 (executable)
index 0000000..640d05d
--- /dev/null
@@ -0,0 +1,126 @@
+// univ.inl --
+// $Id: univ.inl 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Inlined members of the container classes
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_BaseArray
+
+d4_inline int c4_BaseArray::GetLength() const
+{
+  return _size;
+}
+
+d4_inline const void* c4_BaseArray::GetData(int nIndex) const
+{
+  return _data + nIndex;
+}
+
+d4_inline void* c4_BaseArray::GetData(int nIndex)
+{
+  return _data + nIndex;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_PtrArray
+
+d4_inline c4_PtrArray::c4_PtrArray ()
+{ 
+}
+
+d4_inline c4_PtrArray::~c4_PtrArray ()
+{ 
+}
+
+d4_inline int c4_PtrArray::Off(int n_)
+{
+  return n_ * sizeof (void*); 
+}
+
+d4_inline int c4_PtrArray::GetSize() const
+{ 
+  return _vector.GetLength() / sizeof (void*); 
+}
+
+d4_inline void c4_PtrArray::SetSize(int nNewSize, int)
+{ 
+  _vector.SetLength(Off(nNewSize)); 
+}
+
+d4_inline void* c4_PtrArray::GetAt(int nIndex) const
+{ 
+  return *(void* const*) _vector.GetData(Off(nIndex)); 
+}
+
+d4_inline void c4_PtrArray::SetAt(int nIndex, const void* newElement)
+{ 
+  *(const void**) _vector.GetData(Off(nIndex)) = newElement; 
+}
+
+d4_inline void*& c4_PtrArray::ElementAt(int nIndex)
+{ 
+  return *(void**) _vector.GetData(Off(nIndex)); 
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_DWordArray
+
+d4_inline c4_DWordArray::c4_DWordArray ()
+{ 
+}
+
+d4_inline c4_DWordArray::~c4_DWordArray ()
+{ 
+}
+
+d4_inline int c4_DWordArray::Off(int n_)
+{
+  return n_ * sizeof (t4_i32); 
+}
+
+d4_inline int c4_DWordArray::GetSize() const
+{ 
+  return _vector.GetLength() / sizeof (t4_i32); 
+}
+
+d4_inline void c4_DWordArray::SetSize(int nNewSize, int)
+{ 
+  _vector.SetLength(Off(nNewSize)); 
+}
+
+d4_inline t4_i32 c4_DWordArray::GetAt(int nIndex) const
+{ 
+  return *(const t4_i32*) _vector.GetData(Off(nIndex)); 
+}
+
+d4_inline void c4_DWordArray::SetAt(int nIndex, t4_i32 newElement)
+{ 
+  *(t4_i32*) _vector.GetData(Off(nIndex)) = newElement; 
+}
+
+d4_inline t4_i32& c4_DWordArray::ElementAt(int nIndex)
+{ 
+  return *(t4_i32*) _vector.GetData(Off(nIndex)); 
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_StringArray
+
+d4_inline c4_StringArray::c4_StringArray ()
+{ 
+}
+
+d4_inline int c4_StringArray::GetSize() const
+{ 
+  return _ptrs.GetSize(); 
+}
+
+d4_inline const char* c4_StringArray::GetAt(int nIndex) const
+{ 
+  return (const char*) _ptrs.GetAt(nIndex); 
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/view.cpp b/8.x/mk/src/view.cpp
new file mode 100755 (executable)
index 0000000..63a8c60
--- /dev/null
@@ -0,0 +1,1184 @@
+// view.cpp --
+// $Id: view.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Implementation of main classes not involved in persistence
+ */
+
+#include "header.h"
+#include "derived.h"
+#include "custom.h"
+#include "store.h"    // for RelocateRows
+#include "field.h"    // for RelocateRows
+#include "persist.h"
+#include "remap.h"
+
+#if !q4_INLINE
+#include "mk4.inl"
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_ThreadLock
+
+class c4_ThreadLock {
+  public:
+    c4_ThreadLock();
+    ~c4_ThreadLock();
+
+    class Hold {
+      public:
+        Hold();
+        ~Hold();
+    };
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_MULTI
+
+#if q4_WIN32
+
+/*
+ *  On Win32, use a critical section to protect the global symbol table.
+ *  Also uses special thread-safe calls to inc/dec all reference counts.
+ *
+ *  This implementation replaces the previous use of TLS, which cannot
+ *  be used without special tricks in dynamically loaded DLL's, as is
+ *  required for OCX/ActiveX use (which uses LoadLibrary).
+ *
+ *  Note: Could have used MFC's CCriticalSection and CSingleLock classes,
+ *      but the code below is so trivial that it hardly matters.
+ */
+
+#if q4_MSVC && !q4_STRICT
+#pragma warning(disable: 4201) // nonstandard extension used : ...
+#endif 
+#include <windows.h>
+
+static CRITICAL_SECTION gCritSect;
+
+c4_ThreadLock::c4_ThreadLock() {
+  InitializeCriticalSection(&gCritSect);
+}
+
+c4_ThreadLock::~c4_ThreadLock() {
+  DeleteCriticalSection(&gCritSect);
+}
+
+c4_ThreadLock::Hold::Hold() {
+  EnterCriticalSection(&gCritSect);
+}
+
+c4_ThreadLock::Hold::~Hold() {
+  LeaveCriticalSection(&gCritSect);
+}
+
+#else /* q4_WIN32 */
+
+#include <pthread.h>
+
+static pthread_mutex_t gMutex;
+
+d4_inline c4_ThreadLock::c4_ThreadLock() {
+  pthread_mutex_init(&gMutex, 0);
+}
+
+d4_inline c4_ThreadLock::~c4_ThreadLock() {
+  pthread_mutex_destroy(&gMutex);
+}
+
+d4_inline c4_ThreadLock::Hold::Hold() {
+  d4_dbgdef(int r = )pthread_mutex_lock(&gMutex);
+  d4_assert(r == 0);
+}
+
+d4_inline c4_ThreadLock::Hold::~Hold() {
+  d4_dbgdef(int r = )pthread_mutex_unlock(&gMutex);
+  d4_assert(r == 0);
+}
+
+#endif /* q4_WIN32 */
+
+#else /* q4_MULTI */
+
+//  All other implementations revert to the simple "thread-less" case.
+
+d4_inline c4_ThreadLock::c4_ThreadLock(){}
+
+d4_inline c4_ThreadLock::~c4_ThreadLock(){}
+
+d4_inline c4_ThreadLock::Hold::Hold(){}
+
+d4_inline c4_ThreadLock::Hold::~Hold(){}
+
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if q4_LOGPROPMODS
+
+static FILE *sPropModsFile = 0;
+static int sPropModsProp =  - 1;
+
+FILE *f4_LogPropMods(FILE *fp_, int propId_) {
+  FILE *prevfp = sPropModsFile;
+  sPropModsFile = fp_;
+  sPropModsProp = propId_;
+  return prevfp;
+}
+
+void f4_DoLogProp(const c4_Handler *hp_, int id_, const char *fmt_, int arg_) {
+  if (sPropModsFile != 0 && (sPropModsProp < 0 || sPropModsProp == id_)) {
+    fprintf(sPropModsFile, "handler 0x%x id %d: ", hp_, id_);
+    fprintf(sPropModsFile, fmt_, arg_);
+  }
+}
+
+#endif 
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_View
+ *
+ *  A collection of data rows.  This is the central public data structure of
+ *  Metakit (often called "table", "array", or "relation" in other systems).
+ *
+ *  Views are smart pointers to the actual collections, setting a view to a new
+ *  value does not alter the collection to which this view pointed previously.
+ *
+ *  The elements of views can be referred to by their 0-based index, which
+ *  produces a row-reference of type c4_RowRef.  These row references can
+ *  be copied, used to get or set properties, or dereferenced (in which case
+ *  an object of class c4_Row is returned).  Taking the address of a row
+ *  reference produces a c4_Cursor, which acts very much like a pointer.
+ *
+ *  The following code creates a view with 1 row and 2 properties:
+ * @code
+ *    c4_StringProp pName ("name");
+ *    c4_IntProp pAge ("age");
+ *
+ *    c4_Row data;
+ *    pName (data) = "John Williams";
+ *    pAge (data) = 43;
+ *
+ *    c4_View myView;
+ *    myView.Add(row);
+ * @endcode
+ */
+
+/// Construct a view based on a sequence
+c4_View::c4_View(c4_Sequence *seq_): _seq(seq_) {
+  if (!_seq)
+    _seq = d4_new c4_HandlerSeq(0);
+
+  _IncSeqRef();
+}
+
+/// Construct a view based on a custom viewer
+c4_View::c4_View(c4_CustomViewer *viewer_): _seq(0) {
+  d4_assert(viewer_);
+
+  _seq = d4_new c4_CustomSeq(viewer_);
+
+  _IncSeqRef();
+}
+
+/// Construct a view based on an input stream
+c4_View::c4_View(c4_Stream *stream_): _seq(c4_Persist::Load(stream_)) {
+  if (_seq == 0)
+    _seq = d4_new c4_HandlerSeq(0);
+
+  _IncSeqRef();
+}
+
+/// Construct an empty view with one property
+c4_View::c4_View(const c4_Property &prop_): _seq(d4_new c4_HandlerSeq(0)) {
+  _IncSeqRef();
+
+  _seq->PropIndex(prop_);
+}
+
+/// Copy constructor
+c4_View::c4_View(const c4_View &view_): _seq(view_._seq) {
+  _IncSeqRef();
+}
+
+/// Makes this view the same as another one.
+c4_View &c4_View::operator = (const c4_View &view_) {
+  if (_seq != view_._seq) {
+    _DecSeqRef();
+    _seq = view_._seq;
+    _IncSeqRef();
+  }
+  return  *this;
+}
+
+/** Get a single data item in a generic way
+ *
+ * This can be used to access view data in a generalized way.
+ * Useful for c4_CustomViewers which are based on other views.
+ * @return true if the item is non-empty
+ */
+bool c4_View::GetItem(int row_, int col_, c4_Bytes &buf_)const {
+  const c4_Property &prop = NthProperty(col_);
+  return prop(GetAt(row_)).GetData(buf_);
+}
+
+/// Set a single data item in a generic way
+void c4_View::SetItem(int row_, int col_, const c4_Bytes &buf_)const {
+  const c4_Property &prop = NthProperty(col_);
+  prop(GetAt(row_)).SetData(buf_);
+}
+
+/// Set an entry, growing the view if needed
+void c4_View::SetAtGrow(int index_, const c4_RowRef &newElem_) {
+  if (index_ >= GetSize())
+    SetSize(index_ + 1);
+
+  _seq->SetAt(index_, &newElem_);
+}
+
+/** Add a new entry, same as "SetAtGrow(GetSize(), ...)"
+ * @return the index of the newly added row
+ */
+int c4_View::Add(const c4_RowRef &newElem_) {
+  int i = GetSize();
+  InsertAt(i, newElem_);
+  return i;
+}
+
+/** Construct a new view with a copy of the data
+ *
+ * The copy is a deep copy, because subviews are always copied in full.
+ */
+c4_View c4_View::Duplicate()const {
+  // insert all rows, sharing any subviews as needed
+  c4_View result = Clone();
+  result.InsertAt(0, _seq);
+  return result;
+}
+
+/** Constructs a new view with the same structure but no data
+ *
+ * Structural information can only be maintain for the top level,
+ * subviews will be included but without any properties themselves.
+ */
+c4_View c4_View::Clone()const {
+  c4_View view;
+
+  for (int i = 0; i < NumProperties(); ++i)
+    view._seq->PropIndex(NthProperty(i));
+
+  return view;
+}
+
+/** Adds a property column to a view if not already present
+ * @return 0-based column position of the property
+ */
+int c4_View::AddProperty(const c4_Property &prop_) {
+  return _seq->PropIndex(prop_);
+}
+
+/** Returns the N-th property (using zero-based indexing)
+ * @return reference to the specified property
+ */
+const c4_Property &c4_View::NthProperty(int index_  
+  ///< the zero-based property index
+)const {
+  return _seq->NthHandler(index_).Property();
+}
+
+/** Find the index of a property, given its name
+ * @return 0-based column index
+ * @retval -1 property not present in this view
+ */
+int c4_View::FindPropIndexByName(const char *name_  
+  ///< property name (case insensitive)
+)const {
+  // use a slow linear scan to find the untyped property by name
+  for (int i = 0; i < NumProperties(); ++i) {
+    c4_String s = NthProperty(i).Name();
+    if (s.CompareNoCase(name_) == 0)
+      return i;
+  }
+
+  return  - 1;
+}
+
+/** Defines a column for a property.
+ *
+ * The following code defines an empty view with three properties:
+ * @code
+ *  c4_IntProp p1, p2, p3;
+ *  c4_View myView = (p1, p2, p3);
+ * @endcode
+ * @return the new view object (without any data rows)
+ * @sa c4_Property
+ */
+c4_View c4_View::operator, (const c4_Property &prop_)const {
+  c4_View view = Clone();
+  view.AddProperty(prop_);
+  return view;
+}
+
+/// Insert copies of all rows of the specified view
+void c4_View::InsertAt(int index_, const c4_View &view_) {
+  int n = view_.GetSize();
+  if (n > 0) {
+    c4_Row empty;
+
+    InsertAt(index_, empty, n);
+
+    for (int i = 0; i < n; ++i)
+      SetAt(index_ + i, view_[i]);
+  }
+}
+
+bool c4_View::IsCompatibleWith(const c4_View &dest_)const {
+  // can't determine table without handlers (and can't be a table)
+  if (NumProperties() == 0 || dest_.NumProperties() == 0)
+    return false;
+
+  c4_Sequence *s1 = _seq;
+  c4_Sequence *s2 = dest_._seq;
+  c4_HandlerSeq *h1 = (c4_HandlerSeq*)s1->HandlerContext(0);
+  c4_HandlerSeq *h2 = (c4_HandlerSeq*)s2->HandlerContext(0);
+
+  // both must be real handler views, not derived ones
+  if (h1 != s1 || h2 != s2)
+    return false;
+
+  // both must not contain any temporary handlers
+  if (s1->NumHandlers() != h1->NumFields() || s2->NumHandlers() != h2
+    ->NumFields())
+    return false;
+
+  // both must be in the same storage
+  if (h1->Persist() == 0 || h1->Persist() != h2->Persist())
+    return false;
+
+  // both must have the same structure (is this expensive?)
+  c4_String d1 = h1->Definition().Description(true);
+  c4_String d2 = h2->Definition().Description(true);
+  return d1 == d2; // ignores all names
+}
+
+/** Move attached rows to somewhere else in same storage
+ *
+ * There is a lot of trickery going on here.  The whole point of this
+ * code is that moving rows between (compatible!) subviews should not
+ * use copying when potentially large memo's and subviews are involved.
+ * In that case, the best solution is really to move pointers, not data.
+ */
+void c4_View::RelocateRows(int from_, int count_, c4_View &dest_, int pos_) {
+  if (count_ < 0)
+    count_ = GetSize() - from_;
+  if (pos_ < 0)
+    pos_ = dest_.GetSize();
+
+  d4_assert(0 <= from_ && from_ <= GetSize());
+  d4_assert(0 <= count_ && from_ + count_ <= GetSize());
+  d4_assert(0 <= pos_ && pos_ <= dest_.GetSize());
+
+  if (count_ > 0) {
+    // the destination must not be inside the source rows
+    d4_assert(&dest_ != this || from_ > pos_ || pos_ >= from_ + count_);
+
+    // this test is slow, so do it only as a debug check
+    d4_assert(IsCompatibleWith(dest_));
+
+    // make space, swap rows, drop originals
+    c4_Row empty;
+    dest_.InsertAt(pos_, empty, count_);
+
+    // careful if insert moves origin
+    if (&dest_ == this && pos_ <= from_)
+      from_ += count_;
+
+    for (int i = 0; i < count_; ++i)
+      ((c4_HandlerSeq*)_seq)->ExchangeEntries(from_ + i, *(c4_HandlerSeq*)
+        dest_._seq, pos_ + i);
+
+    RemoveAt(from_, count_);
+  }
+}
+
+/** Create view with all rows in natural (property-wise) order
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view.  This "derived" view uses change notification to track
+ * changes to the underlying view, but unfortunately there are some major
+ * limitations with this scheme - one of them being that deriving another
+ * view from this sorted one will not properly track changes.
+ */
+c4_View c4_View::Sort()const {
+  return f4_CreateSort(*_seq);
+}
+
+/** Create view sorted according to the specified properties
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view.  This "derived" view uses change notification to track
+ * changes to the underlying view, but unfortunately there are some major
+ * limitations with this scheme - one of them being that deriving another
+ * view from this sorted one will not properly track changes.
+ */
+c4_View c4_View::SortOn(const c4_View &up_)const {
+  c4_Sequence *seq = f4_CreateProject(*_seq,  *up_._seq, true);
+
+  return f4_CreateSort(*seq);
+}
+
+/** Create sorted view, with some properties sorted in reverse
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view.  This "derived" view uses change notification to track
+ * changes to the underlying view, but unfortunately there are some major
+ * limitations with this scheme - one of them being that deriving another
+ * view from this sorted one will not properly track changes.
+ */
+c4_View c4_View::SortOnReverse(const c4_View &up_,  
+  ///< the view which defines the sort order
+const c4_View &down_  ///< subset of up_, defines reverse order
+)const {
+  c4_Sequence *seq = f4_CreateProject(*_seq,  *up_._seq, true);
+
+  return f4_CreateSort(*seq, down_._seq);
+}
+
+/** Create view with rows matching the specified value
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view.  This "derived" view uses change notification to track
+ * changes to the underlying view, but this only works when based on views
+ * which properly generate change notifications (.e. raw views, other
+ * selections, and projections).
+ */
+c4_View c4_View::Select(const c4_RowRef &crit_)const {
+  return f4_CreateFilter(*_seq, &crit_, &crit_);
+}
+
+/** Create view with row values within the specified range
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view.  This "derived" view uses change notification to track
+ * changes to the underlying view, but this only works when based on views
+ * which properly generate change notifications (.e. raw views, other
+ * selections, and projections).
+ */
+c4_View c4_View::SelectRange(const c4_RowRef &low_,  
+  ///< values of the lower bounds (inclusive)
+const c4_RowRef &high_  ///< values of the upper bounds (inclusive)
+)const {
+  return f4_CreateFilter(*_seq, &low_, &high_);
+}
+
+/** Create view with the specified property arrangement
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view.  This "derived" view uses change notification to track
+ * changes to the underlying view, but this only works when based on views
+ * which properly generate change notifications (.e. raw views, selections,
+ * and other projections).
+ */
+c4_View c4_View::Project(const c4_View &in_)const {
+  return f4_CreateProject(*_seq,  *in_._seq, false);
+}
+
+/** Create derived view with some properties omitted
+ *
+ * The result is virtual, it merely maintains a permutation to access the
+ * underlying view.  This "derived" view uses change notification to track
+ * changes to the underlying view, but this only works when based on views
+ * which properly generate change notifications (.e. raw views, selections,
+ * and other projections).
+ */
+c4_View c4_View::ProjectWithout(const c4_View &out_)const {
+  return f4_CreateProject(*_seq,  *_seq, false, out_._seq);
+}
+
+/** Create view which is a segment/slice (default is up to end)
+ *
+ * Returns a view which is a subset, either a contiguous range, or
+ * a "slice" with element taken from every step_ entries.  If the
+ * step is negative, the same entries are returned, but in reverse
+ * order (start_ is still lower index, it'll then be returned last).
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Slice(int first_, int limit_, int step_)const {
+  return f4_CustSlice(*_seq, first_, limit_, step_);
+}
+
+/** Create view which is the cartesian product with given view
+ *
+ * The cartesian product is defined as every combination of rows
+ * in both views.  The number of entries is the product of the
+ * number of entries in the two views, properties which are present
+ * in both views will use the values defined in this view.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Product(const c4_View &view_)const {
+  return f4_CustProduct(*_seq, view_);
+}
+
+/** Create view which remaps another given view
+ *
+ * Remapping constructs a view with the rows indicated by another
+ * view.  The first property in the order_ view must be an int
+ * property with index values referring to this one.  The size of
+ * the resulting view is determined by the order_ view and can
+ * differ, for example to act as a subset selection (if smaller).
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::RemapWith(const c4_View &view_)const {
+  return f4_CustRemapWith(*_seq, view_);
+}
+
+/** Create view which pairs each row with corresponding row
+ *
+ * This is like a row-by-row concatenation.  Both views must have
+ * the same number of rows, the result has all properties from
+ * this view plus any other properties from the other view.
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Pair(const c4_View &view_)const {
+  return f4_CustPair(*_seq, view_);
+}
+
+/** Create view with rows from another view appended
+ *
+ * Constructs a view which has all rows of this view, and all rows
+ * of the second view appended.  The structure of the second view
+ * is assumed to be identical to this one.  This operation is a bit
+ * similar to appending all rows from the second view, but it does
+ * not actually store the result anywhere, it just looks like it.
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Concat(const c4_View &view_)const {
+  return f4_CustConcat(*_seq, view_);
+}
+
+/** Create view with one property renamed (must be of same type)
+ *
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Rename(const c4_Property &old_, const c4_Property &new_)const {
+  return f4_CustRename(*_seq, old_, new_);
+}
+
+/** Create view with a subview, grouped by the specified properties
+ *
+ * This operation is similar to the SQL 'GROUP BY', but it takes
+ * advantage of the fact that Metakit supports nested views.  The
+ * view returned from this member has one row per distinct group,
+ * with an extra view property holding the remaining properties.
+ * If there are N rows in the original view matching key X, then
+ * the result is a row for key X, with a subview of N rows.  The
+ * properties of the subview are all the properties not in the key.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::GroupBy(const c4_View &keys_,  
+  ///< properties in this view determine grouping
+const c4_ViewProp &result_  ///< name of new subview defined in result
+)const {
+  return f4_CustGroupBy(*_seq, keys_, result_);
+}
+
+/** Create view with count of duplicates, when grouped by key
+ *
+ * This is similar to c4_View::GroupBy, but it determines only the
+ * number of rows in each group and does not create a nested view.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Counts(const c4_View &keys_,  
+  ///< properties in this view determine grouping
+const c4_IntProp &result_  ///< new count property defined in result
+)const {
+  return f4_CustGroupBy(*_seq, keys_, result_); // third arg is c4_IntProp
+}
+
+/** Create view with all duplicate rows omitted
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Unique()const {
+  c4_IntProp count("#N#");
+  return Counts(Clone(), count).ProjectWithout(count);
+}
+
+/** Create view which is the set union (assumes no duplicate rows)
+ *
+ * Calculates the set union.  This will only work if both input
+ * views are sets, i.e. they have no duplicate rows in them.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Union(const c4_View &view_)const {
+  return Concat(view_).Unique();
+}
+
+/** Create view with all rows also in the given view (no dups)
+ *
+ * Calculates the set intersection.  This will only work if both
+ * input views are sets, i.e. they have no duplicate rows in them.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Intersect(const c4_View &view_)const {
+  c4_View v = Concat(view_);
+
+  // assume neither view has any duplicates
+  c4_IntProp count("#N#");
+  return v.Counts(Clone(), count).Select(count[2]).ProjectWithout(count);
+}
+
+/** Create view with all rows not in both views (no dups)
+ *
+ * Calculates the "XOR" of two sets.  This will only work if both
+ * input views are sets, i.e. they have no duplicate rows in them.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Different(const c4_View &view_)const {
+  c4_View v = Concat(view_);
+
+  // assume neither view has any duplicates
+  c4_IntProp count("#N#");
+  return v.Counts(Clone(), count).Select(count[1]).ProjectWithout(count);
+}
+
+/** Create view with all rows not in the given view (no dups)
+ *
+ * Calculates set-difference of this view minus arg view.  Result
+ * is a subset, unlike c4_View::Different. Will only work if both
+ * input views are sets, i.e. they have no duplicate rows in them.
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Minus(const c4_View &view_  ///< the second view
+)const {
+  // inefficient: calculate difference, then keep only those in self
+  return Intersect(Different(view_));
+}
+
+/** Create view with a specific subview expanded, like a join
+ *
+ * This operation is the inverse of c4_View::GroupBy, expanding
+ * all rows in specified subview and returning a view which looks
+ * as if the rows in each subview were "expanded in place".
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::JoinProp(const c4_ViewProp &sub_,  
+  ///< name of the subview to expand
+bool outer_  ///< true: keep rows with empty subviews
+)const {
+  return f4_CustJoinProp(*_seq, sub_, outer_);
+}
+
+/** Create view which is the relational join on the given keys
+ *
+ * This view operation is based on a read-only custom viewer.
+ */
+c4_View c4_View::Join(const c4_View &keys_,  
+  ///< properties in this view determine the join
+const c4_View &view_,  ///< second view participating in the join
+bool outer_  ///< true: keep rows with no match in second view
+)const {
+  // inefficient: calculate difference, then keep only those in self
+  return f4_CustJoin(*_seq, keys_, view_, outer_);
+}
+
+/** Create an identity view which only allows reading
+ *
+ * This view operation is based on a custom viewer.
+ */
+c4_View c4_View::ReadOnly()const {
+  return f4_CreateReadOnly(*_seq);
+}
+
+/** Create mapped view which adds a hash lookup layer
+ *
+ * This view creates and manages a special hash map view, to implement a
+ * fast find on the key.  The key is defined to consist of the first
+ * numKeys_ properties of the underlying view.
+ *
+ * The map_ view must be empty the first time this hash view is used, so
+ * that Metakit can fill it based on whatever rows are already present in
+ * the underlying view.  After that, neither the underlying view nor the
+ * map view may be modified other than through this hash mapping layer.
+ * The defined structure of the map view must be "_H:I,_R:I".
+ *
+ * This view is modifiable.  Insertions and changes to key field properties
+ * can cause rows to be repositioned to maintain hash uniqueness.  Careful:
+ * when a row is changed in such a way that its key is the same as in another
+ * row, that other row will be deleted from the view.
+ *
+ * Example of use:
+ * @code
+ *  c4_View data = storage.GetAs("people[name:S,age:I]");
+ *  c4_View datah = storage.GetAs("people_H[_H:I,_R:I]");
+ *  c4_View hash = raw.Hash(datah, 1);
+ *  ... hash.GetSize() ...
+ *  hash.Add(...)
+ * @endcode
+ */
+c4_View c4_View::Hash(const c4_View &map_, int numKeys_)const {
+  return f4_CreateHash(*_seq, numKeys_, map_._seq);
+}
+
+/** Create mapped view which blocks its rows in two levels
+ *
+ * This view acts like a large flat view, even though the actual rows are
+ * stored in blocks, which are rebalanced automatically to maintain a good 
+ * trade-off between block size and number of blocks.
+ *
+ * The underlying view must be defined with a single view property, with
+ * the structure of the subview being as needed.  An example of a blocked
+ * view definition which will act like a single one containing 2 properties:
+ * @code
+ *  c4_View raw = storage.GetAs("people[_B[name:S,age:I]]");
+ *  c4_View flat = raw.Blocked();
+ *  ... flat.GetSize() ...
+ *  flat.InsertAt(...)
+ * @endcode
+ * 
+ * This view operation is based on a custom viewer and is modifiable.
+ */
+c4_View c4_View::Blocked()const {
+  return f4_CreateBlocked(*_seq);
+}
+
+/** Create mapped view which keeps its rows ordered
+ *
+ * This is an identity view, which has as only use to inform Metakit that
+ * the underlying view can be considered to be sorted on its first numKeys_
+ * properties.  The effect is that c4_View::Find will try to use binary
+ * search when the search includes key properties (results will be identical
+ * to unordered views, the find will just be more efficient).
+ *
+ * This view is modifiable.  Insertions and changes to key field properties
+ * can cause rows to be repositioned to maintain the sort order.  Careful:
+ * when a row is changed in such a way that its key is the same as in another
+ * row, that other row will be deleted from the view.
+ *
+ * This view can be combined with c4_View::Blocked, to create a 2-level
+ * btree structure.
+ */
+c4_View c4_View::Ordered(int numKeys_)const {
+  return f4_CreateOrdered(*_seq, numKeys_);
+}
+
+/** Create mapped view which maintains an index permutation
+ *
+ * This is an identity view which somewhat resembles the ordered view, it
+ * maintains a secondary "map" view to contain the permutation to act as
+ * an index.  The indexed view presents the same order of rows as the
+ * underlying view, but the index map is set up in such a way that binary
+ * search is possible on the keys specified.  When the "unique" parameter
+ * is true, insertions which would create a duplicate key are ignored.
+ *
+ * This view is modifiable.  Careful: when a row is changed in such a way
+ * that its key is the same as in another row, that other row will be
+ * deleted from the view.
+ */
+c4_View c4_View::Indexed(const c4_View &map_, const c4_View &props_, bool
+  unique_)const {
+  return f4_CreateIndexed(*_seq,  *map_._seq, props_, unique_);
+}
+
+/** Return the index of the specified row in this view (or -1)
+ *
+ * This function can be used to "unmap" an index of a derived view back
+ * to the original underlying view.
+ */
+int c4_View::GetIndexOf(const c4_RowRef &row_)const {
+  c4_Cursor cursor = &row_;
+
+  return cursor._seq->RemapIndex(cursor._index, _seq);
+}
+
+/// Restrict the search range for rows
+int c4_View::RestrictSearch(const c4_RowRef &c_, int &pos_, int &count_) {
+  return _seq->RestrictSearch(&c_, pos_, count_) ? 0 : ~0;
+}
+
+/** Find index of the the next entry matching the specified key.
+ *
+ * Defaults to linear search, but hash- and ordered-views will use a better
+ * algorithm if possible.  Only the properties present in the search key
+ * are used to determine whether a row matches the key.
+ * @return position where match occurred
+ * @retval -1 if not found
+ */
+int c4_View::Find(const c4_RowRef &crit_,  ///< the value to look for
+int start_  ///< the index to start with
+)const {
+  d4_assert(start_ >= 0);
+
+  c4_Row copy = crit_; // the lazy (and slow) solution: make a copy
+
+  int count = GetSize() - start_;
+  if (_seq->RestrictSearch(&copy, start_, count)) {
+    c4_View refView = copy.Container();
+    c4_Sequence *refSeq = refView._seq;
+    d4_assert(refSeq != 0);
+
+    c4_Bytes data;
+
+    for (int j = 0; j < count; ++j) {
+      int i;
+
+      for (i = 0; i < refSeq->NumHandlers(); ++i) {
+        c4_Handler &h = refSeq->NthHandler(i); // no context issues
+
+        if (!_seq->Get(start_ + j, h.PropId(), data))
+          h.ClearBytes(data);
+
+        if (h.Compare(0, data) != 0)
+        // always row 0
+          break;
+      }
+
+      if (i == refSeq->NumHandlers())
+        return start_ + j;
+    }
+  }
+
+  return  - 1;
+}
+
+/** Search for a key, using the native sort order of the view
+ * @return position where found, or where it may be inserted,
+ *  this position can also be just past the last row
+ */
+int c4_View::Search(const c4_RowRef &crit_)const {
+  int l =  - 1, u = GetSize();
+  while (l + 1 != u) {
+    const int m = (l + u) >> 1;
+    if (_seq->Compare(m, &crit_) < 0)
+    //if (crit_ > (*this)[m]) // Dec 2001: see comments below
+      l = m;
+    else
+      u = m;
+  }
+
+  return u;
+}
+
+/// Return number of matching keys, and pos of first one as arg
+int c4_View::Locate(const c4_RowRef &crit_, int *pos_)const {
+  // Dec 2001: fixed a problem with searching of partial rows.
+  //
+  // There is an *extremely* tricky issue in here, in that the
+  // comparison operator for rows is not symmetric.  So in the
+  // general case, "a == b" is not euivalent to "b == a".  This
+  // is without doubt a design mistake (and should have at least
+  // been named differently).
+  //
+  // The reason is that the number of properties in both rowrefs
+  // need not be the same.  Only the properties of the leftmost
+  // rowref are compared against the other one.  This also applies
+  // to the other comparisons, i.e. !=, <, >, <=, and >=.
+  //
+  // All Compare calls below have been changed to use comparisons
+  // in the proper order and now use "rowref <op> rowref" syntax.
+
+  c4_Cursor curr(*(c4_Sequence*)_seq, 0); // loses const
+
+  int l =  - 1, u = GetSize();
+  while (l + 1 != u) {
+    curr._index = (l + u) >> 1;
+    if (crit_ >  *curr)
+      l = curr._index;
+    else
+      u = curr._index;
+  }
+
+  if (pos_ != 0)
+    *pos_ = u;
+
+  // only look for more if the search hit an exact match
+  curr._index = u;
+  if (u == GetSize() || crit_ !=  *curr)
+    return 0;
+
+  // as Jon Bentley wrote in DDJ Apr 2000, setting l2 to -1 is better than u
+  int l2 =  - 1, u2 = GetSize();
+  while (l2 + 1 != u2) {
+    curr._index = (l2 + u2) >> 1;
+    if (crit_ >=  *curr)
+      l2 = curr._index;
+    else
+      u2 = curr._index;
+  }
+
+  return u2 - u;
+}
+
+/// Compare two views lexicographically (rows 0..N-1).
+int c4_View::Compare(const c4_View &view_)const {
+  if (_seq == view_._seq)
+    return 0;
+
+  int na = GetSize();
+  int nb = view_.GetSize();
+  int i;
+
+  for (i = 0; i < na && i < nb; ++i)
+    if (GetAt(i) != view_.GetAt(i))
+      return GetAt(i) < view_.GetAt(i) ?  - 1:  + 1;
+
+  return na == nb ? 0 : i < na ?  + 1:  - 1;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_Cursor
+ *
+ *  An iterator for collections of rows (views).
+ *
+ *  Cursor objects can be used to point to specific entries in a view.
+ *  A cursor acts very much like a pointer to a row in a view, and is 
+ *  returned when taking the address of a c4_RowRef.  Dereferencing
+ *  a cursor leads to the original row reference again.  You can construct a
+ *  cursor for a c4_Row, but since such rows are not part of a collection,
+ *  incrementing or decrementing these cursors is meaningless (and wrong). 
+ *
+ *  The usual range of pointer operations can be applied to these objects:
+ *  pre/post-increment and decrement, adding or subtracting integer offsets,
+ *  as well as the full range of comparison operators.  If two cursors
+ *  point to entries in the same view, their difference can be calculated.
+ *
+ *  As with regular pointers, care must be taken to avoid running off of
+ *  either end of a view (the debug build includes assertions to check this).
+ */
+
+/** @class c4_RowRef
+ *
+ *  Reference to a data row, can be used on either side of an assignment.
+ *
+ *  Row references are created when dereferencing a c4_Cursor or when
+ *  indexing an element of a c4_View.  Assignment will change the
+ *  corresponding item.  Rows (objects of type c4_Row) are a special
+ *  case of row references, consisting of a view with exactly one item.
+ *
+ *  Internally, row references are very similar to cursors, in fact they are
+ *  little more than a wrapper around them.  The essential difference is one
+ *  of semantics: comparing row references compares contents, copying row
+ *  references copies the contents, whereas cursor comparison and copying
+ *  deals with the pointer to the row, not its contents.
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// c4_Row
+
+c4_Row::c4_Row(): c4_RowRef(*Allocate()){}
+
+c4_Row::c4_Row(const c4_Row &row_): c4_RowRef(*Allocate()) {
+  operator = (row_);
+}
+
+c4_Row::c4_Row(const c4_RowRef &rowRef_): c4_RowRef(*Allocate()) {
+  operator = (rowRef_);
+}
+
+c4_Row::~c4_Row() {
+  Release(_cursor);
+}
+
+c4_Row &c4_Row::operator = (const c4_Row &row_) {
+  return operator = ((const c4_RowRef &)row_);
+}
+
+/// Assignment from a reference to a row.
+c4_Row &c4_Row::operator = (const c4_RowRef &rowRef_) {
+  d4_assert(_cursor._seq != 0);
+
+  if (_cursor !=  &rowRef_) {
+    d4_assert(_cursor._index == 0);
+    _cursor._seq->SetAt(0, &rowRef_);
+  }
+
+  return  *this;
+}
+
+/// Adds all properties and values into this row.
+void c4_Row::ConcatRow(const c4_RowRef &rowRef_) {
+  d4_assert(_cursor._seq != 0);
+
+  c4_Cursor cursor = &rowRef_; // trick to access private rowRef_._cursor
+  d4_assert(cursor._seq != 0);
+
+  c4_Sequence &rhSeq =  *cursor._seq;
+
+  c4_Bytes data;
+
+  for (int i = 0; i < rhSeq.NumHandlers(); ++i) {
+    c4_Handler &h = rhSeq.NthHandler(i);
+
+    h.GetBytes(cursor._index, data);
+    _cursor._seq->Set(_cursor._index, h.Property(), data);
+  }
+}
+
+c4_Row operator + (const c4_RowRef &a_, const c4_RowRef &b_) {
+  c4_Row row = a_;
+  row.ConcatRow(b_);
+  return row;
+}
+
+c4_Cursor c4_Row::Allocate() {
+  c4_Sequence *seq = d4_new c4_HandlerSeq(0);
+  seq->IncRef();
+
+  seq->Resize(1);
+
+  return c4_Cursor(*seq, 0);
+}
+
+void c4_Row::Release(c4_Cursor row_) {
+  d4_assert(row_._seq != 0);
+  d4_assert(row_._index == 0);
+
+  row_._seq->DecRef();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** @class c4_Property
+ *
+ *  Base class for the basic data types.
+ *
+ *  Property objects exist independently of view, row, and storage objects.
+ *  They have a name and type, and can appear in any number of views.
+ *  You will normally only use derived classes, to maintain strong typing.
+ */
+
+// This is a workaround for the fact that the initialization order of
+// static objects is not always adequate (implementation dependent).
+// Extremely messy solution, to allow statically declared properties.
+//
+// These are the only static variables in the entire Metakit core lib.
+
+static c4_ThreadLock *sThreadLock = 0;
+static c4_StringArray *sPropNames = 0;
+static c4_DWordArray *sPropCounts = 0;
+
+/// Call this to get rid of some internal datastructues (on exit)
+void c4_Property::CleanupInternalData() {
+  delete sPropNames;
+  sPropNames = 0; // race
+
+  delete sPropCounts;
+  sPropCounts = 0; // race
+
+  delete sThreadLock;
+  sThreadLock = 0; // race
+}
+
+c4_Property::c4_Property(char type_, const char *name_): _type(type_) {
+  if (sThreadLock == 0)
+    sThreadLock = d4_new c4_ThreadLock;
+
+  c4_ThreadLock::Hold lock; // grabs the lock until end of scope
+
+  if (sPropNames == 0)
+    sPropNames = d4_new c4_StringArray;
+
+  if (sPropCounts == 0)
+    sPropCounts = d4_new c4_DWordArray;
+
+  c4_String temp = name_;
+
+  _id = sPropNames->GetSize();
+  while (--_id >= 0) {
+    const char *p = sPropNames->GetAt(_id);
+    // optimize for first char case-insensitive match
+    if (((*p ^  *name_) &~0x20) == 0 && temp.CompareNoCase(p) == 0)
+      break;
+  }
+
+  if (_id < 0) {
+    int size = sPropCounts->GetSize();
+
+    for (_id = 0; _id < size; ++_id)
+      if (sPropCounts->GetAt(_id) == 0)
+        break;
+
+    if (_id >= size) {
+      sPropCounts->SetSize(_id + 1);
+      sPropNames->SetSize(_id + 1);
+    }
+
+    sPropCounts->SetAt(_id, 0);
+    sPropNames->SetAt(_id, name_);
+  }
+
+  Refs( + 1);
+}
+
+c4_Property::c4_Property(const c4_Property &prop_): _id(prop_.GetId()), _type
+  (prop_.Type()) {
+  c4_ThreadLock::Hold lock;
+
+  d4_assert(sPropCounts != 0);
+  d4_assert(sPropCounts->GetAt(_id) > 0);
+
+  Refs( + 1);
+}
+
+c4_Property::~c4_Property() {
+  c4_ThreadLock::Hold lock;
+
+  Refs( - 1);
+}
+
+void c4_Property::operator = (const c4_Property &prop_) {
+  c4_ThreadLock::Hold lock;
+
+  prop_.Refs( + 1);
+  Refs( - 1);
+
+  _id = prop_.GetId();
+  _type = prop_.Type();
+}
+
+/// Return the name of this property
+const char *c4_Property::Name()const {
+  c4_ThreadLock::Hold lock;
+
+  d4_assert(sPropNames != 0);
+  return sPropNames->GetAt(_id);
+}
+
+/** Adjust the reference count
+ *
+ *  This is part of the implementation and shouldn't normally be called.
+ *  This code is only called with the lock held, and always thread-safe.
+ */
+void c4_Property::Refs(int diff_)const {
+  d4_assert(diff_ ==  - 1 || diff_ ==  + 1);
+
+  d4_assert(sPropCounts != 0);
+  sPropCounts->ElementAt(_id) += diff_;
+
+#if q4_CHECK
+  // get rid of the cache when the last property goes away
+  static t4_i32 sPropTotals;
+
+  sPropTotals += diff_;
+  if (sPropTotals == 0)
+    CleanupInternalData();
+#endif 
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/viewx.cpp b/8.x/mk/src/viewx.cpp
new file mode 100755 (executable)
index 0000000..6587c41
--- /dev/null
@@ -0,0 +1,782 @@
+// viewx.cpp --
+// $Id: viewx.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+/** @file
+ * Implements c4_Sequence, c4_Reference, and c4_...Ref
+ */
+
+#include "header.h"
+#include "handler.h"
+#include "store.h"
+#include "column.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Sequence::c4_Sequence(): _refCount(0), _dependencies(0), _propertyLimit(0),
+  _tempBuf(0){}
+
+c4_Sequence::~c4_Sequence() {
+  d4_assert(_refCount == 0);
+
+  d4_assert(!_dependencies); // there can be no dependencies left
+
+  ClearCache();
+
+  delete _tempBuf;
+}
+
+c4_Persist *c4_Sequence::Persist()const {
+  return 0;
+}
+
+/// Increment the reference count of this sequence
+void c4_Sequence::IncRef() {
+  ++_refCount;
+
+  d4_assert(_refCount != 0);
+}
+
+/// Decrement the reference count, delete objects when last
+void c4_Sequence::DecRef() {
+  d4_assert(_refCount != 0);
+
+  if (--_refCount == 0)
+    delete this;
+}
+
+/// Return the current reference count
+int c4_Sequence::NumRefs()const {
+  return _refCount;
+}
+
+/// Compare the specified row with another one
+int c4_Sequence::Compare(int index_, c4_Cursor cursor_)const {
+  d4_assert(cursor_._seq != 0);
+
+  c4_Bytes data;
+
+  for (int colNum = 0; colNum < NumHandlers(); ++colNum) {
+    c4_Handler &h = NthHandler(colNum);
+
+    const c4_Sequence *hc = HandlerContext(colNum);
+    int i = RemapIndex(index_, hc);
+
+    if (!cursor_._seq->Get(cursor_._index, h.PropId(), data))
+      h.ClearBytes(data);
+
+    int f = h.Compare(i, data);
+    if (f != 0)
+      return f;
+  }
+
+  return 0;
+}
+
+/// Restrict the search range for rows
+bool c4_Sequence::RestrictSearch(c4_Cursor, int &, int &) {
+  return true;
+}
+
+/// Replace the contents of a specified row
+void c4_Sequence::SetAt(int index_, c4_Cursor newElem_) {
+  d4_assert(newElem_._seq != 0);
+
+  c4_Bytes data;
+
+  c4_Notifier change(this);
+  if (GetDependencies())
+    change.StartSetAt(index_, newElem_);
+
+  for (int i = 0; i < newElem_._seq->NumHandlers(); ++i) {
+    c4_Handler &h = newElem_._seq->NthHandler(i);
+
+    // added 06-12-1999 to do index remapping for derived seq's
+    const c4_Sequence *hc = newElem_._seq->HandlerContext(i);
+    int ri = newElem_._seq->RemapIndex(newElem_._index, hc);
+
+    h.GetBytes(ri, data);
+
+    //    Set(index_, cursor._seq->NthProperty(i), data);
+    int colNum = PropIndex(h.Property());
+    d4_assert(colNum >= 0);
+
+    NthHandler(colNum).Set(index_, data);
+  }
+
+  // if number of props in dest is larger after adding, clear the rest
+  // this way, new props get copied and undefined props get cleared
+  if (newElem_._seq->NumHandlers() < NumHandlers()) {
+    for (int j = 0; j < NumHandlers(); ++j) {
+      c4_Handler &h = NthHandler(j);
+
+      // if the property does not appear in the source
+      if (newElem_._seq->PropIndex(h.PropId()) < 0) {
+        h.ClearBytes(data);
+        h.Set(index_, data);
+      }
+    }
+  }
+}
+
+/// Remap the index to an underlying view
+int c4_Sequence::RemapIndex(int index_, const c4_Sequence *seq_)const {
+  return seq_ == this ? index_ :  - 1;
+}
+
+/// Gives access to a general purpose temporary buffer
+c4_Bytes &c4_Sequence::Buffer() {
+  if (_tempBuf == 0)
+    _tempBuf = d4_new c4_Bytes;
+  return  *_tempBuf;
+}
+
+// 1.8.5: extra buffer to hold returned description strings
+const char *c4_Sequence::UseTempBuffer(const char *str_) {
+  return strcpy((char*)Buffer().SetBuffer(strlen(str_) + 1), str_);
+}
+
+/// Change number of rows, either by inserting or removing them
+void c4_Sequence::Resize(int newSize_, int) {
+  if (NumHandlers() > 0) {
+    int diff = newSize_ - NumRows();
+
+    if (diff > 0) {
+      c4_Row empty; // make sure this doesn't recurse, see below
+      InsertAt(NumRows(), &empty, diff);
+    } else if (diff < 0)
+      RemoveAt(newSize_,  - diff);
+  } else
+  // need special case to avoid recursion for c4_Row allocations
+    SetNumRows(newSize_);
+}
+
+/// Insert one or more rows into this sequence
+void c4_Sequence::InsertAt(int index_, c4_Cursor newElem_, int count_) {
+  d4_assert(newElem_._seq != 0);
+
+  c4_Notifier change(this);
+  if (GetDependencies())
+    change.StartInsertAt(index_, newElem_, count_);
+
+  SetNumRows(NumRows() + count_);
+
+  c4_Bytes data;
+
+  for (int i = 0; i < newElem_._seq->NumHandlers(); ++i) {
+    c4_Handler &h = newElem_._seq->NthHandler(i);
+
+    // added 06-12-1999 to do index remapping for derived seq's
+    const c4_Sequence *hc = newElem_._seq->HandlerContext(i);
+    int ri = newElem_._seq->RemapIndex(newElem_._index, hc);
+
+    int colNum = PropIndex(h.Property());
+    d4_assert(colNum >= 0);
+
+    if (h.Property().Type() == 'V') {
+      // If inserting from self: Make sure we get a copy of the bytes,
+      // so we don't get an invalid pointer if the memory get realloc'ed
+      h.GetBytes(ri, data, newElem_._seq == this);
+
+      // special treatment for subviews, insert empty, then overwrite
+      // changed 19990904 - probably fixes a long-standing limitation
+      c4_Bytes temp;
+      h.ClearBytes(temp);
+
+      c4_Handler &h2 = NthHandler(colNum);
+      h2.Insert(index_, temp, count_);
+
+      for (int j = 0; j < count_; ++j)
+        h2.Set(index_ + j, data);
+    } else {
+      h.GetBytes(ri, data);
+      NthHandler(colNum).Insert(index_, data, count_);
+    }
+  }
+
+  // if number of props in dest is larger after adding, clear the rest
+  // this way, new props get copied and undefined props get cleared
+  if (newElem_._seq->NumHandlers() < NumHandlers()) {
+    for (int j = 0; j < NumHandlers(); ++j) {
+      c4_Handler &h = NthHandler(j);
+
+      // if the property does not appear in the source
+      if (newElem_._seq->PropIndex(h.PropId()) < 0) {
+        h.ClearBytes(data);
+        h.Insert(index_, data, count_);
+      }
+    }
+  }
+}
+
+/// Remove one or more rows from this sequence
+void c4_Sequence::RemoveAt(int index_, int count_) {
+  c4_Notifier change(this);
+  if (GetDependencies())
+    change.StartRemoveAt(index_, count_);
+
+  SetNumRows(NumRows() - count_);
+
+  //! careful, this does no index remapping, wrong for derived seq's
+  for (int i = 0; i < NumHandlers(); ++i)
+    NthHandler(i).Remove(index_, count_);
+}
+
+/// Move a row to another position
+void c4_Sequence::Move(int from_, int to_) {
+  c4_Notifier change(this);
+  if (GetDependencies())
+    change.StartMove(from_, to_);
+
+  //! careful, this does no index remapping, wrong for derived seq's
+  for (int i = 0; i < NumHandlers(); ++i)
+    NthHandler(i).Move(from_, to_);
+}
+
+/// Return the id of the N-th property
+int c4_Sequence::NthPropId(int index_)const {
+  return NthHandler(index_).PropId();
+}
+
+void c4_Sequence::ClearCache() {
+  if (_propertyLimit > 0) {
+    delete [] _propertyMap; // property indexes may change
+    _propertyLimit = 0;
+  }
+}
+
+/// Find the index of a property by its id
+int c4_Sequence::PropIndex(int propId_) {
+  //! CACHING NOTE: derived views will fail if underlying view is restructured
+  //          still, this cache is kept, since sort will fail anyway...
+  //  The only safe change in these cases is adding new properties at the end.
+
+  // use the map for the fastest result once known
+  if (propId_ < _propertyLimit && _propertyMap[propId_] >= 0)
+    return _propertyMap[propId_];
+
+  // locate the property using a linear search, return if not present
+  int n = NumHandlers();
+  do {
+    if (--n < 0)
+      return  - 1;
+  } while (NthPropId(n) != propId_);
+
+  // if the map is too small, resize it (with a little slack)
+  if (propId_ >= _propertyLimit) {
+    int round = (propId_ + 8) &~0x07;
+    short *vec = d4_new short[round];
+
+    for (int i = 0; i < round; ++i)
+      vec[i] = i < _propertyLimit ? _propertyMap[i]:  - 1;
+
+    if (_propertyLimit > 0)
+      delete [] _propertyMap;
+
+    _propertyMap = vec;
+    _propertyLimit = round;
+  }
+
+  // we have a map, adjust the entry and return
+  return _propertyMap[propId_] = n;
+}
+
+/// Find the index of a property, or create a new entry
+int c4_Sequence::PropIndex(const c4_Property &prop_) {
+  int pos = PropIndex(prop_.GetId());
+  if (pos >= 0) {
+    d4_assert(NthHandler(pos).Property().Type() == prop_.Type());
+    return pos;
+  }
+
+  c4_Handler *h = CreateHandler(prop_);
+  d4_assert(h != 0);
+
+  int i = AddHandler(h);
+  if (i >= 0 && NumRows() > 0) {
+    c4_Bytes data;
+    h->ClearBytes(data);
+    h->Insert(0, data, NumRows());
+  }
+
+  return i;
+}
+
+const char *c4_Sequence::Description() {
+  return 0;
+}
+
+int c4_Sequence::ItemSize(int index_, int propId_) {
+  int colNum = PropIndex(propId_);
+  return colNum >= 0 ? NthHandler(colNum).ItemSize(index_):  - 1;
+}
+
+bool c4_Sequence::Get(int index_, int propId_, c4_Bytes &buf_) {
+  int colNum = PropIndex(propId_);
+  if (colNum < 0)
+    return false;
+
+  NthHandler(colNum).GetBytes(index_, buf_);
+  return true;
+}
+
+void c4_Sequence::Set(int index_, const c4_Property &prop_, const c4_Bytes
+  &buf_) {
+  int colNum = PropIndex(prop_);
+  d4_assert(colNum >= 0);
+
+  c4_Handler &h = NthHandler(colNum);
+
+  c4_Notifier change(this);
+  if (GetDependencies())
+    change.StartSet(index_, prop_.GetId(), buf_);
+
+  if (buf_.Size())
+    h.Set(index_, buf_);
+  else {
+    c4_Bytes empty;
+    h.ClearBytes(empty);
+    h.Set(index_, empty);
+  }
+}
+
+/// Register a sequence to receive change notifications
+void c4_Sequence::Attach(c4_Sequence *child_) {
+  IncRef();
+
+  if (!_dependencies)
+    _dependencies = d4_new c4_Dependencies;
+
+  _dependencies->Add(child_);
+}
+
+/// Unregister a sequence which received change notifications
+void c4_Sequence::Detach(c4_Sequence *child_) {
+  d4_assert(_dependencies != 0);
+
+  if (!_dependencies->Remove(child_)) {
+    delete _dependencies;
+    _dependencies = 0;
+  }
+
+  DecRef();
+}
+
+/// Called just before a change is made to the sequence
+c4_Notifier *c4_Sequence::PreChange(c4_Notifier &) {
+  d4_assert(0); // should not be called, because it should not attach
+  return 0;
+}
+
+/// Called after changes have been made to the sequence
+void c4_Sequence::PostChange(c4_Notifier &){}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Reference &c4_Reference::operator = (const c4_Reference &value_) {
+  c4_Bytes result;
+  value_.GetData(result);
+  SetData(result);
+
+  return  *this;
+}
+
+bool operator == (const c4_Reference &a_, const c4_Reference &b_) {
+  c4_Bytes buf1;
+  bool f1 = a_.GetData(buf1);
+
+  c4_Bytes buf2;
+  bool f2 = b_.GetData(buf2);
+
+  // if absent, fill either with zero bytes to match length
+  if (!f1)
+    buf1.SetBufferClear(buf2.Size());
+  if (!f2)
+    buf2.SetBufferClear(buf1.Size());
+
+  return buf1 == buf2;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_IntRef::operator t4_i32()const {
+  c4_Bytes result;
+  if (!GetData(result))
+    return 0;
+
+  d4_assert(result.Size() == sizeof(t4_i32));
+  return *(const t4_i32*)result.Contents();
+}
+
+c4_IntRef &c4_IntRef::operator = (t4_i32 value_) {
+  SetData(c4_Bytes(&value_, sizeof value_));
+  return  *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#if !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+
+c4_LongRef::operator t4_i64()const {
+  c4_Bytes result;
+  if (!GetData(result)) {
+    static t4_i64 zero;
+    return zero;
+  }
+
+  d4_assert(result.Size() == sizeof(t4_i64));
+  return *(const t4_i64*)result.Contents();
+}
+
+c4_LongRef &c4_LongRef::operator = (t4_i64 value_) {
+  SetData(c4_Bytes(&value_, sizeof value_));
+  return  *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_FloatRef::operator double()const {
+  c4_Bytes result;
+  if (!GetData(result))
+    return 0;
+
+  d4_assert(result.Size() == sizeof(float));
+  return *(const float*)result.Contents();
+}
+
+c4_FloatRef &c4_FloatRef::operator = (double value_) {
+  float v = (float)value_; // loses precision
+  SetData(c4_Bytes(&v, sizeof v));
+  return  *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_DoubleRef::operator double()const {
+  c4_Bytes result;
+  if (!GetData(result))
+    return 0;
+
+  d4_assert(result.Size() == sizeof(double));
+  return *(const double*)result.Contents();
+}
+
+c4_DoubleRef &c4_DoubleRef::operator = (double value_) {
+  SetData(c4_Bytes(&value_, sizeof value_));
+  return  *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // !q4_TINY
+/////////////////////////////////////////////////////////////////////////////
+
+c4_BytesRef::operator c4_Bytes()const {
+  c4_Bytes result;
+  GetData(result);
+
+  // the result must immediately be used, its lifetime may be limited
+  return result;
+}
+
+c4_BytesRef &c4_BytesRef::operator = (const c4_Bytes &value_) {
+  SetData(value_);
+  return  *this;
+}
+
+c4_Bytes c4_BytesRef::Access(t4_i32 off_, int len_, bool noCopy_)const {
+  c4_Bytes &buffer = _cursor._seq->Buffer();
+
+  int colNum = _cursor._seq->PropIndex(_property.GetId());
+  if (colNum >= 0) {
+    c4_Handler &h = _cursor._seq->NthHandler(colNum);
+    int sz = h.ItemSize(_cursor._index);
+    if (len_ == 0 || off_ + len_ > sz)
+      len_ = sz - off_;
+
+    if (len_ > 0) {
+      c4_Column *col = h.GetNthMemoCol(_cursor._index, true);
+      if (col != 0) {
+        if (noCopy_) {
+          // 21-11-2005 optimization by A. Stigsen
+          // return just the first segment (even if it is smaller than
+          // len). this avoids any expensive memcopies, but you have to
+          // remember to check length of the returned bytes.
+          c4_ColIter iter(*col, off_, off_ + len_);
+          iter.Next();
+          return c4_Bytes(iter.BufLoad(), iter.BufLen() < len_ ? iter.BufLen():
+            len_);
+        } else {
+          const t4_byte *bytes = col->FetchBytes(off_, len_, buffer, false);
+          if (bytes == buffer.Contents())
+            return buffer;
+          return c4_Bytes(bytes, len_);
+        }
+      } else
+       { // do it the hard way for custom/mapped views (2002-03-13)
+        c4_Bytes result;
+        GetData(result);
+        d4_assert(off_ + len_ <= result.Size());
+        return c4_Bytes(result.Contents() + off_, len_, true);
+      }
+    }
+  }
+
+  return c4_Bytes();
+}
+
+bool c4_BytesRef::Modify(const c4_Bytes &buf_, t4_i32 off_, int diff_)const {
+  int colNum = _cursor._seq->PropIndex(_property.GetId());
+  if (colNum >= 0) {
+    c4_Handler &h = _cursor._seq->NthHandler(colNum);
+    const int n = buf_.Size();
+    const t4_i32 limit = off_ + n; // past changed bytes
+    const t4_i32 overshoot = limit - h.ItemSize(_cursor._index);
+
+    if (diff_ < overshoot)
+      diff_ = overshoot;
+
+    c4_Column *col = h.GetNthMemoCol(_cursor._index, true);
+    if (col != 0) {
+      if (diff_ < 0)
+        col->Shrink(limit,  - diff_);
+      else if (diff_ > 0)
+      // insert bytes in the highest possible spot
+      // if a gap is created, it will contain garbage
+        col->Grow(overshoot > 0 ? col->ColSize(): diff_ > n ? off_ : limit -
+          diff_, diff_);
+
+      col->StoreBytes(off_, buf_);
+    } else
+     { // do it the hard way for custom/mapped views (2002-03-13)
+      c4_Bytes orig;
+      GetData(orig);
+
+      c4_Bytes result;
+      t4_byte *ptr = result.SetBuffer(orig.Size() + diff_);
+
+      memcpy(ptr, orig.Contents(), off_);
+      memcpy(ptr + off_, buf_.Contents(), n);
+      memcpy(ptr + off_ + n, orig.Contents() + off_, orig.Size() - off_);
+
+      SetData(result);
+    }
+    return true;
+  }
+
+  return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_StringRef::operator const char *()const {
+  c4_Bytes result;
+  GetData(result);
+
+  return result.Size() > 0 ? (const char*)result.Contents(): "";
+}
+
+c4_StringRef &c4_StringRef::operator = (const char *value_) {
+  SetData(c4_Bytes(value_, strlen(value_) + 1));
+  return  *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_ViewRef::operator c4_View()const {
+  c4_Bytes result;
+  if (!GetData(result))
+    return (c4_Sequence*)0;
+  // resolve ambiguity
+
+  d4_assert(result.Size() == sizeof(c4_Sequence*));
+  return *(c4_Sequence *const*)result.Contents();
+}
+
+c4_ViewRef &c4_ViewRef::operator = (const c4_View &value_) {
+  SetData(c4_Bytes(&value_._seq, sizeof value_._seq));
+  return  *this;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Stream::~c4_Stream(){}
+
+/////////////////////////////////////////////////////////////////////////////
+
+c4_Strategy::c4_Strategy(): _bytesFlipped(false), _failure(0), _mapStart(0),
+  _dataSize(0), _baseOffset(0), _rootPos( - 1), _rootLen( - 1){}
+
+c4_Strategy::~c4_Strategy() {
+  d4_assert(_mapStart == 0);
+}
+
+/// Read a number of bytes
+int c4_Strategy::DataRead(t4_i32, void *, int) {
+  /*
+  if (_mapStart != 0 && pos_ + length_ <= _dataSize)
+  {
+  memcpy(buffer_, _mapStart + pos_, length_);
+  return length_;
+  }
+   */
+  ++_failure;
+  return  - 1;
+}
+
+/// Write a number of bytes, return true if successful
+void c4_Strategy::DataWrite(t4_i32, const void *, int) {
+  ++_failure;
+}
+
+/// Flush and truncate file
+void c4_Strategy::DataCommit(t4_i32){}
+
+/// Override to support memory-mapped files
+void c4_Strategy::ResetFileMapping(){}
+
+/// Report total size of the datafile
+t4_i32 c4_Strategy::FileSize() {
+  return _dataSize;
+}
+
+/// Return a value to use as fresh generation counter
+t4_i32 c4_Strategy::FreshGeneration() {
+  return 1;
+}
+
+/// Define the base offset where data is stored
+void c4_Strategy::SetBase(t4_i32 base_) {
+  t4_i32 off = base_ - _baseOffset;
+  _baseOffset = base_;
+  _dataSize -= off;
+  if (_mapStart != 0)
+    _mapStart += off;
+}
+
+/*
+end_ is file position to start from (0 defaults to FileSize())
+
+result is the logical end of the datafile (or -1 if no data)
+
+This code uses a tiny state machine so all the code to read and decode
+file marks is in one place within the loop.
+ */
+
+/// Scan datafile head/tail markers, return logical end of data
+t4_i32 c4_Strategy::EndOfData(t4_i32 end_) {
+  enum {
+    kStateAtEnd, kStateCommit, kStateHead, kStateOld, kStateDone
+  };
+
+  t4_i32 pos = (end_ >= 0 ? end_ : FileSize()) - _baseOffset;
+  t4_i32 last = pos;
+  t4_i32 rootPos = 0;
+  t4_i32 rootLen =  - 1; // impossible value, flags old-style header
+  t4_byte mark[8];
+
+  for (int state = kStateAtEnd; state != kStateDone;) {
+    pos -= 8;
+    if (pos + _baseOffset < 0 && state != kStateOld) {
+      // bad offset, try old-style header from start of file
+      pos =  - _baseOffset;
+      state = kStateOld;
+    }
+
+    if (DataRead(pos, &mark, sizeof mark) != sizeof mark)
+      return  - 1;
+
+    t4_i32 count = 0;
+    for (int i = 1; i < 4; ++i)
+      count = (count << 8) + mark[i];
+
+    t4_i32 offset = 0;
+    for (int j = 4; j < 8; ++j)
+      offset = (offset << 8) + mark[j];
+
+    const bool isSkipTail = ((mark[0] & 0xF0) == 0x90 /* 2006-11-11 */ ||
+                             mark[0] == 0x80 && count == 0) && offset > 0;
+    const bool isCommitTail = mark[0] == 0x80 && count > 0 && offset > 0;
+    const bool isHeader = (mark[0] == 'J' || mark[0] == 'L') && (mark[0] ^
+      mark[1]) == ('J' ^ 'L') && mark[2] == 0x1A && (mark[3] & 0x40) == 0;
+      
+    switch (state) {
+      case kStateAtEnd:
+        // no commit tail found yet
+
+        if (isSkipTail) {
+          pos -= offset;
+          last = pos;
+        }
+         else if (isCommitTail) {
+          rootPos = offset;
+          rootLen = count;
+          state = kStateCommit;
+        }
+         else {
+          pos = 8;
+          state = kStateOld;
+        }
+        break;
+
+      case kStateCommit:
+        // commit tail must be preceded by skip tail
+
+        if (!isSkipTail)
+          return  - 1;
+        pos -= offset - 8;
+        state = kStateHead;
+        break;
+
+      case kStateHead:
+        // fetch the header
+
+        if (!isHeader) {
+          pos = 8;
+          state = kStateOld;
+        }
+         else {
+          state = kStateDone;
+        }
+        break;
+
+      case kStateOld:
+        // old format, look for header in first 4 Kb
+
+        if (isHeader && mark[3] == 0x80) {
+          d4_assert(rootPos == 0);
+          for (int k = 8; --k >= 4;)
+          // old header is little-endian
+            rootPos = (rootPos << 8) + mark[k];
+          state = kStateDone;
+        }
+         else {
+          pos += 16;
+          if (pos > 4096)
+            return  - 1;
+        }
+        break;
+    }
+  }
+
+  last += _baseOffset; // all seeks were relative to current offset
+
+  if (end_ >= 0)
+   { // if end was specified, then adjust this strategy object
+    _baseOffset += pos;
+    d4_assert(_baseOffset >= 0);
+    if (_mapStart != 0) {
+      _mapStart += pos;
+      _dataSize -= pos;
+    }
+
+    _rootPos = rootPos;
+    _rootLen = rootLen;
+  }
+
+  d4_assert(mark[0] == 'J' || mark[1] == 'J');
+  _bytesFlipped = (char)*(const short*)mark != 'J';
+
+  return last;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/src/win.h b/8.x/mk/src/win.h
new file mode 100755 (executable)
index 0000000..ce76dd4
--- /dev/null
@@ -0,0 +1,33 @@
+// win.h --
+// $Id: win.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+/** @file
+ * Configuration header for Windows builds
+ */
+
+#if defined (_MSDOS)
+#define q4_DOS 1
+#endif 
+
+#if defined (_WINDOWS)
+#define q4_WIN 1
+#endif 
+
+#if defined (_WIN32)
+#define q4_WIN32 1
+#endif 
+
+#if defined (_WIN32_WCE)       // check for Win CE
+#define q4_WINCE 1
+#define q4_WIN32 1
+#endif 
+
+#if q4_WIN32                    // WIN32 implies WIN
+#undef q4_WIN
+#define q4_WIN 1
+#endif 
+
+#if q4_WIN                      // WIN implies not DOS, even for Win3
+#undef q4_DOS
+#endif
diff --git a/8.x/mk/tcl/Makefile.in b/8.x/mk/tcl/Makefile.in
new file mode 100755 (executable)
index 0000000..ad93db6
--- /dev/null
@@ -0,0 +1,281 @@
+# Makefile.in --
+#
+#      This file is a Makefile for Sample TEA Extension.  If it has the name
+#      "Makefile.in" then it is a template for a Makefile;  to generate the
+#      actual Makefile, run "./configure", which is a configuration script
+#      generated by the "autoconf" program (constructs like "@foo@" will get
+#      replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+# Copyright (c) 2002-2003 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+PKG_SOURCES    = @PKG_SOURCES@
+PKG_OBJECTS    = @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+
+PKG_HEADERS    = @PKG_HEADERS@
+
+PKG_LIB_FILE   = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES   = $(PKG_LIB_FILE)
+BINARIES       = $(lib_BINARIES)
+
+SHELL          = @SHELL@
+
+srcdir         = @srcdir@
+prefix         = @prefix@
+exec_prefix    = @exec_prefix@
+
+bindir         = @bindir@
+libdir         = @libdir@
+includedir     = @includedir@
+datarootdir     = @datarootdir@
+datadir                = @datadir@
+mandir         = @mandir@
+
+DESTDIR                =
+
+PKG_DIR                = $(PACKAGE_NAME)$(PACKAGE_VERSION)
+pkgdatadir     = $(datadir)/$(PKG_DIR)
+pkglibdir      = $(libdir)/$(PKG_DIR)
+pkgincludedir  = $(includedir)/$(PKG_DIR)
+
+top_builddir   = .
+
+INSTALL                = @INSTALL@
+INSTALL_PROGRAM        = @INSTALL_PROGRAM@
+INSTALL_DATA   = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+PACKAGE_NAME   = @PACKAGE_NAME@
+PACKAGE_VERSION        = @PACKAGE_VERSION@
+CC             = @CC@
+CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+EXEEXT         = @EXEEXT@
+LDFLAGS_DEFAULT        = @LDFLAGS_DEFAULT@
+MAKE_LIB       = @MAKE_LIB@
+MAKE_SHARED_LIB        = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB        = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB  = @MAKE_STUB_LIB@
+OBJEXT         = @OBJEXT@
+RANLIB         = @RANLIB@
+RANLIB_STUB    = @RANLIB_STUB@
+SHLIB_CFLAGS   = @SHLIB_CFLAGS@
+SHLIB_LD       = @SHLIB_LD@
+SHLIB_LD_LIBS  = @SHLIB_LD_LIBS@
+STLIB_LD       = @STLIB_LD@
+TCL_BIN_DIR    = @TCL_BIN_DIR@
+TCL_SRC_DIR    = @TCL_SRC_DIR@
+
+#TCL_LIBS      = @TCL_LIBS@
+
+EXTRA_PATH     = $(top_builddir):$(TCL_BIN_DIR)
+TCLLIBPATH     = $(top_builddir)
+TCLSH_ENV      = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
+                 @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+                 PATH="$(EXTRA_PATH):$(PATH)" \
+                 TCLLIBPATH="$(TCLLIBPATH)"
+
+TCLSH_PROG     = @TCLSH_PROG@
+TCLSH          = $(TCLSH_ENV) $(TCLSH_PROG)
+
+SHARED_BUILD   = @SHARED_BUILD@
+
+INCLUDES       = @PKG_INCLUDES@ @TCL_INCLUDES@
+
+PKG_CFLAGS     = @PKG_CFLAGS@
+
+DEFS           = @DEFS@ $(PKG_CFLAGS)
+
+CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl config.h
+CLEANFILES     = @CLEANFILES@
+
+CPPFLAGS       = @CPPFLAGS@
+LIBS           = @PKG_LIBS@ @LIBS@
+AR             = @AR@
+CFLAGS         = @CFLAGS@
+COMPILE                = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+all: binaries libraries doc
+
+binaries: $(BINARIES)
+
+libraries:
+
+doc:
+       @echo "If you have documentation to create, place the commands to"
+       @echo "build the docs in the 'doc:' target.  For example:"
+       @echo "        xml2nroff sample.xml > sample.n"
+       @echo "        xml2html sample.xml > sample.html"
+
+install: all install-binaries install-libraries install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+
+install-libraries: libraries
+       @mkdir -p $(DESTDIR)$(includedir)
+       @echo "Installing header files in $(DESTDIR)$(includedir)"
+       @list='$(PKG_HEADERS)'; for i in $$list; do \
+           echo "Installing $(srcdir)/$$i" ; \
+           $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+       done;
+
+install-doc: doc
+       @mkdir -p $(DESTDIR)$(mandir)/mann
+       @echo "Installing documentation in $(DESTDIR)$(mandir)"
+       @list='$(srcdir)/doc/*.n'; for i in $$list; do \
+           echo "Installing $$i"; \
+           rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
+           $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
+       done
+
+test: binaries libraries
+       $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+shell: binaries libraries
+       @$(TCLSH) $(SCRIPT)
+
+gdb:
+       $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+       -rm -f $(PKG_LIB_FILE)
+       ${MAKE_LIB}
+       $(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+       -rm -f $(PKG_STUB_LIB_FILE)
+       ${MAKE_STUB_LIB}
+       $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win
+VPATH = $(srcdir):$(srcdir)/../src
+
+.cpp.@OBJEXT@:
+       $(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#COMPRESS      = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS       = gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT      = /tmp/dist
+DIST_DIR       = $(DIST_ROOT)/$(PKG_DIR)
+
+dist-clean:
+       rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
+
+dist: dist-clean
+       mkdir -p $(DIST_DIR)
+       cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
+               $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
+               $(DIST_DIR)/
+       chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
+       chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
+
+       for i in $(srcdir)/*.[ch]; do \
+           if [ -f $$i ]; then \
+               cp -p $$i $(DIST_DIR)/ ; \
+           fi; \
+       done;
+
+       mkdir $(DIST_DIR)/tclconfig
+       cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
+               $(DIST_DIR)/tclconfig/
+       chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
+       chmod +x $(DIST_DIR)/tclconfig/install-sh
+
+       list='demos doc generic library mac tests unix win'; \
+       for p in $$list; do \
+           if test -d $(srcdir)/$$p ; then \
+               mkdir $(DIST_DIR)/$$p; \
+               cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
+           fi; \
+       done
+
+       (cd $(DIST_ROOT); $(COMPRESS);)
+
+clean:  
+       -test -z "$(BINARIES)" || rm -f $(BINARIES)
+       -rm -f *.$(OBJEXT) core *.core
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+       -rm -f *.tab.c
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log config.status
+
+install-lib-binaries: binaries
+       @mkdir -p $(DESTDIR)$(pkglibdir)
+       @list='$(lib_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+           stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
+           if test "x$$stub" = "xstub"; then \
+               echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
+           else \
+               echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
+           fi; \
+           ext=`echo $$p|sed -e "s/.*\.//"`; \
+           if test "x$$ext" = "xdll"; then \
+               lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+               if test -f $$lib; then \
+                   echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
+                   $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+               fi; \
+           fi; \
+         fi; \
+       done
+       @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         if test -f $(srcdir)/$$p; then \
+           destp=`basename $$p`; \
+           echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
+           $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
+         fi; \
+       done
+       @if test "x$(SHARED_BUILD)" = "x1"; then \
+           echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
+           $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
+       fi
+
+install-bin-binaries: binaries
+       @mkdir -p $(DESTDIR)$(bindir)
+       @list='$(bin_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+         fi; \
+       done
+
+.SUFFIXES: .cpp .$(OBJEXT)
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+       list='$(lib_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         p=`basename $$p`; \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(bin_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/$$p; \
+       done
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+
+.NOEXPORT:
diff --git a/8.x/mk/tcl/aclocal.m4 b/8.x/mk/tcl/aclocal.m4
new file mode 100755 (executable)
index 0000000..0b05739
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Include the TEA standard macro set
+#
+
+builtin(include,tclconfig/tcl.m4)
+
+#
+# Add here whatever m4 macros you want to define for your package
+#
diff --git a/8.x/mk/tcl/config.h.in b/8.x/mk/tcl/config.h.in
new file mode 100755 (executable)
index 0000000..ba73917
--- /dev/null
@@ -0,0 +1,56 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if the system has the type `long long'. */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+   if it is not supported. */
+#undef inline
diff --git a/8.x/mk/tcl/configure b/8.x/mk/tcl/configure
new file mode 100755 (executable)
index 0000000..51e5bc1
--- /dev/null
@@ -0,0 +1,10773 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for Mk4tcl 2.4.9.7.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='Mk4tcl'
+PACKAGE_TARNAME='mk4tcl'
+PACKAGE_VERSION='2.4.9.7'
+PACKAGE_STRING='Mk4tcl 2.4.9.7'
+PACKAGE_BUGREPORT=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS PKG_SOURCES PKG_OBJECTS CLEANFILES TCL_INCLUDES TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS LD_LIBRARY_PATH_VAR TCL_DBGX CFLAGS_DEFAULT LDFLAGS_DEFAULT MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Mk4tcl 2.4.9.7 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Mk4tcl 2.4.9.7:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-threads        build with threads
+  --enable-shared         build and link with shared libraries (default: on)
+  --enable-64bit          enable 64bit support (default: off)
+  --enable-64bit-vis      enable 64bit Sparc VIS support (default: off)
+  --enable-wince          enable Win/CE support (where applicable)
+  --enable-load           allow dynamic loading and "load" command (default:
+                          on)
+  --enable-symbols        build with debugging symbols (default: off)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-tcl              directory containing tcl configuration
+                          (tclConfig.sh)
+  --with-tclinclude       directory containing the public Tcl header files
+  --with-celib=DIR        use Windows/CE support library from DIR
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+Mk4tcl configure 2.4.9.7
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Mk4tcl $as_me 2.4.9.7, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.6"
+
+    echo "$as_me:$LINENO: checking for correct TEA configuration" >&5
+echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6
+    if test x"${PACKAGE_NAME}" = x ; then
+       { { echo "$as_me:$LINENO: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5
+echo "$as_me: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test x"3.6" = x ; then
+       { { echo "$as_me:$LINENO: error:
+TEA version not specified." >&5
+echo "$as_me: error:
+TEA version not specified." >&2;}
+   { (exit 1); exit 1; }; }
+    elif test "3.6" != "${TEA_VERSION}" ; then
+       echo "$as_me:$LINENO: result: warning: requested TEA version \"3.6\", have \"${TEA_VERSION}\"" >&5
+echo "${ECHO_T}warning: requested TEA version \"3.6\", have \"${TEA_VERSION}\"" >&6
+    else
+       echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5
+echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+           # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CYGPATH+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CYGPATH"; then
+  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CYGPATH="cygpath -w"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+  echo "$as_me:$LINENO: result: $CYGPATH" >&5
+echo "${ECHO_T}$CYGPATH" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+
+
+
+    # This package name must be replaced statically for AC_SUBST to work
+
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in tclconfig $srcdir/tclconfig; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+
+
+
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+
+# Check whether --with-tcl or --without-tcl was given.
+if test "${with_tcl+set}" = set; then
+  withval="$with_tcl"
+  with_tclconfig=${withval}
+fi;
+       echo "$as_me:$LINENO: checking for Tcl configuration" >&5
+echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6
+       if test "${ac_cv_c_tclconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
+echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5
+echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+
+fi
+
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           { echo "$as_me:$LINENO: WARNING: Can't find Tcl configuration definitions" >&5
+echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;}
+           exit 0
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6
+       fi
+    fi
+
+
+    echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        echo "$as_me:$LINENO: result: loading" >&5
+echo "${ECHO_T}loading" >&6
+       . "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
+echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
+           prefix=${TCL_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5
+echo "$as_me: --prefix defaulting to /usr/local" >&6;}
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
+echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5
+echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;}
+           exec_prefix=$prefix
+       fi
+    fi
+
+
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+    # Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5
+echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6
+if test "${tcl_cv_cc_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_pipe=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_pipe=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5
+echo "${ECHO_T}$tcl_cv_cc_pipe" >&6
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+    if test "${TEA_PLATFORM}" = "unix" ; then
+
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking for sin" >&5
+echo $ECHO_N "checking for sin... $ECHO_C" >&6
+if test "${ac_cv_func_sin+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define sin to an innocuous variant, in case <limits.h> declares sin.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define sin innocuous_sin
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char sin (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef sin
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char sin ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_sin) || defined (__stub___sin)
+choke me
+#else
+char (*f) () = sin;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != sin;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_sin=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_sin=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5
+echo "${ECHO_T}$ac_cv_func_sin" >&6
+if test $ac_cv_func_sin = yes; then
+  MATH_LIBS=""
+else
+  MATH_LIBS="-lm"
+fi
+
+    echo "$as_me:$LINENO: checking for main in -lieee" >&5
+echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6
+if test "${ac_cv_lib_ieee_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lieee  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ieee_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ieee_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5
+echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6
+if test $ac_cv_lib_ieee_main = yes; then
+  MATH_LIBS="-lieee $MATH_LIBS"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking for main in -linet" >&5
+echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6
+if test "${ac_cv_lib_inet_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5
+echo "${ECHO_T}$ac_cv_lib_inet_main" >&6
+if test $ac_cv_lib_inet_main = yes; then
+  LIBS="$LIBS -linet"
+fi
+
+    if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking net/errno.h usability" >&5
+echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <net/errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking net/errno.h presence" >&5
+echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <net/errno.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: net/errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_net_errno_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
+
+fi
+if test $ac_cv_header_net_errno_h = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NET_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+if test $ac_cv_func_connect = yes; then
+  tcl_checkSocket=0
+else
+  tcl_checkSocket=1
+fi
+
+    if test "$tcl_checkSocket" = 1; then
+       echo "$as_me:$LINENO: checking for setsockopt" >&5
+echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6
+if test "${ac_cv_func_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define setsockopt to an innocuous variant, in case <limits.h> declares setsockopt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define setsockopt innocuous_setsockopt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char setsockopt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef setsockopt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char setsockopt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_setsockopt) || defined (__stub___setsockopt)
+choke me
+#else
+char (*f) () = setsockopt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != setsockopt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_setsockopt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_func_setsockopt" >&6
+if test $ac_cv_func_setsockopt = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5
+echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char setsockopt ();
+int
+main ()
+{
+setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_setsockopt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6
+if test $ac_cv_lib_socket_setsockopt = yes; then
+  LIBS="$LIBS -lsocket"
+else
+  tcl_checkBoth=1
+fi
+
+fi
+
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       echo "$as_me:$LINENO: checking for accept" >&5
+echo $ECHO_N "checking for accept... $ECHO_C" >&6
+if test "${ac_cv_func_accept+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define accept to an innocuous variant, in case <limits.h> declares accept.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define accept innocuous_accept
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char accept (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef accept
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char accept ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_accept) || defined (__stub___accept)
+choke me
+#else
+char (*f) () = accept;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != accept;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_accept=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_accept=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5
+echo "${ECHO_T}$ac_cv_func_accept" >&6
+if test $ac_cv_func_accept = yes; then
+  tcl_checkNsl=0
+else
+  LIBS=$tk_oldLibs
+fi
+
+    fi
+    echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+char (*f) () = gethostbyname;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != gethostbyname;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
+if test $ac_cv_func_gethostbyname = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  LIBS="$LIBS -lnsl"
+fi
+
+fi
+
+
+    # Don't perform the eval of the libraries here because DL_LIBS
+    # won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+
+
+
+
+    echo "$as_me:$LINENO: checking dirent.h" >&5
+echo $ECHO_N "checking dirent.h... $ECHO_C" >&6
+if test "${tcl_cv_dirent_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_dirent_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_dirent_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5
+echo "${ECHO_T}$tcl_cv_dirent_h" >&6
+
+    if test $tcl_cv_dirent_h = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DIRENT_H 1
+_ACEOF
+
+    fi
+
+    if test "${ac_cv_header_errno_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking errno.h usability" >&5
+echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking errno.h presence" >&5
+echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <errno.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_errno_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+
+fi
+if test $ac_cv_header_errno_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_float_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking float.h usability" >&5
+echo $ECHO_N "checking float.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <float.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking float.h presence" >&5
+echo $ECHO_N "checking float.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <float.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: float.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_float_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6
+
+fi
+if test $ac_cv_header_float_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_FLOAT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_values_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking values.h usability" >&5
+echo $ECHO_N "checking values.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <values.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking values.h presence" >&5
+echo $ECHO_N "checking values.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <values.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: values.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_values_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6
+
+fi
+if test $ac_cv_header_values_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_VALUES_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_limits_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking limits.h usability" >&5
+echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <limits.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking limits.h presence" >&5
+echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <limits.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: limits.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_limits_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6
+
+fi
+if test $ac_cv_header_limits_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIMITS_H 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_LIMITS_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking stdlib.h usability" >&5
+echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <stdlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking stdlib.h presence" >&5
+echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: stdlib.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_stdlib_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
+
+fi
+if test $ac_cv_header_stdlib_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtol" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtoul" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtod" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STDLIB_H 1
+_ACEOF
+
+    fi
+    if test "${ac_cv_header_string_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking string.h usability" >&5
+echo $ECHO_N "checking string.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <string.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking string.h presence" >&5
+echo $ECHO_N "checking string.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: string.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_string_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6
+
+fi
+if test $ac_cv_header_string_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strstr" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strerror" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STRING_H 1
+_ACEOF
+
+    fi
+
+    if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/wait.h usability" >&5
+echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <sys/wait.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/wait.h presence" >&5
+echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/wait.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_wait_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+
+fi
+if test $ac_cv_header_sys_wait_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking dlfcn.h usability" >&5
+echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <dlfcn.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking dlfcn.h presence" >&5
+echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <dlfcn.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_dlfcn_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+
+fi
+if test $ac_cv_header_dlfcn_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DLFCN_H 1
+_ACEOF
+
+fi
+
+
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+
+for ac_header in sys/param.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to the Mk4tcl lists.  ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+
+
+
+    vars="../src/column.cpp
+                ../src/custom.cpp
+                ../src/derived.cpp
+                ../src/field.cpp
+                ../src/fileio.cpp
+                ../src/format.cpp
+                ../src/handler.cpp
+                ../src/persist.cpp
+                ../src/remap.cpp
+                ../src/std.cpp
+                ../src/store.cpp
+                ../src/string.cpp
+                ../src/table.cpp
+                ../src/univ.cpp
+                ../src/view.cpp
+                ../src/viewx.cpp
+                mk4tcl.cpp
+                mk4too.cpp"
+    for i in $vars; do
+       case $i in
+           \$*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5
+echo "$as_me: error: could not find source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+
+
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+
+
+
+    vars="-I\"${srcdir}/../include\" -I\"${srcdir}\" -I."
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+
+
+
+    vars=""
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+
+    PKG_CFLAGS="$PKG_CFLAGS "
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5
+echo "$as_me: error: could not find stub source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+
+
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    cat >>confdefs.h <<\_ACEOF
+#define BUILD_Mk4tcl 1
+_ACEOF
+
+    CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+    #TEA_ADD_SOURCES([win/winFile.c])
+    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+    CLEANFILES=""
+    #TEA_ADD_SOURCES([unix/unixFile.c])
+    #TEA_ADD_LIBS([-lsuperfly])
+fi
+
+
+
+    echo "$as_me:$LINENO: checking for Tcl public headers" >&5
+echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6
+
+
+# Check whether --with-tclinclude or --without-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then
+  withval="$with_tclinclude"
+  with_tclinclude=${withval}
+fi;
+
+    if test "${ac_cv_c_tclh+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5
+echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;}
+   { (exit 1); exit 1; }; }
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+
+fi
+
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       { { echo "$as_me:$LINENO: error: tcl.h not found.  Please specify its location with --with-tclinclude" >&5
+echo "$as_me: error: tcl.h not found.  Please specify its location with --with-tclinclude" >&2;}
+   { (exit 1); exit 1; }; }
+    else
+       echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5
+echo "${ECHO_T}${ac_cv_c_tclh}" >&6
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+
+
+
+    # Check whether --enable-threads or --disable-threads was given.
+if test "${enable_threads+set}" = set; then
+  enableval="$enable_threads"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_THREAD_ALLOC 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+           if test "`uname -s`" = "SunOS" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+           fi
+
+cat >>confdefs.h <<\_ACEOF
+#define _THREAD_SAFE 1
+_ACEOF
+
+           echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6
+if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char __pthread_mutex_init ();
+int
+main ()
+{
+__pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread___pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread___pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6
+if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6
+if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthreads_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthreads_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6
+if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6
+if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_c_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_c_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6
+if test $ac_cv_lib_c_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                   if test "$tcl_ok" = "no"; then
+                       echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6
+if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc_r  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_c_r_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_c_r_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6
+if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           { echo "$as_me:$LINENO: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5
+echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;}
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    echo "$as_me:$LINENO: checking for building with threads" >&5
+echo $ECHO_N "checking for building with threads... $ECHO_C" >&6
+    if test "${TCL_THREADS}" = 1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_THREADS 1
+_ACEOF
+
+       echo "$as_me:$LINENO: result: yes (default)" >&5
+echo "${ECHO_T}yes (default)" >&6
+    else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               { echo "$as_me:$LINENO: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&5
+echo "$as_me: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&2;}
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               { echo "$as_me:$LINENO: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&5
+echo "$as_me: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&2;}
+           fi
+           ;;
+    esac
+
+
+
+    echo "$as_me:$LINENO: checking how to build libraries" >&5
+echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6
+    # Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       echo "$as_me:$LINENO: result: shared" >&5
+echo "${ECHO_T}shared" >&6
+       SHARED_BUILD=1
+    else
+       echo "$as_me:$LINENO: result: static" >&5
+echo "${ECHO_T}static" >&6
+       SHARED_BUILD=0
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_BUILD 1
+_ACEOF
+
+    fi
+
+
+
+
+
+    # Step 0.a: Enable 64 bit support?
+
+    echo "$as_me:$LINENO: checking if 64bit support is requested" >&5
+echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6
+    # Check whether --enable-64bit or --disable-64bit was given.
+if test "${enable_64bit+set}" = set; then
+  enableval="$enable_64bit"
+  do64bit=$enableval
+else
+  do64bit=no
+fi;
+    echo "$as_me:$LINENO: result: $do64bit" >&5
+echo "${ECHO_T}$do64bit" >&6
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5
+echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6
+    # Check whether --enable-64bit-vis or --disable-64bit-vis was given.
+if test "${enable_64bit_vis+set}" = set; then
+  enableval="$enable_64bit_vis"
+  do64bitVIS=$enableval
+else
+  do64bitVIS=no
+fi;
+    echo "$as_me:$LINENO: result: $do64bitVIS" >&5
+echo "${ECHO_T}$do64bitVIS" >&6
+
+    if test "$do64bitVIS" = "yes"; then
+       # Force 64bit on with VIS
+       do64bit=yes
+    fi
+
+    # Step 0.c: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5
+echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6
+       # Check whether --enable-wince or --disable-wince was given.
+if test "${enable_wince+set}" = set; then
+  enableval="$enable_wince"
+  doWince=$enableval
+else
+  doWince=no
+fi;
+       echo "$as_me:$LINENO: result: $doWince" >&5
+echo "${ECHO_T}$doWince" >&6
+    fi
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+
+    echo "$as_me:$LINENO: checking system version" >&5
+echo $ECHO_N "checking system version... $ECHO_C" >&6
+if test "${tcl_cv_sys_version+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5
+echo "$as_me: WARNING: can't find uname command" >&2;}
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $3}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5
+echo "${ECHO_T}$tcl_cv_sys_version" >&6
+    system=$tcl_cv_sys_version
+
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  have_dl=yes
+else
+  have_dl=no
+fi
+
+
+    # Require ranlib early so we can override it in special cases below.
+
+
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    if test "$GCC" = "yes" ; then
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall -Wno-implicit-int"
+    else
+       CFLAGS_WARNING=""
+    fi
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+    # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    case $system in
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+                   { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5
+echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+                   do64bit="no"
+               else
+                   echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
+echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5
+echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               if test "$GCC" = "yes" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5
+echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+
+# Check whether --with-celib or --without-celib was given.
+if test "${with_celib+set}" = set; then
+  withval="$with_celib"
+  with_celibconfig=${withval}
+fi;
+       echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
+echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6
+       if test "${ac_cv_c_celibconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5
+echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+fi
+
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5
+echo "$as_me: error: Cannot find celib support library directory" >&2;}
+   { (exit 1); exit 1; }; }
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5
+echo "${ECHO_T}found $CELIB_DIR" >&6
+       fi
+    fi
+
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
+           if ($1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
+           if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
+           if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5
+echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;}
+   { (exit 1); exit 1; }; }
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+
+    vars="bufferoverflowU.lib"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower($0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+
+cat >>confdefs.h <<_ACEOF
+#define $i 1
+_ACEOF
+
+                   done
+
+cat >>confdefs.h <<_ACEOF
+#define _WIN32_WCE $CEVERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNDER_CE $CEVERSION
+_ACEOF
+
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r)
+                       # ok ...
+                       ;;
+                   *)
+                       CC=${CC}_r
+                       ;;
+               esac
+               echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5
+echo "${ECHO_T}Using $CC for compiling with threads" >&6
+           fi
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
+               if test "$GCC" = "yes" ; then
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+               fi
+           fi
+
+           if test "`uname -m`" = "ia64" ; then
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               if test "$GCC" = "yes" ; then
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               else
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+               fi
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           else
+               if test "$GCC" = "yes" ; then
+                   SHLIB_LD="gcc -shared"
+               else
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+               fi
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+           fi
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
+               case $LIBOBJS in
+    "tclLoadAix.$ac_objext"   | \
+  *" tclLoadAix.$ac_objext"   | \
+    "tclLoadAix.$ac_objext "* | \
+  *" tclLoadAix.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;;
+esac
+
+               DL_LIBS="-lld"
+           fi
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5
+echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6
+if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gettimeofday ();
+int
+main ()
+{
+gettimeofday ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bsd_gettimeofday=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bsd_gettimeofday=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5
+echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6
+if test $ac_cv_lib_bsd_gettimeofday = yes; then
+  libbsd=yes
+else
+  libbsd=no
+fi
+
+           if test $libbsd = yes; then
+               MATH_LIBS="$MATH_LIBS -lbsd"
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_DELTA_FOR_TZ 1
+_ACEOF
+
+           fi
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -nostart"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5
+echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6
+if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbind  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_ntoa ();
+int
+main ()
+{
+inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bind_inet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bind_inet_ntoa=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6
+if test $ac_cv_lib_bind_inet_ntoa = yes; then
+  LIBS="$LIBS -lbind -lsocket"
+fi
+
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD="cc -shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+
+cat >>confdefs.h <<\_ACEOF
+#define _XOPEN_SOURCE_EXTENDED 1
+_ACEOF
+
+           # Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           if test "`uname -m`" = "ia64" ; then
+               SHLIB_SUFFIX=".so"
+           else
+               SHLIB_SUFFIX=".sl"
+           fi
+           echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="gcc -shared"
+               SHLIB_LD_LIBS='${LIBS}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+
+           # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+           #CFLAGS="$CFLAGS +DAportable"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   hpux_arch=`${CC} -dumpmachine`
+                   case $hpux_arch in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD="${CC} -shared"
+                           SHLIB_LD_LIBS='${LIBS}'
+                           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+                           ;;
+                   esac
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+               fi
+           fi
+           ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+           else
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+           fi
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5
+echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
+               else
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               fi
+           fi
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           if test $do64bit = yes; then
+               echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_m64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_m64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_m64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                   CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5
+echo "${ECHO_T}$tcl_cv_cc_m64" >&6
+               if test $tcl_cv_cc_m64 = yes; then
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+               fi
+           fi
+
+           # The combo of gcc + glibc has a bug related
+           # to inlining of functions like strtod(). The
+           # -fno-builtin flag should address this problem
+           # but it does not work. The -fno-inline flag
+           # is kind of overkill but it works.
+           # Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+           if test x"${USE_COMPAT}" != x ; then
+               CFLAGS="$CFLAGS -fno-inline"
+           fi
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD="${CC} -shared"
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD="${CC} -shared "
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-*|FreeBSD-[1-2].*)
+           # NetBSD/SPARC needs -fPIC, -fpic will not do.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6
+           if test $tcl_cv_ld_elf = yes; then
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+           else
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           fi
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
+           case `machine` in
+           sparc|sparc64)
+               SHLIB_CFLAGS="-fPIC";;
+           *)
+               SHLIB_CFLAGS="-fpic";;
+           esac
+           SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6
+           if test $tcl_cv_ld_elf = yes; then
+               LDFLAGS=-Wl,-export-dynamic
+           else
+               LDFLAGS=""
+           fi
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       FreeBSD-*)
+           # FreeBSD 3.* and greater have ELF.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "${TCL_THREADS}" = "1" ; then
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+           fi
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           # To avoid discrepancies between what headers configure sees during
+           # preprocessing tests and compiling tests, move any -isysroot and
+           # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+           CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
+           CFLAGS="`echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
+           if test $do64bit = yes; then
+               case `arch` in
+                   ppc)
+                       echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_arch_ppc64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_arch_ppc64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_arch_ppc64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6
+                       if test $tcl_cv_cc_arch_ppc64 = yes; then
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+                       fi;;
+                   i386)
+                       echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_arch_x86_64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_arch_x86_64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_arch_x86_64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6
+                       if test $tcl_cv_cc_arch_x86_64 = yes; then
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+                       fi;;
+                   *)
+                       { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
+               esac
+           else
+               # Check for combined 32-bit and 64-bit fat build
+               echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
+                   echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
+                   fat_32_64=yes
+           fi
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5
+echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_single_module+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_single_module=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_single_module=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5
+echo "${ECHO_T}$tcl_cv_ld_single_module" >&6
+           if test $tcl_cv_ld_single_module = yes; then
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+           fi
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
+               "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4 && \
+               LDFLAGS="$LDFLAGS -prebind"
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5
+echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_search_paths_first+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_search_paths_first=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_search_paths_first=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5
+echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6
+           if test $tcl_cv_ld_search_paths_first = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+
+           # TEA specific: for Tk extensions, remove 64-bit arch flags from
+           # CFLAGS et al. for combined 32 & 64 bit fat builds as neither
+           # TkAqua nor TkX11 can be built for 64-bit at present.
+           test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}" && for v in CFLAGS CPPFLAGS LDFLAGS; do
+               eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'; done
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="cc -nostdlib -r"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+
+cat >>confdefs.h <<\_ACEOF
+#define _OE_SOCKETS 1
+_ACEOF
+
+           ;;
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export :'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD="ld -shared"
+           else
+               SHLIB_LD="ld -non_shared"
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+           else
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mieee"
+            else
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+           fi
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           if test "${TCL_THREADS}" = "1" ; then
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               if test "$GCC" = "yes" ; then
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+               else
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+               fi
+           fi
+
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           if test "$GCC" = "yes" ; then
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+           else
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+           fi
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[0-6])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               arch=`isainfo`
+               if test "$arch" = "sparcv9 sparc" ; then
+                       if test "$GCC" = "yes" ; then
+                           if test "`gcc -dumpversion | awk -F. '{print $1}'`" -lt "3" ; then
+                               { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
+                           else
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                               LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                               SHLIB_CFLAGS="-fPIC"
+                           fi
+                       else
+                           do64bit_ok=yes
+                           if test "$do64bitVIS" = "yes" ; then
+                               CFLAGS="$CFLAGS -xarch=v9a"
+                               LDFLAGS_ARCH="-xarch=v9a"
+                           else
+                               CFLAGS="$CFLAGS -xarch=v9"
+                               LDFLAGS_ARCH="-xarch=v9"
+                           fi
+                           # Solaris 64 uses this as well
+                           #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+                       fi
+               elif test "$arch" = "amd64 i386" ; then
+                   if test "$GCC" = "yes" ; then
+                       { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+                   else
+                       do64bit_ok=yes
+                       CFLAGS="$CFLAGS -xarch=amd64"
+                       LDFLAGS="$LDFLAGS -xarch=amd64"
+                   fi
+               else
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5
+echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+               fi
+           fi
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               if test "$do64bit_ok" = "yes" ; then
+                   # We need to specify -static-libgcc or we need to
+                   # add the path to the sparv9 libgcc.
+                   # JH: static-libgcc is necessary for core Tcl, but may
+                   # not be necessary for extensions.
+                   SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                   # for finding sparcv9 libgcc, get the regular libgcc
+                   # path, remove so name and append 'sparcv9'
+                   #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                   #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+               fi
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           fi
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5
+echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_Bexport+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_Bexport=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_Bexport=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5
+echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6
+           if test $tcl_cv_ld_Bexport = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
+       { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+    fi
+
+
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    # Check whether --enable-load or --disable-load was given.
+if test "${enable_load+set}" = set; then
+  enableval="$enable_load"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+    if test "$tcl_ok" = "no"; then
+       DL_OBJS=""
+    fi
+
+    if test "x$DL_OBJS" != "x" ; then
+       BUILD_DLTEST="\$(DLTEST_TARGETS)"
+    else
+       echo "Can't figure out how to do dynamic loading or shared libraries"
+       echo "on this system."
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+    fi
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$DL_OBJS" != "tclLoadNone.o" ; then
+       if test "$GCC" = "yes" ; then
+           case $system in
+               AIX-*)
+                   ;;
+               BSD/OS*)
+                   ;;
+               IRIX*)
+                   ;;
+               NetBSD-*|FreeBSD-*)
+                   ;;
+               Darwin-*)
+                   ;;
+               SCO_SV-3.2*)
+                   ;;
+               windows)
+                   ;;
+               *)
+                   SHLIB_CFLAGS="-fPIC"
+                   ;;
+           esac
+       fi
+    fi
+
+    if test "$SHARED_LIB_SUFFIX" = "" ; then
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+    fi
+    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+    fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+
+    echo "$as_me:$LINENO: checking for required early compiler flags" >&5
+echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6
+    tcl_flags=""
+
+    if test "${tcl_cv_flag__isoc99_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__isoc99_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__isoc99_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__isoc99_source=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _ISOC99_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _ISOC99_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile64_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile64_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE64_SOURCE 1
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile64_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__largefile64_source=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE64_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile_source64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile_source64=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE_SOURCE64 1
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile_source64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__largefile_source64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE_SOURCE64 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
+    fi
+
+    if test "x${tcl_flags}" = "x" ; then
+       echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+    else
+       echo "$as_me:$LINENO: result: ${tcl_flags}" >&5
+echo "${ECHO_T}${tcl_flags}" >&6
+    fi
+
+
+    echo "$as_me:$LINENO: checking for 64-bit integer type" >&5
+echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6
+    if test "${tcl_cv_type_64bit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__int64 value = (__int64) 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_type_64bit=__int64
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_type_64bit="long long"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+switch (0) {
+            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+        }
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_type_64bit=${tcl_type_64bit}
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "${tcl_cv_type_64bit}" = none ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_WIDE_INT_IS_LONG 1
+_ACEOF
+
+       echo "$as_me:$LINENO: result: using long" >&5
+echo "${ECHO_T}using long" >&6
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # We actually want to use the default tcl.h checks in this
+       # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       echo "$as_me:$LINENO: result: using Tcl header defaults" >&5
+echo "${ECHO_T}using Tcl header defaults" >&6
+    else
+
+cat >>confdefs.h <<_ACEOF
+#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
+_ACEOF
+
+       echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5
+echo "${ECHO_T}${tcl_cv_type_64bit}" >&6
+
+       # Now check for auxiliary declarations
+       echo "$as_me:$LINENO: checking for struct dirent64" >&5
+echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6
+if test "${tcl_cv_struct_dirent64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/dirent.h>
+int
+main ()
+{
+struct dirent64 p;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_struct_dirent64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_struct_dirent64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5
+echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_DIRENT64 1
+_ACEOF
+
+       fi
+
+       echo "$as_me:$LINENO: checking for struct stat64" >&5
+echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6
+if test "${tcl_cv_struct_stat64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 p;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_struct_stat64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_struct_stat64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5
+echo "${ECHO_T}$tcl_cv_struct_stat64" >&6
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_STAT64 1
+_ACEOF
+
+       fi
+
+
+
+for ac_func in open64 lseek64
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+       echo "$as_me:$LINENO: checking for off64_t" >&5
+echo $ECHO_N "checking for off64_t... $ECHO_C" >&6
+       if test "${tcl_cv_type_off64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+off64_t offset;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_type_off64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_type_off64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+                       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TYPE_OFF64_T 1
+_ACEOF
+
+           echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+           echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+       fi
+    fi
+
+
+
+
+    echo "$as_me:$LINENO: checking for build with symbols" >&5
+echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6
+    # Check whether --enable-symbols or --disable-symbols was given.
+if test "${enable_symbols+set}" = set; then
+  enableval="$enable_symbols"
+  tcl_ok=$enableval
+else
+  tcl_ok=no
+fi;
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
+echo "${ECHO_T}yes (standard debugging)" >&6
+       fi
+    fi
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+
+
+
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_MEM_DEBUG 1
+_ACEOF
+
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5
+echo "${ECHO_T}enabled symbols mem debugging" >&6
+       else
+           echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
+echo "${ECHO_T}enabled $tcl_ok debugging" >&6
+       fi
+    fi
+
+
+if test "${SHARED_BUILD}" = "1"; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_TCL_STUBS 1
+_ACEOF
+fi
+
+
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+
+
+
+
+
+
+
+    echo "$as_me:$LINENO: checking for tclsh" >&5
+echo $ECHO_N "checking for tclsh... $ECHO_C" >&6
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+    fi
+    echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5
+echo "${ECHO_T}${TCLSH_PROG}" >&6
+
+
+
+                              ac_config_files="$ac_config_files Makefile pkgIndex.tcl config.h"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by Mk4tcl $as_me 2.4.9.7, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+Mk4tcl config.status 2.4.9.7
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "pkgIndex.tcl" ) CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;;
+  "config.h" ) CONFIG_FILES="$CONFIG_FILES config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CYGPATH@,$CYGPATH,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t
+s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t
+s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t
+s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t
+s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t
+s,@PKG_HEADERS@,$PKG_HEADERS,;t t
+s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t
+s,@PKG_LIBS@,$PKG_LIBS,;t t
+s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t
+s,@TCL_VERSION@,$TCL_VERSION,;t t
+s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
+s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t
+s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t
+s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t
+s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t
+s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t
+s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t
+s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t
+s,@TCL_LIBS@,$TCL_LIBS,;t t
+s,@TCL_DEFS@,$TCL_DEFS,;t t
+s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t
+s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t
+s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@EGREP@,$EGREP,;t t
+s,@MATH_LIBS@,$MATH_LIBS,;t t
+s,@PKG_SOURCES@,$PKG_SOURCES,;t t
+s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t
+s,@CLEANFILES@,$CLEANFILES,;t t
+s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t
+s,@TCL_THREADS@,$TCL_THREADS,;t t
+s,@SHARED_BUILD@,$SHARED_BUILD,;t t
+s,@AR@,$AR,;t t
+s,@CELIB_DIR@,$CELIB_DIR,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@DL_LIBS@,$DL_LIBS,;t t
+s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t
+s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t
+s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
+s,@STLIB_LD@,$STLIB_LD,;t t
+s,@SHLIB_LD@,$SHLIB_LD,;t t
+s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t
+s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t
+s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t
+s,@TCL_DBGX@,$TCL_DBGX,;t t
+s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t
+s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t
+s,@MAKE_LIB@,$MAKE_LIB,;t t
+s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t
+s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t
+s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t
+s,@RANLIB_STUB@,$RANLIB_STUB,;t t
+s,@TCLSH_PROG@,$TCLSH_PROG,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/8.x/mk/tcl/configure.in b/8.x/mk/tcl/configure.in
new file mode 100755 (executable)
index 0000000..89119b2
--- /dev/null
@@ -0,0 +1,62 @@
+AC_INIT([Mk4tcl], [2.4.9.7])
+TEA_INIT([3.6])
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+TEA_PREFIX
+TEA_SETUP_COMPILER
+
+TEA_ADD_SOURCES([../src/column.cpp
+                ../src/custom.cpp
+                ../src/derived.cpp
+                ../src/field.cpp
+                ../src/fileio.cpp
+                ../src/format.cpp
+                ../src/handler.cpp
+                ../src/persist.cpp
+                ../src/remap.cpp
+                ../src/std.cpp
+                ../src/store.cpp
+                ../src/string.cpp
+                ../src/table.cpp
+                ../src/univ.cpp
+                ../src/view.cpp
+                ../src/viewx.cpp
+                mk4tcl.cpp
+                mk4too.cpp])
+
+TEA_ADD_HEADERS([])
+TEA_ADD_INCLUDES([-I\"${srcdir}/../include\" -I\"${srcdir}\" -I.])
+TEA_ADD_LIBS([])
+TEA_ADD_CFLAGS([])
+TEA_ADD_STUB_SOURCES([])
+TEA_ADD_TCL_SOURCES([])
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    AC_DEFINE(BUILD_Mk4tcl)
+    CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+    #TEA_ADD_SOURCES([win/winFile.c])
+    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+    CLEANFILES=""
+    #TEA_ADD_SOURCES([unix/unixFile.c])
+    #TEA_ADD_LIBS([-lsuperfly])
+fi
+AC_SUBST(CLEANFILES)
+
+TEA_PUBLIC_TCL_HEADERS
+TEA_ENABLE_THREADS
+TEA_ENABLE_SHARED
+TEA_CONFIG_CFLAGS
+TEA_ENABLE_SYMBOLS
+
+if test "${SHARED_BUILD}" = "1"; then
+AC_DEFINE(USE_TCL_STUBS)
+fi
+
+TEA_MAKE_LIB
+TEA_PROG_TCLSH
+
+AC_OUTPUT([Makefile pkgIndex.tcl config.h])
diff --git a/8.x/mk/tcl/mk4tcl.cpp b/8.x/mk/tcl/mk4tcl.cpp
new file mode 100755 (executable)
index 0000000..2517605
--- /dev/null
@@ -0,0 +1,2552 @@
+// mk4tcl.cpp --
+// $Id: mk4tcl.cpp 4452 2008-12-10 22:57:54Z patthoyts $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+
+#include "mk4tcl.h"
+#include "mk4io.h"
+
+#ifndef _WIN32_WCE
+#include <errno.h>
+#endif 
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef EINVAL
+#define EINVAL 9
+#endif 
+
+// stub interface code, removes the need to link with libtclstub*.a
+//#ifdef USE_TCL_STUBS
+//#include "stubtcl.h"
+//#else 
+//#define MyInitStubs(x) 1
+//#endif 
+
+#if 10 * TCL_MAJOR_VERSION + TCL_MINOR_VERSION < 86
+#define Tcl_GetErrorLine(interp) (interp)->errorLine
+#endif
+
+// definition of valid property name - alpha numerics, underscore, percent,
+// or any extended utf-8 character
+#define ISNAME(c)       (isalnum((c)) || (c) == '_' || (c) == '%' || (c) & 0x80)
+///////////////////////////////////////////////////////////////////////////////
+// Defined in this file:
+
+class MkPath;
+class MkWorkspace;
+class Tcl;
+class MkTcl;
+
+///////////////////////////////////////////////////////////////////////////////
+
+// inc'ed whenever a datafile is closed, forces relookup of all paths
+static int generation;
+
+#ifdef TCL_THREADS
+
+// There is a single monolithic mutex for protecting all of Mk4tcl, but it has
+// to be a bit more advanced than Tcl's one since it has to support recursion,
+// i.e. re-entering this code from the *same* thread needs to be allowed.  The
+// recursion can happen in Tcl's type callbacks, see "Tcl_ObjType mkCursorType".
+//
+// We know the current interpreter in all cases, it can be used as mutex owner.
+// So we can be multiple times inside the mutex, but ONLY from a simgle interp.
+// No deadlock is possible, locking is always in the order mkMutex -> infoMutex.
+
+TCL_DECLARE_MUTEX(mkMutex)    // use a single monolithic mutex for now
+TCL_DECLARE_MUTEX(infoMutex)  // use a second mutex to manage the info below
+
+// set to the interp holding the mutex, or to zero when not locked
+static Tcl_Interp *mutex_owner;
+
+// set to the reursion level, > 1 means we've re-entered from same interp
+static int mutex_level;
+  
+static void EnterMutex(Tcl_Interp *ip_) {
+    d4_assert(ip_ != 0);
+    Tcl_MutexLock(&infoMutex);
+    if (ip_ != mutex_owner) {
+        Tcl_MutexUnlock(&infoMutex);
+        Tcl_MutexLock(&mkMutex);
+        Tcl_MutexLock(&infoMutex);
+        d4_assert(mutex_owner == 0);
+        mutex_owner = ip_;
+    }
+    ++mutex_level;
+    Tcl_MutexUnlock(&infoMutex);
+}
+
+static void LeaveMutex() {
+    Tcl_MutexLock(&infoMutex);
+    d4_assert(mutex_owner != 0 && mutex_level > 0);
+    if (--mutex_level == 0) {
+      mutex_owner = 0;
+      Tcl_MutexUnlock(&mkMutex);
+    }
+    Tcl_MutexUnlock(&infoMutex);
+}
+
+#else
+
+#define EnterMutex(x)
+#define LeaveMutex()
+
+#endif
+// put code in this file as a mutex is static in Windows
+int Mk_EvalObj(Tcl_Interp *ip_, Tcl_Obj *cmd_) {
+    LeaveMutex();
+    int e = Tcl_EvalObj(ip_, cmd_);
+    EnterMutex(ip_);
+    return e;
+}
+
+// moved out of member func scope to please HP-UX's aCC:
+
+static const char *getCmds[] =  {
+  "-size", 0
+};
+
+static const char *viewCmds[] =  {
+  "layout", "delete", "size", "properties", "locate", "restrict", "open", "new",
+    "info", 0
+};
+
+static const char *cursorCmds[] =  {
+  "create", "position", "incr", 0
+};
+
+static const char *channelCmds[] =  {
+  "read", "write", "append", 0
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Utility code: return next token up to char < '0', and
+// advance the string pointer past following character.
+
+c4_String f4_GetToken(const char * &str_) {
+  d4_assert(str_);
+
+  const char *p = str_;
+  while (ISNAME(*p) ||  *p == ':')
+    ++p;
+
+  c4_String result(str_, p - str_);
+
+  if (*p)
+    ++p;
+  // advance over seperator - but no check!
+  str_ = p;
+
+  return result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Utility code: true if value contains a word starting with the given prefix
+
+bool MatchOneKeyword(const char *value_, const c4_String &crit_) {
+  int n = crit_.GetLength();
+  if (n == 0)
+    return true;
+
+  char cu = (char)toupper(crit_[0]);
+  char cl = (char)tolower(crit_[0]);
+
+  const char *limit = value_ + strlen(value_) - n;
+  while (value_ <= limit) {
+    c4_String s(value_, n);
+    if (s.CompareNoCase(crit_) == 0)
+      return true;
+
+    while (*++value_)
+      if ((*value_ == cu ||  *value_ == cl) && !isalnum(value_[ - 1]))
+        break;
+  }
+
+  return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// A "storage in a storage" strategy class for Metakit
+// Adapted from MkWrap, the Python interface
+
+class SiasStrategy: public c4_Strategy {
+  public:
+    c4_Storage _storage;
+    c4_View _view;
+    c4_BytesProp _memo;
+    int _row;
+    t4_i32 _position;
+    Tcl_Channel _chan;
+    int _validMask;
+    int _watchMask;
+    Tcl_Interp *_interp;
+
+    SiasStrategy(c4_Storage &storage_, const c4_View &view_, const c4_BytesProp
+      &memo_, int row_): _storage(storage_), _view(view_), _memo(memo_), _row
+      (row_), _position(0), _interp(0) {
+        // set up mapping if the memo itself is mapped in its entirety
+        c4_Strategy &strat = storage_.Strategy();
+        if (strat._mapStart != 0) {
+            c4_RowRef r = _view[_row];
+            c4_Bytes data = _memo(r).Access(0);
+            const t4_byte *ptr = data.Contents();
+            if (data.Size() == _memo(r).GetSize() && strat._mapStart != 0 &&
+              ptr >= strat._mapStart && ptr - strat._mapStart < strat._dataSize)
+              {
+                _mapStart = ptr;
+                _dataSize = data.Size();
+            }
+        }
+    }
+
+    virtual ~SiasStrategy() {
+        _view = c4_View();
+        _mapStart = 0;
+        _dataSize = 0;
+
+        if (_chan != 0)
+          Tcl_UnregisterChannel(_interp, _chan);
+    }
+
+    virtual void DataSeek(t4_i32 position_) {
+        _position = position_;
+    }
+
+    virtual int DataRead(t4_i32 pos_, void *buffer_, int length_) {
+        if (pos_ != ~0)
+          _position = pos_;
+
+        int i = 0;
+
+        while (i < length_) {
+            c4_Bytes data = _memo(_view[_row]).Access(_position + i, length_ -
+              i);
+            int n = data.Size();
+            if (n <= 0)
+              break;
+            memcpy((char*)buffer_ + i, data.Contents(), n);
+            i += n;
+        }
+
+        _position += i;
+        return i;
+    }
+
+    virtual void DataWrite(t4_i32 pos_, const void *buffer_, int length_) {
+        if (pos_ != ~0)
+          _position = pos_;
+
+        c4_Bytes data(buffer_, length_);
+        if (_memo(_view[_row]).Modify(data, _position))
+          _position += length_;
+        else
+          ++_failure;
+    }
+
+    virtual void DataCommit(t4_i32 newSize_) {
+        if (newSize_ > 0)
+          _memo(_view[_row]).Modify(c4_Bytes(), newSize_);
+    }
+
+    virtual void ResetFileMapping() {
+        _mapStart = 0; // never called, but just in case
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// New in 1.2: channel interface to memo fields
+
+typedef SiasStrategy MkChannel;
+
+typedef struct {
+  Tcl_Event header;
+  MkChannel *chan;
+} MkEvent;
+
+static int mkEventProc(Tcl_Event *evPtr, int flags) {
+  MkEvent *me = (MkEvent*)evPtr;
+
+  if (!(flags &TCL_FILE_EVENTS))
+    return 0;
+
+  Tcl_NotifyChannel(me->chan->_chan, me->chan->_watchMask);
+  return 1;
+}
+
+static int mkEventFilter(Tcl_Event *evPtr, ClientData instanceData) {
+  MkEvent *me = (MkEvent*)evPtr;
+  MkChannel *chan = (MkChannel*)instanceData;
+  return evPtr->proc == mkEventProc && me->chan == chan;
+}
+
+static int mkClose(ClientData instanceData, Tcl_Interp *interp) {
+  MkChannel *chan = (MkChannel*)instanceData;
+
+  Tcl_DeleteEvents(mkEventFilter, (ClientData)chan);
+  chan->_chan = 0;
+  delete chan;
+
+  return TCL_OK;
+}
+
+static int mkInput(ClientData instanceData, char *buf, int toRead, int
+  *errorCodePtr) {
+  MkChannel *chan = (MkChannel*)instanceData;
+  return chan->DataRead(~0, buf, toRead);
+}
+
+static int mkOutput(ClientData instanceData, const char *buf, int toWrite, int
+  *errorCodePtr) {
+  MkChannel *chan = (MkChannel*)instanceData;
+  chan->DataWrite(~0, buf, toWrite);
+  if (chan->_failure == 0)
+    return toWrite;
+
+  *errorCodePtr = EINVAL; // hm, bad choice of error code
+  return  - 1;
+}
+
+static int mkSeek(ClientData instanceData, long offset, int seekMode, int
+  *errorCodePtr) {
+  MkChannel *chan = (MkChannel*)instanceData;
+
+  switch (seekMode) {
+    default:
+       *errorCodePtr = EINVAL; // hm, bad choice of error code
+      return  - 1;
+    case 0:
+      break;
+    case 1:
+      offset += chan->_position;
+      break;
+    case 2:
+      offset += chan->_memo(chan->_view[chan->_row]).GetSize();
+      break;
+  }
+
+  chan->DataSeek(offset);
+  return offset;
+}
+
+static void mkWatchChannel(ClientData instanceData, int mask) {
+  MkChannel *chan = (MkChannel*)instanceData;
+  Tcl_Time blockTime =  {
+    0, 0
+  };
+
+  /*
+   * Since the file is always ready for events, we set the block time
+   * to zero so we will poll.
+   */
+
+  chan->_watchMask = mask &chan->_validMask;
+  if (chan->_watchMask) {
+    Tcl_SetMaxBlockTime(&blockTime);
+  }
+}
+
+static int mkGetFile(ClientData instanceData, int direction, ClientData
+  *handlePtr) {
+  return TCL_ERROR;
+}
+
+static Tcl_ChannelType mkChannelType =  {
+  "mk",  /* Type name.                  */
+  0,  /* Set blocking/nonblocking behaviour. NULL'able */
+  mkClose,  /* Close channel, clean instance data      */
+  mkInput,  /* Handle read request               */
+  (Tcl_DriverOutputProc*)mkOutput,  /* Handle write request              */
+  (Tcl_DriverSeekProc*)mkSeek,  /* Move location of access point.    NULL'able
+    */
+  0,  /* Set options.              NULL'able */
+  0,  /* Get options.              NULL'able */
+  (Tcl_DriverWatchProc*)mkWatchChannel,  /* Initialize notifier               */
+  mkGetFile /* Get OS handle from the channel.         */
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Utility code: get a Metakit item and convert it to a Tcl object
+
+Tcl_Obj *GetAsObj(const c4_RowRef &row_, const c4_Property &prop_, Tcl_Obj
+  *obj_) {
+  if (obj_ == 0)
+    obj_ = Tcl_NewObj();
+
+  switch (prop_.Type()) {
+    case 'S':
+       {
+        const char *p = ((c4_StringProp &)prop_)(row_);
+        Tcl_SetStringObj(obj_, (char*)p,  - 1);
+      }
+      break;
+
+    case 'B':
+       {
+        c4_Bytes temp;
+        prop_(row_).GetData(temp);
+        Tcl_SetByteArrayObj(obj_, (t4_byte*)temp.Contents(), temp.Size());
+      }
+      break;
+
+    case 'F':
+      Tcl_SetDoubleObj(obj_, ((c4_FloatProp &)prop_)(row_));
+      break;
+
+    case 'D':
+      Tcl_SetDoubleObj(obj_, ((c4_DoubleProp &)prop_)(row_));
+      break;
+
+#ifdef TCL_WIDE_INT_TYPE
+    case 'L':
+      Tcl_SetWideIntObj(obj_, ((c4_LongProp &)prop_)(row_));
+      break;
+#endif 
+
+    case 'I':
+      Tcl_SetLongObj(obj_, ((c4_IntProp &)prop_)(row_));
+      break;
+
+    case 'V':
+       {
+        c4_View view = ((c4_ViewProp &)prop_)(row_);
+        Tcl_SetIntObj(obj_, view.GetSize());
+      }
+      break;
+
+    default:
+       {
+        KeepRef keeper(obj_); // a funny way to release the value
+      }
+      return 0;
+  }
+
+  return obj_;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Utility code: set a Metakit item and convert it from a Tcl object
+
+int SetAsObj(Tcl_Interp *interp, const c4_RowRef &row_, const c4_Property
+  &prop_, Tcl_Obj *obj_) {
+  int e = TCL_OK;
+
+  switch (prop_.Type()) {
+    case 'S':
+       {
+        int len;
+        const char *ptr = Tcl_GetStringFromObj(obj_, &len);
+        prop_(row_).SetData(c4_Bytes(ptr, len + 1));
+      }
+      break;
+
+    case 'B':
+       {
+        int len;
+        const t4_byte *ptr = Tcl_GetByteArrayFromObj(obj_, &len);
+        prop_(row_).SetData(c4_Bytes(ptr, len));
+      }
+      break;
+
+    case 'F':
+       {
+        double value = 0;
+        e = Tcl_GetDoubleFromObj(interp, obj_, &value);
+        if (e == TCL_OK)
+          ((c4_FloatProp &)prop_)(row_) = (float)value;
+      }
+      break;
+
+    case 'D':
+       {
+        double value = 0;
+        e = Tcl_GetDoubleFromObj(interp, obj_, &value);
+        if (e == TCL_OK)
+          ((c4_DoubleProp &)prop_)(row_) = value;
+      }
+      break;
+
+#ifdef TCL_WIDE_INT_TYPE
+    case 'L':
+       {
+        Tcl_WideInt value = 0;
+        e = Tcl_GetWideIntFromObj(interp, obj_, &value);
+        if (e == TCL_OK)
+          ((c4_LongProp &)prop_)(row_) = value;
+      }
+      break;
+#endif 
+
+    case 'I':
+       {
+        long value = 0;
+        e = Tcl_GetLongFromObj(interp, obj_, &value);
+        if (e == TCL_OK)
+          ((c4_IntProp &)prop_)(row_) = value;
+      }
+      break;
+
+    default:
+      Tcl_SetResult(interp, (char*)"unsupported property type", TCL_STATIC);
+      e = TCL_ERROR;
+  }
+
+  return e;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// In Tcl, streaming I/O uses the Tcl channel interface for loading/saving.
+
+class c4_TclStream: public c4_Stream {
+    Tcl_Channel _stream;
+
+  public:
+    c4_TclStream(Tcl_Channel stream_);
+    virtual ~c4_TclStream();
+
+    virtual int Read(void *buffer_, int length_);
+    virtual bool Write(const void *buffer_, int length_);
+};
+
+c4_TclStream::c4_TclStream(Tcl_Channel stream_): _stream(stream_){}
+
+c4_TclStream::~c4_TclStream(){}
+
+int c4_TclStream::Read(void *buffer_, int length_) {
+  return Tcl_Read(_stream, (char*)buffer_, length_);
+}
+
+bool c4_TclStream::Write(const void *buffer_, int length_) {
+  return Tcl_Write(_stream, (char*)buffer_, length_) >= 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+MkPath::MkPath(MkWorkspace &ws_, const char * &path_, Tcl_Interp *interp):
+  _refs(1), _ws(&ws_), _path(path_), _currGen(generation) {
+  // if this view is not part of any storage, make a new temporary row
+  if (_path.IsEmpty()) {
+    ws_.AllocTempRow(_path);
+    AttachView(interp);
+  } else {
+    int n = AttachView(interp);
+    path_ += n; // move past all processed characters
+
+    // but trim white space and unprocessed tail from stored path
+    while (n > 0 && _path[n - 1] < '0')
+      --n;
+    if (n < _path.GetLength())
+      _path = _path.Left(n);
+  }
+}
+
+MkPath::~MkPath() {
+  // 24-01-2003: paths should not clean up workspaces once exiting
+  if (_currGen != -1)
+    _ws->ForgetPath(this);
+}
+
+#if 0
+static c4_View OpenMapped(c4_View v_, int col_, int row_) {
+  if (col_ < 0)
+    return c4_View();
+
+  const c4_Property &prop = v_.NthProperty(col_);
+  d4_assert(prop.Type() == 'V');
+  if (prop.Type() != 'V')
+    return c4_View();
+
+  c4_View vw = ((c4_ViewProp &)prop)(v_[row_]);
+
+  c4_String name = prop.Name();
+  int h = v_.FindPropIndexByName(name + "_H1");
+  if (h >= 0) {
+    const c4_Property &proph = v_.NthProperty(h);
+    if (proph.Type() == 'V') {
+      c4_View vwh = ((c4_ViewProp &)proph)(v_[row_]);
+      vw = vw.Hash(vwh, 1);
+    }
+  }
+
+  return vw;
+}
+
+#endif 
+
+int MkPath::AttachView(Tcl_Interp * /*interp*/) {
+  const char *base = _path;
+  const char *p = base;
+
+  //  The format of a path description is:
+  //
+  //    storage '.' viewname [ '!' row# '.' viewprop ]*
+  //  or
+  //    storage '.' viewname [ '!' row# '.' viewprop ]* '!' row#
+  //
+  //  In the second case, the trailing row# is ignored.
+
+  MkWorkspace::Item *ip = _ws != 0 ? _ws->Find(f4_GetToken(p)): 0;
+  if (ip != 0) {
+    // 16-1-2003: allow path reference to root view (i.e. storage itself)
+    if (*p == 0) {
+      _view = ip->_storage;
+      return p - base;
+    }
+#if 0
+    c4_View root =  *ip->_storage;
+    int col = root.FindPropIndexByName(f4_GetToken(p));
+    _view = OpenMapped(root, col, 0);
+#else 
+    _view = ip->_storage.View(f4_GetToken(p));
+#endif 
+    while (*p) {
+      if (!isdigit(*p)) {
+        _view = c4_View(); // bad stuff, bail out with an empty view
+        break;
+      }
+
+      const char *q = p;
+
+      int r = atoi(f4_GetToken(p));
+
+      if (! *p)
+        return q - base;
+      // return partial number of chars processed
+
+      //  A future version could parse derived view expressions here.
+      //  Perhaps this could be done as Metakit property expressions.
+
+      int n = _view.FindPropIndexByName(f4_GetToken(p));
+      if (n < 0)
+        return q - base;
+      // make sure the property exists
+
+      const c4_Property &prop = _view.NthProperty(n);
+      if (prop.Type() != 'V')
+        return q - base;
+      // make sure it's a subview
+
+#if 0
+      _view = OpenMapped(_view, n, r);
+#else 
+      _view = ((c4_ViewProp &)prop)(_view[r]);
+      ;
+#endif 
+    }
+  } else
+    _view = c4_View();
+
+  return p - base; // return pointer to ending null byte
+}
+
+int MkPath::Refs(int diff_) {
+  d4_assert( - 1 <= diff_ && diff_ <=  + 1);
+
+  _refs += diff_;
+
+  d4_assert(_refs >= 0);
+
+  if (_refs == 0 && diff_ < 0) {
+    delete this;
+    return 0;
+  }
+
+  return _refs;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+c4_PtrArray *MkWorkspace::Item::_shared = 0;
+
+MkWorkspace::Item::Item(const char *name_, const char *fileName_, int mode_,
+  c4_PtrArray &items_, int index_, bool share_): _name(name_), _fileName
+  (fileName_), _items(items_), _index(index_) {
+  ++generation; // make sure all cached paths refresh on next access
+
+  if (*fileName_) {
+    c4_Storage s(fileName_, mode_);
+    if (!s.Strategy().IsValid())
+      return ;
+    _storage = s;
+  }
+
+  if (_index >= _items.GetSize())
+    _items.SetSize(_index + 1);
+
+  _items.SetAt(_index, this);
+
+  if (share_) {
+    if (_shared == 0)
+      _shared = new c4_PtrArray;
+    _shared->Add(this);
+  }
+}
+
+MkWorkspace::Item::~Item() {
+  //! ForceRefresh();
+  // all views referring to this datafile are made invalid
+  for (int i = 0; i < _paths.GetSize(); ++i) {
+    MkPath *path = (MkPath*)_paths.GetAt(i);
+    if (_index > 0)
+      path->_view = c4_View();
+    path->_path = "?"; // make sure it never matches
+    path->_currGen = -1; // make sure lookup is retried on next use
+    // TODO: get rid of generations, use a "_valid" flag instead
+  }
+  ++generation; // make sure all cached paths refresh on next access
+
+  if (_index < _items.GetSize()) {
+    d4_assert(_items.GetAt(_index) == this || _items.GetAt(_index) == 0);
+    _items.SetAt(_index, 0);
+  }
+
+  if (_shared != 0) {
+    for (int i = 0; i < _shared->GetSize(); ++i)
+    if (_shared->GetAt(i) == this) {
+      _shared->RemoveAt(i);
+      break;
+    }
+
+    if (_shared->GetSize() == 0) {
+      delete _shared;
+      _shared = 0;
+    }
+  }
+}
+
+void MkWorkspace::Item::ForceRefresh() {
+  // all views referring to this datafile are cleared
+  for (int i = 0; i < _paths.GetSize(); ++i) {
+    MkPath *path = (MkPath*)_paths.GetAt(i);
+    path->_view = c4_View();
+  }
+
+  ++generation; // make sure all cached paths refresh on next access
+}
+
+MkWorkspace::MkWorkspace(Tcl_Interp *ip_): _interp(ip_) {
+  new Item("", "", 0, _items, 0);
+
+  // never uses entry zero (so atoi failure in ForgetPath is harmless)
+  _usedRows = _usedBuffer.SetBufferClear(16); 
+    // no realloc for first 16 temp rows
+}
+
+MkWorkspace::~MkWorkspace() {
+  CleanupCommands();
+
+  for (int i = _items.GetSize(); --i >= 0;)
+    delete Nth(i);
+
+  // need this to prevent recursion in Tcl_DeleteAssocData in 8.2 (not 8.0!)
+  Tcl_SetAssocData(_interp, "mk4tcl", 0, 0);
+  Tcl_DeleteAssocData(_interp, "mk4tcl");
+}
+
+void MkWorkspace::DefCmd(MkTcl *cmd_) {
+  _commands.Add(cmd_);
+}
+
+MkWorkspace::Item *MkWorkspace::Define(const char *name_, const char *fileName_,
+  int mode_, bool share_) {
+  Item *ip = Find(name_);
+
+  if (ip == 0) {
+    int n =  - 1;
+    while (++n < _items.GetSize())
+      if (Nth(n) == 0)
+        break;
+
+    ip = new Item(name_, fileName_, mode_, _items, n, share_);
+    if (*fileName_ != 0 && !ip->_storage.Strategy().IsValid()) {
+      delete ip;
+      return 0;
+    }
+  }
+
+  return ip;
+}
+
+MkWorkspace::Item *MkWorkspace::Find(const char *name_)const {
+  for (int i = 0; i < _items.GetSize(); ++i) {
+    Item *ip = Nth(i);
+    if (ip && ip->_name.Compare(name_) == 0)
+      return ip;
+  }
+
+  if (Item::_shared != 0)
+   { // look in the shared pool, if there is one
+    for (int j = 0; j < Item::_shared->GetSize(); ++j) {
+      Item *ip = (Item*)Item::_shared->GetAt(j);
+      if (ip && ip->_name == name_)
+        return ip;
+    }
+  }
+
+  return 0;
+}
+
+int MkWorkspace::NumItems()const {
+  return _items.GetSize();
+}
+
+MkWorkspace::Item *MkWorkspace::Nth(int index_)const {
+  return (Item*)_items.GetAt(index_);
+}
+
+MkPath *MkWorkspace::AddPath(const char * &name_, Tcl_Interp *interp) {
+  const char *p = name_;
+
+  Item *ip = Find(f4_GetToken(p));
+  if (ip == 0) {
+    ip = Nth(0);
+    d4_assert(ip != 0);
+    name_ = ""; // no such tag, assign a temporary one instead
+  } else
+  for (int i = 0; i < ip->_paths.GetSize(); ++i) {
+    MkPath *path = (MkPath*)ip->_paths.GetAt(i);
+    d4_assert(path != 0);
+
+    if (path->_path.CompareNoCase(name_) == 0 && path->_currGen == generation) {
+      path->Refs( + 1);
+      return path;
+    }
+  }
+
+  MkPath *newPath = new MkPath(*this, name_, interp);
+  ip->_paths.Add(newPath);
+
+  return newPath;
+}
+
+void MkWorkspace::AllocTempRow(c4_String &result_) {
+  int i;
+
+  // find an unused row
+  for (i = 1; i < _usedBuffer.Size(); ++i)
+    if (_usedRows[i] == 0)
+      break;
+
+  // allocate new vec if old one is too small, doubling it in size
+  if (i >= _usedBuffer.Size()) {
+    c4_Bytes temp;
+    t4_byte *tempPtr = temp.SetBufferClear(2 *i + 1);
+    memcpy(tempPtr, _usedRows, _usedBuffer.Size());
+
+    _usedBuffer.Swap(temp);
+    _usedRows = tempPtr;
+
+    c4_View v = Nth(0)->_storage.View("");
+    v.SetSize(_usedBuffer.Size());
+  }
+
+  // flag it as being in use
+  _usedRows[i] = 1;
+
+  // temporary rows have special names
+  char buf[20];
+  sprintf(buf, "._!%d._", i);
+  result_ = buf;
+}
+
+void MkWorkspace::ForgetPath(const MkPath *path_) {
+  const char *p = path_->_path;
+
+  Item *ip = Find(f4_GetToken(p));
+  if (ip != 0) {
+    for (int j = 0; j < ip->_paths.GetSize(); ++j)
+    if ((MkPath*)ip->_paths.GetAt(j) == path_) {
+      ip->_paths.RemoveAt(j);
+      break;
+    }
+
+    // last ref to a temporary row determines when to release it
+    if (ip == Nth(0)) {
+      int n = atoi(((const char*)path_->_path) + 3);
+      d4_assert(_usedRows[n] != 0);
+      _usedRows[n] = 0;
+    }
+  }
+}
+
+void MkWorkspace::Invalidate(const MkPath &path_) {
+  const char *p = path_._path;
+
+  c4_String prefix = path_._path + "!";
+  int n = prefix.GetLength();
+
+  Item *ip = Find(f4_GetToken(p));
+  if (ip != 0) {
+    for (int j = 0; j < ip->_paths.GetSize(); ++j) {
+      MkPath *entry = (MkPath*)ip->_paths.GetAt(j);
+      if (strncmp(entry->_path, prefix, n) == 0)
+        entry->_currGen =  - 1;
+      // the next use will reattach
+    }
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Translate between the Metakit and Tcl-style datafile structure descriptions
+
+static c4_String KitToTclDesc(const char *desc_) {
+  c4_Bytes temp;
+  char *p = (char*)temp.SetBuffer(3 *strlen(desc_) + 100);
+
+  while (*desc_) {
+    char *q = p;
+
+    // assume normal property
+    while (ISNAME(*desc_) ||  *desc_ == ':')
+      *p++ =  *desc_++;
+
+    // strip a trailing ':S'
+    if (p[ - 2] == ':' && p[ - 1] == 'S')
+      p -= 2;
+
+    // at end of property, process commas and brackets
+    switch (*desc_++) {
+      // defensive coding, this cannot happen
+      case 0:
+        --desc_;
+        break;
+
+        // opening bracket "xxx[" --> "{xxx {"
+      case '[':
+         {
+          c4_String name(q, p - q);
+          *q++ = '{';
+          strcpy(q, name);
+          ++p;
+
+          *p++ = ' ';
+          *p++ = '{';
+        }
+        break;
+
+        // opening bracket "]" --> "}}"
+      case ']':
+         {
+          *p++ = '}';
+          *p++ = '}';
+        }
+        break;
+
+        // comma separator "," --> " "
+      case ',':
+        *p++ = ' ';
+    }
+  }
+
+  *p++ = 0;
+  return (const char*)temp.Contents();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Interface to Tcl 8.0 type mechanism, defines a new "mkProperty" datatype
+//
+//  Since properties are immutable, we don't need most of the calls.
+
+static void FreePropertyInternalRep(Tcl_Obj *propPtr);
+
+static void DupPropertyInternalRep(Tcl_Obj *, Tcl_Obj*) {
+  d4_assert(false);
+}
+
+static void UpdateStringOfProperty(Tcl_Obj*) {
+  d4_assert(false);
+}
+
+static int SetPropertyFromAny(Tcl_Interp *, Tcl_Obj*) {
+  d4_assert(false);
+  return TCL_OK;
+}
+
+static Tcl_ObjType mkPropertyType =  {
+  (char*)"mkProperty",  // name
+  FreePropertyInternalRep,  // freeIntRepProc
+  DupPropertyInternalRep,  // dupIntRepProc
+  UpdateStringOfProperty,  // updateStringProc
+  SetPropertyFromAny  // setFromAnyProc
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+const c4_Property &AsProperty(Tcl_Obj *objPtr, const c4_View &view_) {
+  void *tag = (&view_[0])._seq; // horrific hack to get at c4_Sequence pointer
+  if (objPtr->typePtr !=  &mkPropertyType || objPtr
+    ->internalRep.twoPtrValue.ptr1 != tag) {
+    CONST86 Tcl_ObjType *oldTypePtr = objPtr->typePtr;
+
+    char type = 'S';
+
+    int length;
+    char *string = Tcl_GetStringFromObj(objPtr, &length);
+    c4_Property *prop;
+
+    if (length > 2 && string[length - 2] == ':') {
+      type = string[length - 1];
+      prop = new c4_Property(type, c4_String(string, length - 2));
+    } else
+     { // look into the view to try to determine the type
+      int n = view_.FindPropIndexByName(string);
+      if (n >= 0)
+        type = view_.NthProperty(n).Type();
+      prop = new c4_Property(type, string);
+    }
+
+    if (oldTypePtr && oldTypePtr->freeIntRepProc)
+      oldTypePtr->freeIntRepProc(objPtr);
+
+    objPtr->typePtr = &mkPropertyType;
+    // use a (char*), because the Mac wants it, others use (void*)
+    objPtr->internalRep.twoPtrValue.ptr1 = tag;
+    objPtr->internalRep.twoPtrValue.ptr2 = (char*)prop;
+  }
+
+  return *(c4_Property*)objPtr->internalRep.twoPtrValue.ptr2;
+}
+
+static void FreePropertyInternalRep(Tcl_Obj *propPtr) {
+  // no mutex protection needed here, MK's own C++ locking is sufficient
+  delete (c4_Property*)propPtr->internalRep.twoPtrValue.ptr2;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Interface to Tcl 8.0 type mechanism, defines a new "mkCursor" datatype
+
+static void FreeCursorInternalRep(Tcl_Obj *propPtr);
+static void DupCursorInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
+//static int SetCursorFromAny(Tcl_Interp* interp, Tcl_Obj* objPtr);
+static void UpdateStringOfCursor(Tcl_Obj *propPtr);
+
+static Tcl_ObjType mkCursorType =  {
+  (char*)"mkCursor",  // name
+  FreeCursorInternalRep,  // freeIntRepProc
+  DupCursorInternalRep,  // dupIntRepProc
+  UpdateStringOfCursor,  // updateStringProc
+  SetCursorFromAny  // setFromAnyProc
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Cursors in Tcl are implemented as a pointer to an MkPath plus an index.
+
+MkPath &AsPath(Tcl_Obj *obj_) {
+  d4_assert(obj_->typePtr ==  &mkCursorType);
+  d4_assert(obj_->internalRep.twoPtrValue.ptr2 != 0);
+
+  return *(MkPath*)obj_->internalRep.twoPtrValue.ptr2;
+}
+
+int &AsIndex(Tcl_Obj *obj_) {
+  d4_assert(obj_->typePtr ==  &mkCursorType);
+  d4_assert(obj_->internalRep.twoPtrValue.ptr2 != 0);
+
+  return (int &)obj_->internalRep.twoPtrValue.ptr1;
+}
+
+static void FreeCursorInternalRep(Tcl_Obj *cursorPtr) {
+  MkPath &path = AsPath(cursorPtr);
+  EnterMutex(path._ws->_interp);
+  path.Refs( - 1);
+  LeaveMutex();
+}
+
+static void DupCursorInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr) {
+  MkPath &path = AsPath(srcPtr);
+  EnterMutex(path._ws->_interp);
+  path.Refs( + 1);
+  copyPtr->internalRep = srcPtr->internalRep;
+  copyPtr->typePtr = &mkCursorType;
+  LeaveMutex();
+}
+
+int SetCursorFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) {
+  d4_assert(interp != 0);
+  EnterMutex(interp);
+
+  // force a relookup if the this object is of the wrong generation
+  if (objPtr->typePtr == &mkCursorType && AsPath(objPtr)._currGen !=
+    generation) {
+    // make sure we have a string representation around
+    if (objPtr->bytes == 0)
+      UpdateStringOfCursor(objPtr);
+
+    // get rid of the object form
+    FreeCursorInternalRep(objPtr);
+    objPtr->typePtr = 0;
+  }
+
+  if (objPtr->typePtr !=  &mkCursorType) {
+    CONST86 Tcl_ObjType *oldTypePtr = objPtr->typePtr;
+
+    const char *string = Tcl_GetStringFromObj(objPtr, 0);
+
+    // dig up the workspace used in this interpreter
+    MkWorkspace *work = (MkWorkspace*)Tcl_GetAssocData(interp, "mk4tcl", 0);
+    // cast required for Mac
+    char *s = (char*)(void*)work->AddPath(string, interp);
+    int i = isdigit(*string) ? atoi(string):  - 1;
+
+    if (oldTypePtr && oldTypePtr->freeIntRepProc)
+      oldTypePtr->freeIntRepProc(objPtr);
+
+    objPtr->typePtr = &mkCursorType;
+    objPtr->internalRep.twoPtrValue.ptr1 = (void*)i;
+    objPtr->internalRep.twoPtrValue.ptr2 = s;
+  }
+
+  LeaveMutex();
+  return TCL_OK;
+}
+
+static void UpdateStringOfCursor(Tcl_Obj *cursorPtr) {
+  MkPath &path = AsPath(cursorPtr);
+  EnterMutex(path._ws->_interp);
+  c4_String s = path._path;
+
+  int index = AsIndex(cursorPtr);
+  if (index >= 0) {
+    char buf[20];
+    sprintf(buf, "%s%d", s.IsEmpty() ? "" : "!", index);
+    s += buf;
+  }
+
+  cursorPtr->length = s.GetLength();
+  cursorPtr->bytes = strcpy(Tcl_Alloc(cursorPtr->length + 1), s);
+  LeaveMutex();
+}
+
+static Tcl_Obj *AllocateNewTempRow(MkWorkspace &work_) {
+  Tcl_Obj *result = Tcl_NewObj();
+
+  const char *empty = "";
+  MkPath *path = work_.AddPath(empty, 0);
+  //  path->_view.SetSize(1);
+
+  result->typePtr = &mkCursorType;
+  result->internalRep.twoPtrValue.ptr2 = (char*)(void*)path;
+  AsIndex(result) = 0;
+
+  Tcl_InvalidateStringRep(result);
+
+  return result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Helper class for the mk::select command, stores params and performs select
+
+TclSelector::TclSelector(Tcl_Interp *interp_, const c4_View &view_): _interp
+  (interp_), _view(view_), _temp(0), _first(0), _count( - 1){}
+
+TclSelector::~TclSelector() {
+  for (int i = 0; i < _conditions.GetSize(); ++i)
+    delete (Condition*)_conditions.GetAt(i);
+}
+
+// convert a property (or list of properties) to an empty view
+c4_View TclSelector::GetAsProps(Tcl_Obj *obj_) {
+  c4_View result;
+
+  Tcl_Obj *o;
+
+  for (int i = 0; Tcl_ListObjIndex(_interp, obj_, i, &o) == TCL_OK && o != 0; 
+    ++i)
+    result.AddProperty(AsProperty(o, _view));
+
+  return result;
+}
+
+int TclSelector::AddCondition(int id_, Tcl_Obj *props_, Tcl_Obj *value_) {
+  c4_View props = GetAsProps(props_);
+  if (props.NumProperties() > 0)
+    _conditions.Add(new Condition(id_, props, value_));
+
+  return TCL_OK;
+}
+
+bool TclSelector::MatchOneString(int id_, const char *value_, const char *crit_)
+  {
+  switch (id_) {
+    case 2:
+      // -exact prop value : exact case-sensitive match
+      return strcmp(value_, crit_) == 0;
+
+    case 3:
+      // -glob prop pattern : match "glob" expression wildcard
+      return Tcl_StringMatch(value_, crit_) > 0;
+
+    case 4:
+      // -regexp prop pattern : match specified regular expression
+      return Tcl_RegExpMatch(_interp, (CONST84 char*)value_, (CONST84 char*)
+        crit_) > 0;
+    case 5:
+      // -keyword prop prefix : match keyword in given property
+      return MatchOneKeyword(value_, crit_);
+
+    case 10:
+      // -globnc prop pattern : match "glob", but not case sensitive
+      return Tcl_StringCaseMatch(value_, crit_, 1) > 0;
+  }
+
+  return false;
+}
+
+bool TclSelector::Match(const c4_RowRef &row_) {
+  // go through each condition and make sure they all match
+  for (int i = 0; i < _conditions.GetSize(); ++i) {
+    const Condition &cond = *(const Condition*)_conditions.GetAt(i);
+
+    bool matched = false;
+
+    // go through each property until one matches
+    for (int j = 0; j < cond._view.NumProperties(); ++j) {
+      const c4_Property &prop = cond._view.NthProperty(j);
+
+      if (cond._id < 2)
+       { // use typed comparison as defined by Metakit
+        c4_Row data; // this is *very* slow in Metakit 1.8
+        if (SetAsObj(_interp, data, prop, cond._crit) != TCL_OK)
+          return false;
+
+        // data is now a row with the criterium as single property
+        matched = cond._id < 0 && data == row_ || cond._id == 0 && data <= row_
+          || cond._id > 0 && data >= row_;
+      } else
+       { // use item value as a string
+        GetAsObj(row_, prop, _temp);
+        matched = MatchOneString(cond._id, Tcl_GetStringFromObj(_temp, NULL),
+          Tcl_GetStringFromObj(cond._crit, NULL));
+        if (matched)
+          break;
+      }
+    }
+
+    if (!matched)
+      return false;
+  }
+
+  return true;
+}
+
+// pick out criteria which specify an exact match
+void TclSelector::ExactKeyProps(const c4_RowRef &row_) {
+  for (int i = 0; i < _conditions.GetSize(); ++i) {
+    const Condition &cond = *(const Condition*)_conditions.GetAt(i);
+    if (cond._id ==  - 1 || cond._id == 2) {
+      for (int j = 0; j < cond._view.NumProperties(); ++j) {
+        const c4_Property &prop = cond._view.NthProperty(j);
+        SetAsObj(_interp, row_, prop, cond._crit);
+      }
+    }
+  }
+}
+
+int TclSelector::DoSelect(Tcl_Obj *list_, c4_View *result_) {
+  c4_IntProp pIndex("index");
+
+  // normalize _first and _count to be in allowable range
+  int n = _view.GetSize();
+  if (_first < 0)
+    _first = 0;
+  if (_first > n)
+    _first = n;
+  if (_count < 0)
+    _count = n;
+  if (_first + _count > n)
+    _count = n - _first;
+
+  c4_View result;
+  result.SetSize(_count); // upper bound
+
+  // keep a temporary around during the comparison loop
+  _temp = Tcl_NewObj();
+  KeepRef keeper(_temp);
+
+  // try to take advantage of key lookup structures
+  c4_Row exact;
+  ExactKeyProps(exact);
+  if (exact.Container().NumProperties() > 0)
+    _view.RestrictSearch(exact, _first, _count);
+
+  // the matching loop where all the hard work is done
+  for (n = 0; _first < _view.GetSize() && n < _count; ++_first)
+    if (Match(_view[_first]))
+      pIndex(result[n++]) = _first;
+
+  result.SetSize(n);
+
+  // set up sorting, this references/loads a lot of extra Metakit code
+  const bool sorted = n > 0 && _sortProps.NumProperties() > 0;
+
+  c4_View mapView;
+  c4_View sortResult;
+  if (sorted) {
+    mapView = _view.RemapWith(result);
+    sortResult = mapView.SortOnReverse(_sortProps, _sortRevProps);
+  }
+
+  // convert result to a Tcl list of ints
+  if (list_ != 0)
+  for (int i = 0; i < n; ++i) {
+    // sorting means we have to lookup the index of the original again
+    int pos = i;
+    if (sorted)
+      pos = mapView.GetIndexOf(sortResult[i]);
+
+    // set up a Tcl integer which holds the selected row index
+    KeepRef o = Tcl_NewIntObj(pIndex(result[pos]));
+
+    if (Tcl_ListObjAppendElement(_interp, list_, o) != TCL_OK)
+      return TCL_ERROR;
+  }
+
+  // added 2003/02/14: return intermediate view, if requested
+  if (result_ != 0)
+    *result_ = sorted ? sortResult : result;
+
+  return TCL_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// The Tcl class is a generic interface to Tcl, providing some C++ wrapping
+
+Tcl::Tcl(Tcl_Interp *ip_): interp(ip_){}
+
+int Tcl::Fail(const char *msg_, int err_) {
+  if (!_error) {
+    if (msg_)
+      Tcl_SetResult(interp, (char*)msg_, TCL_VOLATILE);
+    _error = err_;
+  }
+
+  return _error;
+}
+
+Tcl_Obj *Tcl::tcl_GetObjResult() {
+  return Tcl_GetObjResult(interp);
+}
+
+int Tcl::tcl_SetObjResult(Tcl_Obj *obj_) {
+  Tcl_SetObjResult(interp, obj_);
+  return _error;
+}
+
+int Tcl::tcl_ListObjLength(Tcl_Obj *obj_) {
+  int result;
+  _error = Tcl_ListObjLength(interp, obj_, &result);
+  return _error ?  - 1: result;
+}
+
+void Tcl::tcl_ListObjAppendElement(Tcl_Obj *obj_, Tcl_Obj *value_) {
+  if (!_error)
+    if (value_ == 0)
+      Fail();
+    else
+      _error = Tcl_ListObjAppendElement(interp, obj_, value_);
+}
+
+bool Tcl::tcl_GetBooleanFromObj(Tcl_Obj *obj_) {
+  int value = 0;
+  if (!_error)
+    _error = Tcl_GetBooleanFromObj(interp, obj_, &value);
+  return value != 0;
+}
+
+int Tcl::tcl_GetIntFromObj(Tcl_Obj *obj_) {
+  int value = 0;
+  if (!_error)
+    _error = Tcl_GetIntFromObj(interp, obj_, &value);
+  return value;
+}
+
+long Tcl::tcl_GetLongFromObj(Tcl_Obj *obj_) {
+  long value = 0;
+  if (!_error)
+    _error = Tcl_GetLongFromObj(interp, obj_, &value);
+  return value;
+}
+
+double Tcl::tcl_GetDoubleFromObj(Tcl_Obj *obj_) {
+  double value = 0;
+  if (!_error)
+    _error = Tcl_GetDoubleFromObj(interp, obj_, &value);
+  return value;
+}
+
+int Tcl::tcl_GetIndexFromObj(Tcl_Obj *obj_, const char **table_, const char
+  *msg_) {
+  int index =  - 1;
+  if (!_error)
+    _error = Tcl_GetIndexFromObj(interp, obj_, (CONST84 char **)table_, msg_, 0,
+      &index);
+  return _error == TCL_OK ? index :  - 1;
+}
+
+long Tcl::tcl_ExprLongObj(Tcl_Obj *obj_) {
+  long result = 0;
+  if (!_error)
+    _error = Tcl_ExprLongObj(interp, obj_, &result);
+  return result;
+}
+
+Tcl_Obj *Tcl::GetValue(const c4_RowRef &row_, const c4_Property &prop_, Tcl_Obj
+  *obj_) {
+  obj_ = GetAsObj(row_, prop_, obj_);
+
+  if (!obj_)
+    Fail("unsupported property type");
+
+  return obj_;
+}
+
+Tcl_Obj *Tcl::tcl_NewStringObj(const char *str_, int len_) {
+  return Tcl_NewStringObj((char*)str_, len_);
+}
+
+void Tcl::list2desc(Tcl_Obj *in_, Tcl_Obj *out_) {
+  Tcl_Obj *o,  **ov;
+  int oc;
+  if (Tcl_ListObjGetElements(0, in_, &oc, &ov) == TCL_OK && oc > 0) {
+    char sep = '[';
+    for (int i = 0; i < oc; ++i) {
+      Tcl_AppendToObj(out_, &sep, 1);
+      sep = ',';
+      Tcl_ListObjIndex(0, ov[i], 0, &o);
+      if (o != 0)
+        Tcl_AppendObjToObj(out_, o);
+      Tcl_ListObjIndex(0, ov[i], 1, &o);
+      if (o != 0)
+        list2desc(o, out_);
+    }
+    Tcl_AppendToObj(out_, "]", 1);
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// The MkTcl class adds Metakit-specific utilities and all the command procs.
+
+int MkTcl::Dispatcher(ClientData cd, Tcl_Interp *ip, int oc, Tcl_Obj *const *
+  ov) {
+  MkTcl *self = (MkTcl*)cd;
+
+  if (self == 0 || self->interp != ip) {
+    Tcl_SetResult(ip, (char*)"Initialization error in dispatcher", TCL_STATIC);
+    return TCL_ERROR;
+  }
+
+  return self->Execute(oc, ov);
+}
+
+MkTcl::MkTcl(MkWorkspace *ws_, Tcl_Interp *ip_, int id_, const char *cmd_): Tcl
+  (ip_), id(id_), work(*ws_) {
+  Tcl_CreateObjCommand(ip_, (char*)cmd_, Dispatcher, this, 0);
+}
+
+MkTcl::~MkTcl(){}
+
+c4_View MkTcl::asView(Tcl_Obj *obj_) {
+  SetCursorFromAny(interp, obj_);
+  return AsPath(obj_)._view;
+}
+
+int &MkTcl::changeIndex(Tcl_Obj *obj_) {
+  SetCursorFromAny(interp, obj_);
+  Tcl_InvalidateStringRep(obj_);
+  return AsIndex(obj_);
+}
+
+c4_RowRef MkTcl::asRowRef(Tcl_Obj *obj_, int type_) {
+  c4_View view = asView(obj_);
+  int index = AsIndex(obj_);
+  int size = view.GetSize();
+
+  switch (type_) {
+    case kExtendRow:
+      if (index >= size)
+        view.SetSize(size = index + 1);
+    case kLimitRow:
+      if (index > size)
+        Fail("view index is too large");
+      else if (index < 0)
+        Fail("view index is negative");
+      break;
+
+    case kExistingRow:
+      if (index < 0 || index >= size) {
+        Fail("view index is out of range");
+        break;
+      }
+    case kAnyRow:
+      ;
+  }
+
+  return view[index];
+}
+
+int MkTcl::GetCmd() {
+  c4_RowRef row = asRowRef(objv[1], kExistingRow);
+
+  if (!_error) {
+    const bool returnSize = objc > 2 &&  // fixed 1999-11-19
+    tcl_GetIndexFromObj(objv[2], getCmds) >= 0;
+    if (returnSize) {
+      --objc;
+      ++objv;
+    } else {
+      _error = TCL_OK; // ignore missing option
+      KeepRef o = Tcl_NewObj();
+      tcl_SetObjResult(o);
+    }
+
+    Tcl_Obj *result = tcl_GetObjResult();
+
+    if (objc < 3) {
+      c4_View view = row.Container();
+      for (int i = 0; i < view.NumProperties() && !_error; ++i) {
+        const c4_Property &prop = view.NthProperty(i);
+        if (prop.Type() == 'V')
+          continue;
+        // omit subviews
+
+        tcl_ListObjAppendElement(result, tcl_NewStringObj(prop.Name()));
+        tcl_ListObjAppendElement(result, returnSize ? Tcl_NewIntObj(prop(row)
+          .GetSize()): GetValue(row, prop));
+      }
+    } else if (objc == 3) {
+      const c4_Property &prop = AsProperty(objv[2], row.Container());
+      if (returnSize)
+        Tcl_SetIntObj(result, prop(row).GetSize());
+      else
+        GetValue(row, prop, result);
+    } else {
+      for (int i = 2; i < objc && !_error; ++i) {
+        const c4_Property &prop = AsProperty(objv[i], row.Container());
+        tcl_ListObjAppendElement(result, returnSize ? Tcl_NewIntObj(prop(row)
+          .GetSize()): GetValue(row, prop));
+      }
+    }
+  }
+
+  return _error;
+}
+
+int MkTcl::SetValues(const c4_RowRef &row_, int objc, Tcl_Obj *const * objv) {
+  while (objc >= 2 && !_error) {
+    _error = SetAsObj(interp, row_, AsProperty(objv[0], row_.Container()),
+      objv[1]);
+
+    objc -= 2;
+    objv += 2;
+  }
+
+  return _error;
+}
+
+int MkTcl::SetCmd() {
+  if (objc < 4)
+    return GetCmd();
+
+  int size = asView(objv[1]).GetSize();
+  c4_RowRef row = asRowRef(objv[1], kExtendRow);
+
+  int e = SetValues(row, objc - 2, objv + 2);
+  if (e != TCL_OK)
+    asView(objv[1]).SetSize(size);
+  // 1.1: restore old size on errors
+
+  if (_error)
+    return _error;
+
+  return tcl_SetObjResult(objv[1]);
+}
+
+int MkTcl::RowCmd() {
+  static const char *cmds[] =  {
+    "create", "append", "delete", "insert", "replace", 0
+  };
+
+  // "create" is optional if there are no further args
+  int id = objc <= 1 ? 0 : tcl_GetIndexFromObj(objv[1], cmds);
+  if (id < 0)
+    return _error;
+
+  switch (id) {
+    case 0:
+       {
+        Tcl_Obj *var = AllocateNewTempRow(work);
+        KeepRef keeper(var);
+
+        SetValues(asRowRef(var, kExtendRow), objc - 2, objv + 2);
+        return tcl_SetObjResult(var); // different result
+      }
+
+    case 1:
+       {
+        Tcl_Obj *var = Tcl_DuplicateObj(objv[2]);
+        tcl_SetObjResult(var);
+
+        // used to be a single stmt, avoids bug in gcc 2.7.2 on Linux?
+        int size = asView(var).GetSize();
+        changeIndex(var) = size;
+
+        int oc = objc - 3;
+        Tcl_Obj **ov = (Tcl_Obj **)objv + 3;
+
+        // 2003-03-16, allow giving all pairs as list
+        if (oc == 1 && Tcl_ListObjGetElements(interp, objv[3], &oc, &ov) !=
+          TCL_OK)
+          return TCL_ERROR;
+
+        // 2000-06-15: this will not work with custom viewers which
+        // take over ordering or uniqueness, because such views can
+        // not be resized to create emtpy rows, which get filled in
+        int e = SetValues(asRowRef(var, kExtendRow), oc, ov);
+        if (e != TCL_OK)
+          asView(var).SetSize(size);
+        // 1.1: restore old size on errors
+
+        return e;
+      }
+
+    case 2:
+       {
+        c4_RowRef row = asRowRef(objv[2]);
+        if (_error)
+          return _error;
+
+        c4_View view = row.Container();
+        int index = AsIndex(objv[2]);
+
+        int count = objc > 3 ? tcl_GetIntFromObj(objv[3]): 1;
+        if (count > view.GetSize() - index)
+          count = view.GetSize() - index;
+
+        if (count >= 1) {
+          view.RemoveAt(index, count);
+          work.Invalidate(AsPath(objv[2]));
+        }
+      }
+      break;
+
+    case 3:
+       {
+        c4_RowRef toRow = asRowRef(objv[2], kLimitRow);
+        if (_error)
+          return _error;
+
+        c4_View view = toRow.Container();
+        int n = AsIndex(objv[2]);
+
+        int count = objc > 3 ? tcl_GetIntFromObj(objv[3]): 1;
+        if (count >= 1) {
+          c4_Row temp;
+          view.InsertAt(n, temp, count);
+
+          if (objc > 4) {
+            c4_RowRef fromRow = asRowRef(objv[4]);
+            if (_error)
+              return _error;
+
+            while (--count >= 0)
+              view[n++] = fromRow;
+          }
+          work.Invalidate(AsPath(objv[2]));
+        }
+      }
+      break;
+
+    case 4:
+       {
+        c4_RowRef row = asRowRef(objv[2]);
+        if (_error)
+          return _error;
+
+        if (objc > 3)
+          row = asRowRef(objv[3]);
+        else
+          row = c4_Row();
+      }
+      break;
+  }
+
+  if (_error)
+    return _error;
+
+  return tcl_SetObjResult(objv[2]);
+}
+
+int MkTcl::FileCmd() {
+  static const char *cmds[] =  {
+    "open", "end", "close", "commit", "rollback", "load", "save", "views", 
+      "aside", "autocommit", "space", 0
+  };
+
+  int id = tcl_GetIndexFromObj(objv[1], cmds);
+  if (id < 0)
+    return _error;
+
+  if (id == 0 && objc == 2)
+   { // new in 1.1: return list of db's
+    Tcl_Obj *result = tcl_GetObjResult();
+
+    // skip first entry, which is for temp rows
+    for (int i = 1; i < work.NumItems() && !_error; ++i) {
+      MkWorkspace::Item *ip = work.Nth(i);
+
+      if (ip != 0) {
+        tcl_ListObjAppendElement(result, tcl_NewStringObj(ip->_name));
+        tcl_ListObjAppendElement(result, tcl_NewStringObj(ip->_fileName));
+      }
+    }
+
+    return _error;
+  }
+
+  const char *string = Tcl_GetStringFromObj(objv[2], 0);
+
+  MkWorkspace::Item *np = work.Find(f4_GetToken(string));
+  if (np == 0 && id > 1)
+    return Fail("no storage with this name");
+
+  switch (id) {
+    case 0:
+       { // open
+        if (np != 0)
+          return Fail("file already open");
+
+        int mode = 1;
+        bool nocommit = false, shared = false;
+        static const char *options[] =  {
+          "-readonly", "-extend", "-nocommit", "-shared", 0
+        }
+        ;
+
+        while (objc > 2 &&  *Tcl_GetStringFromObj(objv[objc - 1], 0) == '-')
+        switch (tcl_GetIndexFromObj(objv[--objc], options)) {
+        case 0:
+          mode = 0;
+          break;
+        case 1:
+          mode = 2;
+          break;
+        case 2:
+          nocommit = true;
+          break;
+        case 3:
+          shared = true;
+          break;
+        default:
+          return _error;
+        }
+
+        const char *name = Tcl_GetStringFromObj(objv[2], 0);
+        int len = 0;
+        const char *file = objc < 4 ? "": Tcl_GetStringFromObj(objv[3], &len);
+#ifdef WIN32
+        np = work.Define(name, file, mode, shared);
+#else 
+        Tcl_DString ds;
+        const char *native = Tcl_UtfToExternalDString(NULL, file, len, &ds);
+        np = work.Define(name, native, mode, shared);
+        Tcl_DStringFree(&ds);
+#endif 
+        if (np == 0)
+          return Fail("file open failed");
+
+        if (*file && mode != 0 && !nocommit)
+          np->_storage.AutoCommit();
+      }
+      break;
+
+    case 1:
+       { // end
+        int len;
+        const char *name = Tcl_GetStringFromObj(objv[2], &len);
+        c4_FileStrategy strat;
+#ifdef WIN32
+        int err = strat.DataOpen(name, false);
+#else 
+        Tcl_DString ds;
+        const char *native = Tcl_UtfToExternalDString(NULL, name, len, &ds);
+        int err = strat.DataOpen(native, false);
+        Tcl_DStringFree(&ds);
+#endif 
+        if (!err || !strat.IsValid())
+          return Fail("no such file");
+        t4_i32 end = strat.EndOfData();
+        if (end < 0)
+          return Fail("not a Metakit datafile");
+
+        Tcl_SetIntObj(tcl_GetObjResult(), end);
+        return _error;
+      }
+      break;
+
+    case 2:
+       { // close
+        delete np;
+      }
+      break;
+
+    case 3:
+       { // commit
+        if (!np->_storage.Strategy().IsValid())
+          return Fail("cannot commit temporary dataset");
+
+        np->ForceRefresh(); // detach first
+
+        // 1-Mar-1999: check commit success
+        bool full = objc > 3 && strcmp(Tcl_GetStringFromObj(objv[3], 0), 
+          "-full") == 0;
+        if (!np->_storage.Commit(full))
+          return Fail("I/O error during commit");
+      }
+      break;
+
+    case 4:
+       { // rollback
+        if (!np->_storage.Strategy().IsValid())
+          return Fail("cannot rollback temporary dataset");
+
+        np->ForceRefresh(); // detach first
+
+        bool full = objc > 3 && strcmp(Tcl_GetStringFromObj(objv[3], 0), 
+          "-full") == 0;
+        np->_storage.Rollback(full);
+      }
+      break;
+
+    case 5:
+       { // load
+        char *channel = Tcl_GetStringFromObj(objv[3], 0);
+
+        int mode;
+        Tcl_Channel cp = Tcl_GetChannel(interp, channel, &mode);
+        if (cp == 0 || !(mode &TCL_READABLE))
+          return Fail("load from channel failed");
+
+        if (Tcl_SetChannelOption(interp, cp, "-translation", "binary"))
+          return Fail();
+
+        np->ForceRefresh(); // detach first
+
+        c4_TclStream stream(cp);
+        if (!np->_storage.LoadFrom(stream))
+          return Fail("load error");
+      }
+      break;
+
+    case 6:
+       { // save
+        char *channel = Tcl_GetStringFromObj(objv[3], 0);
+
+        int mode;
+        Tcl_Channel cp = Tcl_GetChannel(interp, channel, &mode);
+        if (cp == 0 || !(mode &TCL_WRITABLE))
+          return Fail("save to channel failed");
+
+        if (Tcl_SetChannelOption(interp, cp, "-translation", "binary"))
+          return Fail();
+
+        c4_TclStream stream(cp);
+        np->_storage.SaveTo(stream);
+      }
+      break;
+
+    case 7:
+       { // views
+        c4_View view = np->_storage;
+        Tcl_Obj *result = tcl_GetObjResult();
+
+        for (int i = 0; i < view.NumProperties() && !_error; ++i) {
+          const c4_Property &prop = view.NthProperty(i);
+          tcl_ListObjAppendElement(result, tcl_NewStringObj(prop.Name()));
+        }
+
+        return _error; // different result
+      }
+
+    case 8:
+       { // aside
+        if (objc != 4)
+          return Fail("mk::file aside: needs 2 storage args");
+
+        const char *as = Tcl_GetStringFromObj(objv[3], 0);
+        MkWorkspace::Item *np2 = work.Find(f4_GetToken(as));
+        if (np2 == 0)
+          return Fail("no storage with this name");
+
+        np->_storage.SetAside(np2->_storage);
+      }
+      break;
+
+    case 9:
+       { // autocommit
+        if (objc != 3)
+          return Fail("mk::file autocommit: too many args");
+
+        np->_storage.AutoCommit();
+      }
+      break;
+
+    case 10:
+       { // space, new on 30-11-2001:  returns allocator used space pairs
+        // nasty hack to obtain the storage's sequence pointer
+        c4_View v = np->_storage;
+        c4_Cursor c = &v[0];
+        c4_Sequence *s = c._seq;
+
+        // even more horrible (i.e. brittle) hack to get the space vector
+        c4_Persist *p = s->Persist();
+        c4_PtrArray *a = p != 0 ? *(c4_PtrArray **)p: 0; // first field
+        if (a == 0)
+          return Fail("storage is not persistent");
+
+        // now return the values as a list
+        Tcl_Obj *r = tcl_GetObjResult();
+        for (int i = 1; i < a->GetSize() - 1 && !_error; ++i)
+          tcl_ListObjAppendElement(r, Tcl_NewLongObj((long)a->GetAt(i)));
+        return _error;
+      }
+  }
+
+  if (_error)
+    return _error;
+
+  return tcl_SetObjResult(objv[2]);
+}
+
+int MkTcl::ViewCmd() {
+  int id = tcl_GetIndexFromObj(objv[1], viewCmds);
+  if (id < 0)
+    return _error;
+
+  switch (id) {
+    case 0:
+      // layout
+      if (objc == 3) {
+        const char *string = Tcl_GetStringFromObj(objv[2], 0);
+
+        MkWorkspace::Item *np = work.Find(f4_GetToken(string));
+        if (np == 0)
+          return Fail("no storage with this name");
+
+        c4_Storage &s = np->_storage;
+
+        const char *p = s.Description(f4_GetToken(string));
+        if (p == 0)
+          return Fail("no view with this name");
+
+        c4_String desc = KitToTclDesc(p);
+        KeepRef o = tcl_NewStringObj(desc);
+        return tcl_SetObjResult(o); // different result
+      }
+      // else fall through
+    case 1:
+       { // delete
+        const char *string = Tcl_GetStringFromObj(objv[2], 0);
+
+        MkWorkspace::Item *np = work.Find(f4_GetToken(string));
+        if (np == 0 && id != 4)
+          return Fail("no storage with this name");
+
+        c4_String s = f4_GetToken(string);
+        if (s.IsEmpty() ||  *string != 0)
+          return Fail("unrecognized view name");
+
+        if (id == 0) {
+          KeepRef o = tcl_NewStringObj(s);
+          list2desc(objv[3], o);
+          const char *desc = Tcl_GetStringFromObj(o, 0);
+          if (desc &&  *desc)
+            np->_storage.GetAs(desc);
+        }
+         else {
+          c4_View v = np->_storage;
+          if (v.FindPropIndexByName(s) < 0)
+            return Fail("no view with this name");
+
+          np->_storage.GetAs(s);
+        }
+
+        np->ForceRefresh(); // make sure views are re-attached
+      }
+      break;
+
+    case 2:
+       { // size
+        c4_View view = asView(objv[2]);
+
+        if (objc > 3) {
+          int i = tcl_GetIntFromObj(objv[3]);
+          if (_error)
+            return _error;
+          view.SetSize(i);
+        }
+
+        Tcl_SetIntObj(tcl_GetObjResult(), view.GetSize());
+        return _error; // different result
+      }
+      break;
+
+    case 3:
+      // properties
+    case 8:
+       { // info (will be deprecated)
+        c4_View view = asView(objv[2]);
+        Tcl_Obj *result = tcl_GetObjResult();
+
+        for (int i = 0; i < view.NumProperties() && !_error; ++i) {
+          const c4_Property &prop = view.NthProperty(i);
+
+          c4_String s = prop.Name();
+          if (prop.Type() != 'S') {
+            s += ":";
+            s += prop.Type();
+          }
+
+          tcl_ListObjAppendElement(result, tcl_NewStringObj(s));
+        }
+
+        return _error;
+      }
+
+    case 4:
+       { // locate
+        c4_View view = asView(objv[2]);
+
+        bool force = strcmp(Tcl_GetStringFromObj(objv[3], 0), "-force") == 0;
+        int k = force ? 4 : 3;
+
+        if (k >= objc)
+          return Fail("no key specified");
+
+        c4_Row key;
+
+        for (int i = 0; k + i < objc; ++i) {
+          const c4_Property &prop = view.NthProperty(i);
+          _error = SetAsObj(interp, key, prop, objv[k + i]);
+          if (_error)
+            return _error;
+        }
+
+        int pos;
+        if (view.Locate(key, &pos) == 0)
+          if (force)
+            view.InsertAt(pos, key);
+          else
+            return Fail("key not found");
+
+        Tcl_SetIntObj(tcl_GetObjResult(), pos);
+        return _error;
+      }
+
+    case 5:
+       { // restrict
+        if (objc <= 5)
+          return Fail("too few args");
+
+        c4_View view = asView(objv[2]);
+        c4_View hview = asView(objv[3]);
+        int nkeys = tcl_GetIntFromObj(objv[4]);
+        view = view.Hash(hview, nkeys);
+
+        c4_Row key;
+
+        for (int i = 0; i + 5 < objc; ++i) {
+          const c4_Property &prop = view.NthProperty(i);
+          _error = SetAsObj(interp, key, prop, objv[i + 5]);
+          if (_error)
+            return _error;
+        }
+
+        int pos = 0;
+        int count = view.GetSize();
+        int result = view.RestrictSearch(key, pos, count);
+
+        Tcl_Obj *r = tcl_GetObjResult();
+        tcl_ListObjAppendElement(r, Tcl_NewIntObj(result));
+        tcl_ListObjAppendElement(r, Tcl_NewIntObj(pos));
+        tcl_ListObjAppendElement(r, Tcl_NewIntObj(count));
+        return _error;
+      }
+
+    case 6:
+       { // open
+        if (objc < 3 || objc > 4)
+          return Fail("wrong number of args");
+
+        c4_View view = asView(objv[2]);
+        const char *name = objc > 3 ? Tcl_GetStringFromObj(objv[3], 0): "";
+
+        MkView *cmd = new MkView(interp, view, name);
+        Tcl_SetStringObj(tcl_GetObjResult(), (char*)(const char*)cmd->CmdName(),
+          - 1);
+        return _error;
+      }
+
+    case 7:
+       { // new ?name?
+        if (objc < 2 || objc > 3)
+          return Fail("wrong number of args");
+
+        c4_View view;
+        const char *name = objc > 3 ? Tcl_GetStringFromObj(objv[2], 0): "";
+
+        MkView *cmd = new MkView(interp, view, name);
+        Tcl_SetStringObj(tcl_GetObjResult(), (char*)(const char*)cmd->CmdName(),
+          - 1);
+        return _error;
+      }
+  }
+
+  if (_error)
+    return _error;
+
+  return tcl_SetObjResult(objv[2]);
+}
+
+int MkTcl::LoopCmd() {
+  Tcl_Obj *value = objc >= 4 ? Tcl_ObjSetVar2(interp, objv[1], 0, objv[2],
+    TCL_LEAVE_ERR_MSG): Tcl_ObjGetVar2(interp, objv[1], 0, TCL_LEAVE_ERR_MSG);
+  if (value == 0)
+    return Fail();
+  // has to exist, can't be valid otherwise
+
+  long first = objc >= 5 ? tcl_ExprLongObj(objv[3]): 0;
+  long limit = objc >= 6 ? tcl_ExprLongObj(objv[4]): asView(value).GetSize();
+  long incr = objc >= 7 ? tcl_ExprLongObj(objv[5]): 1;
+
+  if (incr == 0)
+    Fail("increment must be nonzero");
+
+  if (_error)
+    return _error;
+
+  Tcl_Obj *var = objv[1];
+  Tcl_Obj *cmd = objv[objc - 1];
+
+  for (int i = first;; i += incr) {
+    if (Tcl_IsShared(value))
+      value = Tcl_DuplicateObj(value);
+
+    changeIndex(value) = i;
+
+    if (Tcl_ObjSetVar2(interp, var, 0, value, TCL_LEAVE_ERR_MSG) == 0)
+      return Fail();
+
+    if (!(i < limit && incr > 0 || i > limit && incr < 0))
+      break;
+
+    LeaveMutex();
+    _error = Tcl_EvalObj(interp, cmd);
+    EnterMutex(interp);
+
+    if (_error == TCL_CONTINUE)
+      _error = TCL_OK;
+
+    if (_error) {
+      if (_error == TCL_BREAK)
+        _error = TCL_OK;
+      else if (_error == TCL_ERROR) {
+        char msg[100];
+        sprintf(msg, "\n  (\"mk::loop\" body line %d)", Tcl_GetErrorLine(interp));
+        Tcl_AddObjErrorInfo(interp, msg,  - 1);
+      }
+      break;
+    }
+  }
+
+  if (_error == TCL_OK)
+    Tcl_ResetResult(interp);
+
+  return _error;
+}
+
+int MkTcl::CursorCmd() {
+  int id = tcl_GetIndexFromObj(objv[1], cursorCmds);
+  if (id < 0)
+    return _error;
+
+  Tcl_Obj *name = objv[2];
+
+  Tcl_Obj *var = 0;
+
+  if (id == 0) {
+    var = objc < 4 ? AllocateNewTempRow(work): objv[3]; // create expects a path
+
+    --objc; // shift so the index will be picked up if present
+    ++objv;
+  } else
+   { // alter an existing cursor
+    var = Tcl_ObjGetVar2(interp, name, 0, TCL_LEAVE_ERR_MSG);
+    if (var == 0)
+      return Fail();
+    // has to exist, can't be valid otherwise
+  }
+
+  // about to modify, so make sure we are sole owners
+  Tcl_Obj *original = 0;
+  if (Tcl_IsShared(var)) {
+    original = var;
+    var = Tcl_DuplicateObj(var);
+  }
+
+  KeepRef keeper(var);
+
+  c4_View view = asView(var);
+
+  int value;
+  if (objc <= 3) {
+    if (id == 1)
+     { // position without value returns current value
+      Tcl_SetIntObj(tcl_GetObjResult(), AsIndex(var));
+      return _error;
+    }
+
+    value = id == 0 ? 0 : 1; // create defaults to 0, incr defaults to 1
+  } else if (Tcl_GetIntFromObj(interp, objv[3], &value) != TCL_OK) {
+    const char *step = Tcl_GetStringFromObj(objv[3], 0);
+    if (strcmp(step, "end") == 0)
+      value = view.GetSize() - 1;
+    else {
+      if (original)
+        Tcl_DecrRefCount(original);
+      return Fail();
+    }
+  }
+
+  if (id < 2)
+    changeIndex(var) = value;
+  else
+    changeIndex(var) += value;
+
+  Tcl_Obj *result = Tcl_ObjSetVar2(interp, name, 0, var, TCL_LEAVE_ERR_MSG);
+  if (result == 0)
+    return Fail();
+
+  return tcl_SetObjResult(result);
+}
+
+int MkTcl::SelectCmd() {
+  TclSelector sel(interp, asView(objv[1]));
+
+  static const char *opts[] =  {
+    "-min",  // 0
+    "-max",  // 1
+    "-exact",  // 2
+    "-glob",  // 3
+    "-regexp",  // 4
+    "-keyword",  // 5
+    "-first",  // 6
+    "-count",  // 7
+    "-sort",  // 8
+    "-rsort",  // 9
+    "-globnc",  // 10
+    0
+  };
+
+  while (objc >= 4) {
+    objc -= 2; // gobble next two arguments
+    objv += 2;
+
+    // at this point, *objv is the next option, and objc >= 2
+
+    int id =  - 1;
+
+    const char *p = Tcl_GetStringFromObj(*objv, 0);
+    if (p &&  *p == '-') {
+      id = tcl_GetIndexFromObj(*objv, opts);
+      if (id < 0)
+        return _error;
+    }
+
+    switch (id) {
+      case  - 1:  { // prop value : case-insensitive match
+        _error = sel.AddCondition( - 1, objv[0], objv[1]);
+      }
+      break;
+
+      case 0:
+        // -min prop value : property must be greater or equal to value
+      case 1:
+        // -max prop value : property must be less or equal to value
+      case 2:
+        // -exact prop value : exact case-sensitive match
+      case 3:
+        // -glob prop pattern : match "glob" expression wildcard
+      case 4:
+        // -regexp prop pattern : match specified regular expression
+      case 5:
+        // -keyword prop prefix : match keyword in given property
+      case 10:
+         { // -globnc prop pattern : match "glob", but ignore case
+          if (objc < 3)
+            return Fail("not enough arguments");
+
+          _error = sel.AddCondition(id, objv[1], objv[2]);
+
+          --objc; // gobble a third argument
+          ++objv;
+        }
+        break;
+
+      case 6:
+        // -first pos : searching starts at specified row index
+      case 7:
+         { // -count num : return no more than this many results
+          int n = tcl_GetIntFromObj(objv[1]);
+          if (_error)
+            return _error;
+
+          if (id == 6)
+            sel._first = n;
+          else
+            sel._count = n;
+        }
+        break;
+
+      case 8:
+        // -sort prop : sort on one or more properties, ascending
+      case 9:
+         { // -rsort prop : sort on one or more properties, descending
+          c4_View props = sel.GetAsProps(objv[1]);
+          for (int i = 0; i < props.NumProperties(); ++i) {
+            const c4_Property &prop = props.NthProperty(i);
+
+            sel._sortProps.AddProperty(prop);
+            if (id == 9)
+              sel._sortRevProps.AddProperty(prop);
+          }
+        }
+        break;
+    }
+  }
+
+  if (_error)
+    return _error;
+
+  return sel.DoSelect(tcl_GetObjResult());
+}
+
+int MkTcl::ChannelCmd() {
+  c4_RowRef row = asRowRef(objv[1]);
+  MkPath &path = AsPath(objv[1]);
+  int index = AsIndex(objv[1]);
+
+  if (_error)
+    return _error;
+
+  const c4_BytesProp &memo = (const c4_BytesProp &)AsProperty(objv[2],
+    path._view);
+
+  int id = objc < 4 ? 0 : tcl_GetIndexFromObj(objv[3], channelCmds);
+  if (id < 0)
+    return _error;
+
+  const char *p = path._path;
+  MkWorkspace::Item *ip = work.Find(f4_GetToken(p));
+  if (ip == 0)
+    return Fail("no storage with this name");
+
+  if (id == 1)
+    memo(row).SetData(c4_Bytes());
+  // truncate the existing contents
+
+  int mode = id == 0 ? TCL_READABLE : id == 1 ? TCL_WRITABLE : TCL_READABLE |
+    TCL_WRITABLE;
+
+  MkChannel *mkChan = new MkChannel(ip->_storage, path._view, memo, index);
+  d4_assert(mkChan != 0);
+
+  static int mkChanSeq = 0;
+  char buffer[10];
+  sprintf(buffer, "mk%d", ++mkChanSeq);
+
+  mkChan->_watchMask = 0;
+  mkChan->_validMask = mode;
+  mkChan->_interp = interp;
+  mkChan->_chan = Tcl_CreateChannel(&mkChannelType, buffer, (ClientData)mkChan,
+    mode);
+
+  if (id == 2)
+    Tcl_Seek(mkChan->_chan, 0, SEEK_END);
+
+  Tcl_RegisterChannel(interp, mkChan->_chan);
+
+  if (_error)
+    return _error;
+
+  KeepRef o = tcl_NewStringObj(buffer);
+  return tcl_SetObjResult(o);
+}
+
+int MkTcl::Execute(int oc, Tcl_Obj *const * ov) {
+  struct CmdDef {
+    int min;
+    int max;
+    const char *desc;
+  };
+
+  static CmdDef defTab[] =  {
+     {
+      2, 0, "get cursor ?prop ...?"
+    }
+    ,  {
+      3, 0, "set cursor prop ?value prop value ...?"
+    }
+    ,  {
+      3, 5, "cursor option cursorname ?...?"
+    }
+    ,  {
+      2, 0, "row option ?cursor ...?"
+    }
+    ,  {
+      2, 0, "view option view ?arg?"
+    }
+    ,  {
+      2, 6, "file option ?tag ...?"
+    }
+    ,  {
+      3, 7, "loop cursor ?path first limit incr? {cmds}"
+    }
+    ,  {
+      2, 0, "select path ?...?"
+    }
+    ,  {
+      3, 4, "channel path prop ?mode?"
+    }
+    , 
+    {
+      0, 0, 0
+    }
+    , 
+  };
+
+  _error = TCL_OK;
+
+  CmdDef &cd = defTab[id];
+
+  objc = oc;
+  objv = ov;
+
+  if (oc < cd.min || (cd.max > 0 && oc > cd.max)) {
+    msg = "wrong # args: should be \"mk::";
+    msg += cd.desc;
+    msg += "\"";
+
+    return Fail(msg);
+  }
+
+  EnterMutex(interp);
+  int result = 0;
+  switch (id) {
+    case 0:
+      result = GetCmd();
+      break;
+    case 1:
+      result = SetCmd();
+      break;
+    case 2:
+      result = CursorCmd();
+      break;
+    case 3:
+      result = RowCmd();
+      break;
+    case 4:
+      result = ViewCmd();
+      break;
+    case 5:
+      result = FileCmd();
+      break;
+    case 6:
+      result = LoopCmd();
+      break;
+    case 7:
+      result = SelectCmd();
+      break;
+    case 8:
+      result = ChannelCmd();
+      break;
+  }
+  LeaveMutex();
+  return result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void MkWorkspace::CleanupCommands() {
+  for (int i = 0; i < _commands.GetSize(); ++i)
+    delete (MkTcl*)_commands.GetAt(i);
+  _commands.SetSize(0);
+}
+
+static void ExitProc(ClientData cd_) {
+  delete (MkWorkspace*)cd_;
+}
+
+static void DelProc(ClientData cd_, Tcl_Interp *ip_) {
+  // got here through assoc's delproc, don't trigger again on exit
+  Tcl_DeleteExitHandler(ExitProc, cd_);
+  ExitProc(cd_);
+}
+
+static int Mktcl_Cmds(Tcl_Interp *interp, bool /*safe*/) {
+  if (Tcl_InitStubs(interp, "8.1", 0) == 0)
+    return TCL_ERROR;
+
+  // Create workspace if not present.
+  MkWorkspace *ws = (MkWorkspace*)Tcl_GetAssocData(interp, "mk4tcl", 0);
+  if (ws == 0) {
+    Tcl_RegisterObjType(&mkPropertyType);
+    Tcl_RegisterObjType(&mkCursorType);
+
+    ws = new MkWorkspace(interp);
+    // add an association with delproc to catch "interp delete",
+    // since that does not seem to trigger exitproc handling (!)
+    Tcl_SetAssocData(interp, "mk4tcl", DelProc, ws);
+    Tcl_CreateExitHandler(ExitProc, ws);
+  }
+
+  // this list must match the "CmdDef defTab []" above.
+  static const char *cmds[] =  {
+    "get", "set", "cursor", "row", "view", "file", "loop", "select", "channel", 
+    0
+  };
+
+  c4_String prefix = "mk::";
+
+  for (int i = 0; cmds[i]; ++i)
+    ws->DefCmd(new MkTcl(ws, interp, i, prefix + cmds[i]));
+
+  return Tcl_PkgProvide(interp, "Mk4tcl", "2.4.9.7");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// The proper way to load this extension is with "load mk4tcl.{so,dll} mk4tcl",
+// but 8.0.2 load guesses module "mk" instead of "mk4tcl" (it stops at digits)
+// when the third argument is omitted, allow that too: "load mk4tcl.{so,dll}".
+
+EXTERN int Mk4tcl_Init(Tcl_Interp *interp) {
+  return Mktcl_Cmds(interp, false);
+}
+
+EXTERN int Mk_Init(Tcl_Interp *interp) {
+  return Mktcl_Cmds(interp, false);
+}
+
+EXTERN int Mk4tcl_SafeInit(Tcl_Interp *interp) {
+  return Mktcl_Cmds(interp, true);
+}
+
+EXTERN int Mk_SafeInit(Tcl_Interp *interp) {
+  return Mktcl_Cmds(interp, true);
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/tcl/mk4tcl.h b/8.x/mk/tcl/mk4tcl.h
new file mode 100644 (file)
index 0000000..94a0f6f
--- /dev/null
@@ -0,0 +1,378 @@
+// mk4tcl.h --
+// $Id: mk4tcl.h 4435 2008-08-01 19:58:42Z patthoyts $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "mk4.h"
+#include "mk4str.h"
+#include "../src/univ.h"
+
+#include <tcl.h>
+
+#ifdef BUILD_Mk4tcl
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+#endif
+
+#ifndef d4_assert
+#if q4_INLINE && !q4_CHECK
+// if inlining is on, assume it's release code and disable assertions
+#define d4_assert(x)
+#elif defined (ASSERT)
+#define d4_assert(x) ASSERT(x)
+#else 
+#include <assert.h>
+#define d4_assert(x) assert(x)
+#endif 
+#endif 
+
+#ifndef CONST84
+#define CONST84
+#endif 
+
+#ifndef CONST86
+#define CONST86
+#endif
+
+#ifndef TCL_DECLARE_MUTEX
+#define TCL_DECLARE_MUTEX(v)
+#define Tcl_MutexLock(v)
+#define Tcl_MutexUnlock(v)
+#endif 
+
+///////////////////////////////////////////////////////////////////////////////
+// Defined in this file:
+
+class MkPath;
+class MkWorkspace;
+class Tcl;
+class MkTcl;
+
+///////////////////////////////////////////////////////////////////////////////
+// Utility code: return next token up to char < '0', and
+// advance the string pointer past following character.
+
+c4_String f4_GetToken(const char * &str_);
+
+///////////////////////////////////////////////////////////////////////////////
+// Utility code: true if value contains a word starting with the given prefix
+
+bool MatchOneKeyword(const char *value_, const c4_String &crit_);
+
+///////////////////////////////////////////////////////////////////////////////
+// Utility class: increments and decrements reference count for auto cleanup
+
+class KeepRef {
+    Tcl_Obj *_obj;
+  public:
+    KeepRef(Tcl_Obj *obj_): _obj(obj_) {
+        Tcl_IncrRefCount(_obj);
+    }
+    ~KeepRef() {
+        Tcl_DecrRefCount(_obj);
+    }
+
+    operator Tcl_Obj *()const {
+        return _obj;
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Utility code: get a Metakit item and convert it to a Tcl object
+
+Tcl_Obj *GetAsObj(const c4_RowRef &row_, const c4_Property &prop_, Tcl_Obj
+  *obj_ = 0);
+
+///////////////////////////////////////////////////////////////////////////////
+// Utility code: set a Metakit item and convert it from a Tcl object
+
+int SetAsObj(Tcl_Interp *interp, const c4_RowRef &row_, const c4_Property
+  &prop_, Tcl_Obj *obj_);
+
+///////////////////////////////////////////////////////////////////////////////
+// A path is a view which knows its place, and what workspace it belongs to.
+// Since it contains a string version, its tag can be used to find the item.
+
+class MkPath {
+    int _refs; // reference count
+
+  public:
+    MkPath(MkWorkspace &ws_, const char * &path_, Tcl_Interp *interp);
+    ~MkPath(); // don't use explicit destruction, use Refs(-1)
+
+    int AttachView(Tcl_Interp *interp);
+    int Refs(int diff_);
+
+    MkWorkspace *_ws; // avoid globals, but there is usually just one
+    c4_View _view; // the view corresponding to this path
+    c4_String _path; // describes view, starting with storage tag
+    int _currGen; // tracks the generation to force reloads
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// A workspace manages a number of storage objects and their associated paths.
+
+class MkWorkspace {
+    c4_PtrArray _items; // items, or null if released
+    c4_Bytes _usedBuffer; // buffer, using 1 byte per entry
+    t4_byte *_usedRows; // 1 if that row in item 0 is currently in use
+    c4_PtrArray _commands;
+
+  public:
+    Tcl_Interp *_interp;
+
+    struct Item {
+        const c4_String _name; // the alias for this storage
+        const c4_String _fileName;
+        c4_Storage _storage; // the storage object
+        c4_PtrArray _paths; // the paths associated with this entry
+        c4_PtrArray &_items; // array from which this item is referenced
+        int _index; // position in the _items array
+
+        //Item ();        // special first entry initializer
+        Item(const char *name_, const char *fileName_, int mode_, c4_PtrArray
+          &items_, int index_, bool share_ = false);
+        ~Item();
+
+        void ForceRefresh(); // bump the generation to recreate views
+
+        static c4_PtrArray *_shared; // shared items are also listed here
+    };
+
+    MkWorkspace(Tcl_Interp *ip_);
+    ~MkWorkspace();
+
+    void DefCmd(MkTcl *cmd_); // 1.2: for cleanup
+    void CleanupCommands();
+
+    Item *Define(const char *name_, const char *fileName_, int mode_, bool
+      share_);
+
+    Item *Find(const char *name_)const;
+    int NumItems()const;
+    Item *Nth(int index_)const;
+
+    // create a new path if it doesn't exist, else bump the reference count
+    MkPath *AddPath(const char * &name_, Tcl_Interp *interp);
+    // decrease the reference count, delete path if it is no longer used
+    void ForgetPath(const MkPath *path_);
+    // create a path to a temporary row
+    void AllocTempRow(c4_String &);
+
+    // adjust paths of all subviews if the parent position has changed
+    void Invalidate(const MkPath &path_);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Interface to Tcl 8.0 type mechanism, defines a new "mkProperty" datatype
+//
+//  Since properties are immutable, we don't need most of the calls.
+///////////////////////////////////////////////////////////////////////////////
+
+const c4_Property &AsProperty(Tcl_Obj *objPtr, const c4_View &view_);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Interface to Tcl 8.0 type mechanism, defines a new "mkCursor" datatype
+//
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Cursors in Tcl are implemented as a pointer to an MkPath plus an index.
+
+MkPath &AsPath(Tcl_Obj *obj_);
+int &AsIndex(Tcl_Obj *obj_);
+int SetCursorFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+
+// 24nov02: added to support releasing mutex lock during loop eval's
+int Mk_EvalObj(Tcl_Interp *ip_, Tcl_Obj *cmd_);
+
+///////////////////////////////////////////////////////////////////////////////
+// Helper class for the mk::select command, stores params and performs select
+
+class TclSelector {
+    c4_PtrArray _conditions;
+    Tcl_Interp *_interp;
+    c4_View _view;
+    Tcl_Obj *_temp;
+
+  public:
+    class Condition {
+      public:
+        int _id;
+        c4_View _view;
+        Tcl_Obj *_crit; // no need to incref, original lifetime is guaranteed
+
+        Condition(int id_, const c4_View &view_, Tcl_Obj *crit_): _id(id_),
+          _view(view_), _crit(crit_){}
+    };
+
+    c4_View _sortProps;
+    c4_View _sortRevProps;
+    int _first;
+    int _count;
+
+    TclSelector(Tcl_Interp *interp_, const c4_View &view_);
+    ~TclSelector();
+
+    c4_View GetAsProps(Tcl_Obj *obj_);
+    int AddCondition(int id_, Tcl_Obj *props_, Tcl_Obj *value_);
+    bool MatchOneString(int id_, const char *value_, const char *crit_);
+    bool Match(const c4_RowRef &row_);
+    void ExactKeyProps(const c4_RowRef &row_);
+    int DoSelect(Tcl_Obj *list_, c4_View *result_ = 0);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// The Tcl class is a generic interface to Tcl, providing some C++ wrapping
+
+class Tcl {
+  protected:
+    Tcl_Interp *interp;
+    int _error;
+
+  public:
+    Tcl(Tcl_Interp *ip_);
+
+    int Fail(const char *msg_ = 0, int err_ = TCL_ERROR);
+    Tcl_Obj *tcl_GetObjResult();
+    int tcl_SetObjResult(Tcl_Obj *obj_);
+    int tcl_ListObjLength(Tcl_Obj *obj_);
+    void tcl_ListObjAppendElement(Tcl_Obj *obj_, Tcl_Obj *value_);
+    bool tcl_GetBooleanFromObj(Tcl_Obj *obj_);
+    int tcl_GetIntFromObj(Tcl_Obj *obj_);
+    long tcl_GetLongFromObj(Tcl_Obj *obj_);
+    double tcl_GetDoubleFromObj(Tcl_Obj *obj_);
+    int tcl_GetIndexFromObj(Tcl_Obj *obj_, const char **table_, const char
+      *msg_ = "option");
+    long tcl_ExprLongObj(Tcl_Obj *obj_);
+
+    Tcl_Obj *GetValue(const c4_RowRef &row_, const c4_Property &prop_, Tcl_Obj
+      *obj_ = 0);
+    Tcl_Obj *tcl_NewStringObj(const char *str_, int len_ =  - 1);
+    void list2desc(Tcl_Obj *in, Tcl_Obj *out);
+};
+
+// The MkTcl class adds Metakit-specific utilities and all the command procs.
+
+class MkTcl: public Tcl {
+    int id;
+    int objc;
+    Tcl_Obj *const * objv;
+    c4_String msg;
+    MkWorkspace &work;
+
+    static int Dispatcher(ClientData cd, Tcl_Interp *ip, int oc, Tcl_Obj *const
+      * ov);
+
+  public:
+    enum {
+        kAnyRow, kExistingRow, kLimitRow, kExtendRow
+    };
+
+    MkTcl(MkWorkspace *ws_, Tcl_Interp *ip_, int id_, const char *cmd_);
+    ~MkTcl();
+
+    c4_View asView(Tcl_Obj *obj_);
+    int &changeIndex(Tcl_Obj *obj_);
+    c4_RowRef asRowRef(Tcl_Obj *obj_, int type_ = kExistingRow);
+    int GetCmd();
+    int SetValues(const c4_RowRef &row_, int objc, Tcl_Obj *const * objv);
+    int SetCmd();
+    int RowCmd();
+    int FileCmd();
+    int ViewCmd();
+    int LoopCmd();
+    int CursorCmd();
+    int SelectCmd();
+    int ChannelCmd();
+    int NewCmd();
+    int Try1Cmd();
+    int Try2Cmd();
+    int Try3Cmd();
+#if MKSQL
+    int SqlAuxCmd();
+#endif 
+    int Execute(int oc, Tcl_Obj *const * ov);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class MkView: public Tcl {
+    int objc;
+    Tcl_Obj *const * objv;
+    Tcl_Command cmdToken;
+    c4_String msg;
+    MkWorkspace &work;
+    c4_View view;
+    c4_String cmd;
+
+    static int Dispatcher(ClientData cd, Tcl_Interp *ip, int oc, Tcl_Obj *const
+      * ov);
+    static void DeleteProc(ClientData cd);
+
+  public:
+
+    MkView(Tcl_Interp *ip_, c4_View view_, const char *name = 0);
+    MkView(Tcl_Interp *ip_, const char *name = 0);
+    ~MkView();
+
+    void Register(const char *name);
+
+    static c4_View View(Tcl_Interp *interp, Tcl_Obj *obj);
+
+    c4_String CmdName() {
+        return cmd;
+    }
+
+    int asIndex(c4_View &view, Tcl_Obj *obj_, bool mayExceed_);
+    int SetValues(const c4_RowRef &row_, int objc, Tcl_Obj *const * objv,
+      c4_View &);
+
+    c4_View &View() {
+        return view;
+    }
+
+    int CloseCmd(); // $obj close
+    int DeleteCmd(); // $obj delete cursor ?count?
+    int FindCmd(); // $obj find ?prop value ...?
+    int GetCmd(); // $obj get cursor ?prop prop ...?
+    int ExistsCmd(); // $obj exists cursor
+    int InfoCmd(); // $obj info
+    int InsertCmd(); // $obj insert cursor ?prop prop ...?
+    int OpenCmd(); // $obj open cursor prop
+    int SearchCmd(); // $obj search prop value
+    int SelectCmd(); // $obj select ....
+    int SetCmd(); // $obj set cursor ?prop value ...?
+    int SizeCmd(); // $obj size ?newsize?
+    int LoopCmd(); // $obj loop cursor ?first? ?limit? ?step? {cmds}
+    int ViewCmd(); // $obj view option ?args?
+
+    int CloneCmd(); // $obj view clone
+    int ConcatCmd(); // $obj view concat view
+    int CopyCmd(); // $obj view copy
+    int DifferentCmd(); // $obj view different view
+    int DupCmd(); // $obj view dup
+    int BlockedCmd(); // $obj view blocked
+    int FlattenCmd(); // $obj view flatten prop
+    int GroupByCmd(); // $obj view groupby subview prop ?prop ...?
+    int HashCmd(); // $obj view hash view ?numkeys?
+    int IndexedCmd(); // $obj view indexed map unique prop ?prop ...?
+    int IntersectCmd(); // $obj view intersect view
+    int JoinCmd(); // $obj view join view prop ?prop ...?
+    int MapCmd(); // $obj view map view
+    int MinusCmd(); // $obj view minus view
+    int OrderedCmd(); // $obj view ordered ?numKeys?
+    int PairCmd(); // $obj view pair view
+    int ProductCmd(); // $obj view product view
+    int ProjectCmd(); // $obj view project prop ?prop ...?
+    int RangeCmd(); // $obj view range start ?limit? ?step?
+    int ReadOnlyCmd(); // $obj view readonly
+    int RenameCmd(); // $obj view rename oprop nprop
+    int RestrictCmd(); // $obj view restrict cursor pos count
+    int UnionCmd(); // $obj view union view
+    int UniqueCmd(); // $obj view unique
+
+    int Execute(int oc, Tcl_Obj *const * ov);
+};
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/8.x/mk/tcl/mk4too.cpp b/8.x/mk/tcl/mk4too.cpp
new file mode 100644 (file)
index 0000000..b75bbba
--- /dev/null
@@ -0,0 +1,1042 @@
+// mk4too.cpp -- Tcl object command interface to Metakit
+// $Id: mk4too.cpp 4452 2008-12-10 22:57:54Z patthoyts $
+// This is part of Metakit, see http://www.equi4.com/metakit.html
+// Copyright (C) 2000-2004 by Matt Newman and Jean-Claude Wippler.
+
+#include "mk4tcl.h"
+#include <stdio.h>
+#include <string.h>
+
+#if 10 * TCL_MAJOR_VERSION + TCL_MINOR_VERSION < 86
+#define Tcl_GetErrorLine(interp) (interp)->errorLine
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Defined in this file:
+
+class MkView;
+
+///////////////////////////////////////////////////////////////////////////////
+// The MkView class adds Metakit-specific utilities and all the command procs.
+
+int MkView::Dispatcher(ClientData cd, Tcl_Interp *ip, int oc, Tcl_Obj *const *
+  ov) {
+    MkView *self = (MkView*)cd;
+
+    if (self == 0 || self->interp != ip) {
+        Tcl_SetResult(ip, "Initialization error in dispatcher", TCL_STATIC);
+        return TCL_ERROR;
+    }
+    return self->Execute(oc, ov);
+}
+
+void MkView::DeleteProc(ClientData cd) {
+  MkView *self = (MkView*)cd;
+  delete self;
+}
+
+MkView::MkView(Tcl_Interp *ip_, c4_View view_, const char *name): Tcl(ip_),
+  work(*(MkWorkspace*)Tcl_GetAssocData(interp, "mk4tcl", 0)), view(view_) {
+  Register(name);
+}
+
+MkView::MkView(Tcl_Interp *ip_, const char *name): Tcl(ip_), work(*
+  (MkWorkspace*)Tcl_GetAssocData(interp, "mk4tcl", 0)) {
+  Register(name);
+}
+
+MkView::~MkView(){}
+
+void MkView::Register(const char *name) {
+  static int uid = 0;
+  char buf[32];
+
+  if (name == 0 ||  *name == 0) {
+    sprintf(buf, "%d", uid++);
+    cmd = "view" + (c4_String)buf;
+  } else {
+    cmd = name;
+  }
+  // save token... so I can delete cmd later (even if renamed)
+  cmdToken = Tcl_CreateObjCommand(interp, (char*)(const char*)cmd, MkView
+    ::Dispatcher, this, MkView::DeleteProc);
+}
+
+c4_View MkView::View(Tcl_Interp *interp, Tcl_Obj *obj) {
+  const char *name = Tcl_GetStringFromObj(obj, 0);
+  Tcl_CmdInfo ci;
+
+  if (!Tcl_GetCommandInfo(interp, (char*)name, &ci) || ci.objProc != MkView
+    ::Dispatcher) {
+    //Fail("no such view");
+    c4_View temp;
+    return temp;
+  } else {
+    MkView *v = (MkView*)ci.objClientData;
+    return v->view;
+  }
+}
+
+int MkView::asIndex(c4_View &view, Tcl_Obj *obj_, bool mayExceed_) {
+  int size = view.GetSize();
+  int index;
+
+  if (Tcl_GetIntFromObj(interp, obj_, &index) != TCL_OK) {
+    const char *step = Tcl_GetStringFromObj(obj_, 0);
+    if (step != 0 && strcmp(step, "end") == 0) {
+      index = !mayExceed_ ? size - 1: size;
+      Tcl_ResetResult(interp); // clear error
+      _error = TCL_OK;
+    } else {
+      index =  - 1;
+    }
+  }
+
+  if (mayExceed_) {
+    if (index > size)
+      Fail("view index is too large");
+    else if (index < 0)
+      Fail("view index is negative");
+  } else if (index < 0 || index >= size)
+    Fail("view index is out of range");
+
+  return index;
+}
+
+int MkView::SetValues(const c4_RowRef &row_, int objc, Tcl_Obj *const * objv,
+  c4_View &view_) {
+  if (objc % 2)
+    Fail("bad args: must be prop value pairs");
+
+  while (objc > 0 && !_error) {
+    _error = SetAsObj(interp, row_, AsProperty(objv[0], view_), objv[1]);
+
+    objc -= 2;
+    objv += 2;
+  }
+
+  return _error;
+}
+
+int MkView::Execute(int oc, Tcl_Obj *const * ov) {
+  struct CmdDef {
+    int(MkView:: *proc)();
+    int min;
+    int max;
+    const char *desc;
+  };
+
+  static const char *subCmds[] =  {
+    "close", "delete", "exists", "find", "get", "properties", "insert", "open",
+      "search", "select", "set", "size", "loop", "view", "info",  
+      // will be deprecated (use "properties" instead)
+    0
+  };
+  static CmdDef defTab[] =  {
+    // the "&MkView::" stuff is required for Mac cwpro2
+     {
+       &MkView::CloseCmd, 2, 2, "close"
+    }
+    ,  {
+       &MkView::DeleteCmd, 3, 4, "delete cursor ?cursor2?"
+    }
+    ,  {
+       &MkView::ExistsCmd, 3, 0, "exists cursor ?prop ...?"
+    }
+    ,  {
+       &MkView::FindCmd, 2, 0, "find ?prop value ...?"
+    }
+    ,  {
+       &MkView::GetCmd, 3, 0, "get cursor ?prop ...?"
+    }
+    ,  {
+       &MkView::InfoCmd, 2, 2, "properties"
+    }
+    ,  {
+       &MkView::InsertCmd, 3, 0, "insert cursor ?prop ...?"
+    }
+    ,  {
+       &MkView::OpenCmd, 4, 4, "open cursor prop"
+    }
+    ,  {
+       &MkView::SearchCmd, 4, 4, "search prop value"
+    }
+    ,  {
+       &MkView::SelectCmd, 2, 0, "select ?..?"
+    }
+    ,  {
+       &MkView::SetCmd, 3, 0, "set cursor prop ?value prop value ...?"
+    }
+    ,  {
+       &MkView::SizeCmd, 2, 3, "size ?newsize?"
+    }
+    ,  {
+       &MkView::LoopCmd, 3, 0, "loop cursor ?first? ?limit? ?step? body"
+    }
+    ,  {
+       &MkView::ViewCmd, 3, 0, "view option ?args?"
+    }
+    ,  {
+       &MkView::InfoCmd, 2, 2, "info"
+    }
+    ,  {
+      0, 0, 0, 0
+    }
+    , 
+  };
+  _error = TCL_OK;
+
+  int id = tcl_GetIndexFromObj(ov[1], subCmds);
+
+  if (id ==  - 1)
+    return TCL_ERROR;
+
+  CmdDef &cd = defTab[id];
+
+  objc = oc;
+  objv = ov;
+
+  if (oc < cd.min || (cd.max > 0 && oc > cd.max)) {
+    msg = "wrong # args: should be \"$obj ";
+    msg += cd.desc;
+    msg += "\"";
+
+    return Fail(msg);
+  }
+
+  return (this->*cd.proc)();
+}
+
+//
+// Tcl command methods
+//
+
+int MkView::CloseCmd() {
+  // remove command instance... this will call delete...
+  Tcl_DeleteCommandFromToken(interp, cmdToken);
+  return TCL_OK;
+}
+
+int MkView::DeleteCmd() {
+  int count = 1;
+  int index = asIndex(view, objv[2], true);
+
+  if (_error)
+    return _error;
+
+  if (objc > 3) {
+    int index2 = asIndex(view, objv[3], true);
+
+    if (_error)
+      return _error;
+
+    count = index2 - index + 1;
+  }
+
+  if (count > view.GetSize() - index)
+    count = view.GetSize() - index;
+
+  if (count >= 1) {
+    view.RemoveAt(index, count);
+  }
+  return TCL_OK;
+}
+
+int MkView::ExistsCmd() {
+  asIndex(view, objv[2], false);
+  int r = _error ? 0 : 1;
+  _error = 0;
+  return tcl_SetObjResult(Tcl_NewIntObj(r));
+}
+
+int MkView::FindCmd() {
+  c4_Row row;
+  int idx = 2;
+
+  while (idx < objc && !_error) {
+    _error = SetAsObj(interp, row, AsProperty(objv[idx], view), objv[idx + 1]);
+    idx += 2;
+  }
+  if (_error)
+    return _error;
+
+  idx = view.Find(row, 0);
+  if (idx ==  - 1) {
+    Fail("not found");
+    return TCL_ERROR;
+  }
+  return tcl_SetObjResult(Tcl_NewIntObj(idx));
+}
+
+int MkView::GetCmd() {
+  int index = asIndex(view, objv[2], false);
+  if (_error)
+    return _error;
+
+  Tcl_Obj *result = tcl_GetObjResult();
+  c4_RowRef row = view[index];
+
+  if (objc < 4) {
+    for (int i = 0; i < view.NumProperties() && !_error; ++i) {
+      const c4_Property &prop = view.NthProperty(i);
+      c4_String name = prop.Name();
+
+      if (prop.Type() == 'V')
+        continue;
+      // omit subviews
+
+      tcl_ListObjAppendElement(result, tcl_NewStringObj(name));
+      tcl_ListObjAppendElement(result, GetValue(row, prop));
+    }
+  } else if (objc == 4) {
+    GetValue(row, AsProperty(objv[3], view), result);
+  } else {
+    for (int i = 3; i < objc && !_error; ++i) {
+      const c4_Property &prop = AsProperty(objv[i], view);
+      tcl_ListObjAppendElement(result, GetValue(row, prop));
+    }
+  }
+  return _error;
+}
+
+int MkView::InfoCmd() {
+  Tcl_Obj *result = tcl_GetObjResult();
+
+  for (int i = 0; i < view.NumProperties() && !_error; ++i) {
+    const c4_Property &prop = view.NthProperty(i);
+
+    c4_String s = prop.Name();
+    if (prop.Type() != 'S') {
+      s += ":";
+      s += prop.Type();
+    }
+
+    tcl_ListObjAppendElement(result, tcl_NewStringObj(s));
+  }
+  return tcl_SetObjResult(result);
+}
+
+int MkView::InsertCmd() {
+  int index = asIndex(view, objv[2], true);
+  if (_error)
+    return _error;
+
+  c4_Row temp;
+  SetValues(temp, objc - 3, objv + 3, view);
+  view.InsertAt(index, temp, 1);
+  //SetValues(view[index], objc - 3, objv + 3);
+
+  if (_error) {
+    view.RemoveAt(index, 1); // remove new row on errors
+    return _error;
+  }
+  return tcl_SetObjResult(Tcl_NewIntObj(index));
+}
+
+int MkView::OpenCmd() {
+  int index = asIndex(view, objv[2], false);
+
+  if (_error)
+    return _error;
+
+  const c4_Property &prop = AsProperty(objv[3], view);
+  if (_error)
+    return _error;
+
+  if (prop.Type() != 'V') {
+    Fail("bad property: must be a view");
+    return TCL_ERROR;
+  }
+  MkView *ncmd = new MkView(interp, ((const c4_ViewProp &)prop)(view[index]));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::SearchCmd() {
+  Tcl_Obj *obj_ = objv[3];
+  const c4_Property &prop = AsProperty(objv[2], view);
+  char type = prop.Type();
+  double dblVal = 0, dtmp;
+  long longVal = 0;
+#ifdef TCL_WIDE_INT_TYPE
+  Tcl_WideInt wideVal = 0, wtmp;
+#endif 
+  c4_String strVal;
+
+  int size = view.GetSize();
+  int first = 0, last = size;
+  int row, rc, e;
+
+  switch (type) {
+    case 'S':
+       {
+        strVal = Tcl_GetStringFromObj(obj_, 0);
+      }
+      break;
+
+    case 'F':
+    case 'D':
+       {
+        e = Tcl_GetDoubleFromObj(interp, obj_, &dblVal);
+        if (e != TCL_OK)
+          return e;
+      }
+      break;
+
+#ifdef TCL_WIDE_INT_TYPE
+    case 'L':
+       {
+        e = Tcl_GetWideIntFromObj(interp, obj_, &wideVal);
+        if (e != TCL_OK)
+          return e;
+      }
+      break;
+#endif 
+
+    case 'I':
+       {
+        e = Tcl_GetLongFromObj(interp, obj_, &longVal);
+        if (e != TCL_OK)
+          return e;
+      }
+      break;
+
+    default:
+      Tcl_SetResult(interp, "unsupported property type", TCL_STATIC);
+      return TCL_ERROR;
+  }
+
+  while (first <= last) {
+    row = (first + last) / 2;
+
+    if (row >= size)
+      break;
+
+    switch (type) {
+      case 'S':
+        rc = strVal.CompareNoCase(((c4_StringProp &)prop)(view[row]));
+        break;
+      case 'F':
+        dtmp = dblVal - ((c4_FloatProp &)prop)(view[row]);
+        rc = (dtmp < 0 ?  - 1: (dtmp > 0));
+        break;
+      case 'D':
+        dtmp = dblVal - ((c4_DoubleProp &)prop)(view[row]);
+        rc = (dtmp < 0 ?  - 1: (dtmp > 0));
+        break;
+#ifdef TCL_WIDE_INT_TYPE
+      case 'L':
+        wtmp = wideVal - ((c4_LongProp &)prop)(view[row]);
+        rc = (wtmp < 0 ?  - 1: (wtmp > 0));
+        break;
+#endif 
+      case 'I':
+        rc = longVal - ((c4_IntProp &)prop)(view[row]);
+        break;
+      default:
+        rc = 0; // 27-09-2001, to satisfy MSVC6 warn level 4
+    }
+
+    if (rc == 0) {
+      goto done;
+    } else if (rc > 0) {
+      first = row + 1;
+    } else {
+      last = row - 1;
+    }
+  }
+  // Not found
+  row =  - 1;
+  done: return tcl_SetObjResult(Tcl_NewIntObj(row));
+}
+
+int MkView::SelectCmd() {
+  TclSelector sel(interp, view);
+
+  static const char *opts[] =  {
+    "-min",  // 0
+    "-max",  // 1
+    "-exact",  // 2
+    "-glob",  // 3
+    "-regexp",  // 4
+    "-keyword",  // 5
+    "-first",  // 6
+    "-count",  // 7
+    "-sort",  // 8
+    "-rsort",  // 9
+    "-globnc",  // 10
+    0
+  };
+
+  while (objc >= 4) {
+    objc -= 2; // gobble next two arguments
+    objv += 2;
+
+    // at this point, *objv is the next option, and objc >= 2
+
+    int id =  - 1;
+
+    const char *p = Tcl_GetStringFromObj(*objv, 0);
+    if (p &&  *p == '-') {
+      id = tcl_GetIndexFromObj(*objv, opts);
+      if (id < 0)
+        return _error;
+    }
+
+    switch (id) {
+      case  - 1:  { // prop value : case-insensitive match
+        _error = sel.AddCondition( - 1, objv[0], objv[1]);
+      }
+      break;
+
+      case 0:
+        // -min prop value : property must be greater or equal to value
+      case 1:
+        // -max prop value : property must be less or equal to value
+      case 2:
+        // -exact prop value : exact case-sensitive match
+      case 3:
+        // -glob prop pattern : match "glob" expression wildcard
+      case 4:
+        // -regexp prop pattern : match specified regular expression
+      case 5:
+        // -keyword prop prefix : match keyword in given property
+      case 10:
+         { // -globnc prop pattern : match "glob", but ignore case
+          if (objc < 3)
+            return Fail("not enough arguments");
+
+          _error = sel.AddCondition(id, objv[1], objv[2]);
+
+          --objc; // gobble a third argument
+          ++objv;
+        }
+        break;
+
+      case 6:
+        // -first pos : searching starts at specified row index
+      case 7:
+         { // -count num : return no more than this many results
+          int n = tcl_GetIntFromObj(objv[1]);
+          if (_error)
+            return _error;
+
+          if (id == 6)
+            sel._first = n;
+          else
+            sel._count = n;
+        }
+        break;
+
+      case 8:
+        // -sort prop : sort on one or more properties, ascending
+      case 9:
+         { // -rsort prop : sort on one or more properties, descending
+          c4_View props = sel.GetAsProps(objv[1]);
+          for (int i = 0; i < props.NumProperties(); ++i) {
+            const c4_Property &prop = props.NthProperty(i);
+
+            sel._sortProps.AddProperty(prop);
+            if (id == 9)
+              sel._sortRevProps.AddProperty(prop);
+          }
+        }
+        break;
+    }
+  }
+
+  if (_error)
+    return _error;
+
+  c4_View nview;
+  sel.DoSelect(0, &nview);
+  MkView *ncmd = new MkView(interp, nview);
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::SetCmd() {
+  if (objc < 4)
+    return GetCmd();
+
+  int index = asIndex(view, objv[2], false);
+  if (_error)
+    return _error;
+
+  return SetValues(view[index], objc - 3, objv + 3, view);
+}
+
+int MkView::SizeCmd() {
+  if (objc > 2) {
+    int i = tcl_GetIntFromObj(objv[2]);
+    if (_error)
+      return _error;
+    view.SetSize(i);
+  }
+
+  return tcl_SetObjResult(Tcl_NewIntObj(view.GetSize()));
+}
+
+int MkView::LoopCmd() {
+  long first = 0;
+  long limit = view.GetSize();
+  long incr = 1;
+
+  if (objc >= 5)
+    first = tcl_ExprLongObj(objv[3]);
+
+  if (objc >= 6)
+    limit = tcl_ExprLongObj(objv[4]);
+
+  if (objc >= 7) {
+    incr = tcl_ExprLongObj(objv[5]);
+    if (incr == 0)
+      Fail("increment has to be nonzero");
+  }
+
+  if (_error)
+    return _error;
+
+  Tcl_Obj *vname = objv[2];
+  Tcl_Obj *cmd = objv[objc - 1];
+
+  for (int i = first; i < limit && incr > 0 || i > limit && incr < 0; i += incr)
+    {
+    Tcl_Obj *var = Tcl_ObjSetVar2(interp, vname, 0, Tcl_NewIntObj(i),
+      TCL_LEAVE_ERR_MSG);
+    if (var == 0)
+      return Fail();
+
+    _error = Mk_EvalObj(interp, cmd);
+
+    if (_error) {
+      if (_error == TCL_CONTINUE)
+        _error = TCL_OK;
+      else {
+        if (_error == TCL_BREAK)
+          _error = TCL_OK;
+        else if (_error == TCL_ERROR) {
+          char msg[100];
+          sprintf(msg, "\n  (\"mk::loop\" body line %d)", Tcl_GetErrorLine(interp));
+          Tcl_AddObjErrorInfo(interp, msg,  - 1);
+        }
+        break;
+      }
+    }
+  }
+
+  if (_error == TCL_OK)
+    Tcl_ResetResult(interp);
+
+  return _error;
+}
+
+int MkView::ViewCmd() {
+  struct CmdDef {
+    int(MkView:: *proc)();
+    int min;
+    int max;
+    const char *desc;
+  };
+
+  static const char *subCmds[] =  {
+    "blocked", "clone", "concat", "copy", "different", "dup", "flatten", 
+      "groupby", "hash", "indexed", "intersect", "join", "map", "minus", 
+      "ordered", "pair", "product", "project", "range", "readonly", "rename", 
+      "restrict", "union", "unique", 
+#if 0
+    "==", "!=", "<", ">", "<=", ">=", 
+#endif 
+    0
+  };
+  static CmdDef defTab[] =  {
+    // the "&MkView::" stuff is required for Mac cwpro2
+     {
+       &MkView::BlockedCmd, 2, 2, "blocked"
+    }
+    ,  {
+       &MkView::CloneCmd, 2, 2, "clone"
+    }
+    ,  {
+       &MkView::ConcatCmd, 3, 3, "concat view"
+    }
+    ,  {
+       &MkView::CopyCmd, 2, 3, "copy"
+    }
+    ,  {
+       &MkView::DifferentCmd, 3, 3, "different view"
+    }
+    ,  {
+       &MkView::DupCmd, 2, 2, "dup"
+    }
+    ,  {
+       &MkView::FlattenCmd, 3, 3, "flatten prop"
+    }
+    ,  {
+       &MkView::GroupByCmd, 4, 0, "groupby subview prop ?prop ...?"
+    }
+    ,  {
+       &MkView::HashCmd, 3, 4, "hash map ?numkeys?"
+    }
+    ,  {
+       &MkView::IndexedCmd, 5, 0, "indexed map unique prop ?prop ...?"
+    }
+    ,  {
+       &MkView::IntersectCmd, 3, 3, "intersect view"
+    }
+    ,  {
+       &MkView::JoinCmd, 4, 0, "join view prop ?prop ...?"
+    }
+    ,  {
+       &MkView::MapCmd, 3, 3, "map view"
+    }
+    ,  {
+       &MkView::MinusCmd, 3, 3, "minus view"
+    }
+    ,  {
+       &MkView::OrderedCmd, 2, 3, "ordered ?numkeys?"
+    }
+    ,  {
+       &MkView::PairCmd, 3, 3, "pair view"
+    }
+    ,  {
+       &MkView::ProductCmd, 3, 3, "product view"
+    }
+    ,  {
+       &MkView::ProjectCmd, 3, 0, "project prop ?prop ...?"
+    }
+    ,  {
+       &MkView::RangeCmd, 4, 0, "range start finish ?step?"
+    }
+    ,  {
+       &MkView::ReadOnlyCmd, 2, 2, "readonly"
+    }
+    ,  {
+       &MkView::RenameCmd, 4, 4, "rename oprop nprop"
+    }
+    ,  {
+       &MkView::RestrictCmd, 2, 0, "restrict...."
+    }
+    ,  {
+       &MkView::UnionCmd, 3, 3, "union view"
+    }
+    ,  {
+       &MkView::UniqueCmd, 2, 2, "unique"
+    }
+    , 
+#if 0
+     {
+       &MkView::OperatorCmd, 3, 3, "== view"
+    }
+    ,  {
+       &MkView::OperatorCmd, 3, 3, "!= view"
+    }
+    ,  {
+       &MkView::OperatorCmd, 3, 3, "< view"
+    }
+    ,  {
+       &MkView::OperatorCmd, 3, 3, "> view"
+    }
+    ,  {
+       &MkView::OperatorCmd, 3, 3, "<= view"
+    }
+    ,  {
+       &MkView::OperatorCmd, 3, 3, ">= view"
+    }
+    , 
+#endif 
+     {
+      0, 0, 0, 0
+    }
+    , 
+  };
+  _error = TCL_OK;
+
+  objc--;
+  objv++;
+
+  int id = tcl_GetIndexFromObj(objv[1], subCmds);
+
+  if (id ==  - 1)
+    return TCL_ERROR;
+
+  CmdDef &cd = defTab[id];
+
+  if (objc < cd.min || (cd.max > 0 && objc > cd.max)) {
+    msg = "wrong # args: should be \"$obj view ";
+    msg += cd.desc;
+    msg += "\"";
+
+    return Fail(msg);
+  }
+
+  return (this->*cd.proc)();
+}
+
+//
+// View-based methods (typically return a new view)
+//
+int MkView::BlockedCmd() {
+  MkView *ncmd = new MkView(interp, view.Blocked());
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::DupCmd() {
+  MkView *cmd = new MkView(interp, view);
+
+  return tcl_SetObjResult(tcl_NewStringObj(cmd->CmdName()));
+}
+
+int MkView::CloneCmd() {
+  MkView *cmd = new MkView(interp, view.Clone());
+
+  return tcl_SetObjResult(tcl_NewStringObj(cmd->CmdName()));
+}
+
+int MkView::ConcatCmd() {
+  c4_View nview = View(interp, objv[2]);
+  MkView *ncmd = new MkView(interp, view.Concat(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::DifferentCmd() {
+  c4_View nview = View(interp, objv[2]);
+  MkView *ncmd = new MkView(interp, view.Different(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::CopyCmd() {
+  MkView *cmd = new MkView(interp, view.Duplicate());
+
+  return tcl_SetObjResult(tcl_NewStringObj(cmd->CmdName()));
+}
+
+int MkView::FlattenCmd() {
+  c4_View nview;
+
+  const c4_Property &prop = AsProperty(objv[2], view);
+  if (_error)
+    return _error;
+
+  if (prop.Type() != 'V') {
+    Fail("bad property: must be a view");
+    return TCL_ERROR;
+  }
+  MkView *ncmd = new MkView(interp, view.JoinProp((const c4_ViewProp &)prop));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::GroupByCmd() {
+  const c4_Property &prop = AsProperty(objv[2], view);
+  if (_error)
+    return _error;
+
+  if (prop.Type() != 'V') {
+    Fail("bad property: must be a view");
+    return TCL_ERROR;
+  }
+  c4_View nview;
+
+  for (int i = 3; i < objc && !_error; ++i) {
+    const c4_Property &prop = AsProperty(objv[i], view);
+    nview.AddProperty(prop);
+  }
+  if (_error)
+    return _error;
+
+  MkView *ncmd = new MkView(interp, view.GroupBy(nview, (const c4_ViewProp &)
+    prop));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::HashCmd() {
+  c4_View nview = View(interp, objv[2]);
+  int nkeys = objc > 3 ? tcl_GetIntFromObj(objv[3]): 1;
+  MkView *ncmd = new MkView(interp, view.Hash(nview, nkeys));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::IndexedCmd() {
+  c4_View map = View(interp, objv[2]);
+  bool unique = tcl_GetIntFromObj(objv[3]) != 0;
+
+  c4_View props;
+  for (int i = 4; i < objc && !_error; ++i) {
+    const c4_Property &prop = AsProperty(objv[i], view);
+    props.AddProperty(prop);
+  }
+  if (_error)
+    return _error;
+
+  MkView *ncmd = new MkView(interp, view.Indexed(map, props, unique));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::IntersectCmd() {
+  c4_View nview = View(interp, objv[2]);
+  MkView *ncmd = new MkView(interp, view.Intersect(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::JoinCmd() {
+  c4_View nview = View(interp, objv[2]);
+  c4_View props;
+
+  for (int i = 3; i < objc && !_error; ++i) {
+    const c4_Property &prop = AsProperty(objv[i], view);
+    props.AddProperty(prop);
+  }
+  if (_error)
+    return _error;
+
+  MkView *ncmd = new MkView(interp, view.Join(props, nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::MapCmd() {
+  c4_View nview = View(interp, objv[2]);
+  MkView *ncmd = new MkView(interp, view.RemapWith(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::MinusCmd() {
+  c4_View nview = View(interp, objv[2]);
+  MkView *ncmd = new MkView(interp, view.Minus(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+#if 0
+int MkView::OperatorCmd() {
+  c4_String op = (const char*)Tcl_GetStringFromObj(objv[1], 0);
+  c4_View nview = View(interp, objv[2]);
+  bool rc;
+
+  if (op == "==")
+    rc = (view == nview);
+  else if (op == "!=")
+    rc = (view != nview);
+  else if (op == "<")
+    rc = (view < nview);
+  else if (op == ">")
+    rc = (view > nview);
+  else if (op == ">=")
+    rc = (view >= nview);
+  else if (op == "<=")
+    rc = (view <= nview);
+  else
+    return Fail("bad operator: must be one of ==, !=, <, >, <=, >=");
+
+  return tcl_SetObjResult(Tcl_NewBooleanObj(rc ? 1 : 0));
+}
+
+#endif 
+
+int MkView::OrderedCmd() {
+  int nkeys = objc > 2 ? tcl_GetIntFromObj(objv[2]): 1;
+  MkView *ncmd = new MkView(interp, view.Ordered(nkeys));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::PairCmd() {
+  c4_View nview = View(interp, objv[2]);
+
+  MkView *ncmd = new MkView(interp, view.Pair(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::ProductCmd() {
+  c4_View nview = View(interp, objv[2]);
+  MkView *ncmd = new MkView(interp, view.Product(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::ProjectCmd() {
+  c4_View nview;
+
+  for (int i = 2; i < objc; i++) {
+    const c4_Property &prop = AsProperty(objv[i], view);
+
+    nview.AddProperty(prop);
+  }
+  MkView *ncmd = new MkView(interp, view.Project(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::RangeCmd() {
+  int start = asIndex(view, objv[2], false);
+  if (_error)
+    return _error;
+
+  int finish = objc > 3 ? asIndex(view, objv[3], false) + 1: start + 1;
+  if (_error)
+    return _error;
+
+  int step = objc > 4 ? tcl_GetIntFromObj(objv[4]): 1;
+  if (_error)
+    return _error;
+
+  MkView *ncmd = new MkView(interp, view.Slice(start, finish, step));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::ReadOnlyCmd() {
+  MkView *ncmd = new MkView(interp, view.ReadOnly());
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::RenameCmd() {
+  const c4_Property &oprop = AsProperty(objv[2], view);
+  if (_error)
+    return _error;
+
+  const c4_Property &nprop = AsProperty(objv[3], view);
+  if (_error)
+    return _error;
+
+  MkView *ncmd = new MkView(interp, view.Rename(oprop, nprop));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::RestrictCmd() {
+  int index = asIndex(view, objv[2], false);
+  int pos = tcl_GetIntFromObj(objv[3]);
+  int count = tcl_GetIntFromObj(objv[4]);
+
+  int result = view.RestrictSearch(view[index], pos, count);
+
+  Tcl_Obj *r = tcl_GetObjResult();
+  tcl_ListObjAppendElement(r, Tcl_NewIntObj(result));
+  tcl_ListObjAppendElement(r, Tcl_NewIntObj(pos));
+  tcl_ListObjAppendElement(r, Tcl_NewIntObj(count));
+  return _error;
+}
+
+int MkView::UnionCmd() {
+  c4_View nview = View(interp, objv[2]);
+  MkView *ncmd = new MkView(interp, view.Union(nview));
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
+
+int MkView::UniqueCmd() {
+  MkView *ncmd = new MkView(interp, view.Unique());
+
+  return tcl_SetObjResult(tcl_NewStringObj(ncmd->CmdName()));
+}
diff --git a/8.x/mk/tcl/mkshow.tcl b/8.x/mk/tcl/mkshow.tcl
new file mode 100755 (executable)
index 0000000..4bf0642
--- /dev/null
@@ -0,0 +1,170 @@
+# mkshow.tcl -- Metakit file show utility
+# $Id: mkshow.tcl 1230 2007-03-09 15:58:53Z jcw $
+# This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+package require Mk4tcl
+
+proc dumpView {db view {prop ""}} {
+  array set fields {}
+  set desc {}
+  set work {}
+  
+    # a property list of the form "-file" causes reading from file
+  if {[regexp {^-(.*)} $prop - file]} {
+    if {$file == ""} { set fd stdin } else { set fd [open $file] }
+    set prop {}
+    while {[gets $fd line] >= 0} {
+      lappend prop $line
+    }
+    if {$file != ""} { close $fd }
+  }
+
+    # set up datatypes, build property list if none given 
+  foreach name [mk::view info $db.$view] {
+    if {![regexp {^(.*):(.)} $name - name type]} {
+      set type S
+    }
+    switch $type {
+      M   { set format {fn:(%db)} }
+      V   { set format {s:[#%d]} }
+      default { set format f }
+    }
+    set fields($name) $format
+    lappend desc $name
+  }
+
+    # expand all fields if there is an empty entry
+  set n [lsearch -exact $prop ""]
+  if {$prop == "" || $n >= 0} {
+    set prop [eval lreplace [list $prop] $n $n $desc]
+  }
+
+    # split off commands and formatting details into a work list
+  foreach name $prop {
+    if {![regexp {^([^/]*)/(.*)} $name - name actions]} {
+      set actions ""
+    }
+    if {$actions == "" && [info exists fields($name)]} {
+      set actions $fields($name)
+    }
+    if {![regexp {^([^:]*):(.*)} $actions - actions format]} {
+      set format ""
+    }
+    lappend work $name [split $actions ""] $format
+  }
+
+    # go through each row in the view
+  mk::loop c $db.$view {
+    set r {}
+    foreach {s a f} $work {
+      set gmt 0
+      foreach x $a {
+        switch -- $x {
+
+          f { set s [mk::get $c $s] }
+          n { set s [string length $s] }
+          s { set s [mk::view size $c.$s] }
+
+          g { set gmt [expr {1-$gmt}] }
+          d { set s [clock format $s -format {%Y/%m/%d} -gmt $gmt] }
+          t { set s [clock format $s -format {%H:%M:%S} -gmt $gmt] }
+
+          k { set s [expr {($s+1023)/1024}] }
+          x { binary scan $s H* s }
+          h { set s [join [hexDump $s] \n] }
+
+          z { package require Trf; set s [zip -mode d $s] }
+          b { package require Trf; set s [bz2 -mode d $s] }
+
+          l { puts $r; set r {} }
+
+          i { set s [mk::cursor pos c] }
+                    p { set s $desc }
+                    v { set s $view }
+        }
+      }
+      if {$f != ""} {
+        set s [format $f $s]
+      }
+      lappend r $s
+    }
+    if {[llength $r] > 0} {
+      puts [join $r "  "]
+    }
+  }
+}
+
+proc hexDump {s} {
+    set r {}
+    set n [string length $s]
+    for {set i 0} {$i < $n} {incr i 16} {
+        set t [string range $s $i [expr {$i + 15}]]
+        regsub -all {[^ -~]} $t {.} u
+        binary scan $t H* t
+        lappend r [format {%8d:  %-32s  %-16s} $i $t $u]
+    }
+    return $r
+}
+
+set USAGE "  Usage: mkshow file view ?prop ...?
+
+  file  is the name of the Metakit datafile
+  view  is a view or subview description (e.g. 'view/123.subview')
+  prop  lists of properties (all if omitted, from file if '-file')
+  
+  The properties may not contain a ':X' type specifier, but they may
+  contain a list of action specifiers (i.e. 'prop/abc...').  Each is
+  applied to the result so far.  An optional ':...' introduces a format.
+  An empty argument is expanded to the list of all fields in the view.
+  
+  Examples:
+  mkshow file view         -- one line per row, all properties
+  mkshow file view /i:%5d: \"\"    -- prefix each line with the row #
+  mkshow file view :blah \"\" /l     -- dump each row as a Tcl command
+  mkshow file view name:%-12s    -- just the name, left, fixed width
+  mkshow file view name/fz:%.100s  -- unzip, then show first 100 chars
+  mkshow file view date/fd date/ft -- show field as date and as time
+
+  For a description of all actions specifiers, type 'mkshow -actions'.
+"
+
+set ACTIONS "  Action codes available in mkshow:
+
+  f fetch the property value (this is usually the first action)
+  n returns size of the property value (default for :B and :M)
+  s returns the number of rows in the subview
+  
+  g set gmt mode for following 'd' and 't' actions
+  d converts int seconds to a YYYY/MM/DD value
+  t converts int seconds to a HH:MM:SS value
+  
+  k convert int value to 'kilo' (i.e. '(N+1023)/1024')
+  x convert string value to hexadecimal form
+  h convert string value to a pretty-printed hex dump
+  
+  z uncompress string value using Trf's zip
+  b uncompress string value using Trf's bz2
+  
+  i returns the row number (used without property, i.e. '/i:%5d:')
+  p returns list of all properties (used without property: '/p')
+  v returns the input view path (used without property: '/v')
+
+  l generate output in Tcl list format (must be last arg: '/l')
+  : the remainder of this argument specifies a format string
+"
+
+if {[llength $argv] < 2} {
+    switch -glob -- [lindex $argv 0] {
+        -a*       { puts stderr $ACTIONS }
+        default { puts stderr $USAGE }
+  }
+  exit 1
+}
+
+set file [lindex $argv 0]
+set view [lindex $argv 1]
+set prop [lrange $argv 2 end]
+
+mk::file open db $file -readonly
+
+dumpView db $view $prop
diff --git a/8.x/mk/tcl/pkgIndex.tcl.in b/8.x/mk/tcl/pkgIndex.tcl.in
new file mode 100644 (file)
index 0000000..d7566b4
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Tcl package index file
+#
+package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ \
+    [list load [file join $dir @PKG_LIB_FILE@] @PACKAGE_NAME@]
diff --git a/8.x/mk/tcl/stubtcl.h b/8.x/mk/tcl/stubtcl.h
new file mode 100644 (file)
index 0000000..6288b5c
--- /dev/null
@@ -0,0 +1,38 @@
+/* Internal stub code, copied from CritLib */
+
+TclStubs *tclStubsPtr;
+TclPlatStubs *tclPlatStubsPtr;
+struct TclIntStubs *tclIntStubsPtr;
+struct TclIntPlatStubs *tclIntPlatStubsPtr;
+
+static int MyInitStubs(Tcl_Interp *ip) {
+  typedef struct  {
+    char *result;
+    Tcl_FreeProc *freeProc;
+    int errorLine;
+    TclStubs *stubTable;
+  } HeadOfInterp;
+
+  HeadOfInterp *hoi = (HeadOfInterp*)ip;
+
+  if (hoi->stubTable == NULL || hoi->stubTable->magic != TCL_STUB_MAGIC) {
+    ip->result = "This extension requires stubs-support.";
+    ip->freeProc = TCL_STATIC;
+    return 0;
+  }
+
+  tclStubsPtr = hoi->stubTable;
+
+  if (Tcl_PkgRequire(ip, "Tcl", "8.1", 0) == NULL) {
+    tclStubsPtr = NULL;
+    return 0;
+  }
+
+  if (tclStubsPtr->hooks != NULL) {
+    tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
+    tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs;
+    tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;
+  }
+
+  return 1;
+}
diff --git a/8.x/mk/tcl/tclconfig/README.txt b/8.x/mk/tcl/tclconfig/README.txt
new file mode 100644 (file)
index 0000000..9055a58
--- /dev/null
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension.  For more information on TEA see:
+
+       http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+       http://tcl.sourceforge.net/
+
+This package is a freely available open source package.  You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt     This file
+
+install-sh     Program used for copying binaries and script files
+               to their install locations.
+
+tcl.m4         Collection of Tcl autoconf macros.  Included by a package's
+               aclocal.m4 to define SC_* macros.
diff --git a/8.x/mk/tcl/tclconfig/install-sh b/8.x/mk/tcl/tclconfig/install-sh
new file mode 100755 (executable)
index 0000000..0ff4b6a
--- /dev/null
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+       echo "install:  no destination specified"
+       exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+       dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/8.x/mk/tcl/tclconfig/tcl.m4 b/8.x/mk/tcl/tclconfig/tcl.m4
new file mode 100644 (file)
index 0000000..ed93116
--- /dev/null
@@ -0,0 +1,4031 @@
+# tcl.m4 --
+#
+#      This file provides a set of autoconf macros to help TEA-enable
+#      a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: tcl.m4 1728 2007-06-24 23:37:51Z jcw $
+
+AC_PREREQ(2.57)
+
+dnl TEA extensions pass us the version of TEA they think they
+dnl are compatible with (must be set in TEA_INIT below)
+dnl TEA_VERSION="3.6"
+
+# Possible values for key variables defined:
+#
+# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
+# TEA_PLATFORM        - windows unix
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+#      Locate the tclConfig.sh file and perform a sanity check on
+#      the Tcl compile flags
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tcl=...
+#
+#      Defines the following vars:
+#              TCL_BIN_DIR     Full path to the directory containing
+#                              the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+       AC_ARG_WITH(tcl,
+           AC_HELP_STRING([--with-tcl],
+               [directory containing tcl configuration (tclConfig.sh)]),
+           with_tclconfig=${withval})
+       AC_MSG_CHECKING([for Tcl configuration])
+       AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           AC_MSG_WARN([Can't find Tcl configuration definitions])
+           exit 0
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+#      Locate the tkConfig.sh file
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tk=...
+#
+#      Defines the following vars:
+#              TK_BIN_DIR      Full path to the directory containing
+#                              the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+    #
+    # Ok, lets find the tk configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tk
+    #
+
+    if test x"${no_tk}" = x ; then
+       # we reset no_tk in case something fails here
+       no_tk=true
+       AC_ARG_WITH(tk,
+           AC_HELP_STRING([--with-tk],
+               [directory containing tk configuration (tkConfig.sh)]),
+           with_tkconfig=${withval})
+       AC_MSG_CHECKING([for Tk configuration])
+       AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+           # First check to see if --with-tkconfig was specified.
+           if test x"${with_tkconfig}" != x ; then
+               case ${with_tkconfig} in
+                   */tkConfig.sh )
+                       if test -f ${with_tkconfig}; then
+                           AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+                           with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tkconfig}/tkConfig.sh" ; then
+                   ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tk library
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ../tk \
+                       `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tk \
+                       `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tk \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tk.framework/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tk \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tkconfig}" = x ; then
+           TK_BIN_DIR="# no Tk configs found"
+           AC_MSG_WARN([Can't find Tk configuration definitions])
+           exit 0
+       else
+           no_tk=
+           TK_BIN_DIR=${ac_cv_c_tkconfig}
+           AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+#      Load the tclConfig.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              TCL_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              TCL_BIN_DIR
+#              TCL_SRC_DIR
+#              TCL_LIB_FILE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+    AC_SUBST(TCL_VERSION)
+    AC_SUBST(TCL_BIN_DIR)
+    AC_SUBST(TCL_SRC_DIR)
+
+    AC_SUBST(TCL_LIB_FILE)
+    AC_SUBST(TCL_LIB_FLAG)
+    AC_SUBST(TCL_LIB_SPEC)
+
+    AC_SUBST(TCL_STUB_LIB_FILE)
+    AC_SUBST(TCL_STUB_LIB_FLAG)
+    AC_SUBST(TCL_STUB_LIB_SPEC)
+
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(TCL_DEFS)
+    AC_SUBST(TCL_EXTRA_CFLAGS)
+    AC_SUBST(TCL_LD_FLAGS)
+    AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+#      Load the tkConfig.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              TK_BIN_DIR
+#
+# Results:
+#
+#      Sets the following vars that should be in tkConfig.sh:
+#              TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${TK_BIN_DIR}/tkConfig.sh"
+    else
+        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+    # If the TK_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TK_LIB_SPEC will be set to the value
+    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+    # instead of TK_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        TK_LIB_SPEC=${TK_BUILD_LIB_SPEC}
+        TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC}
+        TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tk was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tk.framework installed in an arbitary location.
+       case ${TK_DEFS} in
+           *TK_FRAMEWORK*)
+               if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+                   for i in "`cd ${TK_BIN_DIR}; pwd`" \
+                            "`cd ${TK_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+                           TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+                   TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}"
+                   TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+    # Ensure windowingsystem is defined
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       case ${TK_DEFS} in
+           *MAC_OSX_TK*)
+               AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+               TEA_WINDOWINGSYSTEM="aqua"
+               ;;
+           *)
+               TEA_WINDOWINGSYSTEM="x11"
+               ;;
+       esac
+    elif test "${TEA_PLATFORM}" = "windows" ; then
+       TEA_WINDOWINGSYSTEM="win32"
+    fi
+
+    AC_SUBST(TK_VERSION)
+    AC_SUBST(TK_BIN_DIR)
+    AC_SUBST(TK_SRC_DIR)
+
+    AC_SUBST(TK_LIB_FILE)
+    AC_SUBST(TK_LIB_FLAG)
+    AC_SUBST(TK_LIB_SPEC)
+
+    AC_SUBST(TK_STUB_LIB_FILE)
+    AC_SUBST(TK_STUB_LIB_FLAG)
+    AC_SUBST(TK_STUB_LIB_SPEC)
+
+    AC_SUBST(TK_LIBS)
+    AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+#      Allows the building of shared libraries
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-shared=yes|no
+#
+#      Defines the following vars:
+#              STATIC_BUILD    Used for building import/export libraries
+#                              on Windows.
+#
+#      Sets the following vars:
+#              SHARED_BUILD    Value of 1 or 0
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SHARED], [
+    AC_MSG_CHECKING([how to build libraries])
+    AC_ARG_ENABLE(shared,
+       AC_HELP_STRING([--enable-shared],
+           [build and link with shared libraries (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       AC_MSG_RESULT([shared])
+       SHARED_BUILD=1
+    else
+       AC_MSG_RESULT([static])
+       SHARED_BUILD=0
+       AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
+    fi
+    AC_SUBST(SHARED_BUILD)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+#      Specify if thread support should be enabled.  If "yes" is specified
+#      as an arg (optional), threads are enabled by default, "no" means
+#      threads are disabled.  "yes" is the default.
+#
+#      TCL_THREADS is checked so that if you are compiling an extension
+#      against a threaded core, your extension must be compiled threaded
+#      as well.
+#
+#      Note that it is legal to have a thread enabled extension run in a
+#      threaded or non-threaded Tcl core, but a non-threaded extension may
+#      only run in a non-threaded Tcl core.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-threads
+#
+#      Sets the following vars:
+#              THREADS_LIBS    Thread library(s)
+#
+#      Defines the following vars:
+#              TCL_THREADS
+#              _REENTRANT
+#              _THREAD_SAFE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+    AC_ARG_ENABLE(threads,
+       AC_HELP_STRING([--enable-threads],
+           [build with threads]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+    
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+           AC_DEFINE(USE_THREAD_ALLOC, 1,
+               [Do we want to use the threaded memory allocator?])
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           if test "`uname -s`" = "SunOS" ; then
+               AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+                       [Do we really want to follow the standard? Yes we do!])
+           fi
+           AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+           AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               AC_CHECK_LIB(pthread, __pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               AC_CHECK_LIB(pthreads, pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   AC_CHECK_LIB(c, pthread_mutex_init,
+                       tcl_ok=yes, tcl_ok=no)
+                   if test "$tcl_ok" = "no"; then
+                       AC_CHECK_LIB(c_r, pthread_mutex_init,
+                           tcl_ok=yes, tcl_ok=no)
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    AC_MSG_CHECKING([for building with threads])
+    if test "${TCL_THREADS}" = 1; then
+       AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+       AC_MSG_RESULT([yes (default)])
+    else
+       AC_MSG_RESULT([no])
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               AC_MSG_WARN([
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads.])
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               AC_MSG_WARN([
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core.])
+           fi
+           ;;
+    esac
+    AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+#      Specify if debugging symbols should be used.
+#      Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+#      none
+#      
+#      TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+#      the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+#      Requires the following vars to be set in the Makefile:
+#              CFLAGS_DEFAULT
+#              LDFLAGS_DEFAULT
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-symbols
+#
+#      Defines the following vars:
+#              CFLAGS_DEFAULT  Sets to $(CFLAGS_DEBUG) if true
+#                              Sets to $(CFLAGS_OPTIMIZE) if false
+#              LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+#                              Sets to $(LDFLAGS_OPTIMIZE) if false
+#              DBGX            Formerly used as debug library extension;
+#                              always blank now.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_CONFIG_CFLAGS])
+    AC_MSG_CHECKING([for build with symbols])
+    AC_ARG_ENABLE(symbols,
+       AC_HELP_STRING([--enable-symbols],
+           [build with debugging symbols (default: off)]),
+       [tcl_ok=$enableval], [tcl_ok=no])
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       AC_MSG_RESULT([no])
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           AC_MSG_RESULT([yes (standard debugging)])
+       fi
+    fi
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+    AC_SUBST(TCL_DBGX)
+    AC_SUBST(CFLAGS_DEFAULT)
+    AC_SUBST(LDFLAGS_DEFAULT)
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+       AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           AC_MSG_RESULT([enabled symbols mem debugging])
+       else
+           AC_MSG_RESULT([enabled $tcl_ok debugging])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+#      Allows use of modern nl_langinfo check for better l10n.
+#      This is only relevant for Unix.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-langinfo=yes|no (default is yes)
+#
+#      Defines the following vars:
+#              HAVE_LANGINFO   Triggers use of nl_langinfo if defined.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+    AC_ARG_ENABLE(langinfo,
+       AC_HELP_STRING([--enable-langinfo],
+           [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+       [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+    HAVE_LANGINFO=0
+    if test "$langinfo_ok" = "yes"; then
+       AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+    fi
+    AC_MSG_CHECKING([whether to use nl_langinfo])
+    if test "$langinfo_ok" = "yes"; then
+       AC_CACHE_VAL(tcl_cv_langinfo_h, [
+           AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+                   [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+       AC_MSG_RESULT([$tcl_cv_langinfo_h])
+       if test $tcl_cv_langinfo_h = yes; then
+           AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+       fi
+    else 
+       AC_MSG_RESULT([$langinfo_ok])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+#      Determine what the system is (some things cannot be easily checked
+#      on a feature-driven basis, alas). This can usually be done via the
+#      "uname" command, but there are a few systems, like Next, where
+#      this doesn't work.
+#
+# Arguments:
+#      none
+#
+# Results:
+#      Defines the following var:
+#
+#      system -        System/platform/version identification code.
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               AC_MSG_WARN([can't find uname command])
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+    ])
+    system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+#      Try to determine the proper flags to pass to the compiler
+#      for building shared libraries and other such nonsense.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substitutes the following vars:
+#
+#       DL_OBJS -       Name of the object file that implements dynamic
+#                       loading for Tcl on this system.
+#       DL_LIBS -       Library file(s) to include in tclsh and other base
+#                       applications in order for the "load" command to work.
+#       LDFLAGS -      Flags to pass to the compiler when linking object
+#                       files into an executable application binary such
+#                       as tclsh.
+#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
+#                       be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+#       CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile.
+#       SHLIB_CFLAGS -  Flags to pass to cc when compiling the components
+#                       of a shared library (may request position-independent
+#                       code, among other things).
+#       SHLIB_LD -      Base command to use for combining object files
+#                       into a shared library.
+#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+#                       creating shared libraries.  This symbol typically
+#                       goes at the end of the "ld" commands that build
+#                       shared libraries. The value of the symbol is
+#                       "${LIBS}" if all of the dependent libraries should
+#                       be specified when creating a shared library.  If
+#                       dependent libraries should not be specified (as on
+#                       SunOS 4.x, where they cause the link to fail, or in
+#                       general if Tcl and Tk aren't themselves shared
+#                       libraries), then this symbol has an empty string
+#                       as its value.
+#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
+#                       extensions.  An empty string means we don't know how
+#                       to use shared libraries on this platform.
+#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
+#                       in a static or shared library name, using the $VERSION variable
+#                       to put the version in the right place.  This is used
+#                       by platforms that need non-standard library names.
+#                       Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
+#                       to have a version after the .so, and ${VERSION}.a
+#                       on AIX, since a shared library needs to have
+#                       a .a extension whereas shared objects for loadable
+#                       extensions have a .so extension.  Defaults to
+#                       ${VERSION}${SHLIB_SUFFIX}.
+#       TCL_NEEDS_EXP_FILE -
+#                       1 means that an export file is needed to link to a
+#                       shared library.
+#       TCL_EXP_FILE -  The name of the installed export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#       TCL_BUILD_EXP_FILE -
+#                       The name of the built export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#      CFLAGS_DEBUG -
+#                      Flags used when running the compiler in debug mode
+#      CFLAGS_OPTIMIZE -
+#                      Flags used when running the compiler in optimize mode
+#      CFLAGS -        Additional CFLAGS added as necessary (usually 64-bit)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+
+    # Step 0.a: Enable 64 bit support?
+
+    AC_MSG_CHECKING([if 64bit support is requested])
+    AC_ARG_ENABLE(64bit,
+       AC_HELP_STRING([--enable-64bit],
+           [enable 64bit support (default: off)]),
+       [do64bit=$enableval], [do64bit=no])
+    AC_MSG_RESULT([$do64bit])
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+    AC_ARG_ENABLE(64bit-vis,
+       AC_HELP_STRING([--enable-64bit-vis],
+           [enable 64bit Sparc VIS support (default: off)]),
+       [do64bitVIS=$enableval], [do64bitVIS=no])
+    AC_MSG_RESULT([$do64bitVIS])
+
+    if test "$do64bitVIS" = "yes"; then
+       # Force 64bit on with VIS
+       do64bit=yes
+    fi
+
+    # Step 0.c: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       AC_MSG_CHECKING([if Windows/CE build is requested])
+       AC_ARG_ENABLE(wince,[  --enable-wince          enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no])
+       AC_MSG_RESULT([$doWince])
+    fi
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+    TEA_CONFIG_SYSTEM
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
+
+    # Require ranlib early so we can override it in special cases below.
+
+    AC_REQUIRE([AC_PROG_RANLIB])
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    if test "$GCC" = "yes" ; then
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall -Wno-implicit-int"
+    else
+       CFLAGS_WARNING=""
+    fi
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
+dnl AC_CHECK_TOOL(AR, ar)
+    AC_CHECK_PROG(AR, ar, ar)
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    case $system in
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+                   AC_MSG_WARN([Ensure latest Platform SDK is installed])
+                   do64bit="no"
+               else
+                   AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+               fi
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+               fi
+               TEA_PATH_CELIB
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+           if ([$]1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+           if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+           if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+                   TEA_ADD_LIBS([bufferoverflowU.lib])
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+                       AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+                   done
+                   AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+                   AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+                   AC_SUBST(CELIB_DIR)
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r)
+                       # ok ...
+                       ;;
+                   *)
+                       CC=${CC}_r
+                       ;;
+               esac
+               AC_MSG_RESULT([Using $CC for compiling with threads])
+           fi
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_WARN([64bit mode not supported with GCC on $system])
+               else 
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+               fi
+           fi
+
+           if test "`uname -m`" = "ia64" ; then
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               if test "$GCC" = "yes" ; then
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               else
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+               fi
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           else
+               if test "$GCC" = "yes" ; then
+                   SHLIB_LD="gcc -shared"
+               else
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+               fi
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+           fi
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
+               AC_LIBOBJ([tclLoadAix])
+               DL_LIBS="-lld"
+           fi
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
+           if test $libbsd = yes; then
+               MATH_LIBS="$MATH_LIBS -lbsd"
+               AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
+           fi
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -nostart"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD="cc -shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+           AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+           # Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           if test "`uname -m`" = "ia64" ; then
+               SHLIB_SUFFIX=".so"
+           else
+               SHLIB_SUFFIX=".sl"
+           fi
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="gcc -shared"
+               SHLIB_LD_LIBS='${LIBS}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+
+           # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+           #CFLAGS="$CFLAGS +DAportable"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   hpux_arch=`${CC} -dumpmachine`
+                   case $hpux_arch in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD="${CC} -shared"
+                           SHLIB_LD_LIBS='${LIBS}'
+                           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           AC_MSG_WARN([64bit mode not supported with GCC on $system])
+                           ;;
+                   esac
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+               fi
+           fi
+           ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+           else
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+           fi
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_WARN([64bit mode not supported by gcc])
+               else
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               fi
+           fi
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           if test $do64bit = yes; then
+               AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+                   CFLAGS=$hold_cflags])
+               if test $tcl_cv_cc_m64 = yes; then
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+               fi
+           fi
+
+           # The combo of gcc + glibc has a bug related
+           # to inlining of functions like strtod(). The
+           # -fno-builtin flag should address this problem
+           # but it does not work. The -fno-inline flag
+           # is kind of overkill but it works.
+           # Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+           if test x"${USE_COMPAT}" != x ; then
+               CFLAGS="$CFLAGS -fno-inline"
+           fi
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD="${CC} -shared"
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD="${CC} -shared "
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-*|FreeBSD-[[1-2]].*)
+           # NetBSD/SPARC needs -fPIC, -fpic will not do.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           if test $tcl_cv_ld_elf = yes; then
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+           else
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           fi
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
+           case `machine` in
+           sparc|sparc64)
+               SHLIB_CFLAGS="-fPIC";;
+           *)
+               SHLIB_CFLAGS="-fpic";;
+           esac
+           SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           if test $tcl_cv_ld_elf = yes; then
+               LDFLAGS=-Wl,-export-dynamic
+           else
+               LDFLAGS=""
+           fi
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       FreeBSD-*)
+           # FreeBSD 3.* and greater have ELF.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "${TCL_THREADS}" = "1" ; then
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+           fi
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           # To avoid discrepancies between what headers configure sees during
+           # preprocessing tests and compiling tests, move any -isysroot and
+           # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+           CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
+           CFLAGS="`echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
+           if test $do64bit = yes; then
+               case `arch` in
+                   ppc)
+                       AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+                               tcl_cv_cc_arch_ppc64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+                                   tcl_cv_cc_arch_ppc64=no)
+                           CFLAGS=$hold_cflags])
+                       if test $tcl_cv_cc_arch_ppc64 = yes; then
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+                       fi;;
+                   i386)
+                       AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+                               tcl_cv_cc_arch_x86_64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+                                   tcl_cv_cc_arch_x86_64=no)
+                           CFLAGS=$hold_cflags])
+                       if test $tcl_cv_cc_arch_x86_64 = yes; then
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+                       fi;;
+                   *)
+                       AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+               esac
+           else
+               # Check for combined 32-bit and 64-bit fat build
+               echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
+                   echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
+                   fat_32_64=yes
+           fi
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_single_module = yes; then
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+           fi
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+               "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4 && \
+               LDFLAGS="$LDFLAGS -prebind"
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_search_paths_first = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+
+           # TEA specific: for Tk extensions, remove 64-bit arch flags from
+           # CFLAGS et al. for combined 32 & 64 bit fat builds as neither
+           # TkAqua nor TkX11 can be built for 64-bit at present.
+           test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}" && for v in CFLAGS CPPFLAGS LDFLAGS; do
+               eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'; done
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="cc -nostdlib -r"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+           AC_DEFINE(_OE_SOCKETS, 1,   # needed in sys/socket.h
+               [Should OS/390 do the right thing with sockets?])
+           ;;      
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export $@:'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD="ld -shared"
+           else
+               SHLIB_LD="ld -non_shared"
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+           else
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mieee"
+            else
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+           fi
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           if test "${TCL_THREADS}" = "1" ; then
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               if test "$GCC" = "yes" ; then
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+               else
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+               fi
+           fi
+
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           if test "$GCC" = "yes" ; then
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+           else
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+           fi
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[[0-6]])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               arch=`isainfo`
+               if test "$arch" = "sparcv9 sparc" ; then
+                       if test "$GCC" = "yes" ; then
+                           if test "`gcc -dumpversion | awk -F. '{print [$]1}'`" -lt "3" ; then
+                               AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+                           else
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                               LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                               SHLIB_CFLAGS="-fPIC"
+                           fi
+                       else
+                           do64bit_ok=yes
+                           if test "$do64bitVIS" = "yes" ; then
+                               CFLAGS="$CFLAGS -xarch=v9a"
+                               LDFLAGS_ARCH="-xarch=v9a"
+                           else
+                               CFLAGS="$CFLAGS -xarch=v9"
+                               LDFLAGS_ARCH="-xarch=v9"
+                           fi
+                           # Solaris 64 uses this as well
+                           #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+                       fi
+               elif test "$arch" = "amd64 i386" ; then
+                   if test "$GCC" = "yes" ; then
+                       AC_MSG_WARN([64bit mode not supported with GCC on $system])
+                   else
+                       do64bit_ok=yes
+                       CFLAGS="$CFLAGS -xarch=amd64"
+                       LDFLAGS="$LDFLAGS -xarch=amd64"
+                   fi
+               else
+                   AC_MSG_WARN([64bit mode not supported for $arch])
+               fi
+           fi
+           
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               if test "$do64bit_ok" = "yes" ; then
+                   # We need to specify -static-libgcc or we need to
+                   # add the path to the sparv9 libgcc.
+                   # JH: static-libgcc is necessary for core Tcl, but may
+                   # not be necessary for extensions.
+                   SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                   # for finding sparcv9 libgcc, get the regular libgcc
+                   # path, remove so name and append 'sparcv9'
+                   #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                   #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+               fi
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           fi
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_Bexport = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
+       AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+    fi
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    AC_ARG_ENABLE(load,
+       AC_HELP_STRING([--enable-load],
+           [allow dynamic loading and "load" command (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+    if test "$tcl_ok" = "no"; then
+       DL_OBJS=""
+    fi
+
+    if test "x$DL_OBJS" != "x" ; then
+       BUILD_DLTEST="\$(DLTEST_TARGETS)"
+    else
+       echo "Can't figure out how to do dynamic loading or shared libraries"
+       echo "on this system."
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+    fi
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$DL_OBJS" != "tclLoadNone.o" ; then
+       if test "$GCC" = "yes" ; then
+           case $system in
+               AIX-*)
+                   ;;
+               BSD/OS*)
+                   ;;
+               IRIX*)
+                   ;;
+               NetBSD-*|FreeBSD-*)
+                   ;;
+               Darwin-*)
+                   ;;
+               SCO_SV-3.2*)
+                   ;;
+               windows)
+                   ;;
+               *)
+                   SHLIB_CFLAGS="-fPIC"
+                   ;;
+           esac
+       fi
+    fi
+
+    if test "$SHARED_LIB_SUFFIX" = "" ; then
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+    fi
+    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+    fi
+
+    AC_SUBST(DL_LIBS)
+
+    AC_SUBST(CFLAGS_DEBUG)
+    AC_SUBST(CFLAGS_OPTIMIZE)
+    AC_SUBST(CFLAGS_WARNING)
+
+    AC_SUBST(STLIB_LD)
+    AC_SUBST(SHLIB_LD)
+
+    AC_SUBST(SHLIB_LD_LIBS)
+    AC_SUBST(SHLIB_CFLAGS)
+
+    AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+    TEA_TCL_EARLY_FLAGS
+    TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+#      Determine which interface to use to talk to the serial port.
+#      Note that #include lines must begin in leftmost column for
+#      some compilers to recognize them as preprocessor directives,
+#      and some build environments have stdin not pointing at a
+#      pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines only one of the following vars:
+#              HAVE_SYS_MODEM_H
+#              USE_TERMIOS
+#              USE_TERMIO
+#              USE_SGTTY
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+    AC_CHECK_HEADERS(sys/modem.h)
+    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+    AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+    }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+    fi])
+    case $tcl_cv_api_serial in
+       termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+       termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+       sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_MISSING_POSIX_HEADERS
+#
+#      Supply substitutes for missing POSIX header files.  Special
+#      notes:
+#          - stdlib.h doesn't define strtol, strtoul, or
+#            strtod insome versions of SunOS
+#          - some versions of string.h don't declare procedures such
+#            as strstr
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              NO_DIRENT_H
+#              NO_ERRNO_H
+#              NO_VALUES_H
+#              HAVE_LIMITS_H or NO_LIMITS_H
+#              NO_STDLIB_H
+#              NO_STRING_H
+#              NO_SYS_WAIT_H
+#              NO_DLFCN_H
+#              HAVE_SYS_PARAM_H
+#
+#              HAVE_STRING_H ?
+#
+# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+# CHECK on limits.h
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
+    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
+    AC_TRY_LINK([#include <sys/types.h>
+#include <dirent.h>], [
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
+
+    if test $tcl_cv_dirent_h = no; then
+       AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
+    fi
+
+    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
+    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
+    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
+    AC_CHECK_HEADER(limits.h,
+       [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
+       [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
+    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
+    fi
+    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
+    fi
+
+    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
+    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+    AC_HAVE_HEADERS(sys/param.h)
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+#      Locate the X11 header files and the X11 library archive.  Try
+#      the ac_path_x macro first, but if it doesn't find the X stuff
+#      (e.g. because there's no xmkmf program) then check through
+#      a list of possible directories.  Under some conditions the
+#      autoconf macro will return an include directory that contains
+#      no include files, so double-check its result just to be safe.
+#
+#      This should be called after TEA_CONFIG_CFLAGS as setting the
+#      LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Sets the following vars:
+#              XINCLUDES
+#              XLIBSW
+#              PKG_LIBS (appends to)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+       TEA_PATH_UNIX_X
+    fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+    AC_PATH_X
+    not_really_there=""
+    if test "$no_x" = ""; then
+       if test "$x_includes" = ""; then
+           AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
+       else
+           if test ! -r $x_includes/X11/Intrinsic.h; then
+               not_really_there="yes"
+           fi
+       fi
+    fi
+    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+       AC_MSG_CHECKING([for X11 header files])
+       found_xincludes="no"
+       AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
+       if test "$found_xincludes" = "no"; then
+           dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+           for i in $dirs ; do
+               if test -r $i/X11/Intrinsic.h; then
+                   AC_MSG_RESULT([$i])
+                   XINCLUDES=" -I$i"
+                   found_xincludes="yes"
+                   break
+               fi
+           done
+       fi
+    else
+       if test "$x_includes" != ""; then
+           XINCLUDES="-I$x_includes"
+           found_xincludes="yes"
+       fi
+    fi
+    if test found_xincludes = "no"; then
+       AC_MSG_RESULT([couldn't find any!])
+    fi
+
+    if test "$no_x" = yes; then
+       AC_MSG_CHECKING([for X11 libraries])
+       XLIBSW=nope
+       dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+       for i in $dirs ; do
+           if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then
+               AC_MSG_RESULT([$i])
+               XLIBSW="-L$i -lX11"
+               x_libraries="$i"
+               break
+           fi
+       done
+    else
+       if test "$x_libraries" = ""; then
+           XLIBSW=-lX11
+       else
+           XLIBSW="-L$x_libraries -lX11"
+       fi
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_MSG_RESULT([could not find any!  Using -lX11.])
+       XLIBSW=-lX11
+    fi
+    if test x"${XLIBSW}" != x ; then
+       PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+#      The statements below check for systems where POSIX-style
+#      non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
+#      On these systems (mostly older ones), use the old BSD-style
+#      FIONBIO approach instead.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              HAVE_SYS_IOCTL_H
+#              HAVE_SYS_FILIO_H
+#              USE_FIONBIO
+#              O_NONBLOCK
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+    AC_CHECK_HEADERS(sys/ioctl.h)
+    AC_CHECK_HEADERS(sys/filio.h)
+    TEA_CONFIG_SYSTEM
+    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+    case $system in
+       # There used to be code here to use FIONBIO under AIX.  However, it
+       # was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
+       # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
+       # code (JO, 5/31/97).
+
+       OSF*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       SunOS-4*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       *)
+           AC_MSG_RESULT([O_NONBLOCK])
+           ;;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANLDER
+#
+#      Checks how the system deals with time.h, what time structures
+#      are used on the system, and what fields the structures have.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              USE_DELTA_FOR_TZ
+#              HAVE_TM_GMTOFF
+#              HAVE_TM_TZADJ
+#              HAVE_TIMEZONE_VAR
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+    AC_CHECK_HEADERS(sys/time.h)
+    AC_HEADER_TIME
+    AC_STRUCT_TIMEZONE
+
+    AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+           tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+    if test $tcl_cv_member_tm_tzadj = yes ; then
+       AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+    fi
+
+    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+           tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+    if test $tcl_cv_member_tm_gmtoff = yes ; then
+       AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+    fi
+
+    #
+    # Its important to include time.h in this check, as some systems
+    # (like convex) have timezone functions, etc.
+    #
+    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+       AC_TRY_COMPILE([#include <time.h>],
+           [extern long timezone;
+           timezone += 1;
+           exit (0);],
+           tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+    if test $tcl_cv_timezone_long = yes ; then
+       AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+    else
+       #
+       # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+       #
+       AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+           AC_TRY_COMPILE([#include <time.h>],
+               [extern time_t timezone;
+               timezone += 1;
+               exit (0);],
+               tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+       if test $tcl_cv_timezone_time = yes ; then
+           AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+#      Under Solaris 2.4, strtod returns the wrong value for the
+#      terminating character under some conditions.  Check for this
+#      and if the problem exists use a substitute procedure
+#      "fixstrtod" (provided by Tcl) that corrects the error.
+#      Also, on Compaq's Tru64 Unix 5.0,
+#      strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Might defines some of the following vars:
+#              strtod (=fixstrtod)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+    if test "$tcl_strtod" = 1; then
+       AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+           AC_TRY_RUN([
+               extern double strtod();
+               int main() {
+                   char *infString="Inf", *nanString="NaN", *spaceString=" ";
+                   char *term;
+                   double value;
+                   value = strtod(infString, &term);
+                   if ((term != infString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(nanString, &term);
+                   if ((term != nanString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(spaceString, &term);
+                   if (term == (spaceString+1)) {
+                       exit(1);
+                   }
+                   exit(0);
+               }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+                   tcl_cv_strtod_buggy=buggy)])
+       if test "$tcl_cv_strtod_buggy" = buggy; then
+           AC_LIBOBJ([fixstrtod])
+           USE_COMPAT=1
+           AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_LINK_LIBS
+#
+#      Search for the libraries needed to link the Tcl shell.
+#      Things like the math library (-lm) and socket stuff (-lsocket vs.
+#      -lnsl) are dealt with here.
+#
+# Arguments:
+#      Requires the following vars to be set in the Makefile:
+#              DL_LIBS
+#              LIBS
+#              MATH_LIBS
+#      
+# Results:
+#
+#      Subst's the following var:
+#              TCL_LIBS
+#              MATH_LIBS
+#
+#      Might append to the following vars:
+#              LIBS
+#
+#      Might define the following vars:
+#              HAVE_NET_ERRNO_H
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_LINK_LIBS], [
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+    AC_CHECK_HEADER(net/errno.h, [
+       AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+    if test "$tcl_checkSocket" = 1; then
+       AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
+           LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
+    fi
+    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
+           [LIBS="$LIBS -lnsl"])])
+    
+    # Don't perform the eval of the libraries here because DL_LIBS
+    # won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(MATH_LIBS)
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+#      Check for what flags are needed to be passed so the correct OS
+#      features are available.
+#
+# Arguments:
+#      None
+#      
+# Results:
+#
+#      Might define the following vars:
+#              _ISOC99_SOURCE
+#              _LARGEFILE64_SOURCE
+#              _LARGEFILE_SOURCE64
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+       AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+           AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+       AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+       tcl_flags="$tcl_flags $1"
+    fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+    AC_MSG_CHECKING([for required early compiler flags])
+    tcl_flags=""
+    TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+       [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+       [struct stat64 buf; int i = stat64("/", &buf);])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+       [char *p = (char *)open64;])
+    if test "x${tcl_flags}" = "x" ; then
+       AC_MSG_RESULT([none])
+    else
+       AC_MSG_RESULT([${tcl_flags}])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+#      Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+#      None
+#      
+# Results:
+#
+#      Might define the following vars:
+#              TCL_WIDE_INT_IS_LONG
+#              TCL_WIDE_INT_TYPE
+#              HAVE_STRUCT_DIRENT64
+#              HAVE_STRUCT_STAT64
+#              HAVE_TYPE_OFF64_T
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+    AC_MSG_CHECKING([for 64-bit integer type])
+    AC_CACHE_VAL(tcl_cv_type_64bit,[
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+           tcl_type_64bit=__int64, tcl_type_64bit="long long")
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        AC_TRY_COMPILE(,[switch (0) { 
+            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; 
+        }],tcl_cv_type_64bit=${tcl_type_64bit})])
+    if test "${tcl_cv_type_64bit}" = none ; then
+       AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+       AC_MSG_RESULT([using long])
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # We actually want to use the default tcl.h checks in this
+       # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       AC_MSG_RESULT([using Tcl header defaults])
+    else
+       AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+           [What type should be used to define wide integers?])
+       AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+       # Now check for auxiliary declarations
+       AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+           AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/dirent.h>],[struct dirent64 p;],
+               tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+       fi
+
+       AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+           AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+               tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+       fi
+
+       AC_CHECK_FUNCS(open64 lseek64)
+       AC_MSG_CHECKING([for off64_t])
+       AC_CACHE_VAL(tcl_cv_type_off64_t,[
+           AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+               tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+       dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+       dnl functions lseek64 and open64 are defined.
+       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+           AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+           AC_MSG_RESULT([yes])
+       else
+           AC_MSG_RESULT([no])
+       fi
+    fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+#      Init various Tcl Extension Architecture (TEA) variables.
+#      This should be the first called TEA_* macro.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              CYGPATH
+#              EXEEXT
+#      Defines only:
+#              TEA_VERSION
+#              TEA_INITED
+#              TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+#      Select the executable extension based on the host type.  This
+#      is a lightweight replacement for AC_EXEEXT that doesn't require
+#      a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.6"
+
+    AC_MSG_CHECKING([for correct TEA configuration])
+    if test x"${PACKAGE_NAME}" = x ; then
+       AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.in])
+    fi
+    if test x"$1" = x ; then
+       AC_MSG_ERROR([
+TEA version not specified.])
+    elif test "$1" != "${TEA_VERSION}" ; then
+       AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
+    else
+       AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+           AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+    AC_SUBST(EXEEXT)
+    AC_SUBST(CYGPATH)
+
+    # This package name must be replaced statically for AC_SUBST to work
+    AC_SUBST(PKG_LIB_FILE)
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+    AC_SUBST(PKG_STUB_LIB_FILE)
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+    AC_SUBST(PKG_TCL_SOURCES)
+    AC_SUBST(PKG_HEADERS)
+    AC_SUBST(PKG_INCLUDES)
+    AC_SUBST(PKG_LIBS)
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_SOURCES
+#              PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       case $i in
+           [\$]*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   AC_MSG_ERROR([could not find source file '$i'])
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+    AC_SUBST(PKG_SOURCES)
+    AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_STUB_SOURCES
+#              PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           AC_MSG_ERROR([could not find stub source file '$i'])
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+#      Specify one or more Tcl source files.  These should be platform
+#      independent runtime files.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+    AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+#      Specify one or more source headers.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+    AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+#      Specify one or more include dirs.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+    vars="$@"
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+    AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+#      Specify one or more libraries.  Users should check for
+#      the right platform before adding to their list.  For Windows,
+#      libraries provided in "foo.lib" format will be converted to
+#      "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+    vars="$@"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+    AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+#      Specify one or more CFLAGS.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+    PKG_CFLAGS="$PKG_CFLAGS $@"
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+#      Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      If --prefix or --exec-prefix was not specified, $prefix and
+#      $exec_prefix will be set to the values given to Tcl when it was
+#      configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+           prefix=${TCL_PREFIX}
+       else
+           AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+           exec_prefix=$prefix
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+#      Do compiler checks the way we want.  This is just a replacement
+#      for AC_PROG_CC in TEA configure.in files to make them cleaner.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    AC_PROG_CC
+    AC_PROG_CPP
+
+    AC_PROG_INSTALL
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    AC_PROG_MAKE_SET
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    AC_PROG_RANLIB
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+    AC_OBJEXT
+    AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+#      Do compiler checks that use the compiler.  This must go after
+#      TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+    AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       AC_CACHE_CHECK([if the compiler understands -pipe],
+           tcl_cv_cc_pipe, [
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+           CFLAGS=$hold_cflags])
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    AC_C_BIGENDIAN
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       TEA_TCL_LINK_LIBS
+       TEA_MISSING_POSIX_HEADERS
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+#      Generate a line that can be used to build a shared/unshared library
+#      in a platform independent manner.
+#
+# Arguments:
+#      none
+#
+#      Requires:
+#
+# Results:
+#
+#      Defines the following vars:
+#      CFLAGS -        Done late here to note disturb other AC macros
+#       MAKE_LIB -      Command to execute to build the Tcl library;
+#                       differs depending on whether or not Tcl is being
+#                       compiled as a shared library.
+#      MAKE_SHARED_LIB Makefile rule for building a shared library
+#      MAKE_STATIC_LIB Makefile rule for building a static library
+#      MAKE_STUB_LIB   Makefile rule for building a stub library
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+    AC_SUBST(MAKE_LIB)
+    AC_SUBST(MAKE_SHARED_LIB)
+    AC_SUBST(MAKE_STATIC_LIB)
+    AC_SUBST(MAKE_STUB_LIB)
+    AC_SUBST(RANLIB_STUB)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+#      Compute the name of an existing object library located in libdir
+#      from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+#      basename        The base name of the library without version
+#                      numbers, extensions, or "lib" prefixes.
+#      extra_dir       Extra directory in which to search for the
+#                      library.  This location is used first, then
+#                      $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+#      TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+#      Defines the following vars:
+#              ${basename}_LIB_NAME    The computed library name.
+#              ${basename}_LIB_SPEC    The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+    AC_MSG_CHECKING([for $1 library])
+
+    # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+    tea_lib_name_dir="${exec_prefix}/lib"
+
+    # Or in a user-specified location.
+
+    if test x"$2" != x ; then
+       tea_extra_lib_dir=$2
+    else
+       tea_extra_lib_dir=NONE
+    fi
+
+    for i in \
+           `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+       if test -f "$i" ; then
+           tea_lib_name_dir=`dirname $i`
+           $1_LIB_NAME=`basename $i`
+           $1_LIB_PATH_NAME=$i
+           break
+       fi
+    done
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+    else
+       # Strip off the leading "lib" and trailing ".a" or ".so"
+
+       tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+       $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+    fi
+
+    if test "x${$1_LIB_NAME}" = x ; then
+       AC_MSG_ERROR([not found])
+    else
+       AC_MSG_RESULT([${$1_LIB_SPEC}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+#      Locate the private Tcl include files
+#
+# Arguments:
+#
+#      Requires:
+#              TCL_SRC_DIR     Assumes that TEA_LOAD_TCLCONFIG has
+#                               already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TCL_TOP_DIR_NATIVE
+#              TCL_GENERIC_DIR_NATIVE
+#              TCL_UNIX_DIR_NATIVE
+#              TCL_WIN_DIR_NATIVE
+#              TCL_BMAP_DIR_NATIVE
+#              TCL_TOOL_DIR_NATIVE
+#              TCL_PLATFORM_DIR_NATIVE
+#              TCL_BIN_DIR_NATIVE
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl private include files])
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+    TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+    TCL_UNIX_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+    TCL_WIN_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+    TCL_BMAP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/bitmaps\"
+    TCL_TOOL_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/tools\"
+    TCL_COMPAT_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/compat\"
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       TCL_PLATFORM_DIR_NATIVE=${TCL_WIN_DIR_NATIVE}
+    else
+       TCL_PLATFORM_DIR_NATIVE=${TCL_UNIX_DIR_NATIVE}
+    fi
+    # We want to ensure these are substituted so as not to require
+    # any *_NATIVE vars be defined in the Makefile
+    TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+    if test "`uname -s`" = "Darwin"; then
+        # If Tcl was built as a framework, attempt to use
+        # the framework's Headers and PrivateHeaders directories
+        case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -d "${TCL_BIN_DIR}/Headers" -a -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+               TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"; else
+               TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"; fi
+               ;;
+       esac
+    else
+       if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+           AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+       fi
+    fi
+
+
+    AC_SUBST(TCL_TOP_DIR_NATIVE)
+    AC_SUBST(TCL_GENERIC_DIR_NATIVE)
+    AC_SUBST(TCL_UNIX_DIR_NATIVE)
+    AC_SUBST(TCL_WIN_DIR_NATIVE)
+    AC_SUBST(TCL_BMAP_DIR_NATIVE)
+    AC_SUBST(TCL_TOOL_DIR_NATIVE)
+    AC_SUBST(TCL_PLATFORM_DIR_NATIVE)
+
+    AC_SUBST(TCL_INCLUDES)
+    AC_MSG_RESULT([Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+#      Locate the installed public Tcl header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tclinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl public headers])
+
+    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tclh, [
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       AC_MSG_ERROR([tcl.h not found.  Please specify its location with --with-tclinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tclh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+#      Locate the private Tk include files
+#
+# Arguments:
+#
+#      Requires:
+#              TK_SRC_DIR      Assumes that TEA_LOAD_TKCONFIG has
+#                               already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk private include files])
+
+    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+    TK_UNIX_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+    TK_WIN_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+    TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+    TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+    if test "${TEA_PLATFORM}" = "windows"; then
+       TK_PLATFORM_DIR_NATIVE=${TK_WIN_DIR_NATIVE}
+    else
+       TK_PLATFORM_DIR_NATIVE=${TK_UNIX_DIR_NATIVE}
+    fi
+    # We want to ensure these are substituted so as not to require
+    # any *_NATIVE vars be defined in the Makefile
+    TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
+       -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       TK_INCLUDES="${TK_INCLUDES} -I${TK_XLIB_DIR_NATIVE}"
+    fi
+    if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       TK_INCLUDES="${TK_INCLUDES} -I${TK_SRC_DIR_NATIVE}/macosx"
+    fi
+    if test "`uname -s`" = "Darwin"; then
+        # If Tk was built as a framework, attempt to use
+        # the framework's Headers and PrivateHeaders directories
+        case ${TK_DEFS} in
+           *TK_FRAMEWORK*)
+               if test -d "${TK_BIN_DIR}/Headers" -a -d "${TK_BIN_DIR}/PrivateHeaders"; then
+               TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"; fi
+               ;;
+       esac
+    else
+       if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+           AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+       fi
+    fi
+
+    AC_SUBST(TK_TOP_DIR_NATIVE)
+    AC_SUBST(TK_UNIX_DIR_NATIVE)
+    AC_SUBST(TK_WIN_DIR_NATIVE)
+    AC_SUBST(TK_GENERIC_DIR_NATIVE)
+    AC_SUBST(TK_XLIB_DIR_NATIVE)
+    AC_SUBST(TK_PLATFORM_DIR_NATIVE)
+
+    AC_SUBST(TK_INCLUDES)
+    AC_MSG_RESULT([Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+#      Locate the installed public Tk header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tkinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk public headers])
+
+    AC_ARG_WITH(tkinclude, [  --with-tkinclude        directory containing the public Tk header files], with_tkinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tkh, [
+       # Use the value from --with-tkinclude, if it was given
+
+       if test x"${with_tkinclude}" != x ; then
+           if test -f "${with_tkinclude}/tk.h" ; then
+               ac_cv_c_tkh=${with_tkinclude}
+           else
+               AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tk was built as a framework, attempt to use
+               # the framework's Headers directory.
+               case ${TK_DEFS} in
+                   *TK_FRAMEWORK*)
+                       list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tk is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TK_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tk's --prefix location,
+           # relative to directory of tkConfig.sh, Tcl's --prefix location, 
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TK_PREFIX}/include      2>/dev/null` \
+               `ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+           fi
+           for i in $list ; do
+               if test -f "$i/tk.h" ; then
+                   ac_cv_c_tkh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tkh}" = x ; then
+       AC_MSG_ERROR([tk.h not found.  Please specify its location with --with-tkinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tkh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TK_INCLUDES)
+
+    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
+       -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       # On Windows and Aqua, we need the X compat headers
+       AC_MSG_CHECKING([for X11 header files])
+       if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+           INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+           TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+           AC_SUBST(TK_XINCLUDES)
+       fi
+       AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+#      Determine the fully qualified path name of the tclsh executable
+#      in the Tcl build directory or the tclsh installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the tclsh executable even if tclsh has not yet been
+#      built in the build directory. The tclsh found is always
+#      associated with a tclConfig.sh file. This tclsh should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+    AC_MSG_CHECKING([for tclsh])
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+    fi
+    AC_MSG_RESULT([${TCLSH_PROG}])
+    AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+#      Determine the fully qualified path name of the wish executable
+#      in the Tk build directory or the wish installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the wish executable even if wish has not yet been
+#      built in the build directory. The wish found is always
+#      associated with a tkConfig.sh file. This wish should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+    AC_MSG_CHECKING([for wish])
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        # tkConfig.sh is in Tk build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="${TK_BIN_DIR}/wish"
+        fi
+    else
+        # tkConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+        fi
+        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${WISH_PROG}" ; then
+                REAL_TK_BIN_DIR="`cd "$i"; pwd`"
+                break
+            fi
+        done
+        WISH_PROG="${REAL_TK_BIN_DIR}/${WISH_PROG}"
+    fi
+    AC_MSG_RESULT([${WISH_PROG}])
+    AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+#      Locate the ${1}Config.sh file and perform a sanity check on
+#      the ${1} compile flags.  These are used by packages like
+#      [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-$1=...
+#
+#      Defines the following vars:
+#              $1_BIN_DIR      Full path to the directory containing
+#                              the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+    #
+    # Ok, lets find the $1 configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-$1
+    #
+
+    if test x"${no_$1}" = x ; then
+       # we reset no_$1 in case something fails here
+       no_$1=true
+       AC_ARG_WITH($1, [  --with-$1              directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+       AC_MSG_CHECKING([for $1 configuration])
+       AC_CACHE_VAL(ac_cv_c_$1config,[
+
+           # First check to see if --with-$1 was specified.
+           if test x"${with_$1config}" != x ; then
+               case ${with_$1config} in
+                   */$1Config.sh )
+                       if test -f ${with_$1config}; then
+                           AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+                           with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+                       fi;;
+               esac
+               if test -f "${with_$1config}/$1Config.sh" ; then
+                   ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+               fi
+           fi
+
+           # then check for a private $1 installation
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in \
+                       ../$1 \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../$1 \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../$1 \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../$1 \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+                   if test -f "$i/unix/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_$1config}" = x ; then
+           $1_BIN_DIR="# no $1 configs found"
+           AC_MSG_WARN([Cannot find $1 configuration definitions])
+           exit 0
+       else
+           no_$1=
+           $1_BIN_DIR=${ac_cv_c_$1config}
+           AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+#      Load the $1Config.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              $1_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              $1_SRC_DIR
+#              $1_LIB_FILE
+#              $1_LIB_SPEC
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${$1_BIN_DIR}/$1Config.sh"
+    else
+        AC_MSG_RESULT([file not found])
+    fi
+
+    #
+    # If the $1_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable $1_LIB_SPEC will be set to the value
+    # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+    # instead of $1_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    #
+
+    if test -f "${$1_BIN_DIR}/Makefile" ; then
+       AC_MSG_WARN([Found Makefile - using build library specs for $1])
+        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+    fi
+
+    AC_SUBST($1_VERSION)
+    AC_SUBST($1_BIN_DIR)
+    AC_SUBST($1_SRC_DIR)
+
+    AC_SUBST($1_LIB_FILE)
+    AC_SUBST($1_LIB_SPEC)
+
+    AC_SUBST($1_STUB_LIB_FILE)
+    AC_SUBST($1_STUB_LIB_SPEC)
+    AC_SUBST($1_STUB_LIB_PATH)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+#      Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-celib=...
+#
+#      Defines the following vars:
+#              CELIB_DIR       Full path to the directory containing
+#                              the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+       AC_ARG_WITH(celib,[  --with-celib=DIR        use Windows/CE support library from DIR], with_celibconfig=${withval})
+       AC_MSG_CHECKING([for Windows/CE celib directory])
+       AC_CACHE_VAL(ac_cv_c_celibconfig,[
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           AC_MSG_ERROR([Cannot find celib support library directory])
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           AC_MSG_RESULT([found $CELIB_DIR])
+       fi
+    fi
+])
+
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/8.x/mk/tcl/tequila/README b/8.x/mk/tcl/tequila/README
new file mode 100644 (file)
index 0000000..2ee876e
--- /dev/null
@@ -0,0 +1,109 @@
+Tequila  -  Sharing and storing global Tcl arrays over the network
+
+            This is now part of the Metakit open source distribution.
+            See the Metakit homepage at http://www.equi4.com/metakit/
+
+
+
+This is the second release of a simple server which lets a number of
+clients share and store data held in global Tcl arrays.  The whole
+mechanism is based on a central server managing all TCP/IP sessions.
+
+All a client needs to do to make an array "myData" available to other
+clients and persistent, is to include the following three lines:
+
+    source tequila.tcl              # load the Tequila client code
+    tequila::open localhost 20458   # connect to server on given port
+    tequila::attach myData          # sets up sharing for "myData"
+    
+The array's contents will be permanently stored by the server, with
+all entries transmitted to the client when attached.  From then on,
+Tcl's traces and background network communication take care of all
+changes.  Whenever a client changes or unsets a value, this effect
+will be propagated to all other clients currently running.
+
+Because all clients continue to use global arrays as if they were
+running standalone, Tequila can be used to build a single application
+first and *then* split it up into several parts.  With care, one can
+also create long-running applications of which parts get extended and
+replaced over time without having to shut down the entire system.
+
+The Tequila server was developed as part of a long-running / multi-
+platform / multi-user project.  It has been in use since April 1999. 
+
+
+What you need to use Tequila
+============================
+
+Tequila consists of a server script and a client package, both written
+in Tcl.  The server stores all data using Metakit, a powerful database
+library which is available for Tcl (through the "Mk4tcl" extension).
+
+There are two ways to run the server:
+
+    - Grab a version of "TclKit", which combines Tcl, Tk, and Metakit
+      in a single installation-less runtime.  There are ready-to-run
+      builds of TclKit for Windows, Solaris, Linux, and more.
+
+    - Get the Mk4tcl extension and use it with your own configuration
+      of Tcl/Tk.  This may be needed if there is no suitable version of
+      TclKit, or if you wish to use this with your own build of Tcl/Tk.
+      
+The client side of Tequila does not require Metakit, and should work
+with every installation of Tcl/Tk (version 8.0 or newer).
+
+
+The TequiCal demo
+=================
+
+TequiCal is a small Tk utility which lets you maintain a calendar of
+yearly events, such as birthdays.  It uses Tequila to store all data,
+and can be used from any workstation which has access to the server.  
+Changes will be seen by other clients as soon as they are entered.
+This very simple demo only uses the Tequila server to share one global
+"calendar" array, even though a single server can serve many different
+clients with a wide variety of shared datasets (changes are only sent
+to those clients which have "attached" themselves to specific arrays).
+
+Running the TequiCal demo is extremely simple with TclKit:
+
+  1)  Get the TclKit executable which matches your platform, then
+      uncompress it (not needed for Windows), and put it somewhere
+      on your execution search path.
+  2)  Get the Tequila distribution and unpack all files if you have
+      not already done so.
+  3)  Start the Tequila server using the command:
+            tclkit tequilas.tcl &
+      (use "tclkit tequilas.tcl" on Windows, then start a new prompt)
+      You should see the text:
+            Tequila server started on port 20458
+  4)  Start the TequiCal demo client using the commnd:
+            tclkit tequical.tcl
+  5)  Go to another terminal, xterm, or MS-DOS shell and start again:
+            tclkit tequical.tcl
+  6)  Now make some changes in the calendar and watch how changes get
+      propagated between the clients, even if on different machines.
+  7)  That's it.  You are looking at a distributed Tcl application.     
+
+You can also use Tequila with an existing installation of Tcl (ver 8),
+by downloading / installing Mk4tcl, which is a compiled Tcl extension.
+Or compile and build all the necessary pieces yourself, of course.
+
+
+The Proxy demo
+==============
+
+The latest version of Tequila supports proxy support for Mk4tcl, which
+means that the client can be set up to pass all its Metakit requests
+down to the server.  By calling "tequila::proxy", clients will be set
+up so all "mk::*" calls are passed on to the server, and results are
+passed back - a basic client/server system (without locking facilities
+between clients, though).  The "proxy.tcl" demo code shows how this is
+used.  To run it, start the tequila server first, then run proxy.tcl.
+
+Note: the "mk::loop" command is not implemented in this release, since
+it needs to be processed in the client.  Use mk::select instead.
+
+
+-- Jean-Claude Wippler <jcw@equi4.com>
diff --git a/8.x/mk/tcl/tequila/proxy.tcl b/8.x/mk/tcl/tequila/proxy.tcl
new file mode 100755 (executable)
index 0000000..c4a5904
--- /dev/null
@@ -0,0 +1,19 @@
+# test the proxy interface to tequila
+# assume tequilas is running on localhost
+
+source tequila.tcl
+
+tequila::open localhost 20458
+
+tequila::proxy ;# this defines all mk::* procs as proxy calls
+                               # datafile 'tqs' is open and ready for use
+
+mk::view layout tqs.people {name country}
+
+mk::row append tqs.people name jc country nl
+mk::row append tqs.people name nb country gr
+
+foreach i [mk::select tqs.people -sort name] {
+       puts [mk::get tqs.people!$i]
+}
+
diff --git a/8.x/mk/tcl/tequila/tequical.tcl b/8.x/mk/tcl/tequila/tequical.tcl
new file mode 100644 (file)
index 0000000..872c64c
--- /dev/null
@@ -0,0 +1,135 @@
+#!/bin/sh
+# Copyright (c) 1999-2000 Jean-Claude Wippler <jcw@equi4.com>
+#
+# TequiCal  -  shared yearly event calendar, a demo based on Tequila
+# \
+exec tclkit "$0" ${1+"$@"}  
+
+proc bgerror message {
+    puts "bgerror: message, errorInfo, and errorCode are\
+            '$message', '$::errorInfo', and '$::errorCode'."
+}
+
+    # present a dialog box asking for a host to connect to
+proc AskSite {{host localhost}} {
+    global as_host as_status
+    set as_host $host
+    toplevel .as
+    wm title .as "Site setup"
+    pack [label .as.l -text "Where is the Tequila server?"] \
+         [entry .as.e -width 30 -textvariable as_host] \
+         [button .as.b -text "OK" -command {set as_status 1}] -padx 4 -pady 4
+    bind .as <Return> {.as.b invoke}
+    bind .as <Escape> {exit}
+    wm protocol .as WM_DELETE_WINDOW {exit}
+    update
+    raise .as
+    .as.e selection adjust end
+    focus .as.e
+    vwait as_status
+    destroy .as
+    return $as_host 
+}
+
+    # set up the main window and the trace on the global shared array
+proc MainWindow {} {
+    global calendar detail
+
+    wm title . "Tequila Calendar Demo"
+    
+    frame .f1
+    scrollbar .f1.sb -command [list .f1.lb yview]
+    listbox .f1.lb -width 50 -height 10 -exportselection 0 \
+        -yscrollcommand [list .f1.sb set]
+    pack .f1.sb -fill y -side right
+    pack .f1.lb -fill both -expand 1
+    
+    frame .f2
+    pack [label .f2.l1 -text "Event:" -anchor e -width 7] -side left
+    pack [entry .f2.e -textvariable detail(e)] -side left -fill x -expand 1
+    
+    frame .f3
+    pack [label .f3.l1 -text "Month:" -anchor e -width 7] \
+         [entry .f3.e1 -textvariable detail(m) -width 3] \
+         [label .f3.l2 -text "  Day:"] \
+         [entry .f3.e2 -textvariable detail(d) -width 3] \
+         [label .f3.l3 -text "    (clear event to delete)" -anchor w] -side left
+    
+    pack .f1 -fill both -expand 1 -padx 4 -pady 4
+    pack .f2 -fill x -padx 4 
+    pack .f3 -anchor w -padx 4 -pady 4
+
+    bind .f1.lb <ButtonPress> {ChooseEntry [.f1.lb nearest %y]}
+    .f1.lb insert end "Loading..."
+
+    ChooseEntry end
+    trace variable detail wu {after cancel FixEntry; after 100 FixEntry; #}
+    trace variable calendar wu {after cancel FixList; after 100 FixList; #}
+}
+
+    # this gets called shortly after each change to the calendar array
+proc FixList {} {
+    global calendar
+    .f1.lb delete 0 end
+    foreach k [lsort [array names calendar]] {
+        .f1.lb insert end $k
+    }
+    .f1.lb insert end "(new entry)"
+}
+
+    # this gets called shortly after each editing change
+proc FixEntry {} {
+    global calendar detail
+    
+    regexp {..$} "00$detail(m)" m
+    regexp {..$} "00$detail(d)" d
+    set new "$m/$d $detail(e)"
+
+    if {$new == $detail(full)} return
+    
+    catch {unset calendar($detail(full))}
+    if {$detail(e) != ""} {
+        set calendar($new) ""
+    }
+    set detail(full) $new
+}
+
+    # called when a list entry has been clicked
+proc ChooseEntry {n} {
+    global detail
+    
+    set detail(full) [.f1.lb get $n]
+    if {![regexp {^(..)/(..) (.*)} $detail(full) x \
+                                    detail(m) detail(d) detail(e)]} {
+        set now [clock seconds]
+        set detail(m) [clock format $now -format %m]
+        set detail(d) [clock format $now -format %d]
+        set detail(e) ""
+    }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Actual work starts here: connect, set up window/traces, and attach.
+
+source tequila.tcl
+
+    # set up a connection to the central Tequila server
+eval tequila::open [AskSite] 20458
+
+    # layout the main window and show it
+MainWindow
+update
+
+    # setup for a global "calendar" array to be shared
+tequila::attach calendar
+
+    # set some initial data when there is nothing yet
+if {[array size calendar] == 0} {
+    foreach x {
+        "01/01 Happy New Year!"
+        "12/25 Christmas Day"
+        "04/07 Someone's birthday (1989)"
+    } {
+        set calendar($x) ""
+    }
+}
diff --git a/8.x/mk/tcl/tequila/tequila.tcl b/8.x/mk/tcl/tequila/tequila.tcl
new file mode 100644 (file)
index 0000000..d1b8066
--- /dev/null
@@ -0,0 +1,144 @@
+# Copyright (C) 1999-2000 Jean-Claude Wippler <jcw@equi4.com>
+#
+# Tequila  -  client interface to the Tequila server
+
+package provide tequila 1.5
+
+namespace eval tequila {
+    namespace export open close do attach
+
+    variable _socket
+    variable _reply
+    
+        # setup communication with the tequila server
+    proc open {addr port} {
+        variable _socket
+        set _socket [socket $addr $port] 
+        fconfigure $_socket -translation binary -buffering none
+        fileevent $_socket readable tequila::privRequest
+    }
+
+        # setup callback for when link to server fails
+    proc failure {cmd} {
+        variable _socket
+        trace variable _socket u $cmd
+    }
+
+        # terminate communication (this is usually not needed)
+    proc close {} {
+        variable _socket
+        ::close $_socket 
+    }
+
+        # set up to pass almost all MK requests through to the server
+        # note that mk::loop is not implemented, is only works locally
+        # added 20-02-2000
+    proc proxy {} {
+        namespace eval ::mk {
+            foreach i {file view row cursor get set select channel} {
+                proc $i {args} "eval ::tequila::do Remote $i \$args"
+            }
+        }
+    }
+    
+        # send a request to the server and wait for a response
+    proc do {args} {
+        variable _socket
+        variable _reply ""
+        
+        catch {
+            puts -nonewline $_socket "[string length $args]\n$args"
+            while {[string length $_reply] == 0} {
+                vwait tequila::_reply
+            }
+        }
+        
+        set error 0
+        set results ""
+        foreach {error results} $_reply break
+        
+        if {[string compare $error 0] == 0} {
+            return $results
+        }
+        
+        if {[string length $results] > 0} {
+            error $results 
+        }
+        
+        error "Failed network request to the server."
+    }
+
+        # prepare for automatic change propagation
+    proc attach {array args} {
+        array set opts {-fetch 1 -tracking 1 -type S}
+        array set opts $args
+        
+        global $array
+        do Define $array 0 $opts(-type)
+        
+        if {$opts(-fetch)} {
+            set command GetAll
+        } else {
+            set command Listing
+        }
+        
+        array set $array [do $command $array $opts(-tracking)]
+        
+        trace variable $array wu tequila::privTracer
+    }
+
+        # called whenever a request comes in (private)
+    proc privRequest {} {
+        variable _socket
+        variable _reply
+        
+        if {[gets $_socket bytes] > 0} {
+            set request [read $_socket $bytes]
+            if ![eof $_socket] {
+                uplevel #0 tequila::privCallBack_$request
+                return
+            } 
+        }
+            # trouble, make sure we stop a pending request
+        set _reply [list 1 "Lost connection with the tequila server."]
+        ::close $_socket 
+        unset _socket
+    }
+
+        # handles traces to propagate changes to the server (private)
+    proc privTracer {a e op} {
+        if {$e != ""} {
+            switch $op {
+                w   { do Set $a $e [set ::${a}($e)] }
+                u   { do Unset $a $e }
+            }
+        }
+    }
+
+        # called by the server to return a result
+    proc privCallBack_Reply {args} {
+        variable _reply
+        set _reply $args
+    }
+
+        # called by the server to propagate an element write
+    proc privCallBack_Set {a e v} {
+        global $a
+        if {![info exists ${a}($e)] || [set ${a}($e)] != $v} {
+            trace vdelete $a wu tequila::privTracer
+            set ${a}($e) $v    
+            trace variable $a wu tequila::privTracer
+        }
+    }
+
+        # called by the server to propagate an element delete
+    proc privCallBack_Unset {a e} {
+        global $a
+        if {[info exists ${a}($e)]} {
+            trace vdelete $a wu tequila::privTracer
+            unset ${a}($e)
+            trace variable $a wu tequila::privTracer
+        }
+    }
+}
+
diff --git a/8.x/mk/tcl/tequila/tequilas.tcl b/8.x/mk/tcl/tequila/tequilas.tcl
new file mode 100644 (file)
index 0000000..fa1507e
--- /dev/null
@@ -0,0 +1,440 @@
+#!/bin/sh
+# Copyright (c) 1999-2000 Jean-Claude Wippler <jcw@equi4.com>
+#
+# Tequilas  -  the "Tequila Server" implements shared persistent arrays
+#\
+exec tclkit "$0" ${1+"$@"}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Imlementation notes:
+#
+# Commands starting with "Tqs" can be called from the remote client
+# The rest uses lowercase "tqs" to prevent this (and for uniqueness)
+#
+# There is one global array which is used for all information which
+# this server needs to carry around and track, called "tqs_info":
+#
+#   tqs_info(pending)   - id of pending "after" request, unset if none
+#   tqs_info(timeout)   - milliSecs before timed commit, unset if never
+#   tqs_info(verbose)   - log level: 0=off, 1=req's, 2=notify, 3=reply
+#
+# External views (type "X") are stored as files in directory, one item
+# per text file.  This can be used to store large amounts of text in
+# regular files, outside Metakit (though commit doesn't apply to them):
+#
+#   tqs_external(view)  - directory name, set for each external view
+#
+# Valid while processing an incoming request:
+#   tqs_info(port)      - socket name of current client request
+#
+# The following will be defined for individual views:
+#   tqs_notify($view)   - socket name of client to notify on changes
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+    # conditonal logging output
+proc tqsPuts {level msg} {
+    global tqs_info
+    if {$level <= $tqs_info(verbose)} {
+        puts $msg
+    }
+}
+
+    # return a displayable string of limited length
+proc tqsDisplay {str len} {
+    if {[string length $str] > $len} {
+        set str "[string range $str 0 $len]..."
+    }
+    regsub -all {[^ -~]} $str {?} str
+    return $str
+}
+
+    # remote execution of any Metakit command, added 20-02-2000
+proc TqsRemote {cmd args} {
+       eval mk::$cmd $args
+}
+
+    # return the names of all views currently on file
+proc TqsInfo {} {
+    mk::file views tqs
+}
+
+    # get or set log level (see above for meaning of values 0..3)
+proc TqsVerbose {{level ""}} {
+    global tqs_info
+    if {$level != ""} {
+        set tqs_info(verbose) $level
+    }
+    return $tqs_info(verbose)
+}
+
+    # define a view (Metakit's equivalent concept for a Tcl array)
+    # if the second argument is true, all existing data is removed
+    # the third arg is used to specify a binary (B) of memo format (M)
+    # if the third arg is "X", use a directory with files for storage
+proc TqsDefine {view {clear 0} {type S}} {
+    if {$type == "X"} {
+        global tqs_external
+        set tqs_external($view) ""
+        if {$clear} {
+            catch {file delete -force $view.data}
+            tqsTrace $view "" u
+        }
+        file mkdir $view.data
+        #catch {mk::view delete tqs.$view}
+    } else {
+        mk::view layout tqs.$view "name text:$type date:I"
+        if {$clear && [mk::view size tqs.$view] > 0} {
+            mk::view size tqs.$view 0
+            tqsTrace $view "" u
+        }
+        #file delete -force $view.data
+    }
+    return
+}
+
+    # get rid of a view
+proc TqsUndefine {view} {
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        file delete -force $view.data
+        unset tqs_external($view)
+    } else {
+        mk::view delete tqs.$view
+    }
+    tqsTrace $view "" u
+    return
+}
+
+    # return the list of all keys, like "array names view"
+proc TqsNames {view} {
+    set result {}
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        foreach x [glob -nocomplain $view.data/*] {
+            regsub {.*/} $x {} x
+            lappend result $x
+        }
+    } else {
+        mk::loop c tqs.$view {
+            lappend result [mk::get $c name]
+        }
+    }
+    return $result
+}
+
+    # return the number of keys, like "array size view"
+proc TqsSize {view} {
+    set result {}
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        set result [llength [glob -nocomplain $view.data/*]]
+    } else {
+        set result [mk::view size tqs.$view]
+    }
+    return $result
+}
+
+    # return an existing value, lookup by key, like "set view(key)"
+proc TqsGet {view key} {
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        set fd [open $view.data/$key]
+        fconfigure $fd -translation binary
+        set v [read $fd]
+        close $fd
+        return $v
+    } else {
+        set n [mk::select tqs.$view name $key]
+        mk::get tqs.$view!$n text ;# throws error if absent
+    }
+}
+
+    # store a value, create if necessary, like "set view(key) data"
+    # the optional last arg can be used to force a specific timestamp
+proc TqsSet {view key data {timestamp ""}} {
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        set fd [open $view.data/$key w]
+        fconfigure $fd -translation binary
+        puts -nonewline $fd $data
+        close $fd
+        # timestamp is ignored
+    } else {
+        set n [mk::select tqs.$view name $key]
+        if {[llength $n] == 0} {
+            set n [mk::view size tqs.$view]
+        } elseif {[mk::get tqs.$view!$n text] == $data} {
+            return ;# no change, ignore
+        }
+        if {$timestamp == ""} {
+            set timestamp [clock seconds]
+        }
+        mk::set tqs.$view!$n name $key text $data date $timestamp
+    }
+    tqsTrace $view $key w
+    return
+}
+
+    # Append a value, create if entry did not exist
+proc TqsAppend {view key data} {
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        set fd [open $view.data/$key a]
+        fconfigure $fd -translation binary
+        puts -nonewline $fd $data
+        close $fd
+    } else {
+        set n [mk::select tqs.$view name $key]
+        if {[llength $n] > 0} {
+            if {[string length $data] == 0} then return ;# no change
+            set data "[mk::get tqs.$view!$n text]$data"
+        }
+        mk::set tqs.$view!$n name $key text $data date [clock seconds]
+    }
+    tqsTrace $view $key w
+    return
+}
+
+    # delete an existing entry by key, similar to "unset view(key)"
+proc TqsUnset {view key} {
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        file delete $view.data/$key
+    } else {
+        set n [mk::select tqs.$view name $key]
+        if {[llength $n] == 0} {
+            return ;# no change, ignore
+        }
+        mk::row delete tqs.$view!$n
+    }
+    tqsTrace $view $key u
+    return
+}
+
+    # return all key/value pairs, like "array get view"
+    # if set, the optional arg sets up change notification
+proc TqsGetAll {view {tracking 0}} {
+    set result {}
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        foreach x [TqsNames $view] {
+            lappend result $x [TqsGet $view $x]
+        }
+    } else {
+        mk::loop c tqs.$view {
+            eval lappend result [mk::get $c name text]
+        }
+    }
+    if {$tracking} { tqsSubscribe $view }
+    return $result
+}
+
+    # like TqsGetAll, returns modification dates instead of contents
+    # this can be used by the client to synchronize and track dates
+    # if set, the optional arg sets up change notification
+proc TqsListing {view {tracking 0}} {
+    set result {}
+    global tqs_external
+    if {[info exists tqs_external($view)]} {
+        foreach x [TqsNames $view] {
+            lappend result $x [file mtime $view.data/$x]
+        }
+    } else {
+        mk::loop c tqs.$view {
+            eval lappend result [mk::get $c name date]
+        }
+    }
+    if {$tracking} { tqsSubscribe $view }
+    return $result
+}
+    
+    # called to set up notification for a client
+proc tqsSubscribe {view} {
+    global tqs_info tqs_notify
+    
+        # remember the client IP and listening number for this view
+    tqsPuts 1 "Notification set up for '$view': $tqs_info(port)"
+    lappend tqs_notify($view) $tqs_info(port)
+}
+
+    # called to unset all notifications for a client
+proc tqsUnsubscribe {port} {
+    global tqs_notify
+    
+    foreach {k v} [array get tqs_notify] {
+        set n [lsearch -exact $v $port]
+        if {$n >= 0} {
+            tqsPuts 1 "  Forget notify for $k"
+
+            if {[llength $v] > 1} {
+                set tqs_notify($k) [lreplace $v $n $n]
+            } else {
+                unset tqs_notify($k)
+                tqsPuts 1 "   No more notifications for $k"
+            }
+        }
+    }
+}
+
+    # set a number of key/value pairs, like "array set view pairs"
+proc TqsSetAll {view pairs} {
+    foreach {key value} $pairs {
+        TqsSet $view $key $value
+    }
+}
+
+    # save changes to file now
+proc TqsCommit {} {
+    global tqs_info
+    
+    set n [clock clicks]
+    mk::file commit tqs
+    tqsPuts 1 "Commit done ([expr {[clock clicks] - $n}])"
+    
+    after cancel TqsCommit
+    catch {unset tqs_info(pending)}
+    return
+}
+
+    # change commit timer, default is to commit with explicit calls
+proc TqsTimer {{timer ""}} {
+    global tqs_info
+    
+    after cancel TqsCommit
+    
+    if {$timer == ""} {
+        catch {unset tqs_info(timeout)}
+    } else {
+        if {[info exists tqs_info(pending)]} {
+            set tqs_info(pending) [after $timer TqsCommit]
+        }
+        set tqs_info(timeout) $timer
+    }
+}
+
+    # handles tracing of all view changes (there's no read tracing)
+    # this is also the place where delayed commits are scheduled
+proc tqsTrace {view key operation} {
+    global tqs_info tqs_notify
+    
+    if [info exists tqs_notify($view)] {
+        switch $operation {
+            w   { set req [list Set $view $key [TqsGet $view $key]] }
+            u   { set req [list Unset $view $key] }
+        }
+        
+            # this is the data that gets sent out
+        set msg "[string length $req]\n$req"
+        
+        foreach p $tqs_notify($view) {
+            if {$p == $tqs_info(port)} continue ;# skip originator
+            
+            if [catch {
+                tqsPuts 2 [tqsDisplay "Notify $p - $req" 65]
+                puts -nonewline $p $msg
+                #flush $p
+            } error] {
+                tqsPuts 1 "Notify to $p failed for $view $key"
+                tqsPuts 1 "  Reason: $error"
+                catch {close $p}
+                tqsUnsubscribe $p
+            }
+        }
+    }
+    
+    if {![info exists tqs_info(pending)] && 
+            [info exists tqs_info(timeout)]} {
+        set tqs_info(pending) [after $tqs_info(timeout) TqsCommit]
+    }
+}
+
+    # called whenever a request comes in
+proc tqsRequest {sock} {
+    global tqs_info
+    
+    if {[gets $sock bytes] > 0} {
+        set request [read $sock [lindex $bytes 0]]
+        if ![eof $sock] {
+                # debugging: incoming request
+            tqsPuts 1 [tqsDisplay " $request" 65]
+            
+            set tqs_info(port) $sock
+            
+            set err [catch {uplevel #0 Tqs$request} reply]
+            set msg [list Reply $err $reply]
+            puts -nonewline $sock "[string length $msg]\n$msg"
+            
+                # debugging: returned results
+            if {[string length $reply] > 0} {
+                tqsPuts 3 "   result: [tqsDisplay $reply 54]"
+            }
+            
+            #flush $sock
+            return
+        } 
+    }
+    
+    tqsPuts 1 "Closing $sock"
+    close $sock 
+    tqsUnsubscribe $sock
+}
+
+    # called whenever a connection is opened
+proc tqsAccept {sock addr port} {
+    global tqs_info
+    fconfigure $sock -translation binary -buffering none
+    fileevent $sock readable [list tqsRequest $sock]
+}
+
+    # this can be called to start a background server
+proc tqsStart {port} {
+    global tqs_notify tqs_external
+
+    array set tqs_notify {}
+    
+    foreach x [glob -nocomplain *.data] {
+        regsub {\.data$} $x {} x
+        set tqs_external($x) ""
+    }
+    
+    socket -server tqsAccept $port
+}
+
+    # this wraps the server into a standalone, it runs until shutdown
+proc tqsRun {port} {
+    global tqs_info
+    
+    set tqs_info(shutdown) [clock seconds]
+    
+        # these status messages are not disabled if verbose is off
+    puts "Tequila server on port $port started."
+    tqsStart $port
+    vwait tqs_info(shutdown)
+    puts "Tequila server on port $port has been shut down."
+}
+
+    # client-callable: terminate a server started with "tqsRun"
+proc TqsShutdown {} {
+    global tqs_info
+
+        # returns number of seconds since the server was started
+        # main effect is setting tqs_info(shutdown), which ends vwait
+    set tqs_info(shutdown) [expr {[clock seconds]-$tqs_info(shutdown)}]
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# This script can be used standalone, in which case the code below will
+# be run, or as part of a scripted document, which expects a "package
+# ifneeded tequilas ..." to have been set up.  In that case, the code
+# below will not be executed, allowing the caller so set up different
+# parameter values before calling tqsRun or tqsStart (background use).
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+if {[lsearch -exact [package names] tequilas] < 0} {
+    package require Mk4tcl
+    mk::file open tqs tequilas.dat -nocommit
+
+    set tqs_info(verbose) 0     ;# default logging is off
+    TqsTimer 30000              ;# default commit timer is 30 seconds
+    tqsRun 20458                ;# default port is 20458
+}
diff --git a/8.x/mk/tcl/tests/all.tcl b/8.x/mk/tcl/tests/all.tcl
new file mode 100755 (executable)
index 0000000..fd8c4ac
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/env tclsh
+
+source [file join [file dir [info script]] initests.tcl]
+
+runAllTests
+
diff --git a/8.x/mk/tcl/tests/basic.test b/8.x/mk/tcl/tests/basic.test
new file mode 100755 (executable)
index 0000000..323f964
--- /dev/null
@@ -0,0 +1,174 @@
+#!/usr/bin/env tclsh
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+  catch { package require ? }
+  lindex [package versions Mk4tcl] end
+} $version
+
+test 1 {} {
+  package require Mk4tcl
+} $version
+
+test 2 {no databases} {
+  set v [mk::file open]
+    # ignore one entry if run from a VFS-based TclKit
+  if {[lindex $v 0] == "exe"} {
+    set v [lrange $v 2 end]
+  }
+} {}
+
+test 3 {temp database} -body {
+  # 2003-10-01: this was wrong when run from tclkit, which has "exe" open
+  #C [mk::file open] {db {}}
+  match "*db {}*" [mk::file open]]
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+test 4 {temp data} -body {
+  mk::view layout db.a {s i:I}
+  set n [mk::row append db.a s one i 1]
+  equal $n db.a!0
+  equal [mk::get $n] {s one i 1}
+  set n [mk::row append db.a s two i 2]
+  equal $n db.a!1
+  equal [mk::get $n] {s two i 2}
+  equal [mk::view size db.a] 2
+  mk::view size db.a 1
+  equal [mk::get db.a!0] {s one i 1}
+  catch {mk::get db.a!1} e
+  equal $e {view index is out of range}
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+test 5 {use same tag twice} -body {
+  catch {mk::file open db} e
+  equal $e {file already open}
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+set f f6.tmp
+test 6 {open file} -body {
+  file delete $f
+  set f $f
+  mk::file open db $f
+  # 2003-10-01: this was wrong when run from tclkit, which has "exe" open
+  #C [mk::file open] [list db $f]
+  match "*[list db $f]*" [mk::file open]
+  assert [file exists $f]
+  mk::file commit db
+    # the file size remains zero, because commit detects no change
+  equal [file size $f] 0
+  mk::view layout db.a s
+  mk::file commit db
+  equal [file size $f] 37
+} -cleanup {mk::file close db}
+file delete $f
+
+set f f7.tmp
+test 7 {open same file again} -body {
+  file delete $f
+  equal [mk::file open db2 $f] db2
+  mk::file close db2
+  return
+} -setup {mk::file open db1 $f} -cleanup {mk::file close db1}
+file delete $f
+
+test 8 {simple select} -body {
+  mk::view layout db.a s
+  foreach x {one One two Two three Three four Four} {
+    mk::row append db.a s $x
+  }
+  equal [mk::select db.a] {0 1 2 3 4 5 6 7}
+  equal [mk::select db.a s three] {4 5}
+  equal [mk::select db.a -exact s three] 4
+  equal [mk::select db.a -min s three] {2 3 4 5}
+  equal [mk::select db.a -max s three] {0 1 4 5 6 7}
+  equal [mk::select db.a -glob s t*] {2 4}
+  equal [mk::select db.a -glob s {[tT]*}] {2 3 4 5}
+  equal [mk::select db.a -regexp s o] {0 2 3 6 7}
+  equal [mk::select db.a -regexp s {[tT]+}] {2 3 4 5}
+  equal [mk::select db.a -keyword s t] {2 3 4 5}
+  equal [mk::select db.a -keyword s tw] {2 3}
+  equal [mk::select db.a -keyword s o] {0 1}
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+test 9 {simple sort} -body {
+  mk::view layout db.a s
+  foreach x {one One two Two three Three four Four} {
+    mk::row append db.a s $x
+  }
+  equal [mk::select db.a -sort s] {6 7 0 1 4 5 2 3}
+  equal [mk::select db.a -rsort s] {2 3 4 5 0 1 6 7}
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+test 10 {get size} -body {
+  mk::view layout db.v {a:I b:I}
+  mk::row append db.v
+  equal [mk::get db.v!0] {a 0 b 0}
+  equal [mk::get db.v!0 -size] {a 0 b 0}
+  equal [mk::get db.v!0 -size a] 0
+  equal [mk::get db.v!0 -size a b] {0 0}
+  foreach {v c} {1 -1 3 -2 15 -4 127 1 -128 1 32767 2 -32768 2 32768 4} {
+    mk::set db.v!0 a $v
+    equal [mk::get db.v!0 -size a] $c
+  }
+  equal [mk::get db.v!0 -size b a] {0 4}
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+test 11 {case-insensitive select} -body {
+  mk::view layout db.a s
+  foreach x {one One two Two three Three four Four} {
+    mk::row append db.a s $x
+  }
+  equal [mk::select db.a -glob s t*] {2 4}
+  equal [mk::select db.a -globnc s t*] {2 3 4 5}
+  equal [mk::select db.a -regexp s t] {2 4}
+  equal [mk::select db.a -regexp s (?i)t] {2 3 4 5}
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+test 12 {channel interface} -body {
+  mk::view layout db.a {m:B}
+  mk::view size db.a 1
+
+  set a 1234567890
+  set b $a$a$a$a$a$a$a$a$a$a
+  set c $b$b$b$b$b$b$b$b$b$b
+  set d $c$c$c$c$c$c$c$c$c$c
+  equal [string length $d] 10000
+
+  set fd [mk::channel db.a!0 m w]
+  puts $fd $a
+  puts $fd $b
+  puts $fd $c
+  puts $fd $d
+  close $fd
+
+  switch $::tcl_platform(platform) {
+    windows { set eolsize 2 }
+    default { set eolsize 1 }
+  }
+  
+  equal [string length [mk::get db.a!0 m]] [expr {11110 + 4 * $eolsize}]
+
+  set fd [mk::channel db.a!0 m]
+  equal [gets $fd] $a
+  equal [gets $fd] $b
+  equal [gets $fd] $c
+  equal [gets $fd] $d
+  equal [gets $fd x] -1
+  close $fd
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+test 13 {recursive subviews} -body {
+  mk::view layout db.v {tag {nest ^}}
+  
+  mk::row append db.v tag a
+  mk::row append db.v!0.nest tag b
+  mk::row append db.v!0.nest!0.nest tag c
+  
+  equal [mk::get db.v!0 tag] a
+  equal [mk::get db.v!0.nest!0 tag] b
+  equal [mk::get db.v!0.nest!0.nest!0 tag] c
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+::tcltest::cleanupTests
diff --git a/8.x/mk/tcl/tests/commit.test b/8.x/mk/tcl/tests/commit.test
new file mode 100755 (executable)
index 0000000..d3c3d4e
--- /dev/null
@@ -0,0 +1,256 @@
+#!/usr/bin/env tclsh
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+  package require Mk4tcl
+} $version
+
+set f f1.dat
+set g $f.aside
+test 1 {simple commit aside} -body {
+  file delete $f $g
+
+  mk::file open db $f
+  mk::view layout db.a i:I
+  mk::row append db.a i 111
+  mk::row append db.a i 222
+  mk::row append db.a i 333
+  mk::file close db
+
+  mk::file open db $f -readonly
+  mk::file open dba $g
+
+  equal [mk::view size db.a] 3
+  mk::file aside db dba
+  equal [mk::view size db.a] 3
+
+  mk::row append db.a i 444
+  mk::row append db.a i 555
+
+  equal [mk::view size db.a] 5
+  mk::file commit db
+  mk::file commit dba
+  equal [mk::view size db.a] 5
+
+  mk::row append db.a i 666
+  equal [mk::view size db.a] 6
+
+  mk::file rollback db
+  equal [mk::view size db.a] 5
+  mk::file rollback db -full
+  equal [mk::view size db.a] 3
+
+  mk::file close db
+  mk::file close dba
+
+  mk::file open db $f -readonly
+  equal [mk::view size db.a] 3
+
+  equal [mk::get db.a!0 i] 111
+  equal [mk::get db.a!1 i] 222
+  equal [mk::get db.a!2 i] 333
+
+  mk::file open dba $g -readonly
+  mk::file aside db dba
+  equal [mk::view size db.a] 5
+
+  equal [mk::get db.a!0 i] 111
+  equal [mk::get db.a!1 i] 222
+  equal [mk::get db.a!2 i] 333
+  equal [mk::get db.a!3 i] 444
+  equal [mk::get db.a!4 i] 555
+} -cleanup {mk::file close db; mk::file close dba}
+file delete $f $g
+
+set f f2.dat
+set g $f.aside
+test 2 {add view commit aside} -body {
+  file delete $f $g
+
+  mk::file open db $f
+  mk::view layout db.a i:I
+  equal [mk::view layout db.a] i:I
+
+  mk::row append db.a i 111
+  mk::file close db
+
+  mk::file open db $f -readonly
+  mk::file open dba $g
+
+  equal [mk::view size db.a] 1
+  mk::file aside db dba
+  equal [mk::view size db.a] 1
+
+  mk::view layout db.a {i:I j:I}
+  equal [mk::view layout db.a] {i:I j:I}
+
+  equal [mk::get db.a!0] {i 111 j 0}
+
+  mk::set db.a!0 j 222
+
+  mk::file commit db
+  mk::file commit dba
+
+  mk::row append db.a i 333 j 444
+  equal [mk::view size db.a] 2
+
+  mk::file rollback db
+  equal [mk::view layout db.a] {i:I j:I}
+  equal [mk::view size db.a] 1
+  equal [mk::get db.a!0] {i 111 j 222}
+
+  mk::file rollback db -full
+  equal [mk::view layout db.a] i:I
+  equal [mk::view size db.a] 1
+  equal [mk::get db.a!0] {i 111}
+
+  mk::file close db
+  mk::file close dba
+
+  mk::file open db $f -readonly
+  equal [mk::view layout db.a] i:I
+  equal [mk::view size db.a] 1
+  equal [mk::get db.a!0] {i 111}
+
+  mk::file open dba $g -readonly
+  mk::file aside db dba
+  equal [mk::view layout db.a] {i:I j:I}
+  equal [mk::view size db.a] 1
+  equal [mk::get db.a!0] {i 111 j 222}
+} -cleanup {mk::file close db; mk::file close dba}
+file delete $f $g
+
+set f f3.dat
+set g $f.aside
+test 3 {removed view commit aside} -body {
+  file delete $f $g
+
+  mk::file open db $f
+  mk::view layout db.a {i:I j:I}
+  equal [mk::view layout db.a] {i:I j:I}
+
+  mk::row append db.a i 111 j 222
+  mk::file close db
+
+  mk::file open db $f -readonly
+  mk::file open dba $g
+
+  equal [mk::view size db.a] 1
+  mk::file aside db dba
+  equal [mk::view size db.a] 1
+
+  mk::view layout db.a i:I
+  equal [mk::view layout db.a] i:I
+
+    # this may be surprisini, but it is correct behavior:
+    # the j prop is still present as *temporary* property
+  equal [mk::get db.a!0] {i 111 j 222}
+
+  mk::file commit db
+  mk::file commit dba
+
+    # even a commit won't make it go away. because the
+    # commit on db is not a real one, and the commit on
+    # dba is not affecting db (in a non-commit-aside
+    # situation, the j prop would be gone by now)
+  equal [mk::get db.a!0] {i 111 j 222}
+
+  mk::file close db
+  mk::file close dba
+
+  mk::file open db $f -readonly
+  equal [mk::view layout db.a] {i:I j:I}
+  equal [mk::view size db.a] 1
+  equal [mk::get db.a!0] {i 111 j 222}
+
+  mk::file open dba $g -readonly
+  mk::file aside db dba
+  equal [mk::view layout db.a] i:I
+  equal [mk::view size db.a] 1
+
+    # this hows that j was indeed a temporary property
+  equal [mk::get db.a!0] {i 111}
+} -cleanup {mk::file close db; mk::file close dba}
+file delete $f $g
+
+set f f4.dat
+set g $f.a1
+set h $f.a2
+test 4 {stacked commit aside} -body {
+  file delete $f $g $h
+
+  mk::file open db0 $f
+  mk::view layout db0.a i:I
+  mk::row append db0.a i 111
+  mk::file close db0 ;# will autocommit
+
+  mk::file open db0 $f -readonly
+  mk::file open db1 $g
+  mk::file aside db0 db1
+  mk::row append db0.a i 222
+  mk::file commit db0
+  mk::file close db0
+  mk::file close db1 ;# will autocommit
+
+  mk::file open db0 $f -readonly
+  mk::file open db1 $g -readonly
+  mk::file open db2 $h
+  mk::file aside db1 db2
+  mk::file aside db0 db1
+  mk::row append db0.a i 333
+  mk::file commit db0
+  mk::file commit db1
+  mk::file close db0
+  mk::file close db1
+  mk::file close db2 ;# will autocommit
+
+  mk::file open db0 $f -readonly
+  equal [mk::view size db0.a] 1
+  equal [mk::get db0.a!0 i] 111
+  mk::file close db0
+
+  mk::file open db0 $f -readonly
+  mk::file open db1 $g -readonly
+  mk::file aside db0 db1
+  equal [mk::view size db0.a] 2
+  equal [mk::get db0.a!1 i] 222
+  mk::file close db0
+  mk::file close db1
+
+  mk::file open db0 $f -readonly
+  mk::file open db1 $g -readonly
+  mk::file open db2 $h -readonly
+  mk::file aside db1 db2
+  mk::file aside db0 db1
+  equal [mk::view size db0.a] 3
+  equal [mk::get db0.a!2 i] 333
+} -cleanup {mk::file close db0; mk::file close db1; mk::file close db2}
+file delete $f $g $h
+
+set f f5.dat
+test 5 {missing/empty file} -body {
+  file delete $f
+  
+  catch {mk::file end $f} err
+  equal $err {no such file}
+  
+  close [open $f w]
+  equal [file size $f] 0
+
+  catch {mk::file end $f} err
+  equal $err {not a Metakit datafile}
+  
+  mk::file open db $f
+  mk::file close db
+  equal [file size $f] 0
+  
+  mk::file open db $f
+  mk::view layout db.a i:I
+  mk::file close db
+  equal [mk::file end $f] 37
+}
+file delete $f
+
+::tcltest::cleanupTests
diff --git a/8.x/mk/tcl/tests/fixed.test b/8.x/mk/tcl/tests/fixed.test
new file mode 100755 (executable)
index 0000000..6095d51
--- /dev/null
@@ -0,0 +1,142 @@
+#!/usr/bin/env tclsh
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+  package require Mk4tcl
+} $version
+
+  # this crashes TclKit 8.0.5, but works with a recent tclkitsh
+  # caused by the Windows 4 Kb mmap-avoid buffer (has been fixed)
+
+set f f1.dat
+test 1 {one thousand properties} -body {
+  file delete $f
+
+  set format ""
+  mk::file open db $f
+
+  for {set i 0} {$i < 1000} {incr i} {
+    lappend format i$i:I
+  }
+  mk::view layout db.v $format
+  mk::file commit db
+  equal [mk::view layout db.v] $format
+} -cleanup {mk::file close db}
+file delete $f
+
+  # MK doesn't return proper format when no rows are present
+  # fixed 03/11/1999 in Mk4tcl 1.2 + Mk 1.9d
+
+set f f2.dat
+test 2 {deeply nested} -body {
+  file delete $f
+
+  set format [list a b]
+  for {set i 0} {$i < 10} {incr i} {
+    set format [list v$i $format]
+  }
+    # the bug is in this view layout (i.e. fetch, setting it works fine)
+  mk::file open db $f
+  mk::view layout db.v $format
+  mk::file commit db
+  equal [mk::view layout db.v] $format
+} -cleanup {mk::file close db}
+file delete $f
+
+  # failed due to bad caching, fixed in 1.9f
+
+test 3 {numeric sorts} -body {
+  mk::view layout db.v {i:I f:F d:D}
+  mk::row append db.v i 44 f   44 d   44
+  mk::row append db.v i 3333 f 3333 d 3333
+  mk::row append db.v i 11 f   11 d   11
+  mk::row append db.v i 22 f   22 d   22
+  mk::row append db.v i 4444 f 4444 d 4444
+  mk::row append db.v i 7777 f 7777 d 7777
+  mk::row append db.v i 6666 f 6666 d 6666
+  mk::row append db.v i  333 f  333 d  333
+  mk::row append db.v i  444 f  444 d  444
+  mk::row append db.v i 1111 f 1111 d 1111
+  mk::row append db.v i 33 f   33 d   33
+  mk::row append db.v i 5555 f 5555 d 5555
+  mk::row append db.v i  222 f  222 d  222
+  mk::row append db.v i  111 f  111 d  111
+  mk::row append db.v i 7777 f 7777 d 7777
+  mk::row append db.v i 55 f   55 d   55
+  mk::row append db.v i 2222 f 2222 d 2222
+  mk::row append db.v i  555 f  555 d  555
+  mk::row append db.v i 77 f   77 d   77
+  mk::row append db.v i 66 f   66 d   66
+  mk::row append db.v i  777 f  777 d  777
+  mk::row append db.v i  666 f  666 d  666
+  set s1 {2 3 10 0 15 19 18 13 12 7 8 17 21 20 9 16 1 4 11 6 5 14}
+  set s2 {5 14 6 11 4 1 16 9 20 21 17 8 7 12 13 18 19 15 0 10 3 2}
+  equal [mk::select db.v -sort i] $s1
+  equal [mk::select db.v -sort f] $s1
+  equal [mk::select db.v -sort d] $s1
+  equal [mk::select db.v -rsort i] $s2
+  equal [mk::select db.v -rsort f] $s2
+  equal [mk::select db.v -rsort d] $s2
+} -setup {mk::file open db} -cleanup {mk::file close db}
+
+  # termination problem reported by MR, fixed 1999-11-11
+  
+test 4 {slave cleanup} -body {
+  interp create sub
+  foreach e [info loaded] {
+    foreach {x y} $e break
+    if {[string match Mk* $y]} {
+      #puts "load $x $y sub"
+      load $x $y sub
+    }
+  }
+  interp delete sub ;# this crashed
+}
+
+  # bug in set-after-get reported by MV, fixed 1999-12-20
+  
+set f f5.dat
+test 5 {set after get} -body {
+  file delete $f
+  
+  mk::file open db $f
+  mk::view layout db.v s
+  set a 1234567890
+  set a $a$a$a$a$a$a$a$a$a$a
+  set a $a$a$a$a$a$a$a$a$a$a
+  set b $a$a$a$a
+  mk::row append db.v s $b  ;# 4000
+  mk::row append db.v s $a  ;# 1000, wraps
+  mk::file commit db
+  set c [mk::get db.v!1 s]
+  mk::set db.v!1 s $c
+  return
+} -cleanup {mk::file close db}
+file delete $f
+
+  # crashed in 2.3.1 alpha
+
+test 6 {open missing file r/o} -body {
+  catch {mk::file open db0 f6.dat -readonly} err
+  equal $err {file open failed}
+}
+
+  # crashed until 2003-02-37
+
+test 7 {relaxed layout list input} -body {
+  mk::view layout db.v { README#2 README#3 }
+} -result db.v -setup {mk::file open db} -cleanup {mk::file close db}
+
+  # crashed until 2004-01-22, MK 2.4.9.2
+
+test 8 {row create} -body {
+  for {set i 0} {$i < 10} {incr i} {
+    mk::row create
+    lappend keep [mk::row create]
+  }
+  unset keep
+}
+
+::tcltest::cleanupTests
diff --git a/8.x/mk/tcl/tests/initests.tcl b/8.x/mk/tcl/tests/initests.tcl
new file mode 100644 (file)
index 0000000..271799d
--- /dev/null
@@ -0,0 +1,70 @@
+# common test setup script
+
+if {[info exists testsInited]} return
+
+package require Tcl 8.4
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+  package require tcltest 2.2
+  namespace import tcltest::*
+}
+
+singleProcess true ;# run without forking
+
+testsDirectory [file dirname [info script]]
+
+# if run from the tests directory, move one level up
+if {[pwd] eq [testsDirectory]} {
+  cd ..
+}
+
+temporaryDirectory [pwd]
+#workingDirectory [file dirname [testsDirectory]]
+
+# TextMate support on Mac OS X: run make before running any test from editor
+if {[info exists env(TM_FILENAME)]} {
+  if {[catch { exec make } msg]} {
+    puts stderr $msg
+    exit 1
+  }
+}
+
+proc readfile {filename} {                                                      
+  set fd [open $filename]                                                       
+  set data [read $fd]                                                           
+  close $fd                                                                     
+  return $data                                                                  
+}
+
+# extract version number from pkgIndex.tcl
+regexp {ifneeded Mk4tcl\s(\S+)\s} [readfile [workingDirectory]/pkgIndex.tcl] - version
+unset -
+
+# make sure the pkgIndex.tcl is found
+if {[lsearch $auto_path [workingDirectory]] < 0} {
+  set auto_path [linsert $auto_path 0 [workingDirectory]]
+}
+
+testConstraint 64bit            [expr {$tcl_platform(wordSize) == 8}]
+testConstraint bigendian        [expr {$tcl_platform(byteOrder) eq "bigEndian"}]
+testConstraint tcl$tcl_version  1
+
+proc assert {ok} {
+  if {!$ok} {
+    return -code error "assertion failed"
+  }
+}
+
+proc equal {expected result} {
+  if {$expected ne $result} {
+    return -code error [list expected $expected got $result]
+  }
+}
+
+proc match {pattern result} {
+  if {![string match $pattern $result]} {
+    return -code error [list pattern $pattern does not match $result]
+  }
+}
+
+set testsInited 1
diff --git a/8.x/mk/tcl/tests/limit.test b/8.x/mk/tcl/tests/limit.test
new file mode 100755 (executable)
index 0000000..64f18ce
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env tclsh
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+  package require Mk4tcl
+} $version
+
+set f f1.dat
+test 1 {lots of properties} -body {
+  file delete $f
+  
+  mk::file open db $f
+  for {set i 0} {$i < 250} {incr i} {
+    lappend format i$i:I
+  }
+  mk::view layout db.v $format
+  mk::file commit db
+  equal [mk::view layout db.v] $format
+} -cleanup {mk::file close db}
+file delete $f
+
+set f f2.dat
+test 2 {string/byte/memo property mix} -body {
+  file delete $f
+
+  mk::file open db $f
+  mk::view layout db.a {s:S b:B}
+
+  set a 123456789012345
+  set b $a$a$a$a$a$a$a$a$a$a
+  set c $b$b$b$b$b$b$b$b$b$b
+  set d $c$c$c$c$c$c$c$c$c$c
+  equal [string length $d] 15000
+
+  mk::row append db.a s A$a b A$a
+  mk::row append db.a s A$d b A$d
+  mk::row append db.a
+
+  mk::row append db.a s B$a b B$a
+  mk::row append db.a s B$d b B$d
+  mk::row append db.a
+
+  mk::file close db
+  mk::file open db $f -readonly
+  
+  equal [mk::get db.a!0 b] A$a
+  equal [mk::get db.a!1 b] A$d
+  equal [mk::get db.a!2 b] {}
+
+  equal [mk::get db.a!0 s] A$a
+  equal [mk::get db.a!1 s] A$d
+  equal [mk::get db.a!2 s] {}
+
+  equal [mk::get db.a!3 b] B$a
+  equal [mk::get db.a!4 b] B$d
+  equal [mk::get db.a!5 b] {}
+
+  equal [mk::get db.a!3 s] B$a
+  equal [mk::get db.a!4 s] B$d
+  equal [mk::get db.a!5 s] {}
+} -cleanup {mk::file close db}
+file delete $f
+
+::tcltest::cleanupTests
diff --git a/8.x/mk/tcl/tests/object.test b/8.x/mk/tcl/tests/object.test
new file mode 100755 (executable)
index 0000000..353b258
--- /dev/null
@@ -0,0 +1,477 @@
+#!/usr/bin/env tclsh
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+  package require Mk4tcl
+} $version
+
+  proc fill {v prop args} {
+    foreach x $args {
+      $v insert end $prop $x
+    }
+  }
+
+  proc dump {v} {
+    set n [$v size]
+    set r {}
+    for {set i 0} {$i < $n} {incr i} {
+      set l {}
+      foreach {x y} [$v get $i] {
+        lappend l $y
+      }
+      lappend r $l
+    }
+    return $r
+  }
+
+set f f1.dat
+test 1 {basic view operations} -body {
+  file delete $f
+  
+  mk::file open db $f
+  mk::view layout db.a {s i:I}
+  set v [mk::view open db.a v]
+  equal $v v
+
+  equal [v info] {s i:I}
+
+  for {set i 0} {$i < 100} {incr i} {
+    v insert end s s$i/$i i $i
+  }
+
+  equal [v size] 100
+  equal [v get 0] {s s0/0 i 0}
+  equal [v get 1] {s s1/1 i 1}
+  equal [v get 99] {s s99/99 i 99}
+
+  equal [v get 9] {s s9/9 i 9}
+  equal [v get 9 s] s9/9
+  equal [v get 9 i] 9
+
+  equal [v find s s12/12] 12
+  catch {v find s blah} e
+  equal $e {not found}
+
+  equal [v find i 23] 23
+  equal [catch {v find i -1}] 1
+
+    # views opened more than once are shared
+  set w [mk::view open db.a]
+  equal [$w size] 100
+  $w insert end s wow i -1
+
+  equal [v size] 101
+  equal [v get end] {s wow i -1}
+
+  $w close
+  v close
+} -cleanup {mk::file close db}
+file delete $f
+
+set f f2.dat
+test 2 {view modifications} -body {
+  file delete $f
+
+  mk::file open db $f
+  mk::view layout db.a i:I
+  mk::view open db.a v
+
+  v insert end i 1
+  v insert end i 2
+  v insert 1 i 3
+  v insert end i 4
+  
+  equal [v size] 4
+  foreach {x y} {0 1  1 3  2 2  3 4} {
+    equal [v get $x i] $y
+  }
+
+  v delete 1
+  v delete [expr {[v size]-1}]
+  
+  equal [v size] 2
+  foreach {x y} {0 1  1 2} {
+    equal [v get $x i] $y
+  }
+
+  v set end i 5
+  v set 0 i 6
+
+  foreach {x y} {0 6  1 5} {
+    equal [v get $x i] $y
+  }
+
+  v close
+} -cleanup {mk::file close db}
+file delete $f
+
+set f f3.dat
+test 3 {view operators} -body {
+  file delete $f
+
+  mk::file open db $f
+  mk::view layout db.a i:I
+  mk::view layout db.b i:I
+  mk::view layout db.c j:I
+  mk::view layout db.d k:I
+  mk::view open db.a v1
+  mk::view open db.b v2
+  mk::view open db.c v3
+  mk::view open db.d v4
+  
+  fill v1 i 1 2 3 4 5
+  fill v2 i 3 4 5 6 7
+  fill v3 j 3 4 5 6 7
+  fill v4 k 1 2 1
+
+  set v [v1 view clone]
+  equal [$v size] 0
+  equal [$v info] i:I
+  $v close
+
+  set v [v1 view copy]
+  equal [dump $v] {1 2 3 4 5}
+  $v close
+
+  set v [v1 view concat v2]
+  equal [dump $v] {1 2 3 4 5 3 4 5 6 7}
+  $v close
+
+  set v [v1 view different v2]
+  equal [dump $v] {1 2 6 7}
+  $v close
+
+  set v [v1 view minus v2]
+  equal [dump $v] {1 2}
+  $v close
+
+  set v [v1 view intersect v2]
+  equal [dump $v] {3 4 5}
+  $v close
+
+  set v [v1 view union v2]
+  equal [dump $v] {1 2 3 4 5 6 7}
+  $v close
+
+  set v [v1 view pair v3]
+  equal [dump $v] {{1 3} {2 4} {3 5} {4 6} {5 7}}
+  $v close
+
+  set v [v2 view range 2 3]
+  equal [dump $v] {5 6}
+  $v close
+
+  set v [v2 view range 3 end]
+  equal [dump $v] {6 7}
+  $v close
+
+  set v [v2 view range 2 4 -1]
+  equal [dump $v] {7 6 5}
+  $v close
+
+  set v [v2 view map v4]
+  equal [dump $v] {4 5 4}
+  $v close
+
+  set v [v4 view unique]
+  equal [dump $v] {1 2}
+  $v close
+
+  v1 close
+  v2 close
+  v3 close
+  v4 close
+} -cleanup {mk::file close db}
+file delete $f
+
+set f f4.dat
+test 4 {hash view} -body {
+  file delete $f
+
+  mk::file open db $f
+  mk::view layout db.data {k:I v:S}
+  mk::view layout db.map {_H:I _R:I}
+  mk::view open db.data v1
+  mk::view open db.map v2
+  rename [v1 view hash v2 1] v3
+
+  v3 insert end k 1 v one
+  v3 insert end k 2 v two
+  v3 insert 1 k 3 v three
+  v3 insert 1 k 4 v four
+  v3 insert 1 k 5 v five
+
+  equal [dump v3] {{1 one} {5 five} {4 four} {3 three} {2 two}}
+
+  equal [v3 find k 3] 3
+  equal [v3 find v three] 3
+
+  v3 delete 1
+
+  equal [v3 find k 3] 2
+  equal [v3 find v three] 2
+
+  v3 delete 2
+
+  equal [catch {v3 find k 3}] 1
+  equal [catch {v3 find v three}] 1
+
+  equal [dump v3] {{1 one} {4 four} {2 two}}
+
+  equal [v3 find k 1] 0
+  equal [v3 find k 4] 1
+  equal [v3 find k 2] 2
+
+  v3 set 1 v nine
+
+  equal [dump v3] {{1 one} {4 nine} {2 two}}
+
+  v3 set 1 k 9
+
+  equal [dump v3] {{1 one} {9 nine} {2 two}}
+
+  equal [v3 find k 1] 0
+  equal [v3 find k 9] 1
+  equal [v3 find k 2] 2
+
+  equal [catch {v3 find k 4}] 1
+
+  v3 set 1 k 1 v clobber
+
+  equal [dump v3] {{1 nine} {2 clobber}}
+
+  # WARNING, the above is a bug, the result *should* have been:
+  # C [dump v3] {{1 clobber} {2 two}}
+  # but due to a nasty problem, a different row gets clobbered
+  # 
+  # There are more such problems, i.e. with a 2-column key, when
+  # changing the key, the intermediate state will be stored and
+  # can delete an unrelated row due to the above deleting effect
+  #
+  # The advice for now is: DO NOT change keys, or ONLY the key
+  # property in a single-prop hash mapping.  In the above case,
+  # "v3 set 1 k 1" would've worked fine (deleting the other row).
+  
+  v3 close
+  v2 close
+  v1 close
+} -cleanup {mk::file close db}
+file delete $f
+
+set f f5.dat
+test 5 {blocked view} -body {
+  file delete $f
+
+  mk::file open db $f
+  mk::view layout db.data {{_B {k:I v:D}}}
+  mk::view open db.data v1
+  rename [v1 view blocked] v2
+
+  set n 2500
+  set nb 4  ;# number of buckets, depends on blocking algorithm
+
+  for {set i 0} {$i < $n} {incr i} {
+    v2 insert end k $i v $i.$i
+  }
+
+  equal [v2 size] $n
+  equal [v1 size] $nb
+
+    # check that all blocks combined have the same number of rows
+  set t 0
+  for {set j 0} {$j < $nb} {incr j} {
+    #puts [mk::view size db.data!$j._B]
+    incr t [mk::view size db.data!$j._B]
+  }
+  equal $t $n
+
+  equal [v2 find k 3] 3
+  equal [v2 find v 3.3] 3
+
+  v2 delete 1
+
+  equal [v2 find k 3] 2
+  equal [v2 find v 3.3] 2
+
+  v2 delete 2
+
+  equal [catch {v2 find k 3}] 1
+  equal [catch {v2 find v 3.3}] 1
+
+  set w [v2 view range 0 3]
+  equal [dump $w] {{0 0.0} {2 2.2} {4 4.4} {5 5.5}}
+  $w close
+
+  v2 insert 2 k 3 v 3.3
+  v2 insert 1 k 1 v 1.1
+
+  for {set i 0} {$i < [v2 size]} {incr i} {
+    v2 delete $i
+  }
+
+  for {set i 0} {$i < [v2 size]} {incr i} {
+    equal [v2 get $i k] [expr {2*$i+1}]
+  }
+
+  assert [expr {[v1 size] < $nb}]
+
+  set t 0
+  for {set j 0} {$j < [v1 size]} {incr j} {
+    #puts [mk::view size db.data!$j._B]
+    incr t [mk::view size db.data!$j._B]
+  }
+  equal $t [v2 size]
+  
+  v2 close
+  v1 close
+} -cleanup {mk::file close db}
+file delete $f
+
+set f f6.dat
+test 6 {ordered view} -body {
+  file delete $f
+
+  mk::file open db $f
+  mk::view layout db.data {k:I v:S}
+  mk::view open db.data v1
+  rename [v1 view ordered 1] v2
+
+  v2 insert end k 1 v one
+  v2 insert end k 5 v five
+  v2 insert end k 4 v four
+  v2 insert end k 3 v three
+  v2 insert end k 2 v two
+
+  equal [dump v2] {{1 one} {2 two} {3 three} {4 four} {5 five}}
+
+  equal [v2 find k 3] 2
+  equal [v2 find v three] 2
+
+  v2 delete 1
+
+  equal [v2 find k 3] 1
+  equal [v2 find v three] 1
+
+  v2 delete 1
+
+  equal [catch {v2 find k 3}] 1
+  equal [catch {v2 find v three}] 1
+
+  equal [dump v2] {{1 one} {4 four} {5 five}}
+
+  equal [v2 find k 1] 0
+  equal [v2 find k 4] 1
+  equal [v2 find k 5] 2
+
+  v2 set 1 v nine
+
+  equal [dump v2] {{1 one} {4 nine} {5 five}}
+
+  v2 set 1 k 9
+
+  equal [dump v2] {{1 one} {5 five} {9 nine}}
+
+  equal [v2 find k 1] 0
+  equal [v2 find k 5] 1
+  equal [v2 find k 9] 2
+
+  equal [catch {v2 find k 4}] 1
+
+  v2 set 1 k 1 v clobber
+
+  equal [dump v2] {{1 five} {9 clobber}}
+
+  # WARNING, same problem as described above, should have been:
+  # C [dump v2] {{1 clobber} {9 nine}}
+  
+  v2 close
+  v1 close
+} -cleanup {mk::file close db}
+file delete $f
+
+set f f7.dat
+test 7 {blocked hash view} -body {
+  file delete $f
+
+  mk::file open db $f
+  mk::view layout db.data {k:I v:S}
+  mk::view layout db.map {{_B {_H:I _R:I}}}
+  mk::view open db.data v1
+  mk::view open db.map v2
+  rename [v2 view blocked] v3
+  rename [v1 view hash v3 1] v4
+
+  v4 insert end k 1 v one
+  v4 insert end k 2 v two
+  v4 insert 1 k 3 v three
+  v4 insert 1 k 4 v four
+  v4 insert 1 k 5 v five
+
+  equal [dump v4] {{1 one} {5 five} {4 four} {3 three} {2 two}}
+  equal [dump v1] {{1 one} {5 five} {4 four} {3 three} {2 two}}
+
+  equal [v2 size] 2
+  equal [v3 size] 9
+
+  equal [v4 find k 3] 3
+  equal [v4 find v three] 3
+
+  v4 delete 1
+
+  equal [v4 find k 3] 2
+  equal [v4 find v three] 2
+
+  v4 delete 2
+
+  equal [catch {v4 find k 3}] 1
+  equal [catch {v4 find v three}] 1
+
+  equal [dump v4] {{1 one} {4 four} {2 two}}
+
+  equal [v4 find k 1] 0
+  equal [v4 find k 4] 1
+  equal [v4 find k 2] 2
+
+  v4 set 1 v nine
+
+  equal [dump v4] {{1 one} {4 nine} {2 two}}
+
+  v4 set 1 k 9
+
+  equal [dump v4] {{1 one} {9 nine} {2 two}}
+
+  equal [v4 find k 1] 0
+  equal [v4 find k 9] 1
+  equal [v4 find k 2] 2
+
+  equal [catch {v4 find k 4}] 1
+
+  v4 set 1 k 1 v clobber
+
+  equal [dump v4] {{1 nine} {2 clobber}}
+
+  # WARNING, same problem as described above, should have been:
+  # C [dump v4] {{1 clobber} {2 two}}
+
+  for {set x 100} {$x <= 999} {incr x} {
+    v4 insert end k $x v v$x
+  }
+
+  # check that the entries all get found
+  for {set x 100} {$x <= 999} {incr x} {
+    equal [expr {$x-98}] [v4 find k $x]
+  }
+
+  equal [v2 size] 4
+  equal [v3 size] 2049
+  
+  v4 close
+  v3 close
+  v2 close
+  v1 close
+} -cleanup {mk::file close db}
+file delete $f
+
+::tcltest::cleanupTests
diff --git a/8.x/mk/tests/ok/b00.txt b/8.x/mk/tests/ok/b00.txt
new file mode 100644 (file)
index 0000000..6a37cfb
--- /dev/null
@@ -0,0 +1,3 @@
+>>> Should fail
+*** Failed: A(false) ***
+<<< done.
diff --git a/8.x/mk/tests/ok/b01.txt b/8.x/mk/tests/ok/b01.txt
new file mode 100644 (file)
index 0000000..814999f
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Should succeed
+<<< done.
diff --git a/8.x/mk/tests/ok/b02.txt b/8.x/mk/tests/ok/b02.txt
new file mode 100644 (file)
index 0000000..ac0e86f
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Int property
+<<< done.
diff --git a/8.x/mk/tests/ok/b03.txt b/8.x/mk/tests/ok/b03.txt
new file mode 100644 (file)
index 0000000..7f33745
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Float property
+<<< done.
diff --git a/8.x/mk/tests/ok/b04.txt b/8.x/mk/tests/ok/b04.txt
new file mode 100644 (file)
index 0000000..741c5e8
--- /dev/null
@@ -0,0 +1,2 @@
+>>> String property
+<<< done.
diff --git a/8.x/mk/tests/ok/b05.txt b/8.x/mk/tests/ok/b05.txt
new file mode 100644 (file)
index 0000000..3abc4fc
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View property
+<<< done.
diff --git a/8.x/mk/tests/ok/b06.txt b/8.x/mk/tests/ok/b06.txt
new file mode 100644 (file)
index 0000000..67a3a44
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View construction
+<<< done.
diff --git a/8.x/mk/tests/ok/b07.txt b/8.x/mk/tests/ok/b07.txt
new file mode 100644 (file)
index 0000000..05bd95f
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Row manipulation
+<<< done.
diff --git a/8.x/mk/tests/ok/b08.txt b/8.x/mk/tests/ok/b08.txt
new file mode 100644 (file)
index 0000000..1d6cd6e
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Row expressions
+<<< done.
diff --git a/8.x/mk/tests/ok/b09.txt b/8.x/mk/tests/ok/b09.txt
new file mode 100644 (file)
index 0000000..6f3c20d
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View manipulation
+<<< done.
diff --git a/8.x/mk/tests/ok/b10.txt b/8.x/mk/tests/ok/b10.txt
new file mode 100644 (file)
index 0000000..55c9a3a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View sorting
+<<< done.
diff --git a/8.x/mk/tests/ok/b11.txt b/8.x/mk/tests/ok/b11.txt
new file mode 100644 (file)
index 0000000..16c5a04
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View selection
+<<< done.
diff --git a/8.x/mk/tests/ok/b12.txt b/8.x/mk/tests/ok/b12.txt
new file mode 100644 (file)
index 0000000..93e30ce
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Add after remove
+<<< done.
diff --git a/8.x/mk/tests/ok/b13.txt b/8.x/mk/tests/ok/b13.txt
new file mode 100644 (file)
index 0000000..d1a9a9b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Clear view entry
+<<< done.
diff --git a/8.x/mk/tests/ok/b14.txt b/8.x/mk/tests/ok/b14.txt
new file mode 100644 (file)
index 0000000..f166c43
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Empty view outlives temp storage
+<<< done.
diff --git a/8.x/mk/tests/ok/b15.txt b/8.x/mk/tests/ok/b15.txt
new file mode 100644 (file)
index 0000000..595ca0e
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View outlives temp storage
+<<< done.
diff --git a/8.x/mk/tests/ok/b16.txt b/8.x/mk/tests/ok/b16.txt
new file mode 100644 (file)
index 0000000..fb43bbf
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View outlives cleared temp storage
+<<< done.
diff --git a/8.x/mk/tests/ok/b17.txt b/8.x/mk/tests/ok/b17.txt
new file mode 100644 (file)
index 0000000..0c61591
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Double property
+<<< done.
diff --git a/8.x/mk/tests/ok/b18.txt b/8.x/mk/tests/ok/b18.txt
new file mode 100644 (file)
index 0000000..e9ff0b4
--- /dev/null
@@ -0,0 +1,2 @@
+>>> SetAtGrow usage
+<<< done.
diff --git a/8.x/mk/tests/ok/b19.txt b/8.x/mk/tests/ok/b19.txt
new file mode 100644 (file)
index 0000000..99c176c
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Bytes property
+<<< done.
diff --git a/8.x/mk/tests/ok/b20.txt b/8.x/mk/tests/ok/b20.txt
new file mode 100644 (file)
index 0000000..849ebf8
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Search sorted view
+<<< done.
diff --git a/8.x/mk/tests/ok/b21.txt b/8.x/mk/tests/ok/b21.txt
new file mode 100644 (file)
index 0000000..33cc19d
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Memo property
+<<< done.
diff --git a/8.x/mk/tests/ok/b22.txt b/8.x/mk/tests/ok/b22.txt
new file mode 100644 (file)
index 0000000..c7612a0
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Stored view references
+<<< done.
diff --git a/8.x/mk/tests/ok/b23.txt b/8.x/mk/tests/ok/b23.txt
new file mode 100755 (executable)
index 0000000..d8967bf
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Sort comparison fix
+<<< done.
diff --git a/8.x/mk/tests/ok/b24.txt b/8.x/mk/tests/ok/b24.txt
new file mode 100755 (executable)
index 0000000..dbf75a5
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Custom view comparisons
+<<< done.
diff --git a/8.x/mk/tests/ok/b25.txt b/8.x/mk/tests/ok/b25.txt
new file mode 100755 (executable)
index 0000000..ab01b4f
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Copy row from derived
+<<< done.
diff --git a/8.x/mk/tests/ok/b26.txt b/8.x/mk/tests/ok/b26.txt
new file mode 100644 (file)
index 0000000..7fd6a5d
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Partial memo field access
+<<< done.
diff --git a/8.x/mk/tests/ok/b27.txt b/8.x/mk/tests/ok/b27.txt
new file mode 100644 (file)
index 0000000..156a2c9
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Copy value to another row
+<<< done.
diff --git a/8.x/mk/tests/ok/c01.txt b/8.x/mk/tests/ok/c01.txt
new file mode 100644 (file)
index 0000000..ce7ebb7
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Slice forward
+<<< done.
diff --git a/8.x/mk/tests/ok/c02.txt b/8.x/mk/tests/ok/c02.txt
new file mode 100644 (file)
index 0000000..50b88f0
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Slice backward
+<<< done.
diff --git a/8.x/mk/tests/ok/c03.txt b/8.x/mk/tests/ok/c03.txt
new file mode 100644 (file)
index 0000000..4feea34
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Slice reverse
+<<< done.
diff --git a/8.x/mk/tests/ok/c04.txt b/8.x/mk/tests/ok/c04.txt
new file mode 100644 (file)
index 0000000..64bf550
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Cartesian product
+<<< done.
diff --git a/8.x/mk/tests/ok/c05.txt b/8.x/mk/tests/ok/c05.txt
new file mode 100644 (file)
index 0000000..7fae13e
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Remapping
+<<< done.
diff --git a/8.x/mk/tests/ok/c06.txt b/8.x/mk/tests/ok/c06.txt
new file mode 100644 (file)
index 0000000..520d9f7
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Pairwise combination
+<<< done.
diff --git a/8.x/mk/tests/ok/c07.txt b/8.x/mk/tests/ok/c07.txt
new file mode 100644 (file)
index 0000000..169aa50
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Concatenate views
+<<< done.
diff --git a/8.x/mk/tests/ok/c08.txt b/8.x/mk/tests/ok/c08.txt
new file mode 100644 (file)
index 0000000..773e1e5
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Rename property
+<<< done.
diff --git a/8.x/mk/tests/ok/c09.txt b/8.x/mk/tests/ok/c09.txt
new file mode 100644 (file)
index 0000000..2d57739
--- /dev/null
@@ -0,0 +1,2 @@
+>>> GroupBy operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c10.txt b/8.x/mk/tests/ok/c10.txt
new file mode 100644 (file)
index 0000000..ddb98fe
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Counts operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c11.txt b/8.x/mk/tests/ok/c11.txt
new file mode 100644 (file)
index 0000000..6d70cd8
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Unique operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c12.txt b/8.x/mk/tests/ok/c12.txt
new file mode 100644 (file)
index 0000000..d66e764
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Union operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c13.txt b/8.x/mk/tests/ok/c13.txt
new file mode 100644 (file)
index 0000000..14f1e97
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Intersect operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c14.txt b/8.x/mk/tests/ok/c14.txt
new file mode 100644 (file)
index 0000000..3edcec0
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Different operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c15.txt b/8.x/mk/tests/ok/c15.txt
new file mode 100755 (executable)
index 0000000..c827c75
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Minus operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c16.txt b/8.x/mk/tests/ok/c16.txt
new file mode 100644 (file)
index 0000000..55d9f69
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View comparisons
+<<< done.
diff --git a/8.x/mk/tests/ok/c17.txt b/8.x/mk/tests/ok/c17.txt
new file mode 100644 (file)
index 0000000..cd2ac75
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Join operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c18.txt b/8.x/mk/tests/ok/c18.txt
new file mode 100755 (executable)
index 0000000..dfdd45a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Groupby sort fix
+<<< done.
diff --git a/8.x/mk/tests/ok/c19.txt b/8.x/mk/tests/ok/c19.txt
new file mode 100755 (executable)
index 0000000..469df00
--- /dev/null
@@ -0,0 +1,2 @@
+>>> JoinProp operation
+<<< done.
diff --git a/8.x/mk/tests/ok/c20.txt b/8.x/mk/tests/ok/c20.txt
new file mode 100644 (file)
index 0000000..cea0b65
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Wide cartesian product
+<<< done.
diff --git a/8.x/mk/tests/ok/c21.txt b/8.x/mk/tests/ok/c21.txt
new file mode 100644 (file)
index 0000000..679055b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Join on compound key
+<<< done.
diff --git a/8.x/mk/tests/ok/c22.txt b/8.x/mk/tests/ok/c22.txt
new file mode 100644 (file)
index 0000000..1646d1a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Groupby with selection
+<<< done.
diff --git a/8.x/mk/tests/ok/d01.txt b/8.x/mk/tests/ok/d01.txt
new file mode 100644 (file)
index 0000000..46092d8
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Commit aside
+<<< done.
diff --git a/8.x/mk/tests/ok/d01a.txt b/8.x/mk/tests/ok/d01a.txt
new file mode 100644 (file)
index 0000000..fb8a3f1
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/d01b.txt b/8.x/mk/tests/ok/d01b.txt
new file mode 100644 (file)
index 0000000..1440d4e
--- /dev/null
@@ -0,0 +1,19 @@
+ VIEW     1 rows = _C:V
+    0: subview '_C'
+   VIEW     4 rows = _O:I _D:V
+      0: 8
+      0: subview '_D'
+     VIEW     1 rows = _K:I _R:I _B:B
+        0: 0 0 (4b)
+      1: 0
+      1: subview '_D'
+     VIEW     1 rows = _K:I _R:I _B:B
+        0: 0 0 (5b)
+      2: 0
+      2: subview '_D'
+     VIEW     1 rows = _K:I _R:I _B:B
+        0: 0 0 (13b)
+      3: 0
+      3: subview '_D'
+     VIEW     1 rows = _K:I _R:I _B:B
+        0: 0 0 (13b)
diff --git a/8.x/mk/tests/ok/e01.txt b/8.x/mk/tests/ok/e01.txt
new file mode 100644 (file)
index 0000000..665b936
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Extend new file
+<<< done.
diff --git a/8.x/mk/tests/ok/e01a.txt b/8.x/mk/tests/ok/e01a.txt
new file mode 100644 (file)
index 0000000..4f2b756
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = p1:I
+      0: 123
+      1: 456
diff --git a/8.x/mk/tests/ok/e02.txt b/8.x/mk/tests/ok/e02.txt
new file mode 100644 (file)
index 0000000..6dd7e4e
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Extend committing twice
+<<< done.
diff --git a/8.x/mk/tests/ok/e02a.txt b/8.x/mk/tests/ok/e02a.txt
new file mode 100644 (file)
index 0000000..4f2b756
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = p1:I
+      0: 123
+      1: 456
diff --git a/8.x/mk/tests/ok/e03.txt b/8.x/mk/tests/ok/e03.txt
new file mode 100644 (file)
index 0000000..8d58f90
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Read during extend
+<<< done.
diff --git a/8.x/mk/tests/ok/e03a.txt b/8.x/mk/tests/ok/e03a.txt
new file mode 100644 (file)
index 0000000..4f2b756
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = p1:I
+      0: 123
+      1: 456
diff --git a/8.x/mk/tests/ok/e04.txt b/8.x/mk/tests/ok/e04.txt
new file mode 100644 (file)
index 0000000..c5ab0c7
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Extend during read
+<<< done.
diff --git a/8.x/mk/tests/ok/e04a.txt b/8.x/mk/tests/ok/e04a.txt
new file mode 100644 (file)
index 0000000..2f613d7
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = p1:I
+      0: 123
+      1: 123
diff --git a/8.x/mk/tests/ok/e05.txt b/8.x/mk/tests/ok/e05.txt
new file mode 100644 (file)
index 0000000..9314db3
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Test memory mapping
+<<< done.
diff --git a/8.x/mk/tests/ok/e05a.txt b/8.x/mk/tests/ok/e05a.txt
new file mode 100644 (file)
index 0000000..a28a7ca
--- /dev/null
@@ -0,0 +1 @@
+ VIEW     1 rows =
diff --git a/8.x/mk/tests/ok/e06.txt b/8.x/mk/tests/ok/e06.txt
new file mode 100644 (file)
index 0000000..62dc321
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Rollback during extend
+<<< done.
diff --git a/8.x/mk/tests/ok/e06a.txt b/8.x/mk/tests/ok/e06a.txt
new file mode 100644 (file)
index 0000000..4f2b756
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = p1:I
+      0: 123
+      1: 456
diff --git a/8.x/mk/tests/ok/f01.txt b/8.x/mk/tests/ok/f01.txt
new file mode 100644 (file)
index 0000000..412c99b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Add view to format
+<<< done.
diff --git a/8.x/mk/tests/ok/f01a.txt b/8.x/mk/tests/ok/f01a.txt
new file mode 100755 (executable)
index 0000000..acb7611
--- /dev/null
@@ -0,0 +1,8 @@
+ VIEW     1 rows = a:V b:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
+    0: subview 'b'
+   VIEW     2 rows = p2:I
+      0: 345
+      1: 567
diff --git a/8.x/mk/tests/ok/f02.txt b/8.x/mk/tests/ok/f02.txt
new file mode 100644 (file)
index 0000000..8ed5930
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Remove view from format
+<<< done.
diff --git a/8.x/mk/tests/ok/f02a.txt b/8.x/mk/tests/ok/f02a.txt
new file mode 100755 (executable)
index 0000000..700609b
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = b:V
+    0: subview 'b'
+   VIEW     2 rows = p2:I
+      0: 345
+      1: 567
diff --git a/8.x/mk/tests/ok/f03.txt b/8.x/mk/tests/ok/f03.txt
new file mode 100644 (file)
index 0000000..461a5b7
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Rollback format change
+<<< done.
diff --git a/8.x/mk/tests/ok/f03a.txt b/8.x/mk/tests/ok/f03a.txt
new file mode 100755 (executable)
index 0000000..fb8a3f1
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/f04.txt b/8.x/mk/tests/ok/f04.txt
new file mode 100644 (file)
index 0000000..237a42f
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Rearrange format
+<<< done.
diff --git a/8.x/mk/tests/ok/f04a.txt b/8.x/mk/tests/ok/f04a.txt
new file mode 100755 (executable)
index 0000000..08b06c5
--- /dev/null
@@ -0,0 +1,8 @@
+ VIEW     1 rows = b:V a:V
+    0: subview 'b'
+   VIEW     2 rows = p2:I
+      0: 345
+      1: 567
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/f05.txt b/8.x/mk/tests/ok/f05.txt
new file mode 100644 (file)
index 0000000..f9fac02
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Nested reformat
+<<< done.
diff --git a/8.x/mk/tests/ok/f05a.txt b/8.x/mk/tests/ok/f05a.txt
new file mode 100755 (executable)
index 0000000..2f38918
--- /dev/null
@@ -0,0 +1,8 @@
+ VIEW     1 rows = a:V b:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
+    0: subview 'b'
+   VIEW     2 rows = p1:I p2:I
+      0: 543 345
+      1: 765 567
diff --git a/8.x/mk/tests/ok/f06.txt b/8.x/mk/tests/ok/f06.txt
new file mode 100644 (file)
index 0000000..039caeb
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Flip foreign data
+<<< done.
diff --git a/8.x/mk/tests/ok/f07.txt b/8.x/mk/tests/ok/f07.txt
new file mode 100644 (file)
index 0000000..bf52b37
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Automatic structure info (obsolete)
+<<< done.
diff --git a/8.x/mk/tests/ok/f07a.txt b/8.x/mk/tests/ok/f07a.txt
new file mode 100755 (executable)
index 0000000..79963d7
--- /dev/null
@@ -0,0 +1,3 @@
+ VIEW     1 rows = dict:V
+    0: subview 'dict'
+   VIEW     0 rows = parent:I index:I view:V
diff --git a/8.x/mk/tests/ok/f08.txt b/8.x/mk/tests/ok/f08.txt
new file mode 100644 (file)
index 0000000..d4e88f8
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Automatic storage format
+<<< done.
diff --git a/8.x/mk/tests/ok/f08a.txt b/8.x/mk/tests/ok/f08a.txt
new file mode 100755 (executable)
index 0000000..7a56c7f
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = dict:V
+    0: subview 'dict'
+   VIEW     3 rows = p1:S p2:S
+      0: 'One' 'Two'
+      1: '' ''
+      2: 'One' 'Two'
diff --git a/8.x/mk/tests/ok/f09.txt b/8.x/mk/tests/ok/f09.txt
new file mode 100644 (file)
index 0000000..d1040e7
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Partial restructuring
+<<< done.
diff --git a/8.x/mk/tests/ok/f09a.txt b/8.x/mk/tests/ok/f09a.txt
new file mode 100755 (executable)
index 0000000..c26f867
--- /dev/null
@@ -0,0 +1,13 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW    10 rows = p1:I p2:I p3:I
+      0: 1000 2000 3000
+      1: 1001 0 0
+      2: 1002 2002 0
+      3: 1003 0 3003
+      4: 1004 2004 0
+      5: 1005 0 0
+      6: 1006 2006 3006
+      7: 1007 0 0
+      8: 1008 2008 0
+      9: 1009 0 3009
diff --git a/8.x/mk/tests/ok/f10.txt b/8.x/mk/tests/ok/f10.txt
new file mode 100644 (file)
index 0000000..848dbdd
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Committed restructuring
+<<< done.
diff --git a/8.x/mk/tests/ok/f10a.txt b/8.x/mk/tests/ok/f10a.txt
new file mode 100755 (executable)
index 0000000..c26f867
--- /dev/null
@@ -0,0 +1,13 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW    10 rows = p1:I p2:I p3:I
+      0: 1000 2000 3000
+      1: 1001 0 0
+      2: 1002 2002 0
+      3: 1003 0 3003
+      4: 1004 2004 0
+      5: 1005 0 0
+      6: 1006 2006 3006
+      7: 1007 0 0
+      8: 1008 2008 0
+      9: 1009 0 3009
diff --git a/8.x/mk/tests/ok/f11.txt b/8.x/mk/tests/ok/f11.txt
new file mode 100755 (executable)
index 0000000..583ec58
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Delete missing view
+<<< done.
diff --git a/8.x/mk/tests/ok/f11a.txt b/8.x/mk/tests/ok/f11a.txt
new file mode 100755 (executable)
index 0000000..a28a7ca
--- /dev/null
@@ -0,0 +1 @@
+ VIEW     1 rows =
diff --git a/8.x/mk/tests/ok/l00.txt b/8.x/mk/tests/ok/l00.txt
new file mode 100644 (file)
index 0000000..b94a9a6
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Lots of properties
+<<< done.
diff --git a/8.x/mk/tests/ok/l00a.txt b/8.x/mk/tests/ok/l00a.txt
new file mode 100755 (executable)
index 0000000..bb0f5c6
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I p2:I p3:I p4:I p5:I p6:I p7:I p8:I p9:I p10:I p11:I p12:I p13:I p14:I p15:I p16:I p17:I p18:I p19:I p20:I p21:I p22:I p23:I p24:I p25:I p26:I p27:I p28:I p29:I p30:I p31:I p32:I p33:I p34:I p35:I p36:I p37:I p38:I p39:I p40:I p41:I p42:I p43:I p44:I p45:I p46:I p47:I p48:I p49:I p50:I p51:I p52:I p53:I p54:I p55:I p56:I p57:I p58:I p59:I p60:I p61:I p62:I p63:I p64:I p65:I p66:I p67:I p68:I p69:I p70:I p71:I p72:I p73:I p74:I p75:I p76:I p77:I p78:I p79:I p80:I p81:I p82:I p83:I p84:I p85:I p86:I p87:I p88:I p89:I p90:I p91:I p92:I p93:I p94:I p95:I p96:I p97:I p98:I p99:I p100:I p101:I p102:I p103:I p104:I p105:I p106:I p107:I p108:I p109:I p110:I p111:I p112:I p113:I p114:I p115:I p116:I p117:I p118:I p119:I p120:I p121:I p122:I p123:I p124:I p125:I p126:I p127:I p128:I p129:I p130:I p131:I p132:I p133:I p134:I p135:I p136:I p137:I p138:I p139:I p140:I p141:I p142:I p143:I p144:I p145:I p146:I p147:I p148:I p149:I
+      0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 123 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/8.x/mk/tests/ok/l01.txt b/8.x/mk/tests/ok/l01.txt
new file mode 100644 (file)
index 0000000..842c943
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Over 32 Kb of integers
+<<< done.
diff --git a/8.x/mk/tests/ok/l01a.txt b/8.x/mk/tests/ok/l01a.txt
new file mode 100755 (executable)
index 0000000..69cad24
--- /dev/null
@@ -0,0 +1,9003 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW  9000 rows = p1:I
+      0: 1000000
+      1: 1000001
+      2: 1000002
+      3: 1000003
+      4: 1000004
+      5: 1000005
+      6: 1000006
+      7: 1000007
+      8: 1000008
+      9: 1000009
+     10: 1000010
+     11: 1000011
+     12: 1000012
+     13: 1000013
+     14: 1000014
+     15: 1000015
+     16: 1000016
+     17: 1000017
+     18: 1000018
+     19: 1000019
+     20: 1000020
+     21: 1000021
+     22: 1000022
+     23: 1000023
+     24: 1000024
+     25: 1000025
+     26: 1000026
+     27: 1000027
+     28: 1000028
+     29: 1000029
+     30: 1000030
+     31: 1000031
+     32: 1000032
+     33: 1000033
+     34: 1000034
+     35: 1000035
+     36: 1000036
+     37: 1000037
+     38: 1000038
+     39: 1000039
+     40: 1000040
+     41: 1000041
+     42: 1000042
+     43: 1000043
+     44: 1000044
+     45: 1000045
+     46: 1000046
+     47: 1000047
+     48: 1000048
+     49: 1000049
+     50: 1000050
+     51: 1000051
+     52: 1000052
+     53: 1000053
+     54: 1000054
+     55: 1000055
+     56: 1000056
+     57: 1000057
+     58: 1000058
+     59: 1000059
+     60: 1000060
+     61: 1000061
+     62: 1000062
+     63: 1000063
+     64: 1000064
+     65: 1000065
+     66: 1000066
+     67: 1000067
+     68: 1000068
+     69: 1000069
+     70: 1000070
+     71: 1000071
+     72: 1000072
+     73: 1000073
+     74: 1000074
+     75: 1000075
+     76: 1000076
+     77: 1000077
+     78: 1000078
+     79: 1000079
+     80: 1000080
+     81: 1000081
+     82: 1000082
+     83: 1000083
+     84: 1000084
+     85: 1000085
+     86: 1000086
+     87: 1000087
+     88: 1000088
+     89: 1000089
+     90: 1000090
+     91: 1000091
+     92: 1000092
+     93: 1000093
+     94: 1000094
+     95: 1000095
+     96: 1000096
+     97: 1000097
+     98: 1000098
+     99: 1000099
+    100: 1000100
+    101: 1000101
+    102: 1000102
+    103: 1000103
+    104: 1000104
+    105: 1000105
+    106: 1000106
+    107: 1000107
+    108: 1000108
+    109: 1000109
+    110: 1000110
+    111: 1000111
+    112: 1000112
+    113: 1000113
+    114: 1000114
+    115: 1000115
+    116: 1000116
+    117: 1000117
+    118: 1000118
+    119: 1000119
+    120: 1000120
+    121: 1000121
+    122: 1000122
+    123: 1000123
+    124: 1000124
+    125: 1000125
+    126: 1000126
+    127: 1000127
+    128: 1000128
+    129: 1000129
+    130: 1000130
+    131: 1000131
+    132: 1000132
+    133: 1000133
+    134: 1000134
+    135: 1000135
+    136: 1000136
+    137: 1000137
+    138: 1000138
+    139: 1000139
+    140: 1000140
+    141: 1000141
+    142: 1000142
+    143: 1000143
+    144: 1000144
+    145: 1000145
+    146: 1000146
+    147: 1000147
+    148: 1000148
+    149: 1000149
+    150: 1000150
+    151: 1000151
+    152: 1000152
+    153: 1000153
+    154: 1000154
+    155: 1000155
+    156: 1000156
+    157: 1000157
+    158: 1000158
+    159: 1000159
+    160: 1000160
+    161: 1000161
+    162: 1000162
+    163: 1000163
+    164: 1000164
+    165: 1000165
+    166: 1000166
+    167: 1000167
+    168: 1000168
+    169: 1000169
+    170: 1000170
+    171: 1000171
+    172: 1000172
+    173: 1000173
+    174: 1000174
+    175: 1000175
+    176: 1000176
+    177: 1000177
+    178: 1000178
+    179: 1000179
+    180: 1000180
+    181: 1000181
+    182: 1000182
+    183: 1000183
+    184: 1000184
+    185: 1000185
+    186: 1000186
+    187: 1000187
+    188: 1000188
+    189: 1000189
+    190: 1000190
+    191: 1000191
+    192: 1000192
+    193: 1000193
+    194: 1000194
+    195: 1000195
+    196: 1000196
+    197: 1000197
+    198: 1000198
+    199: 1000199
+    200: 1000200
+    201: 1000201
+    202: 1000202
+    203: 1000203
+    204: 1000204
+    205: 1000205
+    206: 1000206
+    207: 1000207
+    208: 1000208
+    209: 1000209
+    210: 1000210
+    211: 1000211
+    212: 1000212
+    213: 1000213
+    214: 1000214
+    215: 1000215
+    216: 1000216
+    217: 1000217
+    218: 1000218
+    219: 1000219
+    220: 1000220
+    221: 1000221
+    222: 1000222
+    223: 1000223
+    224: 1000224
+    225: 1000225
+    226: 1000226
+    227: 1000227
+    228: 1000228
+    229: 1000229
+    230: 1000230
+    231: 1000231
+    232: 1000232
+    233: 1000233
+    234: 1000234
+    235: 1000235
+    236: 1000236
+    237: 1000237
+    238: 1000238
+    239: 1000239
+    240: 1000240
+    241: 1000241
+    242: 1000242
+    243: 1000243
+    244: 1000244
+    245: 1000245
+    246: 1000246
+    247: 1000247
+    248: 1000248
+    249: 1000249
+    250: 1000250
+    251: 1000251
+    252: 1000252
+    253: 1000253
+    254: 1000254
+    255: 1000255
+    256: 1000256
+    257: 1000257
+    258: 1000258
+    259: 1000259
+    260: 1000260
+    261: 1000261
+    262: 1000262
+    263: 1000263
+    264: 1000264
+    265: 1000265
+    266: 1000266
+    267: 1000267
+    268: 1000268
+    269: 1000269
+    270: 1000270
+    271: 1000271
+    272: 1000272
+    273: 1000273
+    274: 1000274
+    275: 1000275
+    276: 1000276
+    277: 1000277
+    278: 1000278
+    279: 1000279
+    280: 1000280
+    281: 1000281
+    282: 1000282
+    283: 1000283
+    284: 1000284
+    285: 1000285
+    286: 1000286
+    287: 1000287
+    288: 1000288
+    289: 1000289
+    290: 1000290
+    291: 1000291
+    292: 1000292
+    293: 1000293
+    294: 1000294
+    295: 1000295
+    296: 1000296
+    297: 1000297
+    298: 1000298
+    299: 1000299
+    300: 1000300
+    301: 1000301
+    302: 1000302
+    303: 1000303
+    304: 1000304
+    305: 1000305
+    306: 1000306
+    307: 1000307
+    308: 1000308
+    309: 1000309
+    310: 1000310
+    311: 1000311
+    312: 1000312
+    313: 1000313
+    314: 1000314
+    315: 1000315
+    316: 1000316
+    317: 1000317
+    318: 1000318
+    319: 1000319
+    320: 1000320
+    321: 1000321
+    322: 1000322
+    323: 1000323
+    324: 1000324
+    325: 1000325
+    326: 1000326
+    327: 1000327
+    328: 1000328
+    329: 1000329
+    330: 1000330
+    331: 1000331
+    332: 1000332
+    333: 1000333
+    334: 1000334
+    335: 1000335
+    336: 1000336
+    337: 1000337
+    338: 1000338
+    339: 1000339
+    340: 1000340
+    341: 1000341
+    342: 1000342
+    343: 1000343
+    344: 1000344
+    345: 1000345
+    346: 1000346
+    347: 1000347
+    348: 1000348
+    349: 1000349
+    350: 1000350
+    351: 1000351
+    352: 1000352
+    353: 1000353
+    354: 1000354
+    355: 1000355
+    356: 1000356
+    357: 1000357
+    358: 1000358
+    359: 1000359
+    360: 1000360
+    361: 1000361
+    362: 1000362
+    363: 1000363
+    364: 1000364
+    365: 1000365
+    366: 1000366
+    367: 1000367
+    368: 1000368
+    369: 1000369
+    370: 1000370
+    371: 1000371
+    372: 1000372
+    373: 1000373
+    374: 1000374
+    375: 1000375
+    376: 1000376
+    377: 1000377
+    378: 1000378
+    379: 1000379
+    380: 1000380
+    381: 1000381
+    382: 1000382
+    383: 1000383
+    384: 1000384
+    385: 1000385
+    386: 1000386
+    387: 1000387
+    388: 1000388
+    389: 1000389
+    390: 1000390
+    391: 1000391
+    392: 1000392
+    393: 1000393
+    394: 1000394
+    395: 1000395
+    396: 1000396
+    397: 1000397
+    398: 1000398
+    399: 1000399
+    400: 1000400
+    401: 1000401
+    402: 1000402
+    403: 1000403
+    404: 1000404
+    405: 1000405
+    406: 1000406
+    407: 1000407
+    408: 1000408
+    409: 1000409
+    410: 1000410
+    411: 1000411
+    412: 1000412
+    413: 1000413
+    414: 1000414
+    415: 1000415
+    416: 1000416
+    417: 1000417
+    418: 1000418
+    419: 1000419
+    420: 1000420
+    421: 1000421
+    422: 1000422
+    423: 1000423
+    424: 1000424
+    425: 1000425
+    426: 1000426
+    427: 1000427
+    428: 1000428
+    429: 1000429
+    430: 1000430
+    431: 1000431
+    432: 1000432
+    433: 1000433
+    434: 1000434
+    435: 1000435
+    436: 1000436
+    437: 1000437
+    438: 1000438
+    439: 1000439
+    440: 1000440
+    441: 1000441
+    442: 1000442
+    443: 1000443
+    444: 1000444
+    445: 1000445
+    446: 1000446
+    447: 1000447
+    448: 1000448
+    449: 1000449
+    450: 1000450
+    451: 1000451
+    452: 1000452
+    453: 1000453
+    454: 1000454
+    455: 1000455
+    456: 1000456
+    457: 1000457
+    458: 1000458
+    459: 1000459
+    460: 1000460
+    461: 1000461
+    462: 1000462
+    463: 1000463
+    464: 1000464
+    465: 1000465
+    466: 1000466
+    467: 1000467
+    468: 1000468
+    469: 1000469
+    470: 1000470
+    471: 1000471
+    472: 1000472
+    473: 1000473
+    474: 1000474
+    475: 1000475
+    476: 1000476
+    477: 1000477
+    478: 1000478
+    479: 1000479
+    480: 1000480
+    481: 1000481
+    482: 1000482
+    483: 1000483
+    484: 1000484
+    485: 1000485
+    486: 1000486
+    487: 1000487
+    488: 1000488
+    489: 1000489
+    490: 1000490
+    491: 1000491
+    492: 1000492
+    493: 1000493
+    494: 1000494
+    495: 1000495
+    496: 1000496
+    497: 1000497
+    498: 1000498
+    499: 1000499
+    500: 1000500
+    501: 1000501
+    502: 1000502
+    503: 1000503
+    504: 1000504
+    505: 1000505
+    506: 1000506
+    507: 1000507
+    508: 1000508
+    509: 1000509
+    510: 1000510
+    511: 1000511
+    512: 1000512
+    513: 1000513
+    514: 1000514
+    515: 1000515
+    516: 1000516
+    517: 1000517
+    518: 1000518
+    519: 1000519
+    520: 1000520
+    521: 1000521
+    522: 1000522
+    523: 1000523
+    524: 1000524
+    525: 1000525
+    526: 1000526
+    527: 1000527
+    528: 1000528
+    529: 1000529
+    530: 1000530
+    531: 1000531
+    532: 1000532
+    533: 1000533
+    534: 1000534
+    535: 1000535
+    536: 1000536
+    537: 1000537
+    538: 1000538
+    539: 1000539
+    540: 1000540
+    541: 1000541
+    542: 1000542
+    543: 1000543
+    544: 1000544
+    545: 1000545
+    546: 1000546
+    547: 1000547
+    548: 1000548
+    549: 1000549
+    550: 1000550
+    551: 1000551
+    552: 1000552
+    553: 1000553
+    554: 1000554
+    555: 1000555
+    556: 1000556
+    557: 1000557
+    558: 1000558
+    559: 1000559
+    560: 1000560
+    561: 1000561
+    562: 1000562
+    563: 1000563
+    564: 1000564
+    565: 1000565
+    566: 1000566
+    567: 1000567
+    568: 1000568
+    569: 1000569
+    570: 1000570
+    571: 1000571
+    572: 1000572
+    573: 1000573
+    574: 1000574
+    575: 1000575
+    576: 1000576
+    577: 1000577
+    578: 1000578
+    579: 1000579
+    580: 1000580
+    581: 1000581
+    582: 1000582
+    583: 1000583
+    584: 1000584
+    585: 1000585
+    586: 1000586
+    587: 1000587
+    588: 1000588
+    589: 1000589
+    590: 1000590
+    591: 1000591
+    592: 1000592
+    593: 1000593
+    594: 1000594
+    595: 1000595
+    596: 1000596
+    597: 1000597
+    598: 1000598
+    599: 1000599
+    600: 1000600
+    601: 1000601
+    602: 1000602
+    603: 1000603
+    604: 1000604
+    605: 1000605
+    606: 1000606
+    607: 1000607
+    608: 1000608
+    609: 1000609
+    610: 1000610
+    611: 1000611
+    612: 1000612
+    613: 1000613
+    614: 1000614
+    615: 1000615
+    616: 1000616
+    617: 1000617
+    618: 1000618
+    619: 1000619
+    620: 1000620
+    621: 1000621
+    622: 1000622
+    623: 1000623
+    624: 1000624
+    625: 1000625
+    626: 1000626
+    627: 1000627
+    628: 1000628
+    629: 1000629
+    630: 1000630
+    631: 1000631
+    632: 1000632
+    633: 1000633
+    634: 1000634
+    635: 1000635
+    636: 1000636
+    637: 1000637
+    638: 1000638
+    639: 1000639
+    640: 1000640
+    641: 1000641
+    642: 1000642
+    643: 1000643
+    644: 1000644
+    645: 1000645
+    646: 1000646
+    647: 1000647
+    648: 1000648
+    649: 1000649
+    650: 1000650
+    651: 1000651
+    652: 1000652
+    653: 1000653
+    654: 1000654
+    655: 1000655
+    656: 1000656
+    657: 1000657
+    658: 1000658
+    659: 1000659
+    660: 1000660
+    661: 1000661
+    662: 1000662
+    663: 1000663
+    664: 1000664
+    665: 1000665
+    666: 1000666
+    667: 1000667
+    668: 1000668
+    669: 1000669
+    670: 1000670
+    671: 1000671
+    672: 1000672
+    673: 1000673
+    674: 1000674
+    675: 1000675
+    676: 1000676
+    677: 1000677
+    678: 1000678
+    679: 1000679
+    680: 1000680
+    681: 1000681
+    682: 1000682
+    683: 1000683
+    684: 1000684
+    685: 1000685
+    686: 1000686
+    687: 1000687
+    688: 1000688
+    689: 1000689
+    690: 1000690
+    691: 1000691
+    692: 1000692
+    693: 1000693
+    694: 1000694
+    695: 1000695
+    696: 1000696
+    697: 1000697
+    698: 1000698
+    699: 1000699
+    700: 1000700
+    701: 1000701
+    702: 1000702
+    703: 1000703
+    704: 1000704
+    705: 1000705
+    706: 1000706
+    707: 1000707
+    708: 1000708
+    709: 1000709
+    710: 1000710
+    711: 1000711
+    712: 1000712
+    713: 1000713
+    714: 1000714
+    715: 1000715
+    716: 1000716
+    717: 1000717
+    718: 1000718
+    719: 1000719
+    720: 1000720
+    721: 1000721
+    722: 1000722
+    723: 1000723
+    724: 1000724
+    725: 1000725
+    726: 1000726
+    727: 1000727
+    728: 1000728
+    729: 1000729
+    730: 1000730
+    731: 1000731
+    732: 1000732
+    733: 1000733
+    734: 1000734
+    735: 1000735
+    736: 1000736
+    737: 1000737
+    738: 1000738
+    739: 1000739
+    740: 1000740
+    741: 1000741
+    742: 1000742
+    743: 1000743
+    744: 1000744
+    745: 1000745
+    746: 1000746
+    747: 1000747
+    748: 1000748
+    749: 1000749
+    750: 1000750
+    751: 1000751
+    752: 1000752
+    753: 1000753
+    754: 1000754
+    755: 1000755
+    756: 1000756
+    757: 1000757
+    758: 1000758
+    759: 1000759
+    760: 1000760
+    761: 1000761
+    762: 1000762
+    763: 1000763
+    764: 1000764
+    765: 1000765
+    766: 1000766
+    767: 1000767
+    768: 1000768
+    769: 1000769
+    770: 1000770
+    771: 1000771
+    772: 1000772
+    773: 1000773
+    774: 1000774
+    775: 1000775
+    776: 1000776
+    777: 1000777
+    778: 1000778
+    779: 1000779
+    780: 1000780
+    781: 1000781
+    782: 1000782
+    783: 1000783
+    784: 1000784
+    785: 1000785
+    786: 1000786
+    787: 1000787
+    788: 1000788
+    789: 1000789
+    790: 1000790
+    791: 1000791
+    792: 1000792
+    793: 1000793
+    794: 1000794
+    795: 1000795
+    796: 1000796
+    797: 1000797
+    798: 1000798
+    799: 1000799
+    800: 1000800
+    801: 1000801
+    802: 1000802
+    803: 1000803
+    804: 1000804
+    805: 1000805
+    806: 1000806
+    807: 1000807
+    808: 1000808
+    809: 1000809
+    810: 1000810
+    811: 1000811
+    812: 1000812
+    813: 1000813
+    814: 1000814
+    815: 1000815
+    816: 1000816
+    817: 1000817
+    818: 1000818
+    819: 1000819
+    820: 1000820
+    821: 1000821
+    822: 1000822
+    823: 1000823
+    824: 1000824
+    825: 1000825
+    826: 1000826
+    827: 1000827
+    828: 1000828
+    829: 1000829
+    830: 1000830
+    831: 1000831
+    832: 1000832
+    833: 1000833
+    834: 1000834
+    835: 1000835
+    836: 1000836
+    837: 1000837
+    838: 1000838
+    839: 1000839
+    840: 1000840
+    841: 1000841
+    842: 1000842
+    843: 1000843
+    844: 1000844
+    845: 1000845
+    846: 1000846
+    847: 1000847
+    848: 1000848
+    849: 1000849
+    850: 1000850
+    851: 1000851
+    852: 1000852
+    853: 1000853
+    854: 1000854
+    855: 1000855
+    856: 1000856
+    857: 1000857
+    858: 1000858
+    859: 1000859
+    860: 1000860
+    861: 1000861
+    862: 1000862
+    863: 1000863
+    864: 1000864
+    865: 1000865
+    866: 1000866
+    867: 1000867
+    868: 1000868
+    869: 1000869
+    870: 1000870
+    871: 1000871
+    872: 1000872
+    873: 1000873
+    874: 1000874
+    875: 1000875
+    876: 1000876
+    877: 1000877
+    878: 1000878
+    879: 1000879
+    880: 1000880
+    881: 1000881
+    882: 1000882
+    883: 1000883
+    884: 1000884
+    885: 1000885
+    886: 1000886
+    887: 1000887
+    888: 1000888
+    889: 1000889
+    890: 1000890
+    891: 1000891
+    892: 1000892
+    893: 1000893
+    894: 1000894
+    895: 1000895
+    896: 1000896
+    897: 1000897
+    898: 1000898
+    899: 1000899
+    900: 1000900
+    901: 1000901
+    902: 1000902
+    903: 1000903
+    904: 1000904
+    905: 1000905
+    906: 1000906
+    907: 1000907
+    908: 1000908
+    909: 1000909
+    910: 1000910
+    911: 1000911
+    912: 1000912
+    913: 1000913
+    914: 1000914
+    915: 1000915
+    916: 1000916
+    917: 1000917
+    918: 1000918
+    919: 1000919
+    920: 1000920
+    921: 1000921
+    922: 1000922
+    923: 1000923
+    924: 1000924
+    925: 1000925
+    926: 1000926
+    927: 1000927
+    928: 1000928
+    929: 1000929
+    930: 1000930
+    931: 1000931
+    932: 1000932
+    933: 1000933
+    934: 1000934
+    935: 1000935
+    936: 1000936
+    937: 1000937
+    938: 1000938
+    939: 1000939
+    940: 1000940
+    941: 1000941
+    942: 1000942
+    943: 1000943
+    944: 1000944
+    945: 1000945
+    946: 1000946
+    947: 1000947
+    948: 1000948
+    949: 1000949
+    950: 1000950
+    951: 1000951
+    952: 1000952
+    953: 1000953
+    954: 1000954
+    955: 1000955
+    956: 1000956
+    957: 1000957
+    958: 1000958
+    959: 1000959
+    960: 1000960
+    961: 1000961
+    962: 1000962
+    963: 1000963
+    964: 1000964
+    965: 1000965
+    966: 1000966
+    967: 1000967
+    968: 1000968
+    969: 1000969
+    970: 1000970
+    971: 1000971
+    972: 1000972
+    973: 1000973
+    974: 1000974
+    975: 1000975
+    976: 1000976
+    977: 1000977
+    978: 1000978
+    979: 1000979
+    980: 1000980
+    981: 1000981
+    982: 1000982
+    983: 1000983
+    984: 1000984
+    985: 1000985
+    986: 1000986
+    987: 1000987
+    988: 1000988
+    989: 1000989
+    990: 1000990
+    991: 1000991
+    992: 1000992
+    993: 1000993
+    994: 1000994
+    995: 1000995
+    996: 1000996
+    997: 1000997
+    998: 1000998
+    999: 1000999
+   1000: 1001000
+   1001: 1001001
+   1002: 1001002
+   1003: 1001003
+   1004: 1001004
+   1005: 1001005
+   1006: 1001006
+   1007: 1001007
+   1008: 1001008
+   1009: 1001009
+   1010: 1001010
+   1011: 1001011
+   1012: 1001012
+   1013: 1001013
+   1014: 1001014
+   1015: 1001015
+   1016: 1001016
+   1017: 1001017
+   1018: 1001018
+   1019: 1001019
+   1020: 1001020
+   1021: 1001021
+   1022: 1001022
+   1023: 1001023
+   1024: 1001024
+   1025: 1001025
+   1026: 1001026
+   1027: 1001027
+   1028: 1001028
+   1029: 1001029
+   1030: 1001030
+   1031: 1001031
+   1032: 1001032
+   1033: 1001033
+   1034: 1001034
+   1035: 1001035
+   1036: 1001036
+   1037: 1001037
+   1038: 1001038
+   1039: 1001039
+   1040: 1001040
+   1041: 1001041
+   1042: 1001042
+   1043: 1001043
+   1044: 1001044
+   1045: 1001045
+   1046: 1001046
+   1047: 1001047
+   1048: 1001048
+   1049: 1001049
+   1050: 1001050
+   1051: 1001051
+   1052: 1001052
+   1053: 1001053
+   1054: 1001054
+   1055: 1001055
+   1056: 1001056
+   1057: 1001057
+   1058: 1001058
+   1059: 1001059
+   1060: 1001060
+   1061: 1001061
+   1062: 1001062
+   1063: 1001063
+   1064: 1001064
+   1065: 1001065
+   1066: 1001066
+   1067: 1001067
+   1068: 1001068
+   1069: 1001069
+   1070: 1001070
+   1071: 1001071
+   1072: 1001072
+   1073: 1001073
+   1074: 1001074
+   1075: 1001075
+   1076: 1001076
+   1077: 1001077
+   1078: 1001078
+   1079: 1001079
+   1080: 1001080
+   1081: 1001081
+   1082: 1001082
+   1083: 1001083
+   1084: 1001084
+   1085: 1001085
+   1086: 1001086
+   1087: 1001087
+   1088: 1001088
+   1089: 1001089
+   1090: 1001090
+   1091: 1001091
+   1092: 1001092
+   1093: 1001093
+   1094: 1001094
+   1095: 1001095
+   1096: 1001096
+   1097: 1001097
+   1098: 1001098
+   1099: 1001099
+   1100: 1001100
+   1101: 1001101
+   1102: 1001102
+   1103: 1001103
+   1104: 1001104
+   1105: 1001105
+   1106: 1001106
+   1107: 1001107
+   1108: 1001108
+   1109: 1001109
+   1110: 1001110
+   1111: 1001111
+   1112: 1001112
+   1113: 1001113
+   1114: 1001114
+   1115: 1001115
+   1116: 1001116
+   1117: 1001117
+   1118: 1001118
+   1119: 1001119
+   1120: 1001120
+   1121: 1001121
+   1122: 1001122
+   1123: 1001123
+   1124: 1001124
+   1125: 1001125
+   1126: 1001126
+   1127: 1001127
+   1128: 1001128
+   1129: 1001129
+   1130: 1001130
+   1131: 1001131
+   1132: 1001132
+   1133: 1001133
+   1134: 1001134
+   1135: 1001135
+   1136: 1001136
+   1137: 1001137
+   1138: 1001138
+   1139: 1001139
+   1140: 1001140
+   1141: 1001141
+   1142: 1001142
+   1143: 1001143
+   1144: 1001144
+   1145: 1001145
+   1146: 1001146
+   1147: 1001147
+   1148: 1001148
+   1149: 1001149
+   1150: 1001150
+   1151: 1001151
+   1152: 1001152
+   1153: 1001153
+   1154: 1001154
+   1155: 1001155
+   1156: 1001156
+   1157: 1001157
+   1158: 1001158
+   1159: 1001159
+   1160: 1001160
+   1161: 1001161
+   1162: 1001162
+   1163: 1001163
+   1164: 1001164
+   1165: 1001165
+   1166: 1001166
+   1167: 1001167
+   1168: 1001168
+   1169: 1001169
+   1170: 1001170
+   1171: 1001171
+   1172: 1001172
+   1173: 1001173
+   1174: 1001174
+   1175: 1001175
+   1176: 1001176
+   1177: 1001177
+   1178: 1001178
+   1179: 1001179
+   1180: 1001180
+   1181: 1001181
+   1182: 1001182
+   1183: 1001183
+   1184: 1001184
+   1185: 1001185
+   1186: 1001186
+   1187: 1001187
+   1188: 1001188
+   1189: 1001189
+   1190: 1001190
+   1191: 1001191
+   1192: 1001192
+   1193: 1001193
+   1194: 1001194
+   1195: 1001195
+   1196: 1001196
+   1197: 1001197
+   1198: 1001198
+   1199: 1001199
+   1200: 1001200
+   1201: 1001201
+   1202: 1001202
+   1203: 1001203
+   1204: 1001204
+   1205: 1001205
+   1206: 1001206
+   1207: 1001207
+   1208: 1001208
+   1209: 1001209
+   1210: 1001210
+   1211: 1001211
+   1212: 1001212
+   1213: 1001213
+   1214: 1001214
+   1215: 1001215
+   1216: 1001216
+   1217: 1001217
+   1218: 1001218
+   1219: 1001219
+   1220: 1001220
+   1221: 1001221
+   1222: 1001222
+   1223: 1001223
+   1224: 1001224
+   1225: 1001225
+   1226: 1001226
+   1227: 1001227
+   1228: 1001228
+   1229: 1001229
+   1230: 1001230
+   1231: 1001231
+   1232: 1001232
+   1233: 1001233
+   1234: 1001234
+   1235: 1001235
+   1236: 1001236
+   1237: 1001237
+   1238: 1001238
+   1239: 1001239
+   1240: 1001240
+   1241: 1001241
+   1242: 1001242
+   1243: 1001243
+   1244: 1001244
+   1245: 1001245
+   1246: 1001246
+   1247: 1001247
+   1248: 1001248
+   1249: 1001249
+   1250: 1001250
+   1251: 1001251
+   1252: 1001252
+   1253: 1001253
+   1254: 1001254
+   1255: 1001255
+   1256: 1001256
+   1257: 1001257
+   1258: 1001258
+   1259: 1001259
+   1260: 1001260
+   1261: 1001261
+   1262: 1001262
+   1263: 1001263
+   1264: 1001264
+   1265: 1001265
+   1266: 1001266
+   1267: 1001267
+   1268: 1001268
+   1269: 1001269
+   1270: 1001270
+   1271: 1001271
+   1272: 1001272
+   1273: 1001273
+   1274: 1001274
+   1275: 1001275
+   1276: 1001276
+   1277: 1001277
+   1278: 1001278
+   1279: 1001279
+   1280: 1001280
+   1281: 1001281
+   1282: 1001282
+   1283: 1001283
+   1284: 1001284
+   1285: 1001285
+   1286: 1001286
+   1287: 1001287
+   1288: 1001288
+   1289: 1001289
+   1290: 1001290
+   1291: 1001291
+   1292: 1001292
+   1293: 1001293
+   1294: 1001294
+   1295: 1001295
+   1296: 1001296
+   1297: 1001297
+   1298: 1001298
+   1299: 1001299
+   1300: 1001300
+   1301: 1001301
+   1302: 1001302
+   1303: 1001303
+   1304: 1001304
+   1305: 1001305
+   1306: 1001306
+   1307: 1001307
+   1308: 1001308
+   1309: 1001309
+   1310: 1001310
+   1311: 1001311
+   1312: 1001312
+   1313: 1001313
+   1314: 1001314
+   1315: 1001315
+   1316: 1001316
+   1317: 1001317
+   1318: 1001318
+   1319: 1001319
+   1320: 1001320
+   1321: 1001321
+   1322: 1001322
+   1323: 1001323
+   1324: 1001324
+   1325: 1001325
+   1326: 1001326
+   1327: 1001327
+   1328: 1001328
+   1329: 1001329
+   1330: 1001330
+   1331: 1001331
+   1332: 1001332
+   1333: 1001333
+   1334: 1001334
+   1335: 1001335
+   1336: 1001336
+   1337: 1001337
+   1338: 1001338
+   1339: 1001339
+   1340: 1001340
+   1341: 1001341
+   1342: 1001342
+   1343: 1001343
+   1344: 1001344
+   1345: 1001345
+   1346: 1001346
+   1347: 1001347
+   1348: 1001348
+   1349: 1001349
+   1350: 1001350
+   1351: 1001351
+   1352: 1001352
+   1353: 1001353
+   1354: 1001354
+   1355: 1001355
+   1356: 1001356
+   1357: 1001357
+   1358: 1001358
+   1359: 1001359
+   1360: 1001360
+   1361: 1001361
+   1362: 1001362
+   1363: 1001363
+   1364: 1001364
+   1365: 1001365
+   1366: 1001366
+   1367: 1001367
+   1368: 1001368
+   1369: 1001369
+   1370: 1001370
+   1371: 1001371
+   1372: 1001372
+   1373: 1001373
+   1374: 1001374
+   1375: 1001375
+   1376: 1001376
+   1377: 1001377
+   1378: 1001378
+   1379: 1001379
+   1380: 1001380
+   1381: 1001381
+   1382: 1001382
+   1383: 1001383
+   1384: 1001384
+   1385: 1001385
+   1386: 1001386
+   1387: 1001387
+   1388: 1001388
+   1389: 1001389
+   1390: 1001390
+   1391: 1001391
+   1392: 1001392
+   1393: 1001393
+   1394: 1001394
+   1395: 1001395
+   1396: 1001396
+   1397: 1001397
+   1398: 1001398
+   1399: 1001399
+   1400: 1001400
+   1401: 1001401
+   1402: 1001402
+   1403: 1001403
+   1404: 1001404
+   1405: 1001405
+   1406: 1001406
+   1407: 1001407
+   1408: 1001408
+   1409: 1001409
+   1410: 1001410
+   1411: 1001411
+   1412: 1001412
+   1413: 1001413
+   1414: 1001414
+   1415: 1001415
+   1416: 1001416
+   1417: 1001417
+   1418: 1001418
+   1419: 1001419
+   1420: 1001420
+   1421: 1001421
+   1422: 1001422
+   1423: 1001423
+   1424: 1001424
+   1425: 1001425
+   1426: 1001426
+   1427: 1001427
+   1428: 1001428
+   1429: 1001429
+   1430: 1001430
+   1431: 1001431
+   1432: 1001432
+   1433: 1001433
+   1434: 1001434
+   1435: 1001435
+   1436: 1001436
+   1437: 1001437
+   1438: 1001438
+   1439: 1001439
+   1440: 1001440
+   1441: 1001441
+   1442: 1001442
+   1443: 1001443
+   1444: 1001444
+   1445: 1001445
+   1446: 1001446
+   1447: 1001447
+   1448: 1001448
+   1449: 1001449
+   1450: 1001450
+   1451: 1001451
+   1452: 1001452
+   1453: 1001453
+   1454: 1001454
+   1455: 1001455
+   1456: 1001456
+   1457: 1001457
+   1458: 1001458
+   1459: 1001459
+   1460: 1001460
+   1461: 1001461
+   1462: 1001462
+   1463: 1001463
+   1464: 1001464
+   1465: 1001465
+   1466: 1001466
+   1467: 1001467
+   1468: 1001468
+   1469: 1001469
+   1470: 1001470
+   1471: 1001471
+   1472: 1001472
+   1473: 1001473
+   1474: 1001474
+   1475: 1001475
+   1476: 1001476
+   1477: 1001477
+   1478: 1001478
+   1479: 1001479
+   1480: 1001480
+   1481: 1001481
+   1482: 1001482
+   1483: 1001483
+   1484: 1001484
+   1485: 1001485
+   1486: 1001486
+   1487: 1001487
+   1488: 1001488
+   1489: 1001489
+   1490: 1001490
+   1491: 1001491
+   1492: 1001492
+   1493: 1001493
+   1494: 1001494
+   1495: 1001495
+   1496: 1001496
+   1497: 1001497
+   1498: 1001498
+   1499: 1001499
+   1500: 1001500
+   1501: 1001501
+   1502: 1001502
+   1503: 1001503
+   1504: 1001504
+   1505: 1001505
+   1506: 1001506
+   1507: 1001507
+   1508: 1001508
+   1509: 1001509
+   1510: 1001510
+   1511: 1001511
+   1512: 1001512
+   1513: 1001513
+   1514: 1001514
+   1515: 1001515
+   1516: 1001516
+   1517: 1001517
+   1518: 1001518
+   1519: 1001519
+   1520: 1001520
+   1521: 1001521
+   1522: 1001522
+   1523: 1001523
+   1524: 1001524
+   1525: 1001525
+   1526: 1001526
+   1527: 1001527
+   1528: 1001528
+   1529: 1001529
+   1530: 1001530
+   1531: 1001531
+   1532: 1001532
+   1533: 1001533
+   1534: 1001534
+   1535: 1001535
+   1536: 1001536
+   1537: 1001537
+   1538: 1001538
+   1539: 1001539
+   1540: 1001540
+   1541: 1001541
+   1542: 1001542
+   1543: 1001543
+   1544: 1001544
+   1545: 1001545
+   1546: 1001546
+   1547: 1001547
+   1548: 1001548
+   1549: 1001549
+   1550: 1001550
+   1551: 1001551
+   1552: 1001552
+   1553: 1001553
+   1554: 1001554
+   1555: 1001555
+   1556: 1001556
+   1557: 1001557
+   1558: 1001558
+   1559: 1001559
+   1560: 1001560
+   1561: 1001561
+   1562: 1001562
+   1563: 1001563
+   1564: 1001564
+   1565: 1001565
+   1566: 1001566
+   1567: 1001567
+   1568: 1001568
+   1569: 1001569
+   1570: 1001570
+   1571: 1001571
+   1572: 1001572
+   1573: 1001573
+   1574: 1001574
+   1575: 1001575
+   1576: 1001576
+   1577: 1001577
+   1578: 1001578
+   1579: 1001579
+   1580: 1001580
+   1581: 1001581
+   1582: 1001582
+   1583: 1001583
+   1584: 1001584
+   1585: 1001585
+   1586: 1001586
+   1587: 1001587
+   1588: 1001588
+   1589: 1001589
+   1590: 1001590
+   1591: 1001591
+   1592: 1001592
+   1593: 1001593
+   1594: 1001594
+   1595: 1001595
+   1596: 1001596
+   1597: 1001597
+   1598: 1001598
+   1599: 1001599
+   1600: 1001600
+   1601: 1001601
+   1602: 1001602
+   1603: 1001603
+   1604: 1001604
+   1605: 1001605
+   1606: 1001606
+   1607: 1001607
+   1608: 1001608
+   1609: 1001609
+   1610: 1001610
+   1611: 1001611
+   1612: 1001612
+   1613: 1001613
+   1614: 1001614
+   1615: 1001615
+   1616: 1001616
+   1617: 1001617
+   1618: 1001618
+   1619: 1001619
+   1620: 1001620
+   1621: 1001621
+   1622: 1001622
+   1623: 1001623
+   1624: 1001624
+   1625: 1001625
+   1626: 1001626
+   1627: 1001627
+   1628: 1001628
+   1629: 1001629
+   1630: 1001630
+   1631: 1001631
+   1632: 1001632
+   1633: 1001633
+   1634: 1001634
+   1635: 1001635
+   1636: 1001636
+   1637: 1001637
+   1638: 1001638
+   1639: 1001639
+   1640: 1001640
+   1641: 1001641
+   1642: 1001642
+   1643: 1001643
+   1644: 1001644
+   1645: 1001645
+   1646: 1001646
+   1647: 1001647
+   1648: 1001648
+   1649: 1001649
+   1650: 1001650
+   1651: 1001651
+   1652: 1001652
+   1653: 1001653
+   1654: 1001654
+   1655: 1001655
+   1656: 1001656
+   1657: 1001657
+   1658: 1001658
+   1659: 1001659
+   1660: 1001660
+   1661: 1001661
+   1662: 1001662
+   1663: 1001663
+   1664: 1001664
+   1665: 1001665
+   1666: 1001666
+   1667: 1001667
+   1668: 1001668
+   1669: 1001669
+   1670: 1001670
+   1671: 1001671
+   1672: 1001672
+   1673: 1001673
+   1674: 1001674
+   1675: 1001675
+   1676: 1001676
+   1677: 1001677
+   1678: 1001678
+   1679: 1001679
+   1680: 1001680
+   1681: 1001681
+   1682: 1001682
+   1683: 1001683
+   1684: 1001684
+   1685: 1001685
+   1686: 1001686
+   1687: 1001687
+   1688: 1001688
+   1689: 1001689
+   1690: 1001690
+   1691: 1001691
+   1692: 1001692
+   1693: 1001693
+   1694: 1001694
+   1695: 1001695
+   1696: 1001696
+   1697: 1001697
+   1698: 1001698
+   1699: 1001699
+   1700: 1001700
+   1701: 1001701
+   1702: 1001702
+   1703: 1001703
+   1704: 1001704
+   1705: 1001705
+   1706: 1001706
+   1707: 1001707
+   1708: 1001708
+   1709: 1001709
+   1710: 1001710
+   1711: 1001711
+   1712: 1001712
+   1713: 1001713
+   1714: 1001714
+   1715: 1001715
+   1716: 1001716
+   1717: 1001717
+   1718: 1001718
+   1719: 1001719
+   1720: 1001720
+   1721: 1001721
+   1722: 1001722
+   1723: 1001723
+   1724: 1001724
+   1725: 1001725
+   1726: 1001726
+   1727: 1001727
+   1728: 1001728
+   1729: 1001729
+   1730: 1001730
+   1731: 1001731
+   1732: 1001732
+   1733: 1001733
+   1734: 1001734
+   1735: 1001735
+   1736: 1001736
+   1737: 1001737
+   1738: 1001738
+   1739: 1001739
+   1740: 1001740
+   1741: 1001741
+   1742: 1001742
+   1743: 1001743
+   1744: 1001744
+   1745: 1001745
+   1746: 1001746
+   1747: 1001747
+   1748: 1001748
+   1749: 1001749
+   1750: 1001750
+   1751: 1001751
+   1752: 1001752
+   1753: 1001753
+   1754: 1001754
+   1755: 1001755
+   1756: 1001756
+   1757: 1001757
+   1758: 1001758
+   1759: 1001759
+   1760: 1001760
+   1761: 1001761
+   1762: 1001762
+   1763: 1001763
+   1764: 1001764
+   1765: 1001765
+   1766: 1001766
+   1767: 1001767
+   1768: 1001768
+   1769: 1001769
+   1770: 1001770
+   1771: 1001771
+   1772: 1001772
+   1773: 1001773
+   1774: 1001774
+   1775: 1001775
+   1776: 1001776
+   1777: 1001777
+   1778: 1001778
+   1779: 1001779
+   1780: 1001780
+   1781: 1001781
+   1782: 1001782
+   1783: 1001783
+   1784: 1001784
+   1785: 1001785
+   1786: 1001786
+   1787: 1001787
+   1788: 1001788
+   1789: 1001789
+   1790: 1001790
+   1791: 1001791
+   1792: 1001792
+   1793: 1001793
+   1794: 1001794
+   1795: 1001795
+   1796: 1001796
+   1797: 1001797
+   1798: 1001798
+   1799: 1001799
+   1800: 1001800
+   1801: 1001801
+   1802: 1001802
+   1803: 1001803
+   1804: 1001804
+   1805: 1001805
+   1806: 1001806
+   1807: 1001807
+   1808: 1001808
+   1809: 1001809
+   1810: 1001810
+   1811: 1001811
+   1812: 1001812
+   1813: 1001813
+   1814: 1001814
+   1815: 1001815
+   1816: 1001816
+   1817: 1001817
+   1818: 1001818
+   1819: 1001819
+   1820: 1001820
+   1821: 1001821
+   1822: 1001822
+   1823: 1001823
+   1824: 1001824
+   1825: 1001825
+   1826: 1001826
+   1827: 1001827
+   1828: 1001828
+   1829: 1001829
+   1830: 1001830
+   1831: 1001831
+   1832: 1001832
+   1833: 1001833
+   1834: 1001834
+   1835: 1001835
+   1836: 1001836
+   1837: 1001837
+   1838: 1001838
+   1839: 1001839
+   1840: 1001840
+   1841: 1001841
+   1842: 1001842
+   1843: 1001843
+   1844: 1001844
+   1845: 1001845
+   1846: 1001846
+   1847: 1001847
+   1848: 1001848
+   1849: 1001849
+   1850: 1001850
+   1851: 1001851
+   1852: 1001852
+   1853: 1001853
+   1854: 1001854
+   1855: 1001855
+   1856: 1001856
+   1857: 1001857
+   1858: 1001858
+   1859: 1001859
+   1860: 1001860
+   1861: 1001861
+   1862: 1001862
+   1863: 1001863
+   1864: 1001864
+   1865: 1001865
+   1866: 1001866
+   1867: 1001867
+   1868: 1001868
+   1869: 1001869
+   1870: 1001870
+   1871: 1001871
+   1872: 1001872
+   1873: 1001873
+   1874: 1001874
+   1875: 1001875
+   1876: 1001876
+   1877: 1001877
+   1878: 1001878
+   1879: 1001879
+   1880: 1001880
+   1881: 1001881
+   1882: 1001882
+   1883: 1001883
+   1884: 1001884
+   1885: 1001885
+   1886: 1001886
+   1887: 1001887
+   1888: 1001888
+   1889: 1001889
+   1890: 1001890
+   1891: 1001891
+   1892: 1001892
+   1893: 1001893
+   1894: 1001894
+   1895: 1001895
+   1896: 1001896
+   1897: 1001897
+   1898: 1001898
+   1899: 1001899
+   1900: 1001900
+   1901: 1001901
+   1902: 1001902
+   1903: 1001903
+   1904: 1001904
+   1905: 1001905
+   1906: 1001906
+   1907: 1001907
+   1908: 1001908
+   1909: 1001909
+   1910: 1001910
+   1911: 1001911
+   1912: 1001912
+   1913: 1001913
+   1914: 1001914
+   1915: 1001915
+   1916: 1001916
+   1917: 1001917
+   1918: 1001918
+   1919: 1001919
+   1920: 1001920
+   1921: 1001921
+   1922: 1001922
+   1923: 1001923
+   1924: 1001924
+   1925: 1001925
+   1926: 1001926
+   1927: 1001927
+   1928: 1001928
+   1929: 1001929
+   1930: 1001930
+   1931: 1001931
+   1932: 1001932
+   1933: 1001933
+   1934: 1001934
+   1935: 1001935
+   1936: 1001936
+   1937: 1001937
+   1938: 1001938
+   1939: 1001939
+   1940: 1001940
+   1941: 1001941
+   1942: 1001942
+   1943: 1001943
+   1944: 1001944
+   1945: 1001945
+   1946: 1001946
+   1947: 1001947
+   1948: 1001948
+   1949: 1001949
+   1950: 1001950
+   1951: 1001951
+   1952: 1001952
+   1953: 1001953
+   1954: 1001954
+   1955: 1001955
+   1956: 1001956
+   1957: 1001957
+   1958: 1001958
+   1959: 1001959
+   1960: 1001960
+   1961: 1001961
+   1962: 1001962
+   1963: 1001963
+   1964: 1001964
+   1965: 1001965
+   1966: 1001966
+   1967: 1001967
+   1968: 1001968
+   1969: 1001969
+   1970: 1001970
+   1971: 1001971
+   1972: 1001972
+   1973: 1001973
+   1974: 1001974
+   1975: 1001975
+   1976: 1001976
+   1977: 1001977
+   1978: 1001978
+   1979: 1001979
+   1980: 1001980
+   1981: 1001981
+   1982: 1001982
+   1983: 1001983
+   1984: 1001984
+   1985: 1001985
+   1986: 1001986
+   1987: 1001987
+   1988: 1001988
+   1989: 1001989
+   1990: 1001990
+   1991: 1001991
+   1992: 1001992
+   1993: 1001993
+   1994: 1001994
+   1995: 1001995
+   1996: 1001996
+   1997: 1001997
+   1998: 1001998
+   1999: 1001999
+   2000: 1002000
+   2001: 1002001
+   2002: 1002002
+   2003: 1002003
+   2004: 1002004
+   2005: 1002005
+   2006: 1002006
+   2007: 1002007
+   2008: 1002008
+   2009: 1002009
+   2010: 1002010
+   2011: 1002011
+   2012: 1002012
+   2013: 1002013
+   2014: 1002014
+   2015: 1002015
+   2016: 1002016
+   2017: 1002017
+   2018: 1002018
+   2019: 1002019
+   2020: 1002020
+   2021: 1002021
+   2022: 1002022
+   2023: 1002023
+   2024: 1002024
+   2025: 1002025
+   2026: 1002026
+   2027: 1002027
+   2028: 1002028
+   2029: 1002029
+   2030: 1002030
+   2031: 1002031
+   2032: 1002032
+   2033: 1002033
+   2034: 1002034
+   2035: 1002035
+   2036: 1002036
+   2037: 1002037
+   2038: 1002038
+   2039: 1002039
+   2040: 1002040
+   2041: 1002041
+   2042: 1002042
+   2043: 1002043
+   2044: 1002044
+   2045: 1002045
+   2046: 1002046
+   2047: 1002047
+   2048: 1002048
+   2049: 1002049
+   2050: 1002050
+   2051: 1002051
+   2052: 1002052
+   2053: 1002053
+   2054: 1002054
+   2055: 1002055
+   2056: 1002056
+   2057: 1002057
+   2058: 1002058
+   2059: 1002059
+   2060: 1002060
+   2061: 1002061
+   2062: 1002062
+   2063: 1002063
+   2064: 1002064
+   2065: 1002065
+   2066: 1002066
+   2067: 1002067
+   2068: 1002068
+   2069: 1002069
+   2070: 1002070
+   2071: 1002071
+   2072: 1002072
+   2073: 1002073
+   2074: 1002074
+   2075: 1002075
+   2076: 1002076
+   2077: 1002077
+   2078: 1002078
+   2079: 1002079
+   2080: 1002080
+   2081: 1002081
+   2082: 1002082
+   2083: 1002083
+   2084: 1002084
+   2085: 1002085
+   2086: 1002086
+   2087: 1002087
+   2088: 1002088
+   2089: 1002089
+   2090: 1002090
+   2091: 1002091
+   2092: 1002092
+   2093: 1002093
+   2094: 1002094
+   2095: 1002095
+   2096: 1002096
+   2097: 1002097
+   2098: 1002098
+   2099: 1002099
+   2100: 1002100
+   2101: 1002101
+   2102: 1002102
+   2103: 1002103
+   2104: 1002104
+   2105: 1002105
+   2106: 1002106
+   2107: 1002107
+   2108: 1002108
+   2109: 1002109
+   2110: 1002110
+   2111: 1002111
+   2112: 1002112
+   2113: 1002113
+   2114: 1002114
+   2115: 1002115
+   2116: 1002116
+   2117: 1002117
+   2118: 1002118
+   2119: 1002119
+   2120: 1002120
+   2121: 1002121
+   2122: 1002122
+   2123: 1002123
+   2124: 1002124
+   2125: 1002125
+   2126: 1002126
+   2127: 1002127
+   2128: 1002128
+   2129: 1002129
+   2130: 1002130
+   2131: 1002131
+   2132: 1002132
+   2133: 1002133
+   2134: 1002134
+   2135: 1002135
+   2136: 1002136
+   2137: 1002137
+   2138: 1002138
+   2139: 1002139
+   2140: 1002140
+   2141: 1002141
+   2142: 1002142
+   2143: 1002143
+   2144: 1002144
+   2145: 1002145
+   2146: 1002146
+   2147: 1002147
+   2148: 1002148
+   2149: 1002149
+   2150: 1002150
+   2151: 1002151
+   2152: 1002152
+   2153: 1002153
+   2154: 1002154
+   2155: 1002155
+   2156: 1002156
+   2157: 1002157
+   2158: 1002158
+   2159: 1002159
+   2160: 1002160
+   2161: 1002161
+   2162: 1002162
+   2163: 1002163
+   2164: 1002164
+   2165: 1002165
+   2166: 1002166
+   2167: 1002167
+   2168: 1002168
+   2169: 1002169
+   2170: 1002170
+   2171: 1002171
+   2172: 1002172
+   2173: 1002173
+   2174: 1002174
+   2175: 1002175
+   2176: 1002176
+   2177: 1002177
+   2178: 1002178
+   2179: 1002179
+   2180: 1002180
+   2181: 1002181
+   2182: 1002182
+   2183: 1002183
+   2184: 1002184
+   2185: 1002185
+   2186: 1002186
+   2187: 1002187
+   2188: 1002188
+   2189: 1002189
+   2190: 1002190
+   2191: 1002191
+   2192: 1002192
+   2193: 1002193
+   2194: 1002194
+   2195: 1002195
+   2196: 1002196
+   2197: 1002197
+   2198: 1002198
+   2199: 1002199
+   2200: 1002200
+   2201: 1002201
+   2202: 1002202
+   2203: 1002203
+   2204: 1002204
+   2205: 1002205
+   2206: 1002206
+   2207: 1002207
+   2208: 1002208
+   2209: 1002209
+   2210: 1002210
+   2211: 1002211
+   2212: 1002212
+   2213: 1002213
+   2214: 1002214
+   2215: 1002215
+   2216: 1002216
+   2217: 1002217
+   2218: 1002218
+   2219: 1002219
+   2220: 1002220
+   2221: 1002221
+   2222: 1002222
+   2223: 1002223
+   2224: 1002224
+   2225: 1002225
+   2226: 1002226
+   2227: 1002227
+   2228: 1002228
+   2229: 1002229
+   2230: 1002230
+   2231: 1002231
+   2232: 1002232
+   2233: 1002233
+   2234: 1002234
+   2235: 1002235
+   2236: 1002236
+   2237: 1002237
+   2238: 1002238
+   2239: 1002239
+   2240: 1002240
+   2241: 1002241
+   2242: 1002242
+   2243: 1002243
+   2244: 1002244
+   2245: 1002245
+   2246: 1002246
+   2247: 1002247
+   2248: 1002248
+   2249: 1002249
+   2250: 1002250
+   2251: 1002251
+   2252: 1002252
+   2253: 1002253
+   2254: 1002254
+   2255: 1002255
+   2256: 1002256
+   2257: 1002257
+   2258: 1002258
+   2259: 1002259
+   2260: 1002260
+   2261: 1002261
+   2262: 1002262
+   2263: 1002263
+   2264: 1002264
+   2265: 1002265
+   2266: 1002266
+   2267: 1002267
+   2268: 1002268
+   2269: 1002269
+   2270: 1002270
+   2271: 1002271
+   2272: 1002272
+   2273: 1002273
+   2274: 1002274
+   2275: 1002275
+   2276: 1002276
+   2277: 1002277
+   2278: 1002278
+   2279: 1002279
+   2280: 1002280
+   2281: 1002281
+   2282: 1002282
+   2283: 1002283
+   2284: 1002284
+   2285: 1002285
+   2286: 1002286
+   2287: 1002287
+   2288: 1002288
+   2289: 1002289
+   2290: 1002290
+   2291: 1002291
+   2292: 1002292
+   2293: 1002293
+   2294: 1002294
+   2295: 1002295
+   2296: 1002296
+   2297: 1002297
+   2298: 1002298
+   2299: 1002299
+   2300: 1002300
+   2301: 1002301
+   2302: 1002302
+   2303: 1002303
+   2304: 1002304
+   2305: 1002305
+   2306: 1002306
+   2307: 1002307
+   2308: 1002308
+   2309: 1002309
+   2310: 1002310
+   2311: 1002311
+   2312: 1002312
+   2313: 1002313
+   2314: 1002314
+   2315: 1002315
+   2316: 1002316
+   2317: 1002317
+   2318: 1002318
+   2319: 1002319
+   2320: 1002320
+   2321: 1002321
+   2322: 1002322
+   2323: 1002323
+   2324: 1002324
+   2325: 1002325
+   2326: 1002326
+   2327: 1002327
+   2328: 1002328
+   2329: 1002329
+   2330: 1002330
+   2331: 1002331
+   2332: 1002332
+   2333: 1002333
+   2334: 1002334
+   2335: 1002335
+   2336: 1002336
+   2337: 1002337
+   2338: 1002338
+   2339: 1002339
+   2340: 1002340
+   2341: 1002341
+   2342: 1002342
+   2343: 1002343
+   2344: 1002344
+   2345: 1002345
+   2346: 1002346
+   2347: 1002347
+   2348: 1002348
+   2349: 1002349
+   2350: 1002350
+   2351: 1002351
+   2352: 1002352
+   2353: 1002353
+   2354: 1002354
+   2355: 1002355
+   2356: 1002356
+   2357: 1002357
+   2358: 1002358
+   2359: 1002359
+   2360: 1002360
+   2361: 1002361
+   2362: 1002362
+   2363: 1002363
+   2364: 1002364
+   2365: 1002365
+   2366: 1002366
+   2367: 1002367
+   2368: 1002368
+   2369: 1002369
+   2370: 1002370
+   2371: 1002371
+   2372: 1002372
+   2373: 1002373
+   2374: 1002374
+   2375: 1002375
+   2376: 1002376
+   2377: 1002377
+   2378: 1002378
+   2379: 1002379
+   2380: 1002380
+   2381: 1002381
+   2382: 1002382
+   2383: 1002383
+   2384: 1002384
+   2385: 1002385
+   2386: 1002386
+   2387: 1002387
+   2388: 1002388
+   2389: 1002389
+   2390: 1002390
+   2391: 1002391
+   2392: 1002392
+   2393: 1002393
+   2394: 1002394
+   2395: 1002395
+   2396: 1002396
+   2397: 1002397
+   2398: 1002398
+   2399: 1002399
+   2400: 1002400
+   2401: 1002401
+   2402: 1002402
+   2403: 1002403
+   2404: 1002404
+   2405: 1002405
+   2406: 1002406
+   2407: 1002407
+   2408: 1002408
+   2409: 1002409
+   2410: 1002410
+   2411: 1002411
+   2412: 1002412
+   2413: 1002413
+   2414: 1002414
+   2415: 1002415
+   2416: 1002416
+   2417: 1002417
+   2418: 1002418
+   2419: 1002419
+   2420: 1002420
+   2421: 1002421
+   2422: 1002422
+   2423: 1002423
+   2424: 1002424
+   2425: 1002425
+   2426: 1002426
+   2427: 1002427
+   2428: 1002428
+   2429: 1002429
+   2430: 1002430
+   2431: 1002431
+   2432: 1002432
+   2433: 1002433
+   2434: 1002434
+   2435: 1002435
+   2436: 1002436
+   2437: 1002437
+   2438: 1002438
+   2439: 1002439
+   2440: 1002440
+   2441: 1002441
+   2442: 1002442
+   2443: 1002443
+   2444: 1002444
+   2445: 1002445
+   2446: 1002446
+   2447: 1002447
+   2448: 1002448
+   2449: 1002449
+   2450: 1002450
+   2451: 1002451
+   2452: 1002452
+   2453: 1002453
+   2454: 1002454
+   2455: 1002455
+   2456: 1002456
+   2457: 1002457
+   2458: 1002458
+   2459: 1002459
+   2460: 1002460
+   2461: 1002461
+   2462: 1002462
+   2463: 1002463
+   2464: 1002464
+   2465: 1002465
+   2466: 1002466
+   2467: 1002467
+   2468: 1002468
+   2469: 1002469
+   2470: 1002470
+   2471: 1002471
+   2472: 1002472
+   2473: 1002473
+   2474: 1002474
+   2475: 1002475
+   2476: 1002476
+   2477: 1002477
+   2478: 1002478
+   2479: 1002479
+   2480: 1002480
+   2481: 1002481
+   2482: 1002482
+   2483: 1002483
+   2484: 1002484
+   2485: 1002485
+   2486: 1002486
+   2487: 1002487
+   2488: 1002488
+   2489: 1002489
+   2490: 1002490
+   2491: 1002491
+   2492: 1002492
+   2493: 1002493
+   2494: 1002494
+   2495: 1002495
+   2496: 1002496
+   2497: 1002497
+   2498: 1002498
+   2499: 1002499
+   2500: 1002500
+   2501: 1002501
+   2502: 1002502
+   2503: 1002503
+   2504: 1002504
+   2505: 1002505
+   2506: 1002506
+   2507: 1002507
+   2508: 1002508
+   2509: 1002509
+   2510: 1002510
+   2511: 1002511
+   2512: 1002512
+   2513: 1002513
+   2514: 1002514
+   2515: 1002515
+   2516: 1002516
+   2517: 1002517
+   2518: 1002518
+   2519: 1002519
+   2520: 1002520
+   2521: 1002521
+   2522: 1002522
+   2523: 1002523
+   2524: 1002524
+   2525: 1002525
+   2526: 1002526
+   2527: 1002527
+   2528: 1002528
+   2529: 1002529
+   2530: 1002530
+   2531: 1002531
+   2532: 1002532
+   2533: 1002533
+   2534: 1002534
+   2535: 1002535
+   2536: 1002536
+   2537: 1002537
+   2538: 1002538
+   2539: 1002539
+   2540: 1002540
+   2541: 1002541
+   2542: 1002542
+   2543: 1002543
+   2544: 1002544
+   2545: 1002545
+   2546: 1002546
+   2547: 1002547
+   2548: 1002548
+   2549: 1002549
+   2550: 1002550
+   2551: 1002551
+   2552: 1002552
+   2553: 1002553
+   2554: 1002554
+   2555: 1002555
+   2556: 1002556
+   2557: 1002557
+   2558: 1002558
+   2559: 1002559
+   2560: 1002560
+   2561: 1002561
+   2562: 1002562
+   2563: 1002563
+   2564: 1002564
+   2565: 1002565
+   2566: 1002566
+   2567: 1002567
+   2568: 1002568
+   2569: 1002569
+   2570: 1002570
+   2571: 1002571
+   2572: 1002572
+   2573: 1002573
+   2574: 1002574
+   2575: 1002575
+   2576: 1002576
+   2577: 1002577
+   2578: 1002578
+   2579: 1002579
+   2580: 1002580
+   2581: 1002581
+   2582: 1002582
+   2583: 1002583
+   2584: 1002584
+   2585: 1002585
+   2586: 1002586
+   2587: 1002587
+   2588: 1002588
+   2589: 1002589
+   2590: 1002590
+   2591: 1002591
+   2592: 1002592
+   2593: 1002593
+   2594: 1002594
+   2595: 1002595
+   2596: 1002596
+   2597: 1002597
+   2598: 1002598
+   2599: 1002599
+   2600: 1002600
+   2601: 1002601
+   2602: 1002602
+   2603: 1002603
+   2604: 1002604
+   2605: 1002605
+   2606: 1002606
+   2607: 1002607
+   2608: 1002608
+   2609: 1002609
+   2610: 1002610
+   2611: 1002611
+   2612: 1002612
+   2613: 1002613
+   2614: 1002614
+   2615: 1002615
+   2616: 1002616
+   2617: 1002617
+   2618: 1002618
+   2619: 1002619
+   2620: 1002620
+   2621: 1002621
+   2622: 1002622
+   2623: 1002623
+   2624: 1002624
+   2625: 1002625
+   2626: 1002626
+   2627: 1002627
+   2628: 1002628
+   2629: 1002629
+   2630: 1002630
+   2631: 1002631
+   2632: 1002632
+   2633: 1002633
+   2634: 1002634
+   2635: 1002635
+   2636: 1002636
+   2637: 1002637
+   2638: 1002638
+   2639: 1002639
+   2640: 1002640
+   2641: 1002641
+   2642: 1002642
+   2643: 1002643
+   2644: 1002644
+   2645: 1002645
+   2646: 1002646
+   2647: 1002647
+   2648: 1002648
+   2649: 1002649
+   2650: 1002650
+   2651: 1002651
+   2652: 1002652
+   2653: 1002653
+   2654: 1002654
+   2655: 1002655
+   2656: 1002656
+   2657: 1002657
+   2658: 1002658
+   2659: 1002659
+   2660: 1002660
+   2661: 1002661
+   2662: 1002662
+   2663: 1002663
+   2664: 1002664
+   2665: 1002665
+   2666: 1002666
+   2667: 1002667
+   2668: 1002668
+   2669: 1002669
+   2670: 1002670
+   2671: 1002671
+   2672: 1002672
+   2673: 1002673
+   2674: 1002674
+   2675: 1002675
+   2676: 1002676
+   2677: 1002677
+   2678: 1002678
+   2679: 1002679
+   2680: 1002680
+   2681: 1002681
+   2682: 1002682
+   2683: 1002683
+   2684: 1002684
+   2685: 1002685
+   2686: 1002686
+   2687: 1002687
+   2688: 1002688
+   2689: 1002689
+   2690: 1002690
+   2691: 1002691
+   2692: 1002692
+   2693: 1002693
+   2694: 1002694
+   2695: 1002695
+   2696: 1002696
+   2697: 1002697
+   2698: 1002698
+   2699: 1002699
+   2700: 1002700
+   2701: 1002701
+   2702: 1002702
+   2703: 1002703
+   2704: 1002704
+   2705: 1002705
+   2706: 1002706
+   2707: 1002707
+   2708: 1002708
+   2709: 1002709
+   2710: 1002710
+   2711: 1002711
+   2712: 1002712
+   2713: 1002713
+   2714: 1002714
+   2715: 1002715
+   2716: 1002716
+   2717: 1002717
+   2718: 1002718
+   2719: 1002719
+   2720: 1002720
+   2721: 1002721
+   2722: 1002722
+   2723: 1002723
+   2724: 1002724
+   2725: 1002725
+   2726: 1002726
+   2727: 1002727
+   2728: 1002728
+   2729: 1002729
+   2730: 1002730
+   2731: 1002731
+   2732: 1002732
+   2733: 1002733
+   2734: 1002734
+   2735: 1002735
+   2736: 1002736
+   2737: 1002737
+   2738: 1002738
+   2739: 1002739
+   2740: 1002740
+   2741: 1002741
+   2742: 1002742
+   2743: 1002743
+   2744: 1002744
+   2745: 1002745
+   2746: 1002746
+   2747: 1002747
+   2748: 1002748
+   2749: 1002749
+   2750: 1002750
+   2751: 1002751
+   2752: 1002752
+   2753: 1002753
+   2754: 1002754
+   2755: 1002755
+   2756: 1002756
+   2757: 1002757
+   2758: 1002758
+   2759: 1002759
+   2760: 1002760
+   2761: 1002761
+   2762: 1002762
+   2763: 1002763
+   2764: 1002764
+   2765: 1002765
+   2766: 1002766
+   2767: 1002767
+   2768: 1002768
+   2769: 1002769
+   2770: 1002770
+   2771: 1002771
+   2772: 1002772
+   2773: 1002773
+   2774: 1002774
+   2775: 1002775
+   2776: 1002776
+   2777: 1002777
+   2778: 1002778
+   2779: 1002779
+   2780: 1002780
+   2781: 1002781
+   2782: 1002782
+   2783: 1002783
+   2784: 1002784
+   2785: 1002785
+   2786: 1002786
+   2787: 1002787
+   2788: 1002788
+   2789: 1002789
+   2790: 1002790
+   2791: 1002791
+   2792: 1002792
+   2793: 1002793
+   2794: 1002794
+   2795: 1002795
+   2796: 1002796
+   2797: 1002797
+   2798: 1002798
+   2799: 1002799
+   2800: 1002800
+   2801: 1002801
+   2802: 1002802
+   2803: 1002803
+   2804: 1002804
+   2805: 1002805
+   2806: 1002806
+   2807: 1002807
+   2808: 1002808
+   2809: 1002809
+   2810: 1002810
+   2811: 1002811
+   2812: 1002812
+   2813: 1002813
+   2814: 1002814
+   2815: 1002815
+   2816: 1002816
+   2817: 1002817
+   2818: 1002818
+   2819: 1002819
+   2820: 1002820
+   2821: 1002821
+   2822: 1002822
+   2823: 1002823
+   2824: 1002824
+   2825: 1002825
+   2826: 1002826
+   2827: 1002827
+   2828: 1002828
+   2829: 1002829
+   2830: 1002830
+   2831: 1002831
+   2832: 1002832
+   2833: 1002833
+   2834: 1002834
+   2835: 1002835
+   2836: 1002836
+   2837: 1002837
+   2838: 1002838
+   2839: 1002839
+   2840: 1002840
+   2841: 1002841
+   2842: 1002842
+   2843: 1002843
+   2844: 1002844
+   2845: 1002845
+   2846: 1002846
+   2847: 1002847
+   2848: 1002848
+   2849: 1002849
+   2850: 1002850
+   2851: 1002851
+   2852: 1002852
+   2853: 1002853
+   2854: 1002854
+   2855: 1002855
+   2856: 1002856
+   2857: 1002857
+   2858: 1002858
+   2859: 1002859
+   2860: 1002860
+   2861: 1002861
+   2862: 1002862
+   2863: 1002863
+   2864: 1002864
+   2865: 1002865
+   2866: 1002866
+   2867: 1002867
+   2868: 1002868
+   2869: 1002869
+   2870: 1002870
+   2871: 1002871
+   2872: 1002872
+   2873: 1002873
+   2874: 1002874
+   2875: 1002875
+   2876: 1002876
+   2877: 1002877
+   2878: 1002878
+   2879: 1002879
+   2880: 1002880
+   2881: 1002881
+   2882: 1002882
+   2883: 1002883
+   2884: 1002884
+   2885: 1002885
+   2886: 1002886
+   2887: 1002887
+   2888: 1002888
+   2889: 1002889
+   2890: 1002890
+   2891: 1002891
+   2892: 1002892
+   2893: 1002893
+   2894: 1002894
+   2895: 1002895
+   2896: 1002896
+   2897: 1002897
+   2898: 1002898
+   2899: 1002899
+   2900: 1002900
+   2901: 1002901
+   2902: 1002902
+   2903: 1002903
+   2904: 1002904
+   2905: 1002905
+   2906: 1002906
+   2907: 1002907
+   2908: 1002908
+   2909: 1002909
+   2910: 1002910
+   2911: 1002911
+   2912: 1002912
+   2913: 1002913
+   2914: 1002914
+   2915: 1002915
+   2916: 1002916
+   2917: 1002917
+   2918: 1002918
+   2919: 1002919
+   2920: 1002920
+   2921: 1002921
+   2922: 1002922
+   2923: 1002923
+   2924: 1002924
+   2925: 1002925
+   2926: 1002926
+   2927: 1002927
+   2928: 1002928
+   2929: 1002929
+   2930: 1002930
+   2931: 1002931
+   2932: 1002932
+   2933: 1002933
+   2934: 1002934
+   2935: 1002935
+   2936: 1002936
+   2937: 1002937
+   2938: 1002938
+   2939: 1002939
+   2940: 1002940
+   2941: 1002941
+   2942: 1002942
+   2943: 1002943
+   2944: 1002944
+   2945: 1002945
+   2946: 1002946
+   2947: 1002947
+   2948: 1002948
+   2949: 1002949
+   2950: 1002950
+   2951: 1002951
+   2952: 1002952
+   2953: 1002953
+   2954: 1002954
+   2955: 1002955
+   2956: 1002956
+   2957: 1002957
+   2958: 1002958
+   2959: 1002959
+   2960: 1002960
+   2961: 1002961
+   2962: 1002962
+   2963: 1002963
+   2964: 1002964
+   2965: 1002965
+   2966: 1002966
+   2967: 1002967
+   2968: 1002968
+   2969: 1002969
+   2970: 1002970
+   2971: 1002971
+   2972: 1002972
+   2973: 1002973
+   2974: 1002974
+   2975: 1002975
+   2976: 1002976
+   2977: 1002977
+   2978: 1002978
+   2979: 1002979
+   2980: 1002980
+   2981: 1002981
+   2982: 1002982
+   2983: 1002983
+   2984: 1002984
+   2985: 1002985
+   2986: 1002986
+   2987: 1002987
+   2988: 1002988
+   2989: 1002989
+   2990: 1002990
+   2991: 1002991
+   2992: 1002992
+   2993: 1002993
+   2994: 1002994
+   2995: 1002995
+   2996: 1002996
+   2997: 1002997
+   2998: 1002998
+   2999: 1002999
+   3000: 1003000
+   3001: 1003001
+   3002: 1003002
+   3003: 1003003
+   3004: 1003004
+   3005: 1003005
+   3006: 1003006
+   3007: 1003007
+   3008: 1003008
+   3009: 1003009
+   3010: 1003010
+   3011: 1003011
+   3012: 1003012
+   3013: 1003013
+   3014: 1003014
+   3015: 1003015
+   3016: 1003016
+   3017: 1003017
+   3018: 1003018
+   3019: 1003019
+   3020: 1003020
+   3021: 1003021
+   3022: 1003022
+   3023: 1003023
+   3024: 1003024
+   3025: 1003025
+   3026: 1003026
+   3027: 1003027
+   3028: 1003028
+   3029: 1003029
+   3030: 1003030
+   3031: 1003031
+   3032: 1003032
+   3033: 1003033
+   3034: 1003034
+   3035: 1003035
+   3036: 1003036
+   3037: 1003037
+   3038: 1003038
+   3039: 1003039
+   3040: 1003040
+   3041: 1003041
+   3042: 1003042
+   3043: 1003043
+   3044: 1003044
+   3045: 1003045
+   3046: 1003046
+   3047: 1003047
+   3048: 1003048
+   3049: 1003049
+   3050: 1003050
+   3051: 1003051
+   3052: 1003052
+   3053: 1003053
+   3054: 1003054
+   3055: 1003055
+   3056: 1003056
+   3057: 1003057
+   3058: 1003058
+   3059: 1003059
+   3060: 1003060
+   3061: 1003061
+   3062: 1003062
+   3063: 1003063
+   3064: 1003064
+   3065: 1003065
+   3066: 1003066
+   3067: 1003067
+   3068: 1003068
+   3069: 1003069
+   3070: 1003070
+   3071: 1003071
+   3072: 1003072
+   3073: 1003073
+   3074: 1003074
+   3075: 1003075
+   3076: 1003076
+   3077: 1003077
+   3078: 1003078
+   3079: 1003079
+   3080: 1003080
+   3081: 1003081
+   3082: 1003082
+   3083: 1003083
+   3084: 1003084
+   3085: 1003085
+   3086: 1003086
+   3087: 1003087
+   3088: 1003088
+   3089: 1003089
+   3090: 1003090
+   3091: 1003091
+   3092: 1003092
+   3093: 1003093
+   3094: 1003094
+   3095: 1003095
+   3096: 1003096
+   3097: 1003097
+   3098: 1003098
+   3099: 1003099
+   3100: 1003100
+   3101: 1003101
+   3102: 1003102
+   3103: 1003103
+   3104: 1003104
+   3105: 1003105
+   3106: 1003106
+   3107: 1003107
+   3108: 1003108
+   3109: 1003109
+   3110: 1003110
+   3111: 1003111
+   3112: 1003112
+   3113: 1003113
+   3114: 1003114
+   3115: 1003115
+   3116: 1003116
+   3117: 1003117
+   3118: 1003118
+   3119: 1003119
+   3120: 1003120
+   3121: 1003121
+   3122: 1003122
+   3123: 1003123
+   3124: 1003124
+   3125: 1003125
+   3126: 1003126
+   3127: 1003127
+   3128: 1003128
+   3129: 1003129
+   3130: 1003130
+   3131: 1003131
+   3132: 1003132
+   3133: 1003133
+   3134: 1003134
+   3135: 1003135
+   3136: 1003136
+   3137: 1003137
+   3138: 1003138
+   3139: 1003139
+   3140: 1003140
+   3141: 1003141
+   3142: 1003142
+   3143: 1003143
+   3144: 1003144
+   3145: 1003145
+   3146: 1003146
+   3147: 1003147
+   3148: 1003148
+   3149: 1003149
+   3150: 1003150
+   3151: 1003151
+   3152: 1003152
+   3153: 1003153
+   3154: 1003154
+   3155: 1003155
+   3156: 1003156
+   3157: 1003157
+   3158: 1003158
+   3159: 1003159
+   3160: 1003160
+   3161: 1003161
+   3162: 1003162
+   3163: 1003163
+   3164: 1003164
+   3165: 1003165
+   3166: 1003166
+   3167: 1003167
+   3168: 1003168
+   3169: 1003169
+   3170: 1003170
+   3171: 1003171
+   3172: 1003172
+   3173: 1003173
+   3174: 1003174
+   3175: 1003175
+   3176: 1003176
+   3177: 1003177
+   3178: 1003178
+   3179: 1003179
+   3180: 1003180
+   3181: 1003181
+   3182: 1003182
+   3183: 1003183
+   3184: 1003184
+   3185: 1003185
+   3186: 1003186
+   3187: 1003187
+   3188: 1003188
+   3189: 1003189
+   3190: 1003190
+   3191: 1003191
+   3192: 1003192
+   3193: 1003193
+   3194: 1003194
+   3195: 1003195
+   3196: 1003196
+   3197: 1003197
+   3198: 1003198
+   3199: 1003199
+   3200: 1003200
+   3201: 1003201
+   3202: 1003202
+   3203: 1003203
+   3204: 1003204
+   3205: 1003205
+   3206: 1003206
+   3207: 1003207
+   3208: 1003208
+   3209: 1003209
+   3210: 1003210
+   3211: 1003211
+   3212: 1003212
+   3213: 1003213
+   3214: 1003214
+   3215: 1003215
+   3216: 1003216
+   3217: 1003217
+   3218: 1003218
+   3219: 1003219
+   3220: 1003220
+   3221: 1003221
+   3222: 1003222
+   3223: 1003223
+   3224: 1003224
+   3225: 1003225
+   3226: 1003226
+   3227: 1003227
+   3228: 1003228
+   3229: 1003229
+   3230: 1003230
+   3231: 1003231
+   3232: 1003232
+   3233: 1003233
+   3234: 1003234
+   3235: 1003235
+   3236: 1003236
+   3237: 1003237
+   3238: 1003238
+   3239: 1003239
+   3240: 1003240
+   3241: 1003241
+   3242: 1003242
+   3243: 1003243
+   3244: 1003244
+   3245: 1003245
+   3246: 1003246
+   3247: 1003247
+   3248: 1003248
+   3249: 1003249
+   3250: 1003250
+   3251: 1003251
+   3252: 1003252
+   3253: 1003253
+   3254: 1003254
+   3255: 1003255
+   3256: 1003256
+   3257: 1003257
+   3258: 1003258
+   3259: 1003259
+   3260: 1003260
+   3261: 1003261
+   3262: 1003262
+   3263: 1003263
+   3264: 1003264
+   3265: 1003265
+   3266: 1003266
+   3267: 1003267
+   3268: 1003268
+   3269: 1003269
+   3270: 1003270
+   3271: 1003271
+   3272: 1003272
+   3273: 1003273
+   3274: 1003274
+   3275: 1003275
+   3276: 1003276
+   3277: 1003277
+   3278: 1003278
+   3279: 1003279
+   3280: 1003280
+   3281: 1003281
+   3282: 1003282
+   3283: 1003283
+   3284: 1003284
+   3285: 1003285
+   3286: 1003286
+   3287: 1003287
+   3288: 1003288
+   3289: 1003289
+   3290: 1003290
+   3291: 1003291
+   3292: 1003292
+   3293: 1003293
+   3294: 1003294
+   3295: 1003295
+   3296: 1003296
+   3297: 1003297
+   3298: 1003298
+   3299: 1003299
+   3300: 1003300
+   3301: 1003301
+   3302: 1003302
+   3303: 1003303
+   3304: 1003304
+   3305: 1003305
+   3306: 1003306
+   3307: 1003307
+   3308: 1003308
+   3309: 1003309
+   3310: 1003310
+   3311: 1003311
+   3312: 1003312
+   3313: 1003313
+   3314: 1003314
+   3315: 1003315
+   3316: 1003316
+   3317: 1003317
+   3318: 1003318
+   3319: 1003319
+   3320: 1003320
+   3321: 1003321
+   3322: 1003322
+   3323: 1003323
+   3324: 1003324
+   3325: 1003325
+   3326: 1003326
+   3327: 1003327
+   3328: 1003328
+   3329: 1003329
+   3330: 1003330
+   3331: 1003331
+   3332: 1003332
+   3333: 1003333
+   3334: 1003334
+   3335: 1003335
+   3336: 1003336
+   3337: 1003337
+   3338: 1003338
+   3339: 1003339
+   3340: 1003340
+   3341: 1003341
+   3342: 1003342
+   3343: 1003343
+   3344: 1003344
+   3345: 1003345
+   3346: 1003346
+   3347: 1003347
+   3348: 1003348
+   3349: 1003349
+   3350: 1003350
+   3351: 1003351
+   3352: 1003352
+   3353: 1003353
+   3354: 1003354
+   3355: 1003355
+   3356: 1003356
+   3357: 1003357
+   3358: 1003358
+   3359: 1003359
+   3360: 1003360
+   3361: 1003361
+   3362: 1003362
+   3363: 1003363
+   3364: 1003364
+   3365: 1003365
+   3366: 1003366
+   3367: 1003367
+   3368: 1003368
+   3369: 1003369
+   3370: 1003370
+   3371: 1003371
+   3372: 1003372
+   3373: 1003373
+   3374: 1003374
+   3375: 1003375
+   3376: 1003376
+   3377: 1003377
+   3378: 1003378
+   3379: 1003379
+   3380: 1003380
+   3381: 1003381
+   3382: 1003382
+   3383: 1003383
+   3384: 1003384
+   3385: 1003385
+   3386: 1003386
+   3387: 1003387
+   3388: 1003388
+   3389: 1003389
+   3390: 1003390
+   3391: 1003391
+   3392: 1003392
+   3393: 1003393
+   3394: 1003394
+   3395: 1003395
+   3396: 1003396
+   3397: 1003397
+   3398: 1003398
+   3399: 1003399
+   3400: 1003400
+   3401: 1003401
+   3402: 1003402
+   3403: 1003403
+   3404: 1003404
+   3405: 1003405
+   3406: 1003406
+   3407: 1003407
+   3408: 1003408
+   3409: 1003409
+   3410: 1003410
+   3411: 1003411
+   3412: 1003412
+   3413: 1003413
+   3414: 1003414
+   3415: 1003415
+   3416: 1003416
+   3417: 1003417
+   3418: 1003418
+   3419: 1003419
+   3420: 1003420
+   3421: 1003421
+   3422: 1003422
+   3423: 1003423
+   3424: 1003424
+   3425: 1003425
+   3426: 1003426
+   3427: 1003427
+   3428: 1003428
+   3429: 1003429
+   3430: 1003430
+   3431: 1003431
+   3432: 1003432
+   3433: 1003433
+   3434: 1003434
+   3435: 1003435
+   3436: 1003436
+   3437: 1003437
+   3438: 1003438
+   3439: 1003439
+   3440: 1003440
+   3441: 1003441
+   3442: 1003442
+   3443: 1003443
+   3444: 1003444
+   3445: 1003445
+   3446: 1003446
+   3447: 1003447
+   3448: 1003448
+   3449: 1003449
+   3450: 1003450
+   3451: 1003451
+   3452: 1003452
+   3453: 1003453
+   3454: 1003454
+   3455: 1003455
+   3456: 1003456
+   3457: 1003457
+   3458: 1003458
+   3459: 1003459
+   3460: 1003460
+   3461: 1003461
+   3462: 1003462
+   3463: 1003463
+   3464: 1003464
+   3465: 1003465
+   3466: 1003466
+   3467: 1003467
+   3468: 1003468
+   3469: 1003469
+   3470: 1003470
+   3471: 1003471
+   3472: 1003472
+   3473: 1003473
+   3474: 1003474
+   3475: 1003475
+   3476: 1003476
+   3477: 1003477
+   3478: 1003478
+   3479: 1003479
+   3480: 1003480
+   3481: 1003481
+   3482: 1003482
+   3483: 1003483
+   3484: 1003484
+   3485: 1003485
+   3486: 1003486
+   3487: 1003487
+   3488: 1003488
+   3489: 1003489
+   3490: 1003490
+   3491: 1003491
+   3492: 1003492
+   3493: 1003493
+   3494: 1003494
+   3495: 1003495
+   3496: 1003496
+   3497: 1003497
+   3498: 1003498
+   3499: 1003499
+   3500: 1003500
+   3501: 1003501
+   3502: 1003502
+   3503: 1003503
+   3504: 1003504
+   3505: 1003505
+   3506: 1003506
+   3507: 1003507
+   3508: 1003508
+   3509: 1003509
+   3510: 1003510
+   3511: 1003511
+   3512: 1003512
+   3513: 1003513
+   3514: 1003514
+   3515: 1003515
+   3516: 1003516
+   3517: 1003517
+   3518: 1003518
+   3519: 1003519
+   3520: 1003520
+   3521: 1003521
+   3522: 1003522
+   3523: 1003523
+   3524: 1003524
+   3525: 1003525
+   3526: 1003526
+   3527: 1003527
+   3528: 1003528
+   3529: 1003529
+   3530: 1003530
+   3531: 1003531
+   3532: 1003532
+   3533: 1003533
+   3534: 1003534
+   3535: 1003535
+   3536: 1003536
+   3537: 1003537
+   3538: 1003538
+   3539: 1003539
+   3540: 1003540
+   3541: 1003541
+   3542: 1003542
+   3543: 1003543
+   3544: 1003544
+   3545: 1003545
+   3546: 1003546
+   3547: 1003547
+   3548: 1003548
+   3549: 1003549
+   3550: 1003550
+   3551: 1003551
+   3552: 1003552
+   3553: 1003553
+   3554: 1003554
+   3555: 1003555
+   3556: 1003556
+   3557: 1003557
+   3558: 1003558
+   3559: 1003559
+   3560: 1003560
+   3561: 1003561
+   3562: 1003562
+   3563: 1003563
+   3564: 1003564
+   3565: 1003565
+   3566: 1003566
+   3567: 1003567
+   3568: 1003568
+   3569: 1003569
+   3570: 1003570
+   3571: 1003571
+   3572: 1003572
+   3573: 1003573
+   3574: 1003574
+   3575: 1003575
+   3576: 1003576
+   3577: 1003577
+   3578: 1003578
+   3579: 1003579
+   3580: 1003580
+   3581: 1003581
+   3582: 1003582
+   3583: 1003583
+   3584: 1003584
+   3585: 1003585
+   3586: 1003586
+   3587: 1003587
+   3588: 1003588
+   3589: 1003589
+   3590: 1003590
+   3591: 1003591
+   3592: 1003592
+   3593: 1003593
+   3594: 1003594
+   3595: 1003595
+   3596: 1003596
+   3597: 1003597
+   3598: 1003598
+   3599: 1003599
+   3600: 1003600
+   3601: 1003601
+   3602: 1003602
+   3603: 1003603
+   3604: 1003604
+   3605: 1003605
+   3606: 1003606
+   3607: 1003607
+   3608: 1003608
+   3609: 1003609
+   3610: 1003610
+   3611: 1003611
+   3612: 1003612
+   3613: 1003613
+   3614: 1003614
+   3615: 1003615
+   3616: 1003616
+   3617: 1003617
+   3618: 1003618
+   3619: 1003619
+   3620: 1003620
+   3621: 1003621
+   3622: 1003622
+   3623: 1003623
+   3624: 1003624
+   3625: 1003625
+   3626: 1003626
+   3627: 1003627
+   3628: 1003628
+   3629: 1003629
+   3630: 1003630
+   3631: 1003631
+   3632: 1003632
+   3633: 1003633
+   3634: 1003634
+   3635: 1003635
+   3636: 1003636
+   3637: 1003637
+   3638: 1003638
+   3639: 1003639
+   3640: 1003640
+   3641: 1003641
+   3642: 1003642
+   3643: 1003643
+   3644: 1003644
+   3645: 1003645
+   3646: 1003646
+   3647: 1003647
+   3648: 1003648
+   3649: 1003649
+   3650: 1003650
+   3651: 1003651
+   3652: 1003652
+   3653: 1003653
+   3654: 1003654
+   3655: 1003655
+   3656: 1003656
+   3657: 1003657
+   3658: 1003658
+   3659: 1003659
+   3660: 1003660
+   3661: 1003661
+   3662: 1003662
+   3663: 1003663
+   3664: 1003664
+   3665: 1003665
+   3666: 1003666
+   3667: 1003667
+   3668: 1003668
+   3669: 1003669
+   3670: 1003670
+   3671: 1003671
+   3672: 1003672
+   3673: 1003673
+   3674: 1003674
+   3675: 1003675
+   3676: 1003676
+   3677: 1003677
+   3678: 1003678
+   3679: 1003679
+   3680: 1003680
+   3681: 1003681
+   3682: 1003682
+   3683: 1003683
+   3684: 1003684
+   3685: 1003685
+   3686: 1003686
+   3687: 1003687
+   3688: 1003688
+   3689: 1003689
+   3690: 1003690
+   3691: 1003691
+   3692: 1003692
+   3693: 1003693
+   3694: 1003694
+   3695: 1003695
+   3696: 1003696
+   3697: 1003697
+   3698: 1003698
+   3699: 1003699
+   3700: 1003700
+   3701: 1003701
+   3702: 1003702
+   3703: 1003703
+   3704: 1003704
+   3705: 1003705
+   3706: 1003706
+   3707: 1003707
+   3708: 1003708
+   3709: 1003709
+   3710: 1003710
+   3711: 1003711
+   3712: 1003712
+   3713: 1003713
+   3714: 1003714
+   3715: 1003715
+   3716: 1003716
+   3717: 1003717
+   3718: 1003718
+   3719: 1003719
+   3720: 1003720
+   3721: 1003721
+   3722: 1003722
+   3723: 1003723
+   3724: 1003724
+   3725: 1003725
+   3726: 1003726
+   3727: 1003727
+   3728: 1003728
+   3729: 1003729
+   3730: 1003730
+   3731: 1003731
+   3732: 1003732
+   3733: 1003733
+   3734: 1003734
+   3735: 1003735
+   3736: 1003736
+   3737: 1003737
+   3738: 1003738
+   3739: 1003739
+   3740: 1003740
+   3741: 1003741
+   3742: 1003742
+   3743: 1003743
+   3744: 1003744
+   3745: 1003745
+   3746: 1003746
+   3747: 1003747
+   3748: 1003748
+   3749: 1003749
+   3750: 1003750
+   3751: 1003751
+   3752: 1003752
+   3753: 1003753
+   3754: 1003754
+   3755: 1003755
+   3756: 1003756
+   3757: 1003757
+   3758: 1003758
+   3759: 1003759
+   3760: 1003760
+   3761: 1003761
+   3762: 1003762
+   3763: 1003763
+   3764: 1003764
+   3765: 1003765
+   3766: 1003766
+   3767: 1003767
+   3768: 1003768
+   3769: 1003769
+   3770: 1003770
+   3771: 1003771
+   3772: 1003772
+   3773: 1003773
+   3774: 1003774
+   3775: 1003775
+   3776: 1003776
+   3777: 1003777
+   3778: 1003778
+   3779: 1003779
+   3780: 1003780
+   3781: 1003781
+   3782: 1003782
+   3783: 1003783
+   3784: 1003784
+   3785: 1003785
+   3786: 1003786
+   3787: 1003787
+   3788: 1003788
+   3789: 1003789
+   3790: 1003790
+   3791: 1003791
+   3792: 1003792
+   3793: 1003793
+   3794: 1003794
+   3795: 1003795
+   3796: 1003796
+   3797: 1003797
+   3798: 1003798
+   3799: 1003799
+   3800: 1003800
+   3801: 1003801
+   3802: 1003802
+   3803: 1003803
+   3804: 1003804
+   3805: 1003805
+   3806: 1003806
+   3807: 1003807
+   3808: 1003808
+   3809: 1003809
+   3810: 1003810
+   3811: 1003811
+   3812: 1003812
+   3813: 1003813
+   3814: 1003814
+   3815: 1003815
+   3816: 1003816
+   3817: 1003817
+   3818: 1003818
+   3819: 1003819
+   3820: 1003820
+   3821: 1003821
+   3822: 1003822
+   3823: 1003823
+   3824: 1003824
+   3825: 1003825
+   3826: 1003826
+   3827: 1003827
+   3828: 1003828
+   3829: 1003829
+   3830: 1003830
+   3831: 1003831
+   3832: 1003832
+   3833: 1003833
+   3834: 1003834
+   3835: 1003835
+   3836: 1003836
+   3837: 1003837
+   3838: 1003838
+   3839: 1003839
+   3840: 1003840
+   3841: 1003841
+   3842: 1003842
+   3843: 1003843
+   3844: 1003844
+   3845: 1003845
+   3846: 1003846
+   3847: 1003847
+   3848: 1003848
+   3849: 1003849
+   3850: 1003850
+   3851: 1003851
+   3852: 1003852
+   3853: 1003853
+   3854: 1003854
+   3855: 1003855
+   3856: 1003856
+   3857: 1003857
+   3858: 1003858
+   3859: 1003859
+   3860: 1003860
+   3861: 1003861
+   3862: 1003862
+   3863: 1003863
+   3864: 1003864
+   3865: 1003865
+   3866: 1003866
+   3867: 1003867
+   3868: 1003868
+   3869: 1003869
+   3870: 1003870
+   3871: 1003871
+   3872: 1003872
+   3873: 1003873
+   3874: 1003874
+   3875: 1003875
+   3876: 1003876
+   3877: 1003877
+   3878: 1003878
+   3879: 1003879
+   3880: 1003880
+   3881: 1003881
+   3882: 1003882
+   3883: 1003883
+   3884: 1003884
+   3885: 1003885
+   3886: 1003886
+   3887: 1003887
+   3888: 1003888
+   3889: 1003889
+   3890: 1003890
+   3891: 1003891
+   3892: 1003892
+   3893: 1003893
+   3894: 1003894
+   3895: 1003895
+   3896: 1003896
+   3897: 1003897
+   3898: 1003898
+   3899: 1003899
+   3900: 1003900
+   3901: 1003901
+   3902: 1003902
+   3903: 1003903
+   3904: 1003904
+   3905: 1003905
+   3906: 1003906
+   3907: 1003907
+   3908: 1003908
+   3909: 1003909
+   3910: 1003910
+   3911: 1003911
+   3912: 1003912
+   3913: 1003913
+   3914: 1003914
+   3915: 1003915
+   3916: 1003916
+   3917: 1003917
+   3918: 1003918
+   3919: 1003919
+   3920: 1003920
+   3921: 1003921
+   3922: 1003922
+   3923: 1003923
+   3924: 1003924
+   3925: 1003925
+   3926: 1003926
+   3927: 1003927
+   3928: 1003928
+   3929: 1003929
+   3930: 1003930
+   3931: 1003931
+   3932: 1003932
+   3933: 1003933
+   3934: 1003934
+   3935: 1003935
+   3936: 1003936
+   3937: 1003937
+   3938: 1003938
+   3939: 1003939
+   3940: 1003940
+   3941: 1003941
+   3942: 1003942
+   3943: 1003943
+   3944: 1003944
+   3945: 1003945
+   3946: 1003946
+   3947: 1003947
+   3948: 1003948
+   3949: 1003949
+   3950: 1003950
+   3951: 1003951
+   3952: 1003952
+   3953: 1003953
+   3954: 1003954
+   3955: 1003955
+   3956: 1003956
+   3957: 1003957
+   3958: 1003958
+   3959: 1003959
+   3960: 1003960
+   3961: 1003961
+   3962: 1003962
+   3963: 1003963
+   3964: 1003964
+   3965: 1003965
+   3966: 1003966
+   3967: 1003967
+   3968: 1003968
+   3969: 1003969
+   3970: 1003970
+   3971: 1003971
+   3972: 1003972
+   3973: 1003973
+   3974: 1003974
+   3975: 1003975
+   3976: 1003976
+   3977: 1003977
+   3978: 1003978
+   3979: 1003979
+   3980: 1003980
+   3981: 1003981
+   3982: 1003982
+   3983: 1003983
+   3984: 1003984
+   3985: 1003985
+   3986: 1003986
+   3987: 1003987
+   3988: 1003988
+   3989: 1003989
+   3990: 1003990
+   3991: 1003991
+   3992: 1003992
+   3993: 1003993
+   3994: 1003994
+   3995: 1003995
+   3996: 1003996
+   3997: 1003997
+   3998: 1003998
+   3999: 1003999
+   4000: 1004000
+   4001: 1004001
+   4002: 1004002
+   4003: 1004003
+   4004: 1004004
+   4005: 1004005
+   4006: 1004006
+   4007: 1004007
+   4008: 1004008
+   4009: 1004009
+   4010: 1004010
+   4011: 1004011
+   4012: 1004012
+   4013: 1004013
+   4014: 1004014
+   4015: 1004015
+   4016: 1004016
+   4017: 1004017
+   4018: 1004018
+   4019: 1004019
+   4020: 1004020
+   4021: 1004021
+   4022: 1004022
+   4023: 1004023
+   4024: 1004024
+   4025: 1004025
+   4026: 1004026
+   4027: 1004027
+   4028: 1004028
+   4029: 1004029
+   4030: 1004030
+   4031: 1004031
+   4032: 1004032
+   4033: 1004033
+   4034: 1004034
+   4035: 1004035
+   4036: 1004036
+   4037: 1004037
+   4038: 1004038
+   4039: 1004039
+   4040: 1004040
+   4041: 1004041
+   4042: 1004042
+   4043: 1004043
+   4044: 1004044
+   4045: 1004045
+   4046: 1004046
+   4047: 1004047
+   4048: 1004048
+   4049: 1004049
+   4050: 1004050
+   4051: 1004051
+   4052: 1004052
+   4053: 1004053
+   4054: 1004054
+   4055: 1004055
+   4056: 1004056
+   4057: 1004057
+   4058: 1004058
+   4059: 1004059
+   4060: 1004060
+   4061: 1004061
+   4062: 1004062
+   4063: 1004063
+   4064: 1004064
+   4065: 1004065
+   4066: 1004066
+   4067: 1004067
+   4068: 1004068
+   4069: 1004069
+   4070: 1004070
+   4071: 1004071
+   4072: 1004072
+   4073: 1004073
+   4074: 1004074
+   4075: 1004075
+   4076: 1004076
+   4077: 1004077
+   4078: 1004078
+   4079: 1004079
+   4080: 1004080
+   4081: 1004081
+   4082: 1004082
+   4083: 1004083
+   4084: 1004084
+   4085: 1004085
+   4086: 1004086
+   4087: 1004087
+   4088: 1004088
+   4089: 1004089
+   4090: 1004090
+   4091: 1004091
+   4092: 1004092
+   4093: 1004093
+   4094: 1004094
+   4095: 1004095
+   4096: 1004096
+   4097: 1004097
+   4098: 1004098
+   4099: 1004099
+   4100: 1004100
+   4101: 1004101
+   4102: 1004102
+   4103: 1004103
+   4104: 1004104
+   4105: 1004105
+   4106: 1004106
+   4107: 1004107
+   4108: 1004108
+   4109: 1004109
+   4110: 1004110
+   4111: 1004111
+   4112: 1004112
+   4113: 1004113
+   4114: 1004114
+   4115: 1004115
+   4116: 1004116
+   4117: 1004117
+   4118: 1004118
+   4119: 1004119
+   4120: 1004120
+   4121: 1004121
+   4122: 1004122
+   4123: 1004123
+   4124: 1004124
+   4125: 1004125
+   4126: 1004126
+   4127: 1004127
+   4128: 1004128
+   4129: 1004129
+   4130: 1004130
+   4131: 1004131
+   4132: 1004132
+   4133: 1004133
+   4134: 1004134
+   4135: 1004135
+   4136: 1004136
+   4137: 1004137
+   4138: 1004138
+   4139: 1004139
+   4140: 1004140
+   4141: 1004141
+   4142: 1004142
+   4143: 1004143
+   4144: 1004144
+   4145: 1004145
+   4146: 1004146
+   4147: 1004147
+   4148: 1004148
+   4149: 1004149
+   4150: 1004150
+   4151: 1004151
+   4152: 1004152
+   4153: 1004153
+   4154: 1004154
+   4155: 1004155
+   4156: 1004156
+   4157: 1004157
+   4158: 1004158
+   4159: 1004159
+   4160: 1004160
+   4161: 1004161
+   4162: 1004162
+   4163: 1004163
+   4164: 1004164
+   4165: 1004165
+   4166: 1004166
+   4167: 1004167
+   4168: 1004168
+   4169: 1004169
+   4170: 1004170
+   4171: 1004171
+   4172: 1004172
+   4173: 1004173
+   4174: 1004174
+   4175: 1004175
+   4176: 1004176
+   4177: 1004177
+   4178: 1004178
+   4179: 1004179
+   4180: 1004180
+   4181: 1004181
+   4182: 1004182
+   4183: 1004183
+   4184: 1004184
+   4185: 1004185
+   4186: 1004186
+   4187: 1004187
+   4188: 1004188
+   4189: 1004189
+   4190: 1004190
+   4191: 1004191
+   4192: 1004192
+   4193: 1004193
+   4194: 1004194
+   4195: 1004195
+   4196: 1004196
+   4197: 1004197
+   4198: 1004198
+   4199: 1004199
+   4200: 1004200
+   4201: 1004201
+   4202: 1004202
+   4203: 1004203
+   4204: 1004204
+   4205: 1004205
+   4206: 1004206
+   4207: 1004207
+   4208: 1004208
+   4209: 1004209
+   4210: 1004210
+   4211: 1004211
+   4212: 1004212
+   4213: 1004213
+   4214: 1004214
+   4215: 1004215
+   4216: 1004216
+   4217: 1004217
+   4218: 1004218
+   4219: 1004219
+   4220: 1004220
+   4221: 1004221
+   4222: 1004222
+   4223: 1004223
+   4224: 1004224
+   4225: 1004225
+   4226: 1004226
+   4227: 1004227
+   4228: 1004228
+   4229: 1004229
+   4230: 1004230
+   4231: 1004231
+   4232: 1004232
+   4233: 1004233
+   4234: 1004234
+   4235: 1004235
+   4236: 1004236
+   4237: 1004237
+   4238: 1004238
+   4239: 1004239
+   4240: 1004240
+   4241: 1004241
+   4242: 1004242
+   4243: 1004243
+   4244: 1004244
+   4245: 1004245
+   4246: 1004246
+   4247: 1004247
+   4248: 1004248
+   4249: 1004249
+   4250: 1004250
+   4251: 1004251
+   4252: 1004252
+   4253: 1004253
+   4254: 1004254
+   4255: 1004255
+   4256: 1004256
+   4257: 1004257
+   4258: 1004258
+   4259: 1004259
+   4260: 1004260
+   4261: 1004261
+   4262: 1004262
+   4263: 1004263
+   4264: 1004264
+   4265: 1004265
+   4266: 1004266
+   4267: 1004267
+   4268: 1004268
+   4269: 1004269
+   4270: 1004270
+   4271: 1004271
+   4272: 1004272
+   4273: 1004273
+   4274: 1004274
+   4275: 1004275
+   4276: 1004276
+   4277: 1004277
+   4278: 1004278
+   4279: 1004279
+   4280: 1004280
+   4281: 1004281
+   4282: 1004282
+   4283: 1004283
+   4284: 1004284
+   4285: 1004285
+   4286: 1004286
+   4287: 1004287
+   4288: 1004288
+   4289: 1004289
+   4290: 1004290
+   4291: 1004291
+   4292: 1004292
+   4293: 1004293
+   4294: 1004294
+   4295: 1004295
+   4296: 1004296
+   4297: 1004297
+   4298: 1004298
+   4299: 1004299
+   4300: 1004300
+   4301: 1004301
+   4302: 1004302
+   4303: 1004303
+   4304: 1004304
+   4305: 1004305
+   4306: 1004306
+   4307: 1004307
+   4308: 1004308
+   4309: 1004309
+   4310: 1004310
+   4311: 1004311
+   4312: 1004312
+   4313: 1004313
+   4314: 1004314
+   4315: 1004315
+   4316: 1004316
+   4317: 1004317
+   4318: 1004318
+   4319: 1004319
+   4320: 1004320
+   4321: 1004321
+   4322: 1004322
+   4323: 1004323
+   4324: 1004324
+   4325: 1004325
+   4326: 1004326
+   4327: 1004327
+   4328: 1004328
+   4329: 1004329
+   4330: 1004330
+   4331: 1004331
+   4332: 1004332
+   4333: 1004333
+   4334: 1004334
+   4335: 1004335
+   4336: 1004336
+   4337: 1004337
+   4338: 1004338
+   4339: 1004339
+   4340: 1004340
+   4341: 1004341
+   4342: 1004342
+   4343: 1004343
+   4344: 1004344
+   4345: 1004345
+   4346: 1004346
+   4347: 1004347
+   4348: 1004348
+   4349: 1004349
+   4350: 1004350
+   4351: 1004351
+   4352: 1004352
+   4353: 1004353
+   4354: 1004354
+   4355: 1004355
+   4356: 1004356
+   4357: 1004357
+   4358: 1004358
+   4359: 1004359
+   4360: 1004360
+   4361: 1004361
+   4362: 1004362
+   4363: 1004363
+   4364: 1004364
+   4365: 1004365
+   4366: 1004366
+   4367: 1004367
+   4368: 1004368
+   4369: 1004369
+   4370: 1004370
+   4371: 1004371
+   4372: 1004372
+   4373: 1004373
+   4374: 1004374
+   4375: 1004375
+   4376: 1004376
+   4377: 1004377
+   4378: 1004378
+   4379: 1004379
+   4380: 1004380
+   4381: 1004381
+   4382: 1004382
+   4383: 1004383
+   4384: 1004384
+   4385: 1004385
+   4386: 1004386
+   4387: 1004387
+   4388: 1004388
+   4389: 1004389
+   4390: 1004390
+   4391: 1004391
+   4392: 1004392
+   4393: 1004393
+   4394: 1004394
+   4395: 1004395
+   4396: 1004396
+   4397: 1004397
+   4398: 1004398
+   4399: 1004399
+   4400: 1004400
+   4401: 1004401
+   4402: 1004402
+   4403: 1004403
+   4404: 1004404
+   4405: 1004405
+   4406: 1004406
+   4407: 1004407
+   4408: 1004408
+   4409: 1004409
+   4410: 1004410
+   4411: 1004411
+   4412: 1004412
+   4413: 1004413
+   4414: 1004414
+   4415: 1004415
+   4416: 1004416
+   4417: 1004417
+   4418: 1004418
+   4419: 1004419
+   4420: 1004420
+   4421: 1004421
+   4422: 1004422
+   4423: 1004423
+   4424: 1004424
+   4425: 1004425
+   4426: 1004426
+   4427: 1004427
+   4428: 1004428
+   4429: 1004429
+   4430: 1004430
+   4431: 1004431
+   4432: 1004432
+   4433: 1004433
+   4434: 1004434
+   4435: 1004435
+   4436: 1004436
+   4437: 1004437
+   4438: 1004438
+   4439: 1004439
+   4440: 1004440
+   4441: 1004441
+   4442: 1004442
+   4443: 1004443
+   4444: 1004444
+   4445: 1004445
+   4446: 1004446
+   4447: 1004447
+   4448: 1004448
+   4449: 1004449
+   4450: 1004450
+   4451: 1004451
+   4452: 1004452
+   4453: 1004453
+   4454: 1004454
+   4455: 1004455
+   4456: 1004456
+   4457: 1004457
+   4458: 1004458
+   4459: 1004459
+   4460: 1004460
+   4461: 1004461
+   4462: 1004462
+   4463: 1004463
+   4464: 1004464
+   4465: 1004465
+   4466: 1004466
+   4467: 1004467
+   4468: 1004468
+   4469: 1004469
+   4470: 1004470
+   4471: 1004471
+   4472: 1004472
+   4473: 1004473
+   4474: 1004474
+   4475: 1004475
+   4476: 1004476
+   4477: 1004477
+   4478: 1004478
+   4479: 1004479
+   4480: 1004480
+   4481: 1004481
+   4482: 1004482
+   4483: 1004483
+   4484: 1004484
+   4485: 1004485
+   4486: 1004486
+   4487: 1004487
+   4488: 1004488
+   4489: 1004489
+   4490: 1004490
+   4491: 1004491
+   4492: 1004492
+   4493: 1004493
+   4494: 1004494
+   4495: 1004495
+   4496: 1004496
+   4497: 1004497
+   4498: 1004498
+   4499: 1004499
+   4500: 1004500
+   4501: 1004501
+   4502: 1004502
+   4503: 1004503
+   4504: 1004504
+   4505: 1004505
+   4506: 1004506
+   4507: 1004507
+   4508: 1004508
+   4509: 1004509
+   4510: 1004510
+   4511: 1004511
+   4512: 1004512
+   4513: 1004513
+   4514: 1004514
+   4515: 1004515
+   4516: 1004516
+   4517: 1004517
+   4518: 1004518
+   4519: 1004519
+   4520: 1004520
+   4521: 1004521
+   4522: 1004522
+   4523: 1004523
+   4524: 1004524
+   4525: 1004525
+   4526: 1004526
+   4527: 1004527
+   4528: 1004528
+   4529: 1004529
+   4530: 1004530
+   4531: 1004531
+   4532: 1004532
+   4533: 1004533
+   4534: 1004534
+   4535: 1004535
+   4536: 1004536
+   4537: 1004537
+   4538: 1004538
+   4539: 1004539
+   4540: 1004540
+   4541: 1004541
+   4542: 1004542
+   4543: 1004543
+   4544: 1004544
+   4545: 1004545
+   4546: 1004546
+   4547: 1004547
+   4548: 1004548
+   4549: 1004549
+   4550: 1004550
+   4551: 1004551
+   4552: 1004552
+   4553: 1004553
+   4554: 1004554
+   4555: 1004555
+   4556: 1004556
+   4557: 1004557
+   4558: 1004558
+   4559: 1004559
+   4560: 1004560
+   4561: 1004561
+   4562: 1004562
+   4563: 1004563
+   4564: 1004564
+   4565: 1004565
+   4566: 1004566
+   4567: 1004567
+   4568: 1004568
+   4569: 1004569
+   4570: 1004570
+   4571: 1004571
+   4572: 1004572
+   4573: 1004573
+   4574: 1004574
+   4575: 1004575
+   4576: 1004576
+   4577: 1004577
+   4578: 1004578
+   4579: 1004579
+   4580: 1004580
+   4581: 1004581
+   4582: 1004582
+   4583: 1004583
+   4584: 1004584
+   4585: 1004585
+   4586: 1004586
+   4587: 1004587
+   4588: 1004588
+   4589: 1004589
+   4590: 1004590
+   4591: 1004591
+   4592: 1004592
+   4593: 1004593
+   4594: 1004594
+   4595: 1004595
+   4596: 1004596
+   4597: 1004597
+   4598: 1004598
+   4599: 1004599
+   4600: 1004600
+   4601: 1004601
+   4602: 1004602
+   4603: 1004603
+   4604: 1004604
+   4605: 1004605
+   4606: 1004606
+   4607: 1004607
+   4608: 1004608
+   4609: 1004609
+   4610: 1004610
+   4611: 1004611
+   4612: 1004612
+   4613: 1004613
+   4614: 1004614
+   4615: 1004615
+   4616: 1004616
+   4617: 1004617
+   4618: 1004618
+   4619: 1004619
+   4620: 1004620
+   4621: 1004621
+   4622: 1004622
+   4623: 1004623
+   4624: 1004624
+   4625: 1004625
+   4626: 1004626
+   4627: 1004627
+   4628: 1004628
+   4629: 1004629
+   4630: 1004630
+   4631: 1004631
+   4632: 1004632
+   4633: 1004633
+   4634: 1004634
+   4635: 1004635
+   4636: 1004636
+   4637: 1004637
+   4638: 1004638
+   4639: 1004639
+   4640: 1004640
+   4641: 1004641
+   4642: 1004642
+   4643: 1004643
+   4644: 1004644
+   4645: 1004645
+   4646: 1004646
+   4647: 1004647
+   4648: 1004648
+   4649: 1004649
+   4650: 1004650
+   4651: 1004651
+   4652: 1004652
+   4653: 1004653
+   4654: 1004654
+   4655: 1004655
+   4656: 1004656
+   4657: 1004657
+   4658: 1004658
+   4659: 1004659
+   4660: 1004660
+   4661: 1004661
+   4662: 1004662
+   4663: 1004663
+   4664: 1004664
+   4665: 1004665
+   4666: 1004666
+   4667: 1004667
+   4668: 1004668
+   4669: 1004669
+   4670: 1004670
+   4671: 1004671
+   4672: 1004672
+   4673: 1004673
+   4674: 1004674
+   4675: 1004675
+   4676: 1004676
+   4677: 1004677
+   4678: 1004678
+   4679: 1004679
+   4680: 1004680
+   4681: 1004681
+   4682: 1004682
+   4683: 1004683
+   4684: 1004684
+   4685: 1004685
+   4686: 1004686
+   4687: 1004687
+   4688: 1004688
+   4689: 1004689
+   4690: 1004690
+   4691: 1004691
+   4692: 1004692
+   4693: 1004693
+   4694: 1004694
+   4695: 1004695
+   4696: 1004696
+   4697: 1004697
+   4698: 1004698
+   4699: 1004699
+   4700: 1004700
+   4701: 1004701
+   4702: 1004702
+   4703: 1004703
+   4704: 1004704
+   4705: 1004705
+   4706: 1004706
+   4707: 1004707
+   4708: 1004708
+   4709: 1004709
+   4710: 1004710
+   4711: 1004711
+   4712: 1004712
+   4713: 1004713
+   4714: 1004714
+   4715: 1004715
+   4716: 1004716
+   4717: 1004717
+   4718: 1004718
+   4719: 1004719
+   4720: 1004720
+   4721: 1004721
+   4722: 1004722
+   4723: 1004723
+   4724: 1004724
+   4725: 1004725
+   4726: 1004726
+   4727: 1004727
+   4728: 1004728
+   4729: 1004729
+   4730: 1004730
+   4731: 1004731
+   4732: 1004732
+   4733: 1004733
+   4734: 1004734
+   4735: 1004735
+   4736: 1004736
+   4737: 1004737
+   4738: 1004738
+   4739: 1004739
+   4740: 1004740
+   4741: 1004741
+   4742: 1004742
+   4743: 1004743
+   4744: 1004744
+   4745: 1004745
+   4746: 1004746
+   4747: 1004747
+   4748: 1004748
+   4749: 1004749
+   4750: 1004750
+   4751: 1004751
+   4752: 1004752
+   4753: 1004753
+   4754: 1004754
+   4755: 1004755
+   4756: 1004756
+   4757: 1004757
+   4758: 1004758
+   4759: 1004759
+   4760: 1004760
+   4761: 1004761
+   4762: 1004762
+   4763: 1004763
+   4764: 1004764
+   4765: 1004765
+   4766: 1004766
+   4767: 1004767
+   4768: 1004768
+   4769: 1004769
+   4770: 1004770
+   4771: 1004771
+   4772: 1004772
+   4773: 1004773
+   4774: 1004774
+   4775: 1004775
+   4776: 1004776
+   4777: 1004777
+   4778: 1004778
+   4779: 1004779
+   4780: 1004780
+   4781: 1004781
+   4782: 1004782
+   4783: 1004783
+   4784: 1004784
+   4785: 1004785
+   4786: 1004786
+   4787: 1004787
+   4788: 1004788
+   4789: 1004789
+   4790: 1004790
+   4791: 1004791
+   4792: 1004792
+   4793: 1004793
+   4794: 1004794
+   4795: 1004795
+   4796: 1004796
+   4797: 1004797
+   4798: 1004798
+   4799: 1004799
+   4800: 1004800
+   4801: 1004801
+   4802: 1004802
+   4803: 1004803
+   4804: 1004804
+   4805: 1004805
+   4806: 1004806
+   4807: 1004807
+   4808: 1004808
+   4809: 1004809
+   4810: 1004810
+   4811: 1004811
+   4812: 1004812
+   4813: 1004813
+   4814: 1004814
+   4815: 1004815
+   4816: 1004816
+   4817: 1004817
+   4818: 1004818
+   4819: 1004819
+   4820: 1004820
+   4821: 1004821
+   4822: 1004822
+   4823: 1004823
+   4824: 1004824
+   4825: 1004825
+   4826: 1004826
+   4827: 1004827
+   4828: 1004828
+   4829: 1004829
+   4830: 1004830
+   4831: 1004831
+   4832: 1004832
+   4833: 1004833
+   4834: 1004834
+   4835: 1004835
+   4836: 1004836
+   4837: 1004837
+   4838: 1004838
+   4839: 1004839
+   4840: 1004840
+   4841: 1004841
+   4842: 1004842
+   4843: 1004843
+   4844: 1004844
+   4845: 1004845
+   4846: 1004846
+   4847: 1004847
+   4848: 1004848
+   4849: 1004849
+   4850: 1004850
+   4851: 1004851
+   4852: 1004852
+   4853: 1004853
+   4854: 1004854
+   4855: 1004855
+   4856: 1004856
+   4857: 1004857
+   4858: 1004858
+   4859: 1004859
+   4860: 1004860
+   4861: 1004861
+   4862: 1004862
+   4863: 1004863
+   4864: 1004864
+   4865: 1004865
+   4866: 1004866
+   4867: 1004867
+   4868: 1004868
+   4869: 1004869
+   4870: 1004870
+   4871: 1004871
+   4872: 1004872
+   4873: 1004873
+   4874: 1004874
+   4875: 1004875
+   4876: 1004876
+   4877: 1004877
+   4878: 1004878
+   4879: 1004879
+   4880: 1004880
+   4881: 1004881
+   4882: 1004882
+   4883: 1004883
+   4884: 1004884
+   4885: 1004885
+   4886: 1004886
+   4887: 1004887
+   4888: 1004888
+   4889: 1004889
+   4890: 1004890
+   4891: 1004891
+   4892: 1004892
+   4893: 1004893
+   4894: 1004894
+   4895: 1004895
+   4896: 1004896
+   4897: 1004897
+   4898: 1004898
+   4899: 1004899
+   4900: 1004900
+   4901: 1004901
+   4902: 1004902
+   4903: 1004903
+   4904: 1004904
+   4905: 1004905
+   4906: 1004906
+   4907: 1004907
+   4908: 1004908
+   4909: 1004909
+   4910: 1004910
+   4911: 1004911
+   4912: 1004912
+   4913: 1004913
+   4914: 1004914
+   4915: 1004915
+   4916: 1004916
+   4917: 1004917
+   4918: 1004918
+   4919: 1004919
+   4920: 1004920
+   4921: 1004921
+   4922: 1004922
+   4923: 1004923
+   4924: 1004924
+   4925: 1004925
+   4926: 1004926
+   4927: 1004927
+   4928: 1004928
+   4929: 1004929
+   4930: 1004930
+   4931: 1004931
+   4932: 1004932
+   4933: 1004933
+   4934: 1004934
+   4935: 1004935
+   4936: 1004936
+   4937: 1004937
+   4938: 1004938
+   4939: 1004939
+   4940: 1004940
+   4941: 1004941
+   4942: 1004942
+   4943: 1004943
+   4944: 1004944
+   4945: 1004945
+   4946: 1004946
+   4947: 1004947
+   4948: 1004948
+   4949: 1004949
+   4950: 1004950
+   4951: 1004951
+   4952: 1004952
+   4953: 1004953
+   4954: 1004954
+   4955: 1004955
+   4956: 1004956
+   4957: 1004957
+   4958: 1004958
+   4959: 1004959
+   4960: 1004960
+   4961: 1004961
+   4962: 1004962
+   4963: 1004963
+   4964: 1004964
+   4965: 1004965
+   4966: 1004966
+   4967: 1004967
+   4968: 1004968
+   4969: 1004969
+   4970: 1004970
+   4971: 1004971
+   4972: 1004972
+   4973: 1004973
+   4974: 1004974
+   4975: 1004975
+   4976: 1004976
+   4977: 1004977
+   4978: 1004978
+   4979: 1004979
+   4980: 1004980
+   4981: 1004981
+   4982: 1004982
+   4983: 1004983
+   4984: 1004984
+   4985: 1004985
+   4986: 1004986
+   4987: 1004987
+   4988: 1004988
+   4989: 1004989
+   4990: 1004990
+   4991: 1004991
+   4992: 1004992
+   4993: 1004993
+   4994: 1004994
+   4995: 1004995
+   4996: 1004996
+   4997: 1004997
+   4998: 1004998
+   4999: 1004999
+   5000: 1005000
+   5001: 1005001
+   5002: 1005002
+   5003: 1005003
+   5004: 1005004
+   5005: 1005005
+   5006: 1005006
+   5007: 1005007
+   5008: 1005008
+   5009: 1005009
+   5010: 1005010
+   5011: 1005011
+   5012: 1005012
+   5013: 1005013
+   5014: 1005014
+   5015: 1005015
+   5016: 1005016
+   5017: 1005017
+   5018: 1005018
+   5019: 1005019
+   5020: 1005020
+   5021: 1005021
+   5022: 1005022
+   5023: 1005023
+   5024: 1005024
+   5025: 1005025
+   5026: 1005026
+   5027: 1005027
+   5028: 1005028
+   5029: 1005029
+   5030: 1005030
+   5031: 1005031
+   5032: 1005032
+   5033: 1005033
+   5034: 1005034
+   5035: 1005035
+   5036: 1005036
+   5037: 1005037
+   5038: 1005038
+   5039: 1005039
+   5040: 1005040
+   5041: 1005041
+   5042: 1005042
+   5043: 1005043
+   5044: 1005044
+   5045: 1005045
+   5046: 1005046
+   5047: 1005047
+   5048: 1005048
+   5049: 1005049
+   5050: 1005050
+   5051: 1005051
+   5052: 1005052
+   5053: 1005053
+   5054: 1005054
+   5055: 1005055
+   5056: 1005056
+   5057: 1005057
+   5058: 1005058
+   5059: 1005059
+   5060: 1005060
+   5061: 1005061
+   5062: 1005062
+   5063: 1005063
+   5064: 1005064
+   5065: 1005065
+   5066: 1005066
+   5067: 1005067
+   5068: 1005068
+   5069: 1005069
+   5070: 1005070
+   5071: 1005071
+   5072: 1005072
+   5073: 1005073
+   5074: 1005074
+   5075: 1005075
+   5076: 1005076
+   5077: 1005077
+   5078: 1005078
+   5079: 1005079
+   5080: 1005080
+   5081: 1005081
+   5082: 1005082
+   5083: 1005083
+   5084: 1005084
+   5085: 1005085
+   5086: 1005086
+   5087: 1005087
+   5088: 1005088
+   5089: 1005089
+   5090: 1005090
+   5091: 1005091
+   5092: 1005092
+   5093: 1005093
+   5094: 1005094
+   5095: 1005095
+   5096: 1005096
+   5097: 1005097
+   5098: 1005098
+   5099: 1005099
+   5100: 1005100
+   5101: 1005101
+   5102: 1005102
+   5103: 1005103
+   5104: 1005104
+   5105: 1005105
+   5106: 1005106
+   5107: 1005107
+   5108: 1005108
+   5109: 1005109
+   5110: 1005110
+   5111: 1005111
+   5112: 1005112
+   5113: 1005113
+   5114: 1005114
+   5115: 1005115
+   5116: 1005116
+   5117: 1005117
+   5118: 1005118
+   5119: 1005119
+   5120: 1005120
+   5121: 1005121
+   5122: 1005122
+   5123: 1005123
+   5124: 1005124
+   5125: 1005125
+   5126: 1005126
+   5127: 1005127
+   5128: 1005128
+   5129: 1005129
+   5130: 1005130
+   5131: 1005131
+   5132: 1005132
+   5133: 1005133
+   5134: 1005134
+   5135: 1005135
+   5136: 1005136
+   5137: 1005137
+   5138: 1005138
+   5139: 1005139
+   5140: 1005140
+   5141: 1005141
+   5142: 1005142
+   5143: 1005143
+   5144: 1005144
+   5145: 1005145
+   5146: 1005146
+   5147: 1005147
+   5148: 1005148
+   5149: 1005149
+   5150: 1005150
+   5151: 1005151
+   5152: 1005152
+   5153: 1005153
+   5154: 1005154
+   5155: 1005155
+   5156: 1005156
+   5157: 1005157
+   5158: 1005158
+   5159: 1005159
+   5160: 1005160
+   5161: 1005161
+   5162: 1005162
+   5163: 1005163
+   5164: 1005164
+   5165: 1005165
+   5166: 1005166
+   5167: 1005167
+   5168: 1005168
+   5169: 1005169
+   5170: 1005170
+   5171: 1005171
+   5172: 1005172
+   5173: 1005173
+   5174: 1005174
+   5175: 1005175
+   5176: 1005176
+   5177: 1005177
+   5178: 1005178
+   5179: 1005179
+   5180: 1005180
+   5181: 1005181
+   5182: 1005182
+   5183: 1005183
+   5184: 1005184
+   5185: 1005185
+   5186: 1005186
+   5187: 1005187
+   5188: 1005188
+   5189: 1005189
+   5190: 1005190
+   5191: 1005191
+   5192: 1005192
+   5193: 1005193
+   5194: 1005194
+   5195: 1005195
+   5196: 1005196
+   5197: 1005197
+   5198: 1005198
+   5199: 1005199
+   5200: 1005200
+   5201: 1005201
+   5202: 1005202
+   5203: 1005203
+   5204: 1005204
+   5205: 1005205
+   5206: 1005206
+   5207: 1005207
+   5208: 1005208
+   5209: 1005209
+   5210: 1005210
+   5211: 1005211
+   5212: 1005212
+   5213: 1005213
+   5214: 1005214
+   5215: 1005215
+   5216: 1005216
+   5217: 1005217
+   5218: 1005218
+   5219: 1005219
+   5220: 1005220
+   5221: 1005221
+   5222: 1005222
+   5223: 1005223
+   5224: 1005224
+   5225: 1005225
+   5226: 1005226
+   5227: 1005227
+   5228: 1005228
+   5229: 1005229
+   5230: 1005230
+   5231: 1005231
+   5232: 1005232
+   5233: 1005233
+   5234: 1005234
+   5235: 1005235
+   5236: 1005236
+   5237: 1005237
+   5238: 1005238
+   5239: 1005239
+   5240: 1005240
+   5241: 1005241
+   5242: 1005242
+   5243: 1005243
+   5244: 1005244
+   5245: 1005245
+   5246: 1005246
+   5247: 1005247
+   5248: 1005248
+   5249: 1005249
+   5250: 1005250
+   5251: 1005251
+   5252: 1005252
+   5253: 1005253
+   5254: 1005254
+   5255: 1005255
+   5256: 1005256
+   5257: 1005257
+   5258: 1005258
+   5259: 1005259
+   5260: 1005260
+   5261: 1005261
+   5262: 1005262
+   5263: 1005263
+   5264: 1005264
+   5265: 1005265
+   5266: 1005266
+   5267: 1005267
+   5268: 1005268
+   5269: 1005269
+   5270: 1005270
+   5271: 1005271
+   5272: 1005272
+   5273: 1005273
+   5274: 1005274
+   5275: 1005275
+   5276: 1005276
+   5277: 1005277
+   5278: 1005278
+   5279: 1005279
+   5280: 1005280
+   5281: 1005281
+   5282: 1005282
+   5283: 1005283
+   5284: 1005284
+   5285: 1005285
+   5286: 1005286
+   5287: 1005287
+   5288: 1005288
+   5289: 1005289
+   5290: 1005290
+   5291: 1005291
+   5292: 1005292
+   5293: 1005293
+   5294: 1005294
+   5295: 1005295
+   5296: 1005296
+   5297: 1005297
+   5298: 1005298
+   5299: 1005299
+   5300: 1005300
+   5301: 1005301
+   5302: 1005302
+   5303: 1005303
+   5304: 1005304
+   5305: 1005305
+   5306: 1005306
+   5307: 1005307
+   5308: 1005308
+   5309: 1005309
+   5310: 1005310
+   5311: 1005311
+   5312: 1005312
+   5313: 1005313
+   5314: 1005314
+   5315: 1005315
+   5316: 1005316
+   5317: 1005317
+   5318: 1005318
+   5319: 1005319
+   5320: 1005320
+   5321: 1005321
+   5322: 1005322
+   5323: 1005323
+   5324: 1005324
+   5325: 1005325
+   5326: 1005326
+   5327: 1005327
+   5328: 1005328
+   5329: 1005329
+   5330: 1005330
+   5331: 1005331
+   5332: 1005332
+   5333: 1005333
+   5334: 1005334
+   5335: 1005335
+   5336: 1005336
+   5337: 1005337
+   5338: 1005338
+   5339: 1005339
+   5340: 1005340
+   5341: 1005341
+   5342: 1005342
+   5343: 1005343
+   5344: 1005344
+   5345: 1005345
+   5346: 1005346
+   5347: 1005347
+   5348: 1005348
+   5349: 1005349
+   5350: 1005350
+   5351: 1005351
+   5352: 1005352
+   5353: 1005353
+   5354: 1005354
+   5355: 1005355
+   5356: 1005356
+   5357: 1005357
+   5358: 1005358
+   5359: 1005359
+   5360: 1005360
+   5361: 1005361
+   5362: 1005362
+   5363: 1005363
+   5364: 1005364
+   5365: 1005365
+   5366: 1005366
+   5367: 1005367
+   5368: 1005368
+   5369: 1005369
+   5370: 1005370
+   5371: 1005371
+   5372: 1005372
+   5373: 1005373
+   5374: 1005374
+   5375: 1005375
+   5376: 1005376
+   5377: 1005377
+   5378: 1005378
+   5379: 1005379
+   5380: 1005380
+   5381: 1005381
+   5382: 1005382
+   5383: 1005383
+   5384: 1005384
+   5385: 1005385
+   5386: 1005386
+   5387: 1005387
+   5388: 1005388
+   5389: 1005389
+   5390: 1005390
+   5391: 1005391
+   5392: 1005392
+   5393: 1005393
+   5394: 1005394
+   5395: 1005395
+   5396: 1005396
+   5397: 1005397
+   5398: 1005398
+   5399: 1005399
+   5400: 1005400
+   5401: 1005401
+   5402: 1005402
+   5403: 1005403
+   5404: 1005404
+   5405: 1005405
+   5406: 1005406
+   5407: 1005407
+   5408: 1005408
+   5409: 1005409
+   5410: 1005410
+   5411: 1005411
+   5412: 1005412
+   5413: 1005413
+   5414: 1005414
+   5415: 1005415
+   5416: 1005416
+   5417: 1005417
+   5418: 1005418
+   5419: 1005419
+   5420: 1005420
+   5421: 1005421
+   5422: 1005422
+   5423: 1005423
+   5424: 1005424
+   5425: 1005425
+   5426: 1005426
+   5427: 1005427
+   5428: 1005428
+   5429: 1005429
+   5430: 1005430
+   5431: 1005431
+   5432: 1005432
+   5433: 1005433
+   5434: 1005434
+   5435: 1005435
+   5436: 1005436
+   5437: 1005437
+   5438: 1005438
+   5439: 1005439
+   5440: 1005440
+   5441: 1005441
+   5442: 1005442
+   5443: 1005443
+   5444: 1005444
+   5445: 1005445
+   5446: 1005446
+   5447: 1005447
+   5448: 1005448
+   5449: 1005449
+   5450: 1005450
+   5451: 1005451
+   5452: 1005452
+   5453: 1005453
+   5454: 1005454
+   5455: 1005455
+   5456: 1005456
+   5457: 1005457
+   5458: 1005458
+   5459: 1005459
+   5460: 1005460
+   5461: 1005461
+   5462: 1005462
+   5463: 1005463
+   5464: 1005464
+   5465: 1005465
+   5466: 1005466
+   5467: 1005467
+   5468: 1005468
+   5469: 1005469
+   5470: 1005470
+   5471: 1005471
+   5472: 1005472
+   5473: 1005473
+   5474: 1005474
+   5475: 1005475
+   5476: 1005476
+   5477: 1005477
+   5478: 1005478
+   5479: 1005479
+   5480: 1005480
+   5481: 1005481
+   5482: 1005482
+   5483: 1005483
+   5484: 1005484
+   5485: 1005485
+   5486: 1005486
+   5487: 1005487
+   5488: 1005488
+   5489: 1005489
+   5490: 1005490
+   5491: 1005491
+   5492: 1005492
+   5493: 1005493
+   5494: 1005494
+   5495: 1005495
+   5496: 1005496
+   5497: 1005497
+   5498: 1005498
+   5499: 1005499
+   5500: 1005500
+   5501: 1005501
+   5502: 1005502
+   5503: 1005503
+   5504: 1005504
+   5505: 1005505
+   5506: 1005506
+   5507: 1005507
+   5508: 1005508
+   5509: 1005509
+   5510: 1005510
+   5511: 1005511
+   5512: 1005512
+   5513: 1005513
+   5514: 1005514
+   5515: 1005515
+   5516: 1005516
+   5517: 1005517
+   5518: 1005518
+   5519: 1005519
+   5520: 1005520
+   5521: 1005521
+   5522: 1005522
+   5523: 1005523
+   5524: 1005524
+   5525: 1005525
+   5526: 1005526
+   5527: 1005527
+   5528: 1005528
+   5529: 1005529
+   5530: 1005530
+   5531: 1005531
+   5532: 1005532
+   5533: 1005533
+   5534: 1005534
+   5535: 1005535
+   5536: 1005536
+   5537: 1005537
+   5538: 1005538
+   5539: 1005539
+   5540: 1005540
+   5541: 1005541
+   5542: 1005542
+   5543: 1005543
+   5544: 1005544
+   5545: 1005545
+   5546: 1005546
+   5547: 1005547
+   5548: 1005548
+   5549: 1005549
+   5550: 1005550
+   5551: 1005551
+   5552: 1005552
+   5553: 1005553
+   5554: 1005554
+   5555: 1005555
+   5556: 1005556
+   5557: 1005557
+   5558: 1005558
+   5559: 1005559
+   5560: 1005560
+   5561: 1005561
+   5562: 1005562
+   5563: 1005563
+   5564: 1005564
+   5565: 1005565
+   5566: 1005566
+   5567: 1005567
+   5568: 1005568
+   5569: 1005569
+   5570: 1005570
+   5571: 1005571
+   5572: 1005572
+   5573: 1005573
+   5574: 1005574
+   5575: 1005575
+   5576: 1005576
+   5577: 1005577
+   5578: 1005578
+   5579: 1005579
+   5580: 1005580
+   5581: 1005581
+   5582: 1005582
+   5583: 1005583
+   5584: 1005584
+   5585: 1005585
+   5586: 1005586
+   5587: 1005587
+   5588: 1005588
+   5589: 1005589
+   5590: 1005590
+   5591: 1005591
+   5592: 1005592
+   5593: 1005593
+   5594: 1005594
+   5595: 1005595
+   5596: 1005596
+   5597: 1005597
+   5598: 1005598
+   5599: 1005599
+   5600: 1005600
+   5601: 1005601
+   5602: 1005602
+   5603: 1005603
+   5604: 1005604
+   5605: 1005605
+   5606: 1005606
+   5607: 1005607
+   5608: 1005608
+   5609: 1005609
+   5610: 1005610
+   5611: 1005611
+   5612: 1005612
+   5613: 1005613
+   5614: 1005614
+   5615: 1005615
+   5616: 1005616
+   5617: 1005617
+   5618: 1005618
+   5619: 1005619
+   5620: 1005620
+   5621: 1005621
+   5622: 1005622
+   5623: 1005623
+   5624: 1005624
+   5625: 1005625
+   5626: 1005626
+   5627: 1005627
+   5628: 1005628
+   5629: 1005629
+   5630: 1005630
+   5631: 1005631
+   5632: 1005632
+   5633: 1005633
+   5634: 1005634
+   5635: 1005635
+   5636: 1005636
+   5637: 1005637
+   5638: 1005638
+   5639: 1005639
+   5640: 1005640
+   5641: 1005641
+   5642: 1005642
+   5643: 1005643
+   5644: 1005644
+   5645: 1005645
+   5646: 1005646
+   5647: 1005647
+   5648: 1005648
+   5649: 1005649
+   5650: 1005650
+   5651: 1005651
+   5652: 1005652
+   5653: 1005653
+   5654: 1005654
+   5655: 1005655
+   5656: 1005656
+   5657: 1005657
+   5658: 1005658
+   5659: 1005659
+   5660: 1005660
+   5661: 1005661
+   5662: 1005662
+   5663: 1005663
+   5664: 1005664
+   5665: 1005665
+   5666: 1005666
+   5667: 1005667
+   5668: 1005668
+   5669: 1005669
+   5670: 1005670
+   5671: 1005671
+   5672: 1005672
+   5673: 1005673
+   5674: 1005674
+   5675: 1005675
+   5676: 1005676
+   5677: 1005677
+   5678: 1005678
+   5679: 1005679
+   5680: 1005680
+   5681: 1005681
+   5682: 1005682
+   5683: 1005683
+   5684: 1005684
+   5685: 1005685
+   5686: 1005686
+   5687: 1005687
+   5688: 1005688
+   5689: 1005689
+   5690: 1005690
+   5691: 1005691
+   5692: 1005692
+   5693: 1005693
+   5694: 1005694
+   5695: 1005695
+   5696: 1005696
+   5697: 1005697
+   5698: 1005698
+   5699: 1005699
+   5700: 1005700
+   5701: 1005701
+   5702: 1005702
+   5703: 1005703
+   5704: 1005704
+   5705: 1005705
+   5706: 1005706
+   5707: 1005707
+   5708: 1005708
+   5709: 1005709
+   5710: 1005710
+   5711: 1005711
+   5712: 1005712
+   5713: 1005713
+   5714: 1005714
+   5715: 1005715
+   5716: 1005716
+   5717: 1005717
+   5718: 1005718
+   5719: 1005719
+   5720: 1005720
+   5721: 1005721
+   5722: 1005722
+   5723: 1005723
+   5724: 1005724
+   5725: 1005725
+   5726: 1005726
+   5727: 1005727
+   5728: 1005728
+   5729: 1005729
+   5730: 1005730
+   5731: 1005731
+   5732: 1005732
+   5733: 1005733
+   5734: 1005734
+   5735: 1005735
+   5736: 1005736
+   5737: 1005737
+   5738: 1005738
+   5739: 1005739
+   5740: 1005740
+   5741: 1005741
+   5742: 1005742
+   5743: 1005743
+   5744: 1005744
+   5745: 1005745
+   5746: 1005746
+   5747: 1005747
+   5748: 1005748
+   5749: 1005749
+   5750: 1005750
+   5751: 1005751
+   5752: 1005752
+   5753: 1005753
+   5754: 1005754
+   5755: 1005755
+   5756: 1005756
+   5757: 1005757
+   5758: 1005758
+   5759: 1005759
+   5760: 1005760
+   5761: 1005761
+   5762: 1005762
+   5763: 1005763
+   5764: 1005764
+   5765: 1005765
+   5766: 1005766
+   5767: 1005767
+   5768: 1005768
+   5769: 1005769
+   5770: 1005770
+   5771: 1005771
+   5772: 1005772
+   5773: 1005773
+   5774: 1005774
+   5775: 1005775
+   5776: 1005776
+   5777: 1005777
+   5778: 1005778
+   5779: 1005779
+   5780: 1005780
+   5781: 1005781
+   5782: 1005782
+   5783: 1005783
+   5784: 1005784
+   5785: 1005785
+   5786: 1005786
+   5787: 1005787
+   5788: 1005788
+   5789: 1005789
+   5790: 1005790
+   5791: 1005791
+   5792: 1005792
+   5793: 1005793
+   5794: 1005794
+   5795: 1005795
+   5796: 1005796
+   5797: 1005797
+   5798: 1005798
+   5799: 1005799
+   5800: 1005800
+   5801: 1005801
+   5802: 1005802
+   5803: 1005803
+   5804: 1005804
+   5805: 1005805
+   5806: 1005806
+   5807: 1005807
+   5808: 1005808
+   5809: 1005809
+   5810: 1005810
+   5811: 1005811
+   5812: 1005812
+   5813: 1005813
+   5814: 1005814
+   5815: 1005815
+   5816: 1005816
+   5817: 1005817
+   5818: 1005818
+   5819: 1005819
+   5820: 1005820
+   5821: 1005821
+   5822: 1005822
+   5823: 1005823
+   5824: 1005824
+   5825: 1005825
+   5826: 1005826
+   5827: 1005827
+   5828: 1005828
+   5829: 1005829
+   5830: 1005830
+   5831: 1005831
+   5832: 1005832
+   5833: 1005833
+   5834: 1005834
+   5835: 1005835
+   5836: 1005836
+   5837: 1005837
+   5838: 1005838
+   5839: 1005839
+   5840: 1005840
+   5841: 1005841
+   5842: 1005842
+   5843: 1005843
+   5844: 1005844
+   5845: 1005845
+   5846: 1005846
+   5847: 1005847
+   5848: 1005848
+   5849: 1005849
+   5850: 1005850
+   5851: 1005851
+   5852: 1005852
+   5853: 1005853
+   5854: 1005854
+   5855: 1005855
+   5856: 1005856
+   5857: 1005857
+   5858: 1005858
+   5859: 1005859
+   5860: 1005860
+   5861: 1005861
+   5862: 1005862
+   5863: 1005863
+   5864: 1005864
+   5865: 1005865
+   5866: 1005866
+   5867: 1005867
+   5868: 1005868
+   5869: 1005869
+   5870: 1005870
+   5871: 1005871
+   5872: 1005872
+   5873: 1005873
+   5874: 1005874
+   5875: 1005875
+   5876: 1005876
+   5877: 1005877
+   5878: 1005878
+   5879: 1005879
+   5880: 1005880
+   5881: 1005881
+   5882: 1005882
+   5883: 1005883
+   5884: 1005884
+   5885: 1005885
+   5886: 1005886
+   5887: 1005887
+   5888: 1005888
+   5889: 1005889
+   5890: 1005890
+   5891: 1005891
+   5892: 1005892
+   5893: 1005893
+   5894: 1005894
+   5895: 1005895
+   5896: 1005896
+   5897: 1005897
+   5898: 1005898
+   5899: 1005899
+   5900: 1005900
+   5901: 1005901
+   5902: 1005902
+   5903: 1005903
+   5904: 1005904
+   5905: 1005905
+   5906: 1005906
+   5907: 1005907
+   5908: 1005908
+   5909: 1005909
+   5910: 1005910
+   5911: 1005911
+   5912: 1005912
+   5913: 1005913
+   5914: 1005914
+   5915: 1005915
+   5916: 1005916
+   5917: 1005917
+   5918: 1005918
+   5919: 1005919
+   5920: 1005920
+   5921: 1005921
+   5922: 1005922
+   5923: 1005923
+   5924: 1005924
+   5925: 1005925
+   5926: 1005926
+   5927: 1005927
+   5928: 1005928
+   5929: 1005929
+   5930: 1005930
+   5931: 1005931
+   5932: 1005932
+   5933: 1005933
+   5934: 1005934
+   5935: 1005935
+   5936: 1005936
+   5937: 1005937
+   5938: 1005938
+   5939: 1005939
+   5940: 1005940
+   5941: 1005941
+   5942: 1005942
+   5943: 1005943
+   5944: 1005944
+   5945: 1005945
+   5946: 1005946
+   5947: 1005947
+   5948: 1005948
+   5949: 1005949
+   5950: 1005950
+   5951: 1005951
+   5952: 1005952
+   5953: 1005953
+   5954: 1005954
+   5955: 1005955
+   5956: 1005956
+   5957: 1005957
+   5958: 1005958
+   5959: 1005959
+   5960: 1005960
+   5961: 1005961
+   5962: 1005962
+   5963: 1005963
+   5964: 1005964
+   5965: 1005965
+   5966: 1005966
+   5967: 1005967
+   5968: 1005968
+   5969: 1005969
+   5970: 1005970
+   5971: 1005971
+   5972: 1005972
+   5973: 1005973
+   5974: 1005974
+   5975: 1005975
+   5976: 1005976
+   5977: 1005977
+   5978: 1005978
+   5979: 1005979
+   5980: 1005980
+   5981: 1005981
+   5982: 1005982
+   5983: 1005983
+   5984: 1005984
+   5985: 1005985
+   5986: 1005986
+   5987: 1005987
+   5988: 1005988
+   5989: 1005989
+   5990: 1005990
+   5991: 1005991
+   5992: 1005992
+   5993: 1005993
+   5994: 1005994
+   5995: 1005995
+   5996: 1005996
+   5997: 1005997
+   5998: 1005998
+   5999: 1005999
+   6000: 1006000
+   6001: 1006001
+   6002: 1006002
+   6003: 1006003
+   6004: 1006004
+   6005: 1006005
+   6006: 1006006
+   6007: 1006007
+   6008: 1006008
+   6009: 1006009
+   6010: 1006010
+   6011: 1006011
+   6012: 1006012
+   6013: 1006013
+   6014: 1006014
+   6015: 1006015
+   6016: 1006016
+   6017: 1006017
+   6018: 1006018
+   6019: 1006019
+   6020: 1006020
+   6021: 1006021
+   6022: 1006022
+   6023: 1006023
+   6024: 1006024
+   6025: 1006025
+   6026: 1006026
+   6027: 1006027
+   6028: 1006028
+   6029: 1006029
+   6030: 1006030
+   6031: 1006031
+   6032: 1006032
+   6033: 1006033
+   6034: 1006034
+   6035: 1006035
+   6036: 1006036
+   6037: 1006037
+   6038: 1006038
+   6039: 1006039
+   6040: 1006040
+   6041: 1006041
+   6042: 1006042
+   6043: 1006043
+   6044: 1006044
+   6045: 1006045
+   6046: 1006046
+   6047: 1006047
+   6048: 1006048
+   6049: 1006049
+   6050: 1006050
+   6051: 1006051
+   6052: 1006052
+   6053: 1006053
+   6054: 1006054
+   6055: 1006055
+   6056: 1006056
+   6057: 1006057
+   6058: 1006058
+   6059: 1006059
+   6060: 1006060
+   6061: 1006061
+   6062: 1006062
+   6063: 1006063
+   6064: 1006064
+   6065: 1006065
+   6066: 1006066
+   6067: 1006067
+   6068: 1006068
+   6069: 1006069
+   6070: 1006070
+   6071: 1006071
+   6072: 1006072
+   6073: 1006073
+   6074: 1006074
+   6075: 1006075
+   6076: 1006076
+   6077: 1006077
+   6078: 1006078
+   6079: 1006079
+   6080: 1006080
+   6081: 1006081
+   6082: 1006082
+   6083: 1006083
+   6084: 1006084
+   6085: 1006085
+   6086: 1006086
+   6087: 1006087
+   6088: 1006088
+   6089: 1006089
+   6090: 1006090
+   6091: 1006091
+   6092: 1006092
+   6093: 1006093
+   6094: 1006094
+   6095: 1006095
+   6096: 1006096
+   6097: 1006097
+   6098: 1006098
+   6099: 1006099
+   6100: 1006100
+   6101: 1006101
+   6102: 1006102
+   6103: 1006103
+   6104: 1006104
+   6105: 1006105
+   6106: 1006106
+   6107: 1006107
+   6108: 1006108
+   6109: 1006109
+   6110: 1006110
+   6111: 1006111
+   6112: 1006112
+   6113: 1006113
+   6114: 1006114
+   6115: 1006115
+   6116: 1006116
+   6117: 1006117
+   6118: 1006118
+   6119: 1006119
+   6120: 1006120
+   6121: 1006121
+   6122: 1006122
+   6123: 1006123
+   6124: 1006124
+   6125: 1006125
+   6126: 1006126
+   6127: 1006127
+   6128: 1006128
+   6129: 1006129
+   6130: 1006130
+   6131: 1006131
+   6132: 1006132
+   6133: 1006133
+   6134: 1006134
+   6135: 1006135
+   6136: 1006136
+   6137: 1006137
+   6138: 1006138
+   6139: 1006139
+   6140: 1006140
+   6141: 1006141
+   6142: 1006142
+   6143: 1006143
+   6144: 1006144
+   6145: 1006145
+   6146: 1006146
+   6147: 1006147
+   6148: 1006148
+   6149: 1006149
+   6150: 1006150
+   6151: 1006151
+   6152: 1006152
+   6153: 1006153
+   6154: 1006154
+   6155: 1006155
+   6156: 1006156
+   6157: 1006157
+   6158: 1006158
+   6159: 1006159
+   6160: 1006160
+   6161: 1006161
+   6162: 1006162
+   6163: 1006163
+   6164: 1006164
+   6165: 1006165
+   6166: 1006166
+   6167: 1006167
+   6168: 1006168
+   6169: 1006169
+   6170: 1006170
+   6171: 1006171
+   6172: 1006172
+   6173: 1006173
+   6174: 1006174
+   6175: 1006175
+   6176: 1006176
+   6177: 1006177
+   6178: 1006178
+   6179: 1006179
+   6180: 1006180
+   6181: 1006181
+   6182: 1006182
+   6183: 1006183
+   6184: 1006184
+   6185: 1006185
+   6186: 1006186
+   6187: 1006187
+   6188: 1006188
+   6189: 1006189
+   6190: 1006190
+   6191: 1006191
+   6192: 1006192
+   6193: 1006193
+   6194: 1006194
+   6195: 1006195
+   6196: 1006196
+   6197: 1006197
+   6198: 1006198
+   6199: 1006199
+   6200: 1006200
+   6201: 1006201
+   6202: 1006202
+   6203: 1006203
+   6204: 1006204
+   6205: 1006205
+   6206: 1006206
+   6207: 1006207
+   6208: 1006208
+   6209: 1006209
+   6210: 1006210
+   6211: 1006211
+   6212: 1006212
+   6213: 1006213
+   6214: 1006214
+   6215: 1006215
+   6216: 1006216
+   6217: 1006217
+   6218: 1006218
+   6219: 1006219
+   6220: 1006220
+   6221: 1006221
+   6222: 1006222
+   6223: 1006223
+   6224: 1006224
+   6225: 1006225
+   6226: 1006226
+   6227: 1006227
+   6228: 1006228
+   6229: 1006229
+   6230: 1006230
+   6231: 1006231
+   6232: 1006232
+   6233: 1006233
+   6234: 1006234
+   6235: 1006235
+   6236: 1006236
+   6237: 1006237
+   6238: 1006238
+   6239: 1006239
+   6240: 1006240
+   6241: 1006241
+   6242: 1006242
+   6243: 1006243
+   6244: 1006244
+   6245: 1006245
+   6246: 1006246
+   6247: 1006247
+   6248: 1006248
+   6249: 1006249
+   6250: 1006250
+   6251: 1006251
+   6252: 1006252
+   6253: 1006253
+   6254: 1006254
+   6255: 1006255
+   6256: 1006256
+   6257: 1006257
+   6258: 1006258
+   6259: 1006259
+   6260: 1006260
+   6261: 1006261
+   6262: 1006262
+   6263: 1006263
+   6264: 1006264
+   6265: 1006265
+   6266: 1006266
+   6267: 1006267
+   6268: 1006268
+   6269: 1006269
+   6270: 1006270
+   6271: 1006271
+   6272: 1006272
+   6273: 1006273
+   6274: 1006274
+   6275: 1006275
+   6276: 1006276
+   6277: 1006277
+   6278: 1006278
+   6279: 1006279
+   6280: 1006280
+   6281: 1006281
+   6282: 1006282
+   6283: 1006283
+   6284: 1006284
+   6285: 1006285
+   6286: 1006286
+   6287: 1006287
+   6288: 1006288
+   6289: 1006289
+   6290: 1006290
+   6291: 1006291
+   6292: 1006292
+   6293: 1006293
+   6294: 1006294
+   6295: 1006295
+   6296: 1006296
+   6297: 1006297
+   6298: 1006298
+   6299: 1006299
+   6300: 1006300
+   6301: 1006301
+   6302: 1006302
+   6303: 1006303
+   6304: 1006304
+   6305: 1006305
+   6306: 1006306
+   6307: 1006307
+   6308: 1006308
+   6309: 1006309
+   6310: 1006310
+   6311: 1006311
+   6312: 1006312
+   6313: 1006313
+   6314: 1006314
+   6315: 1006315
+   6316: 1006316
+   6317: 1006317
+   6318: 1006318
+   6319: 1006319
+   6320: 1006320
+   6321: 1006321
+   6322: 1006322
+   6323: 1006323
+   6324: 1006324
+   6325: 1006325
+   6326: 1006326
+   6327: 1006327
+   6328: 1006328
+   6329: 1006329
+   6330: 1006330
+   6331: 1006331
+   6332: 1006332
+   6333: 1006333
+   6334: 1006334
+   6335: 1006335
+   6336: 1006336
+   6337: 1006337
+   6338: 1006338
+   6339: 1006339
+   6340: 1006340
+   6341: 1006341
+   6342: 1006342
+   6343: 1006343
+   6344: 1006344
+   6345: 1006345
+   6346: 1006346
+   6347: 1006347
+   6348: 1006348
+   6349: 1006349
+   6350: 1006350
+   6351: 1006351
+   6352: 1006352
+   6353: 1006353
+   6354: 1006354
+   6355: 1006355
+   6356: 1006356
+   6357: 1006357
+   6358: 1006358
+   6359: 1006359
+   6360: 1006360
+   6361: 1006361
+   6362: 1006362
+   6363: 1006363
+   6364: 1006364
+   6365: 1006365
+   6366: 1006366
+   6367: 1006367
+   6368: 1006368
+   6369: 1006369
+   6370: 1006370
+   6371: 1006371
+   6372: 1006372
+   6373: 1006373
+   6374: 1006374
+   6375: 1006375
+   6376: 1006376
+   6377: 1006377
+   6378: 1006378
+   6379: 1006379
+   6380: 1006380
+   6381: 1006381
+   6382: 1006382
+   6383: 1006383
+   6384: 1006384
+   6385: 1006385
+   6386: 1006386
+   6387: 1006387
+   6388: 1006388
+   6389: 1006389
+   6390: 1006390
+   6391: 1006391
+   6392: 1006392
+   6393: 1006393
+   6394: 1006394
+   6395: 1006395
+   6396: 1006396
+   6397: 1006397
+   6398: 1006398
+   6399: 1006399
+   6400: 1006400
+   6401: 1006401
+   6402: 1006402
+   6403: 1006403
+   6404: 1006404
+   6405: 1006405
+   6406: 1006406
+   6407: 1006407
+   6408: 1006408
+   6409: 1006409
+   6410: 1006410
+   6411: 1006411
+   6412: 1006412
+   6413: 1006413
+   6414: 1006414
+   6415: 1006415
+   6416: 1006416
+   6417: 1006417
+   6418: 1006418
+   6419: 1006419
+   6420: 1006420
+   6421: 1006421
+   6422: 1006422
+   6423: 1006423
+   6424: 1006424
+   6425: 1006425
+   6426: 1006426
+   6427: 1006427
+   6428: 1006428
+   6429: 1006429
+   6430: 1006430
+   6431: 1006431
+   6432: 1006432
+   6433: 1006433
+   6434: 1006434
+   6435: 1006435
+   6436: 1006436
+   6437: 1006437
+   6438: 1006438
+   6439: 1006439
+   6440: 1006440
+   6441: 1006441
+   6442: 1006442
+   6443: 1006443
+   6444: 1006444
+   6445: 1006445
+   6446: 1006446
+   6447: 1006447
+   6448: 1006448
+   6449: 1006449
+   6450: 1006450
+   6451: 1006451
+   6452: 1006452
+   6453: 1006453
+   6454: 1006454
+   6455: 1006455
+   6456: 1006456
+   6457: 1006457
+   6458: 1006458
+   6459: 1006459
+   6460: 1006460
+   6461: 1006461
+   6462: 1006462
+   6463: 1006463
+   6464: 1006464
+   6465: 1006465
+   6466: 1006466
+   6467: 1006467
+   6468: 1006468
+   6469: 1006469
+   6470: 1006470
+   6471: 1006471
+   6472: 1006472
+   6473: 1006473
+   6474: 1006474
+   6475: 1006475
+   6476: 1006476
+   6477: 1006477
+   6478: 1006478
+   6479: 1006479
+   6480: 1006480
+   6481: 1006481
+   6482: 1006482
+   6483: 1006483
+   6484: 1006484
+   6485: 1006485
+   6486: 1006486
+   6487: 1006487
+   6488: 1006488
+   6489: 1006489
+   6490: 1006490
+   6491: 1006491
+   6492: 1006492
+   6493: 1006493
+   6494: 1006494
+   6495: 1006495
+   6496: 1006496
+   6497: 1006497
+   6498: 1006498
+   6499: 1006499
+   6500: 1006500
+   6501: 1006501
+   6502: 1006502
+   6503: 1006503
+   6504: 1006504
+   6505: 1006505
+   6506: 1006506
+   6507: 1006507
+   6508: 1006508
+   6509: 1006509
+   6510: 1006510
+   6511: 1006511
+   6512: 1006512
+   6513: 1006513
+   6514: 1006514
+   6515: 1006515
+   6516: 1006516
+   6517: 1006517
+   6518: 1006518
+   6519: 1006519
+   6520: 1006520
+   6521: 1006521
+   6522: 1006522
+   6523: 1006523
+   6524: 1006524
+   6525: 1006525
+   6526: 1006526
+   6527: 1006527
+   6528: 1006528
+   6529: 1006529
+   6530: 1006530
+   6531: 1006531
+   6532: 1006532
+   6533: 1006533
+   6534: 1006534
+   6535: 1006535
+   6536: 1006536
+   6537: 1006537
+   6538: 1006538
+   6539: 1006539
+   6540: 1006540
+   6541: 1006541
+   6542: 1006542
+   6543: 1006543
+   6544: 1006544
+   6545: 1006545
+   6546: 1006546
+   6547: 1006547
+   6548: 1006548
+   6549: 1006549
+   6550: 1006550
+   6551: 1006551
+   6552: 1006552
+   6553: 1006553
+   6554: 1006554
+   6555: 1006555
+   6556: 1006556
+   6557: 1006557
+   6558: 1006558
+   6559: 1006559
+   6560: 1006560
+   6561: 1006561
+   6562: 1006562
+   6563: 1006563
+   6564: 1006564
+   6565: 1006565
+   6566: 1006566
+   6567: 1006567
+   6568: 1006568
+   6569: 1006569
+   6570: 1006570
+   6571: 1006571
+   6572: 1006572
+   6573: 1006573
+   6574: 1006574
+   6575: 1006575
+   6576: 1006576
+   6577: 1006577
+   6578: 1006578
+   6579: 1006579
+   6580: 1006580
+   6581: 1006581
+   6582: 1006582
+   6583: 1006583
+   6584: 1006584
+   6585: 1006585
+   6586: 1006586
+   6587: 1006587
+   6588: 1006588
+   6589: 1006589
+   6590: 1006590
+   6591: 1006591
+   6592: 1006592
+   6593: 1006593
+   6594: 1006594
+   6595: 1006595
+   6596: 1006596
+   6597: 1006597
+   6598: 1006598
+   6599: 1006599
+   6600: 1006600
+   6601: 1006601
+   6602: 1006602
+   6603: 1006603
+   6604: 1006604
+   6605: 1006605
+   6606: 1006606
+   6607: 1006607
+   6608: 1006608
+   6609: 1006609
+   6610: 1006610
+   6611: 1006611
+   6612: 1006612
+   6613: 1006613
+   6614: 1006614
+   6615: 1006615
+   6616: 1006616
+   6617: 1006617
+   6618: 1006618
+   6619: 1006619
+   6620: 1006620
+   6621: 1006621
+   6622: 1006622
+   6623: 1006623
+   6624: 1006624
+   6625: 1006625
+   6626: 1006626
+   6627: 1006627
+   6628: 1006628
+   6629: 1006629
+   6630: 1006630
+   6631: 1006631
+   6632: 1006632
+   6633: 1006633
+   6634: 1006634
+   6635: 1006635
+   6636: 1006636
+   6637: 1006637
+   6638: 1006638
+   6639: 1006639
+   6640: 1006640
+   6641: 1006641
+   6642: 1006642
+   6643: 1006643
+   6644: 1006644
+   6645: 1006645
+   6646: 1006646
+   6647: 1006647
+   6648: 1006648
+   6649: 1006649
+   6650: 1006650
+   6651: 1006651
+   6652: 1006652
+   6653: 1006653
+   6654: 1006654
+   6655: 1006655
+   6656: 1006656
+   6657: 1006657
+   6658: 1006658
+   6659: 1006659
+   6660: 1006660
+   6661: 1006661
+   6662: 1006662
+   6663: 1006663
+   6664: 1006664
+   6665: 1006665
+   6666: 1006666
+   6667: 1006667
+   6668: 1006668
+   6669: 1006669
+   6670: 1006670
+   6671: 1006671
+   6672: 1006672
+   6673: 1006673
+   6674: 1006674
+   6675: 1006675
+   6676: 1006676
+   6677: 1006677
+   6678: 1006678
+   6679: 1006679
+   6680: 1006680
+   6681: 1006681
+   6682: 1006682
+   6683: 1006683
+   6684: 1006684
+   6685: 1006685
+   6686: 1006686
+   6687: 1006687
+   6688: 1006688
+   6689: 1006689
+   6690: 1006690
+   6691: 1006691
+   6692: 1006692
+   6693: 1006693
+   6694: 1006694
+   6695: 1006695
+   6696: 1006696
+   6697: 1006697
+   6698: 1006698
+   6699: 1006699
+   6700: 1006700
+   6701: 1006701
+   6702: 1006702
+   6703: 1006703
+   6704: 1006704
+   6705: 1006705
+   6706: 1006706
+   6707: 1006707
+   6708: 1006708
+   6709: 1006709
+   6710: 1006710
+   6711: 1006711
+   6712: 1006712
+   6713: 1006713
+   6714: 1006714
+   6715: 1006715
+   6716: 1006716
+   6717: 1006717
+   6718: 1006718
+   6719: 1006719
+   6720: 1006720
+   6721: 1006721
+   6722: 1006722
+   6723: 1006723
+   6724: 1006724
+   6725: 1006725
+   6726: 1006726
+   6727: 1006727
+   6728: 1006728
+   6729: 1006729
+   6730: 1006730
+   6731: 1006731
+   6732: 1006732
+   6733: 1006733
+   6734: 1006734
+   6735: 1006735
+   6736: 1006736
+   6737: 1006737
+   6738: 1006738
+   6739: 1006739
+   6740: 1006740
+   6741: 1006741
+   6742: 1006742
+   6743: 1006743
+   6744: 1006744
+   6745: 1006745
+   6746: 1006746
+   6747: 1006747
+   6748: 1006748
+   6749: 1006749
+   6750: 1006750
+   6751: 1006751
+   6752: 1006752
+   6753: 1006753
+   6754: 1006754
+   6755: 1006755
+   6756: 1006756
+   6757: 1006757
+   6758: 1006758
+   6759: 1006759
+   6760: 1006760
+   6761: 1006761
+   6762: 1006762
+   6763: 1006763
+   6764: 1006764
+   6765: 1006765
+   6766: 1006766
+   6767: 1006767
+   6768: 1006768
+   6769: 1006769
+   6770: 1006770
+   6771: 1006771
+   6772: 1006772
+   6773: 1006773
+   6774: 1006774
+   6775: 1006775
+   6776: 1006776
+   6777: 1006777
+   6778: 1006778
+   6779: 1006779
+   6780: 1006780
+   6781: 1006781
+   6782: 1006782
+   6783: 1006783
+   6784: 1006784
+   6785: 1006785
+   6786: 1006786
+   6787: 1006787
+   6788: 1006788
+   6789: 1006789
+   6790: 1006790
+   6791: 1006791
+   6792: 1006792
+   6793: 1006793
+   6794: 1006794
+   6795: 1006795
+   6796: 1006796
+   6797: 1006797
+   6798: 1006798
+   6799: 1006799
+   6800: 1006800
+   6801: 1006801
+   6802: 1006802
+   6803: 1006803
+   6804: 1006804
+   6805: 1006805
+   6806: 1006806
+   6807: 1006807
+   6808: 1006808
+   6809: 1006809
+   6810: 1006810
+   6811: 1006811
+   6812: 1006812
+   6813: 1006813
+   6814: 1006814
+   6815: 1006815
+   6816: 1006816
+   6817: 1006817
+   6818: 1006818
+   6819: 1006819
+   6820: 1006820
+   6821: 1006821
+   6822: 1006822
+   6823: 1006823
+   6824: 1006824
+   6825: 1006825
+   6826: 1006826
+   6827: 1006827
+   6828: 1006828
+   6829: 1006829
+   6830: 1006830
+   6831: 1006831
+   6832: 1006832
+   6833: 1006833
+   6834: 1006834
+   6835: 1006835
+   6836: 1006836
+   6837: 1006837
+   6838: 1006838
+   6839: 1006839
+   6840: 1006840
+   6841: 1006841
+   6842: 1006842
+   6843: 1006843
+   6844: 1006844
+   6845: 1006845
+   6846: 1006846
+   6847: 1006847
+   6848: 1006848
+   6849: 1006849
+   6850: 1006850
+   6851: 1006851
+   6852: 1006852
+   6853: 1006853
+   6854: 1006854
+   6855: 1006855
+   6856: 1006856
+   6857: 1006857
+   6858: 1006858
+   6859: 1006859
+   6860: 1006860
+   6861: 1006861
+   6862: 1006862
+   6863: 1006863
+   6864: 1006864
+   6865: 1006865
+   6866: 1006866
+   6867: 1006867
+   6868: 1006868
+   6869: 1006869
+   6870: 1006870
+   6871: 1006871
+   6872: 1006872
+   6873: 1006873
+   6874: 1006874
+   6875: 1006875
+   6876: 1006876
+   6877: 1006877
+   6878: 1006878
+   6879: 1006879
+   6880: 1006880
+   6881: 1006881
+   6882: 1006882
+   6883: 1006883
+   6884: 1006884
+   6885: 1006885
+   6886: 1006886
+   6887: 1006887
+   6888: 1006888
+   6889: 1006889
+   6890: 1006890
+   6891: 1006891
+   6892: 1006892
+   6893: 1006893
+   6894: 1006894
+   6895: 1006895
+   6896: 1006896
+   6897: 1006897
+   6898: 1006898
+   6899: 1006899
+   6900: 1006900
+   6901: 1006901
+   6902: 1006902
+   6903: 1006903
+   6904: 1006904
+   6905: 1006905
+   6906: 1006906
+   6907: 1006907
+   6908: 1006908
+   6909: 1006909
+   6910: 1006910
+   6911: 1006911
+   6912: 1006912
+   6913: 1006913
+   6914: 1006914
+   6915: 1006915
+   6916: 1006916
+   6917: 1006917
+   6918: 1006918
+   6919: 1006919
+   6920: 1006920
+   6921: 1006921
+   6922: 1006922
+   6923: 1006923
+   6924: 1006924
+   6925: 1006925
+   6926: 1006926
+   6927: 1006927
+   6928: 1006928
+   6929: 1006929
+   6930: 1006930
+   6931: 1006931
+   6932: 1006932
+   6933: 1006933
+   6934: 1006934
+   6935: 1006935
+   6936: 1006936
+   6937: 1006937
+   6938: 1006938
+   6939: 1006939
+   6940: 1006940
+   6941: 1006941
+   6942: 1006942
+   6943: 1006943
+   6944: 1006944
+   6945: 1006945
+   6946: 1006946
+   6947: 1006947
+   6948: 1006948
+   6949: 1006949
+   6950: 1006950
+   6951: 1006951
+   6952: 1006952
+   6953: 1006953
+   6954: 1006954
+   6955: 1006955
+   6956: 1006956
+   6957: 1006957
+   6958: 1006958
+   6959: 1006959
+   6960: 1006960
+   6961: 1006961
+   6962: 1006962
+   6963: 1006963
+   6964: 1006964
+   6965: 1006965
+   6966: 1006966
+   6967: 1006967
+   6968: 1006968
+   6969: 1006969
+   6970: 1006970
+   6971: 1006971
+   6972: 1006972
+   6973: 1006973
+   6974: 1006974
+   6975: 1006975
+   6976: 1006976
+   6977: 1006977
+   6978: 1006978
+   6979: 1006979
+   6980: 1006980
+   6981: 1006981
+   6982: 1006982
+   6983: 1006983
+   6984: 1006984
+   6985: 1006985
+   6986: 1006986
+   6987: 1006987
+   6988: 1006988
+   6989: 1006989
+   6990: 1006990
+   6991: 1006991
+   6992: 1006992
+   6993: 1006993
+   6994: 1006994
+   6995: 1006995
+   6996: 1006996
+   6997: 1006997
+   6998: 1006998
+   6999: 1006999
+   7000: 1007000
+   7001: 1007001
+   7002: 1007002
+   7003: 1007003
+   7004: 1007004
+   7005: 1007005
+   7006: 1007006
+   7007: 1007007
+   7008: 1007008
+   7009: 1007009
+   7010: 1007010
+   7011: 1007011
+   7012: 1007012
+   7013: 1007013
+   7014: 1007014
+   7015: 1007015
+   7016: 1007016
+   7017: 1007017
+   7018: 1007018
+   7019: 1007019
+   7020: 1007020
+   7021: 1007021
+   7022: 1007022
+   7023: 1007023
+   7024: 1007024
+   7025: 1007025
+   7026: 1007026
+   7027: 1007027
+   7028: 1007028
+   7029: 1007029
+   7030: 1007030
+   7031: 1007031
+   7032: 1007032
+   7033: 1007033
+   7034: 1007034
+   7035: 1007035
+   7036: 1007036
+   7037: 1007037
+   7038: 1007038
+   7039: 1007039
+   7040: 1007040
+   7041: 1007041
+   7042: 1007042
+   7043: 1007043
+   7044: 1007044
+   7045: 1007045
+   7046: 1007046
+   7047: 1007047
+   7048: 1007048
+   7049: 1007049
+   7050: 1007050
+   7051: 1007051
+   7052: 1007052
+   7053: 1007053
+   7054: 1007054
+   7055: 1007055
+   7056: 1007056
+   7057: 1007057
+   7058: 1007058
+   7059: 1007059
+   7060: 1007060
+   7061: 1007061
+   7062: 1007062
+   7063: 1007063
+   7064: 1007064
+   7065: 1007065
+   7066: 1007066
+   7067: 1007067
+   7068: 1007068
+   7069: 1007069
+   7070: 1007070
+   7071: 1007071
+   7072: 1007072
+   7073: 1007073
+   7074: 1007074
+   7075: 1007075
+   7076: 1007076
+   7077: 1007077
+   7078: 1007078
+   7079: 1007079
+   7080: 1007080
+   7081: 1007081
+   7082: 1007082
+   7083: 1007083
+   7084: 1007084
+   7085: 1007085
+   7086: 1007086
+   7087: 1007087
+   7088: 1007088
+   7089: 1007089
+   7090: 1007090
+   7091: 1007091
+   7092: 1007092
+   7093: 1007093
+   7094: 1007094
+   7095: 1007095
+   7096: 1007096
+   7097: 1007097
+   7098: 1007098
+   7099: 1007099
+   7100: 1007100
+   7101: 1007101
+   7102: 1007102
+   7103: 1007103
+   7104: 1007104
+   7105: 1007105
+   7106: 1007106
+   7107: 1007107
+   7108: 1007108
+   7109: 1007109
+   7110: 1007110
+   7111: 1007111
+   7112: 1007112
+   7113: 1007113
+   7114: 1007114
+   7115: 1007115
+   7116: 1007116
+   7117: 1007117
+   7118: 1007118
+   7119: 1007119
+   7120: 1007120
+   7121: 1007121
+   7122: 1007122
+   7123: 1007123
+   7124: 1007124
+   7125: 1007125
+   7126: 1007126
+   7127: 1007127
+   7128: 1007128
+   7129: 1007129
+   7130: 1007130
+   7131: 1007131
+   7132: 1007132
+   7133: 1007133
+   7134: 1007134
+   7135: 1007135
+   7136: 1007136
+   7137: 1007137
+   7138: 1007138
+   7139: 1007139
+   7140: 1007140
+   7141: 1007141
+   7142: 1007142
+   7143: 1007143
+   7144: 1007144
+   7145: 1007145
+   7146: 1007146
+   7147: 1007147
+   7148: 1007148
+   7149: 1007149
+   7150: 1007150
+   7151: 1007151
+   7152: 1007152
+   7153: 1007153
+   7154: 1007154
+   7155: 1007155
+   7156: 1007156
+   7157: 1007157
+   7158: 1007158
+   7159: 1007159
+   7160: 1007160
+   7161: 1007161
+   7162: 1007162
+   7163: 1007163
+   7164: 1007164
+   7165: 1007165
+   7166: 1007166
+   7167: 1007167
+   7168: 1007168
+   7169: 1007169
+   7170: 1007170
+   7171: 1007171
+   7172: 1007172
+   7173: 1007173
+   7174: 1007174
+   7175: 1007175
+   7176: 1007176
+   7177: 1007177
+   7178: 1007178
+   7179: 1007179
+   7180: 1007180
+   7181: 1007181
+   7182: 1007182
+   7183: 1007183
+   7184: 1007184
+   7185: 1007185
+   7186: 1007186
+   7187: 1007187
+   7188: 1007188
+   7189: 1007189
+   7190: 1007190
+   7191: 1007191
+   7192: 1007192
+   7193: 1007193
+   7194: 1007194
+   7195: 1007195
+   7196: 1007196
+   7197: 1007197
+   7198: 1007198
+   7199: 1007199
+   7200: 1007200
+   7201: 1007201
+   7202: 1007202
+   7203: 1007203
+   7204: 1007204
+   7205: 1007205
+   7206: 1007206
+   7207: 1007207
+   7208: 1007208
+   7209: 1007209
+   7210: 1007210
+   7211: 1007211
+   7212: 1007212
+   7213: 1007213
+   7214: 1007214
+   7215: 1007215
+   7216: 1007216
+   7217: 1007217
+   7218: 1007218
+   7219: 1007219
+   7220: 1007220
+   7221: 1007221
+   7222: 1007222
+   7223: 1007223
+   7224: 1007224
+   7225: 1007225
+   7226: 1007226
+   7227: 1007227
+   7228: 1007228
+   7229: 1007229
+   7230: 1007230
+   7231: 1007231
+   7232: 1007232
+   7233: 1007233
+   7234: 1007234
+   7235: 1007235
+   7236: 1007236
+   7237: 1007237
+   7238: 1007238
+   7239: 1007239
+   7240: 1007240
+   7241: 1007241
+   7242: 1007242
+   7243: 1007243
+   7244: 1007244
+   7245: 1007245
+   7246: 1007246
+   7247: 1007247
+   7248: 1007248
+   7249: 1007249
+   7250: 1007250
+   7251: 1007251
+   7252: 1007252
+   7253: 1007253
+   7254: 1007254
+   7255: 1007255
+   7256: 1007256
+   7257: 1007257
+   7258: 1007258
+   7259: 1007259
+   7260: 1007260
+   7261: 1007261
+   7262: 1007262
+   7263: 1007263
+   7264: 1007264
+   7265: 1007265
+   7266: 1007266
+   7267: 1007267
+   7268: 1007268
+   7269: 1007269
+   7270: 1007270
+   7271: 1007271
+   7272: 1007272
+   7273: 1007273
+   7274: 1007274
+   7275: 1007275
+   7276: 1007276
+   7277: 1007277
+   7278: 1007278
+   7279: 1007279
+   7280: 1007280
+   7281: 1007281
+   7282: 1007282
+   7283: 1007283
+   7284: 1007284
+   7285: 1007285
+   7286: 1007286
+   7287: 1007287
+   7288: 1007288
+   7289: 1007289
+   7290: 1007290
+   7291: 1007291
+   7292: 1007292
+   7293: 1007293
+   7294: 1007294
+   7295: 1007295
+   7296: 1007296
+   7297: 1007297
+   7298: 1007298
+   7299: 1007299
+   7300: 1007300
+   7301: 1007301
+   7302: 1007302
+   7303: 1007303
+   7304: 1007304
+   7305: 1007305
+   7306: 1007306
+   7307: 1007307
+   7308: 1007308
+   7309: 1007309
+   7310: 1007310
+   7311: 1007311
+   7312: 1007312
+   7313: 1007313
+   7314: 1007314
+   7315: 1007315
+   7316: 1007316
+   7317: 1007317
+   7318: 1007318
+   7319: 1007319
+   7320: 1007320
+   7321: 1007321
+   7322: 1007322
+   7323: 1007323
+   7324: 1007324
+   7325: 1007325
+   7326: 1007326
+   7327: 1007327
+   7328: 1007328
+   7329: 1007329
+   7330: 1007330
+   7331: 1007331
+   7332: 1007332
+   7333: 1007333
+   7334: 1007334
+   7335: 1007335
+   7336: 1007336
+   7337: 1007337
+   7338: 1007338
+   7339: 1007339
+   7340: 1007340
+   7341: 1007341
+   7342: 1007342
+   7343: 1007343
+   7344: 1007344
+   7345: 1007345
+   7346: 1007346
+   7347: 1007347
+   7348: 1007348
+   7349: 1007349
+   7350: 1007350
+   7351: 1007351
+   7352: 1007352
+   7353: 1007353
+   7354: 1007354
+   7355: 1007355
+   7356: 1007356
+   7357: 1007357
+   7358: 1007358
+   7359: 1007359
+   7360: 1007360
+   7361: 1007361
+   7362: 1007362
+   7363: 1007363
+   7364: 1007364
+   7365: 1007365
+   7366: 1007366
+   7367: 1007367
+   7368: 1007368
+   7369: 1007369
+   7370: 1007370
+   7371: 1007371
+   7372: 1007372
+   7373: 1007373
+   7374: 1007374
+   7375: 1007375
+   7376: 1007376
+   7377: 1007377
+   7378: 1007378
+   7379: 1007379
+   7380: 1007380
+   7381: 1007381
+   7382: 1007382
+   7383: 1007383
+   7384: 1007384
+   7385: 1007385
+   7386: 1007386
+   7387: 1007387
+   7388: 1007388
+   7389: 1007389
+   7390: 1007390
+   7391: 1007391
+   7392: 1007392
+   7393: 1007393
+   7394: 1007394
+   7395: 1007395
+   7396: 1007396
+   7397: 1007397
+   7398: 1007398
+   7399: 1007399
+   7400: 1007400
+   7401: 1007401
+   7402: 1007402
+   7403: 1007403
+   7404: 1007404
+   7405: 1007405
+   7406: 1007406
+   7407: 1007407
+   7408: 1007408
+   7409: 1007409
+   7410: 1007410
+   7411: 1007411
+   7412: 1007412
+   7413: 1007413
+   7414: 1007414
+   7415: 1007415
+   7416: 1007416
+   7417: 1007417
+   7418: 1007418
+   7419: 1007419
+   7420: 1007420
+   7421: 1007421
+   7422: 1007422
+   7423: 1007423
+   7424: 1007424
+   7425: 1007425
+   7426: 1007426
+   7427: 1007427
+   7428: 1007428
+   7429: 1007429
+   7430: 1007430
+   7431: 1007431
+   7432: 1007432
+   7433: 1007433
+   7434: 1007434
+   7435: 1007435
+   7436: 1007436
+   7437: 1007437
+   7438: 1007438
+   7439: 1007439
+   7440: 1007440
+   7441: 1007441
+   7442: 1007442
+   7443: 1007443
+   7444: 1007444
+   7445: 1007445
+   7446: 1007446
+   7447: 1007447
+   7448: 1007448
+   7449: 1007449
+   7450: 1007450
+   7451: 1007451
+   7452: 1007452
+   7453: 1007453
+   7454: 1007454
+   7455: 1007455
+   7456: 1007456
+   7457: 1007457
+   7458: 1007458
+   7459: 1007459
+   7460: 1007460
+   7461: 1007461
+   7462: 1007462
+   7463: 1007463
+   7464: 1007464
+   7465: 1007465
+   7466: 1007466
+   7467: 1007467
+   7468: 1007468
+   7469: 1007469
+   7470: 1007470
+   7471: 1007471
+   7472: 1007472
+   7473: 1007473
+   7474: 1007474
+   7475: 1007475
+   7476: 1007476
+   7477: 1007477
+   7478: 1007478
+   7479: 1007479
+   7480: 1007480
+   7481: 1007481
+   7482: 1007482
+   7483: 1007483
+   7484: 1007484
+   7485: 1007485
+   7486: 1007486
+   7487: 1007487
+   7488: 1007488
+   7489: 1007489
+   7490: 1007490
+   7491: 1007491
+   7492: 1007492
+   7493: 1007493
+   7494: 1007494
+   7495: 1007495
+   7496: 1007496
+   7497: 1007497
+   7498: 1007498
+   7499: 1007499
+   7500: 1007500
+   7501: 1007501
+   7502: 1007502
+   7503: 1007503
+   7504: 1007504
+   7505: 1007505
+   7506: 1007506
+   7507: 1007507
+   7508: 1007508
+   7509: 1007509
+   7510: 1007510
+   7511: 1007511
+   7512: 1007512
+   7513: 1007513
+   7514: 1007514
+   7515: 1007515
+   7516: 1007516
+   7517: 1007517
+   7518: 1007518
+   7519: 1007519
+   7520: 1007520
+   7521: 1007521
+   7522: 1007522
+   7523: 1007523
+   7524: 1007524
+   7525: 1007525
+   7526: 1007526
+   7527: 1007527
+   7528: 1007528
+   7529: 1007529
+   7530: 1007530
+   7531: 1007531
+   7532: 1007532
+   7533: 1007533
+   7534: 1007534
+   7535: 1007535
+   7536: 1007536
+   7537: 1007537
+   7538: 1007538
+   7539: 1007539
+   7540: 1007540
+   7541: 1007541
+   7542: 1007542
+   7543: 1007543
+   7544: 1007544
+   7545: 1007545
+   7546: 1007546
+   7547: 1007547
+   7548: 1007548
+   7549: 1007549
+   7550: 1007550
+   7551: 1007551
+   7552: 1007552
+   7553: 1007553
+   7554: 1007554
+   7555: 1007555
+   7556: 1007556
+   7557: 1007557
+   7558: 1007558
+   7559: 1007559
+   7560: 1007560
+   7561: 1007561
+   7562: 1007562
+   7563: 1007563
+   7564: 1007564
+   7565: 1007565
+   7566: 1007566
+   7567: 1007567
+   7568: 1007568
+   7569: 1007569
+   7570: 1007570
+   7571: 1007571
+   7572: 1007572
+   7573: 1007573
+   7574: 1007574
+   7575: 1007575
+   7576: 1007576
+   7577: 1007577
+   7578: 1007578
+   7579: 1007579
+   7580: 1007580
+   7581: 1007581
+   7582: 1007582
+   7583: 1007583
+   7584: 1007584
+   7585: 1007585
+   7586: 1007586
+   7587: 1007587
+   7588: 1007588
+   7589: 1007589
+   7590: 1007590
+   7591: 1007591
+   7592: 1007592
+   7593: 1007593
+   7594: 1007594
+   7595: 1007595
+   7596: 1007596
+   7597: 1007597
+   7598: 1007598
+   7599: 1007599
+   7600: 1007600
+   7601: 1007601
+   7602: 1007602
+   7603: 1007603
+   7604: 1007604
+   7605: 1007605
+   7606: 1007606
+   7607: 1007607
+   7608: 1007608
+   7609: 1007609
+   7610: 1007610
+   7611: 1007611
+   7612: 1007612
+   7613: 1007613
+   7614: 1007614
+   7615: 1007615
+   7616: 1007616
+   7617: 1007617
+   7618: 1007618
+   7619: 1007619
+   7620: 1007620
+   7621: 1007621
+   7622: 1007622
+   7623: 1007623
+   7624: 1007624
+   7625: 1007625
+   7626: 1007626
+   7627: 1007627
+   7628: 1007628
+   7629: 1007629
+   7630: 1007630
+   7631: 1007631
+   7632: 1007632
+   7633: 1007633
+   7634: 1007634
+   7635: 1007635
+   7636: 1007636
+   7637: 1007637
+   7638: 1007638
+   7639: 1007639
+   7640: 1007640
+   7641: 1007641
+   7642: 1007642
+   7643: 1007643
+   7644: 1007644
+   7645: 1007645
+   7646: 1007646
+   7647: 1007647
+   7648: 1007648
+   7649: 1007649
+   7650: 1007650
+   7651: 1007651
+   7652: 1007652
+   7653: 1007653
+   7654: 1007654
+   7655: 1007655
+   7656: 1007656
+   7657: 1007657
+   7658: 1007658
+   7659: 1007659
+   7660: 1007660
+   7661: 1007661
+   7662: 1007662
+   7663: 1007663
+   7664: 1007664
+   7665: 1007665
+   7666: 1007666
+   7667: 1007667
+   7668: 1007668
+   7669: 1007669
+   7670: 1007670
+   7671: 1007671
+   7672: 1007672
+   7673: 1007673
+   7674: 1007674
+   7675: 1007675
+   7676: 1007676
+   7677: 1007677
+   7678: 1007678
+   7679: 1007679
+   7680: 1007680
+   7681: 1007681
+   7682: 1007682
+   7683: 1007683
+   7684: 1007684
+   7685: 1007685
+   7686: 1007686
+   7687: 1007687
+   7688: 1007688
+   7689: 1007689
+   7690: 1007690
+   7691: 1007691
+   7692: 1007692
+   7693: 1007693
+   7694: 1007694
+   7695: 1007695
+   7696: 1007696
+   7697: 1007697
+   7698: 1007698
+   7699: 1007699
+   7700: 1007700
+   7701: 1007701
+   7702: 1007702
+   7703: 1007703
+   7704: 1007704
+   7705: 1007705
+   7706: 1007706
+   7707: 1007707
+   7708: 1007708
+   7709: 1007709
+   7710: 1007710
+   7711: 1007711
+   7712: 1007712
+   7713: 1007713
+   7714: 1007714
+   7715: 1007715
+   7716: 1007716
+   7717: 1007717
+   7718: 1007718
+   7719: 1007719
+   7720: 1007720
+   7721: 1007721
+   7722: 1007722
+   7723: 1007723
+   7724: 1007724
+   7725: 1007725
+   7726: 1007726
+   7727: 1007727
+   7728: 1007728
+   7729: 1007729
+   7730: 1007730
+   7731: 1007731
+   7732: 1007732
+   7733: 1007733
+   7734: 1007734
+   7735: 1007735
+   7736: 1007736
+   7737: 1007737
+   7738: 1007738
+   7739: 1007739
+   7740: 1007740
+   7741: 1007741
+   7742: 1007742
+   7743: 1007743
+   7744: 1007744
+   7745: 1007745
+   7746: 1007746
+   7747: 1007747
+   7748: 1007748
+   7749: 1007749
+   7750: 1007750
+   7751: 1007751
+   7752: 1007752
+   7753: 1007753
+   7754: 1007754
+   7755: 1007755
+   7756: 1007756
+   7757: 1007757
+   7758: 1007758
+   7759: 1007759
+   7760: 1007760
+   7761: 1007761
+   7762: 1007762
+   7763: 1007763
+   7764: 1007764
+   7765: 1007765
+   7766: 1007766
+   7767: 1007767
+   7768: 1007768
+   7769: 1007769
+   7770: 1007770
+   7771: 1007771
+   7772: 1007772
+   7773: 1007773
+   7774: 1007774
+   7775: 1007775
+   7776: 1007776
+   7777: 1007777
+   7778: 1007778
+   7779: 1007779
+   7780: 1007780
+   7781: 1007781
+   7782: 1007782
+   7783: 1007783
+   7784: 1007784
+   7785: 1007785
+   7786: 1007786
+   7787: 1007787
+   7788: 1007788
+   7789: 1007789
+   7790: 1007790
+   7791: 1007791
+   7792: 1007792
+   7793: 1007793
+   7794: 1007794
+   7795: 1007795
+   7796: 1007796
+   7797: 1007797
+   7798: 1007798
+   7799: 1007799
+   7800: 1007800
+   7801: 1007801
+   7802: 1007802
+   7803: 1007803
+   7804: 1007804
+   7805: 1007805
+   7806: 1007806
+   7807: 1007807
+   7808: 1007808
+   7809: 1007809
+   7810: 1007810
+   7811: 1007811
+   7812: 1007812
+   7813: 1007813
+   7814: 1007814
+   7815: 1007815
+   7816: 1007816
+   7817: 1007817
+   7818: 1007818
+   7819: 1007819
+   7820: 1007820
+   7821: 1007821
+   7822: 1007822
+   7823: 1007823
+   7824: 1007824
+   7825: 1007825
+   7826: 1007826
+   7827: 1007827
+   7828: 1007828
+   7829: 1007829
+   7830: 1007830
+   7831: 1007831
+   7832: 1007832
+   7833: 1007833
+   7834: 1007834
+   7835: 1007835
+   7836: 1007836
+   7837: 1007837
+   7838: 1007838
+   7839: 1007839
+   7840: 1007840
+   7841: 1007841
+   7842: 1007842
+   7843: 1007843
+   7844: 1007844
+   7845: 1007845
+   7846: 1007846
+   7847: 1007847
+   7848: 1007848
+   7849: 1007849
+   7850: 1007850
+   7851: 1007851
+   7852: 1007852
+   7853: 1007853
+   7854: 1007854
+   7855: 1007855
+   7856: 1007856
+   7857: 1007857
+   7858: 1007858
+   7859: 1007859
+   7860: 1007860
+   7861: 1007861
+   7862: 1007862
+   7863: 1007863
+   7864: 1007864
+   7865: 1007865
+   7866: 1007866
+   7867: 1007867
+   7868: 1007868
+   7869: 1007869
+   7870: 1007870
+   7871: 1007871
+   7872: 1007872
+   7873: 1007873
+   7874: 1007874
+   7875: 1007875
+   7876: 1007876
+   7877: 1007877
+   7878: 1007878
+   7879: 1007879
+   7880: 1007880
+   7881: 1007881
+   7882: 1007882
+   7883: 1007883
+   7884: 1007884
+   7885: 1007885
+   7886: 1007886
+   7887: 1007887
+   7888: 1007888
+   7889: 1007889
+   7890: 1007890
+   7891: 1007891
+   7892: 1007892
+   7893: 1007893
+   7894: 1007894
+   7895: 1007895
+   7896: 1007896
+   7897: 1007897
+   7898: 1007898
+   7899: 1007899
+   7900: 1007900
+   7901: 1007901
+   7902: 1007902
+   7903: 1007903
+   7904: 1007904
+   7905: 1007905
+   7906: 1007906
+   7907: 1007907
+   7908: 1007908
+   7909: 1007909
+   7910: 1007910
+   7911: 1007911
+   7912: 1007912
+   7913: 1007913
+   7914: 1007914
+   7915: 1007915
+   7916: 1007916
+   7917: 1007917
+   7918: 1007918
+   7919: 1007919
+   7920: 1007920
+   7921: 1007921
+   7922: 1007922
+   7923: 1007923
+   7924: 1007924
+   7925: 1007925
+   7926: 1007926
+   7927: 1007927
+   7928: 1007928
+   7929: 1007929
+   7930: 1007930
+   7931: 1007931
+   7932: 1007932
+   7933: 1007933
+   7934: 1007934
+   7935: 1007935
+   7936: 1007936
+   7937: 1007937
+   7938: 1007938
+   7939: 1007939
+   7940: 1007940
+   7941: 1007941
+   7942: 1007942
+   7943: 1007943
+   7944: 1007944
+   7945: 1007945
+   7946: 1007946
+   7947: 1007947
+   7948: 1007948
+   7949: 1007949
+   7950: 1007950
+   7951: 1007951
+   7952: 1007952
+   7953: 1007953
+   7954: 1007954
+   7955: 1007955
+   7956: 1007956
+   7957: 1007957
+   7958: 1007958
+   7959: 1007959
+   7960: 1007960
+   7961: 1007961
+   7962: 1007962
+   7963: 1007963
+   7964: 1007964
+   7965: 1007965
+   7966: 1007966
+   7967: 1007967
+   7968: 1007968
+   7969: 1007969
+   7970: 1007970
+   7971: 1007971
+   7972: 1007972
+   7973: 1007973
+   7974: 1007974
+   7975: 1007975
+   7976: 1007976
+   7977: 1007977
+   7978: 1007978
+   7979: 1007979
+   7980: 1007980
+   7981: 1007981
+   7982: 1007982
+   7983: 1007983
+   7984: 1007984
+   7985: 1007985
+   7986: 1007986
+   7987: 1007987
+   7988: 1007988
+   7989: 1007989
+   7990: 1007990
+   7991: 1007991
+   7992: 1007992
+   7993: 1007993
+   7994: 1007994
+   7995: 1007995
+   7996: 1007996
+   7997: 1007997
+   7998: 1007998
+   7999: 1007999
+   8000: 1008000
+   8001: 1008001
+   8002: 1008002
+   8003: 1008003
+   8004: 1008004
+   8005: 1008005
+   8006: 1008006
+   8007: 1008007
+   8008: 1008008
+   8009: 1008009
+   8010: 1008010
+   8011: 1008011
+   8012: 1008012
+   8013: 1008013
+   8014: 1008014
+   8015: 1008015
+   8016: 1008016
+   8017: 1008017
+   8018: 1008018
+   8019: 1008019
+   8020: 1008020
+   8021: 1008021
+   8022: 1008022
+   8023: 1008023
+   8024: 1008024
+   8025: 1008025
+   8026: 1008026
+   8027: 1008027
+   8028: 1008028
+   8029: 1008029
+   8030: 1008030
+   8031: 1008031
+   8032: 1008032
+   8033: 1008033
+   8034: 1008034
+   8035: 1008035
+   8036: 1008036
+   8037: 1008037
+   8038: 1008038
+   8039: 1008039
+   8040: 1008040
+   8041: 1008041
+   8042: 1008042
+   8043: 1008043
+   8044: 1008044
+   8045: 1008045
+   8046: 1008046
+   8047: 1008047
+   8048: 1008048
+   8049: 1008049
+   8050: 1008050
+   8051: 1008051
+   8052: 1008052
+   8053: 1008053
+   8054: 1008054
+   8055: 1008055
+   8056: 1008056
+   8057: 1008057
+   8058: 1008058
+   8059: 1008059
+   8060: 1008060
+   8061: 1008061
+   8062: 1008062
+   8063: 1008063
+   8064: 1008064
+   8065: 1008065
+   8066: 1008066
+   8067: 1008067
+   8068: 1008068
+   8069: 1008069
+   8070: 1008070
+   8071: 1008071
+   8072: 1008072
+   8073: 1008073
+   8074: 1008074
+   8075: 1008075
+   8076: 1008076
+   8077: 1008077
+   8078: 1008078
+   8079: 1008079
+   8080: 1008080
+   8081: 1008081
+   8082: 1008082
+   8083: 1008083
+   8084: 1008084
+   8085: 1008085
+   8086: 1008086
+   8087: 1008087
+   8088: 1008088
+   8089: 1008089
+   8090: 1008090
+   8091: 1008091
+   8092: 1008092
+   8093: 1008093
+   8094: 1008094
+   8095: 1008095
+   8096: 1008096
+   8097: 1008097
+   8098: 1008098
+   8099: 1008099
+   8100: 1008100
+   8101: 1008101
+   8102: 1008102
+   8103: 1008103
+   8104: 1008104
+   8105: 1008105
+   8106: 1008106
+   8107: 1008107
+   8108: 1008108
+   8109: 1008109
+   8110: 1008110
+   8111: 1008111
+   8112: 1008112
+   8113: 1008113
+   8114: 1008114
+   8115: 1008115
+   8116: 1008116
+   8117: 1008117
+   8118: 1008118
+   8119: 1008119
+   8120: 1008120
+   8121: 1008121
+   8122: 1008122
+   8123: 1008123
+   8124: 1008124
+   8125: 1008125
+   8126: 1008126
+   8127: 1008127
+   8128: 1008128
+   8129: 1008129
+   8130: 1008130
+   8131: 1008131
+   8132: 1008132
+   8133: 1008133
+   8134: 1008134
+   8135: 1008135
+   8136: 1008136
+   8137: 1008137
+   8138: 1008138
+   8139: 1008139
+   8140: 1008140
+   8141: 1008141
+   8142: 1008142
+   8143: 1008143
+   8144: 1008144
+   8145: 1008145
+   8146: 1008146
+   8147: 1008147
+   8148: 1008148
+   8149: 1008149
+   8150: 1008150
+   8151: 1008151
+   8152: 1008152
+   8153: 1008153
+   8154: 1008154
+   8155: 1008155
+   8156: 1008156
+   8157: 1008157
+   8158: 1008158
+   8159: 1008159
+   8160: 1008160
+   8161: 1008161
+   8162: 1008162
+   8163: 1008163
+   8164: 1008164
+   8165: 1008165
+   8166: 1008166
+   8167: 1008167
+   8168: 1008168
+   8169: 1008169
+   8170: 1008170
+   8171: 1008171
+   8172: 1008172
+   8173: 1008173
+   8174: 1008174
+   8175: 1008175
+   8176: 1008176
+   8177: 1008177
+   8178: 1008178
+   8179: 1008179
+   8180: 1008180
+   8181: 1008181
+   8182: 1008182
+   8183: 1008183
+   8184: 1008184
+   8185: 1008185
+   8186: 1008186
+   8187: 1008187
+   8188: 1008188
+   8189: 1008189
+   8190: 1008190
+   8191: 1008191
+   8192: 1008192
+   8193: 1008193
+   8194: 1008194
+   8195: 1008195
+   8196: 1008196
+   8197: 1008197
+   8198: 1008198
+   8199: 1008199
+   8200: 1008200
+   8201: 1008201
+   8202: 1008202
+   8203: 1008203
+   8204: 1008204
+   8205: 1008205
+   8206: 1008206
+   8207: 1008207
+   8208: 1008208
+   8209: 1008209
+   8210: 1008210
+   8211: 1008211
+   8212: 1008212
+   8213: 1008213
+   8214: 1008214
+   8215: 1008215
+   8216: 1008216
+   8217: 1008217
+   8218: 1008218
+   8219: 1008219
+   8220: 1008220
+   8221: 1008221
+   8222: 1008222
+   8223: 1008223
+   8224: 1008224
+   8225: 1008225
+   8226: 1008226
+   8227: 1008227
+   8228: 1008228
+   8229: 1008229
+   8230: 1008230
+   8231: 1008231
+   8232: 1008232
+   8233: 1008233
+   8234: 1008234
+   8235: 1008235
+   8236: 1008236
+   8237: 1008237
+   8238: 1008238
+   8239: 1008239
+   8240: 1008240
+   8241: 1008241
+   8242: 1008242
+   8243: 1008243
+   8244: 1008244
+   8245: 1008245
+   8246: 1008246
+   8247: 1008247
+   8248: 1008248
+   8249: 1008249
+   8250: 1008250
+   8251: 1008251
+   8252: 1008252
+   8253: 1008253
+   8254: 1008254
+   8255: 1008255
+   8256: 1008256
+   8257: 1008257
+   8258: 1008258
+   8259: 1008259
+   8260: 1008260
+   8261: 1008261
+   8262: 1008262
+   8263: 1008263
+   8264: 1008264
+   8265: 1008265
+   8266: 1008266
+   8267: 1008267
+   8268: 1008268
+   8269: 1008269
+   8270: 1008270
+   8271: 1008271
+   8272: 1008272
+   8273: 1008273
+   8274: 1008274
+   8275: 1008275
+   8276: 1008276
+   8277: 1008277
+   8278: 1008278
+   8279: 1008279
+   8280: 1008280
+   8281: 1008281
+   8282: 1008282
+   8283: 1008283
+   8284: 1008284
+   8285: 1008285
+   8286: 1008286
+   8287: 1008287
+   8288: 1008288
+   8289: 1008289
+   8290: 1008290
+   8291: 1008291
+   8292: 1008292
+   8293: 1008293
+   8294: 1008294
+   8295: 1008295
+   8296: 1008296
+   8297: 1008297
+   8298: 1008298
+   8299: 1008299
+   8300: 1008300
+   8301: 1008301
+   8302: 1008302
+   8303: 1008303
+   8304: 1008304
+   8305: 1008305
+   8306: 1008306
+   8307: 1008307
+   8308: 1008308
+   8309: 1008309
+   8310: 1008310
+   8311: 1008311
+   8312: 1008312
+   8313: 1008313
+   8314: 1008314
+   8315: 1008315
+   8316: 1008316
+   8317: 1008317
+   8318: 1008318
+   8319: 1008319
+   8320: 1008320
+   8321: 1008321
+   8322: 1008322
+   8323: 1008323
+   8324: 1008324
+   8325: 1008325
+   8326: 1008326
+   8327: 1008327
+   8328: 1008328
+   8329: 1008329
+   8330: 1008330
+   8331: 1008331
+   8332: 1008332
+   8333: 1008333
+   8334: 1008334
+   8335: 1008335
+   8336: 1008336
+   8337: 1008337
+   8338: 1008338
+   8339: 1008339
+   8340: 1008340
+   8341: 1008341
+   8342: 1008342
+   8343: 1008343
+   8344: 1008344
+   8345: 1008345
+   8346: 1008346
+   8347: 1008347
+   8348: 1008348
+   8349: 1008349
+   8350: 1008350
+   8351: 1008351
+   8352: 1008352
+   8353: 1008353
+   8354: 1008354
+   8355: 1008355
+   8356: 1008356
+   8357: 1008357
+   8358: 1008358
+   8359: 1008359
+   8360: 1008360
+   8361: 1008361
+   8362: 1008362
+   8363: 1008363
+   8364: 1008364
+   8365: 1008365
+   8366: 1008366
+   8367: 1008367
+   8368: 1008368
+   8369: 1008369
+   8370: 1008370
+   8371: 1008371
+   8372: 1008372
+   8373: 1008373
+   8374: 1008374
+   8375: 1008375
+   8376: 1008376
+   8377: 1008377
+   8378: 1008378
+   8379: 1008379
+   8380: 1008380
+   8381: 1008381
+   8382: 1008382
+   8383: 1008383
+   8384: 1008384
+   8385: 1008385
+   8386: 1008386
+   8387: 1008387
+   8388: 1008388
+   8389: 1008389
+   8390: 1008390
+   8391: 1008391
+   8392: 1008392
+   8393: 1008393
+   8394: 1008394
+   8395: 1008395
+   8396: 1008396
+   8397: 1008397
+   8398: 1008398
+   8399: 1008399
+   8400: 1008400
+   8401: 1008401
+   8402: 1008402
+   8403: 1008403
+   8404: 1008404
+   8405: 1008405
+   8406: 1008406
+   8407: 1008407
+   8408: 1008408
+   8409: 1008409
+   8410: 1008410
+   8411: 1008411
+   8412: 1008412
+   8413: 1008413
+   8414: 1008414
+   8415: 1008415
+   8416: 1008416
+   8417: 1008417
+   8418: 1008418
+   8419: 1008419
+   8420: 1008420
+   8421: 1008421
+   8422: 1008422
+   8423: 1008423
+   8424: 1008424
+   8425: 1008425
+   8426: 1008426
+   8427: 1008427
+   8428: 1008428
+   8429: 1008429
+   8430: 1008430
+   8431: 1008431
+   8432: 1008432
+   8433: 1008433
+   8434: 1008434
+   8435: 1008435
+   8436: 1008436
+   8437: 1008437
+   8438: 1008438
+   8439: 1008439
+   8440: 1008440
+   8441: 1008441
+   8442: 1008442
+   8443: 1008443
+   8444: 1008444
+   8445: 1008445
+   8446: 1008446
+   8447: 1008447
+   8448: 1008448
+   8449: 1008449
+   8450: 1008450
+   8451: 1008451
+   8452: 1008452
+   8453: 1008453
+   8454: 1008454
+   8455: 1008455
+   8456: 1008456
+   8457: 1008457
+   8458: 1008458
+   8459: 1008459
+   8460: 1008460
+   8461: 1008461
+   8462: 1008462
+   8463: 1008463
+   8464: 1008464
+   8465: 1008465
+   8466: 1008466
+   8467: 1008467
+   8468: 1008468
+   8469: 1008469
+   8470: 1008470
+   8471: 1008471
+   8472: 1008472
+   8473: 1008473
+   8474: 1008474
+   8475: 1008475
+   8476: 1008476
+   8477: 1008477
+   8478: 1008478
+   8479: 1008479
+   8480: 1008480
+   8481: 1008481
+   8482: 1008482
+   8483: 1008483
+   8484: 1008484
+   8485: 1008485
+   8486: 1008486
+   8487: 1008487
+   8488: 1008488
+   8489: 1008489
+   8490: 1008490
+   8491: 1008491
+   8492: 1008492
+   8493: 1008493
+   8494: 1008494
+   8495: 1008495
+   8496: 1008496
+   8497: 1008497
+   8498: 1008498
+   8499: 1008499
+   8500: 1008500
+   8501: 1008501
+   8502: 1008502
+   8503: 1008503
+   8504: 1008504
+   8505: 1008505
+   8506: 1008506
+   8507: 1008507
+   8508: 1008508
+   8509: 1008509
+   8510: 1008510
+   8511: 1008511
+   8512: 1008512
+   8513: 1008513
+   8514: 1008514
+   8515: 1008515
+   8516: 1008516
+   8517: 1008517
+   8518: 1008518
+   8519: 1008519
+   8520: 1008520
+   8521: 1008521
+   8522: 1008522
+   8523: 1008523
+   8524: 1008524
+   8525: 1008525
+   8526: 1008526
+   8527: 1008527
+   8528: 1008528
+   8529: 1008529
+   8530: 1008530
+   8531: 1008531
+   8532: 1008532
+   8533: 1008533
+   8534: 1008534
+   8535: 1008535
+   8536: 1008536
+   8537: 1008537
+   8538: 1008538
+   8539: 1008539
+   8540: 1008540
+   8541: 1008541
+   8542: 1008542
+   8543: 1008543
+   8544: 1008544
+   8545: 1008545
+   8546: 1008546
+   8547: 1008547
+   8548: 1008548
+   8549: 1008549
+   8550: 1008550
+   8551: 1008551
+   8552: 1008552
+   8553: 1008553
+   8554: 1008554
+   8555: 1008555
+   8556: 1008556
+   8557: 1008557
+   8558: 1008558
+   8559: 1008559
+   8560: 1008560
+   8561: 1008561
+   8562: 1008562
+   8563: 1008563
+   8564: 1008564
+   8565: 1008565
+   8566: 1008566
+   8567: 1008567
+   8568: 1008568
+   8569: 1008569
+   8570: 1008570
+   8571: 1008571
+   8572: 1008572
+   8573: 1008573
+   8574: 1008574
+   8575: 1008575
+   8576: 1008576
+   8577: 1008577
+   8578: 1008578
+   8579: 1008579
+   8580: 1008580
+   8581: 1008581
+   8582: 1008582
+   8583: 1008583
+   8584: 1008584
+   8585: 1008585
+   8586: 1008586
+   8587: 1008587
+   8588: 1008588
+   8589: 1008589
+   8590: 1008590
+   8591: 1008591
+   8592: 1008592
+   8593: 1008593
+   8594: 1008594
+   8595: 1008595
+   8596: 1008596
+   8597: 1008597
+   8598: 1008598
+   8599: 1008599
+   8600: 1008600
+   8601: 1008601
+   8602: 1008602
+   8603: 1008603
+   8604: 1008604
+   8605: 1008605
+   8606: 1008606
+   8607: 1008607
+   8608: 1008608
+   8609: 1008609
+   8610: 1008610
+   8611: 1008611
+   8612: 1008612
+   8613: 1008613
+   8614: 1008614
+   8615: 1008615
+   8616: 1008616
+   8617: 1008617
+   8618: 1008618
+   8619: 1008619
+   8620: 1008620
+   8621: 1008621
+   8622: 1008622
+   8623: 1008623
+   8624: 1008624
+   8625: 1008625
+   8626: 1008626
+   8627: 1008627
+   8628: 1008628
+   8629: 1008629
+   8630: 1008630
+   8631: 1008631
+   8632: 1008632
+   8633: 1008633
+   8634: 1008634
+   8635: 1008635
+   8636: 1008636
+   8637: 1008637
+   8638: 1008638
+   8639: 1008639
+   8640: 1008640
+   8641: 1008641
+   8642: 1008642
+   8643: 1008643
+   8644: 1008644
+   8645: 1008645
+   8646: 1008646
+   8647: 1008647
+   8648: 1008648
+   8649: 1008649
+   8650: 1008650
+   8651: 1008651
+   8652: 1008652
+   8653: 1008653
+   8654: 1008654
+   8655: 1008655
+   8656: 1008656
+   8657: 1008657
+   8658: 1008658
+   8659: 1008659
+   8660: 1008660
+   8661: 1008661
+   8662: 1008662
+   8663: 1008663
+   8664: 1008664
+   8665: 1008665
+   8666: 1008666
+   8667: 1008667
+   8668: 1008668
+   8669: 1008669
+   8670: 1008670
+   8671: 1008671
+   8672: 1008672
+   8673: 1008673
+   8674: 1008674
+   8675: 1008675
+   8676: 1008676
+   8677: 1008677
+   8678: 1008678
+   8679: 1008679
+   8680: 1008680
+   8681: 1008681
+   8682: 1008682
+   8683: 1008683
+   8684: 1008684
+   8685: 1008685
+   8686: 1008686
+   8687: 1008687
+   8688: 1008688
+   8689: 1008689
+   8690: 1008690
+   8691: 1008691
+   8692: 1008692
+   8693: 1008693
+   8694: 1008694
+   8695: 1008695
+   8696: 1008696
+   8697: 1008697
+   8698: 1008698
+   8699: 1008699
+   8700: 1008700
+   8701: 1008701
+   8702: 1008702
+   8703: 1008703
+   8704: 1008704
+   8705: 1008705
+   8706: 1008706
+   8707: 1008707
+   8708: 1008708
+   8709: 1008709
+   8710: 1008710
+   8711: 1008711
+   8712: 1008712
+   8713: 1008713
+   8714: 1008714
+   8715: 1008715
+   8716: 1008716
+   8717: 1008717
+   8718: 1008718
+   8719: 1008719
+   8720: 1008720
+   8721: 1008721
+   8722: 1008722
+   8723: 1008723
+   8724: 1008724
+   8725: 1008725
+   8726: 1008726
+   8727: 1008727
+   8728: 1008728
+   8729: 1008729
+   8730: 1008730
+   8731: 1008731
+   8732: 1008732
+   8733: 1008733
+   8734: 1008734
+   8735: 1008735
+   8736: 1008736
+   8737: 1008737
+   8738: 1008738
+   8739: 1008739
+   8740: 1008740
+   8741: 1008741
+   8742: 1008742
+   8743: 1008743
+   8744: 1008744
+   8745: 1008745
+   8746: 1008746
+   8747: 1008747
+   8748: 1008748
+   8749: 1008749
+   8750: 1008750
+   8751: 1008751
+   8752: 1008752
+   8753: 1008753
+   8754: 1008754
+   8755: 1008755
+   8756: 1008756
+   8757: 1008757
+   8758: 1008758
+   8759: 1008759
+   8760: 1008760
+   8761: 1008761
+   8762: 1008762
+   8763: 1008763
+   8764: 1008764
+   8765: 1008765
+   8766: 1008766
+   8767: 1008767
+   8768: 1008768
+   8769: 1008769
+   8770: 1008770
+   8771: 1008771
+   8772: 1008772
+   8773: 1008773
+   8774: 1008774
+   8775: 1008775
+   8776: 1008776
+   8777: 1008777
+   8778: 1008778
+   8779: 1008779
+   8780: 1008780
+   8781: 1008781
+   8782: 1008782
+   8783: 1008783
+   8784: 1008784
+   8785: 1008785
+   8786: 1008786
+   8787: 1008787
+   8788: 1008788
+   8789: 1008789
+   8790: 1008790
+   8791: 1008791
+   8792: 1008792
+   8793: 1008793
+   8794: 1008794
+   8795: 1008795
+   8796: 1008796
+   8797: 1008797
+   8798: 1008798
+   8799: 1008799
+   8800: 1008800
+   8801: 1008801
+   8802: 1008802
+   8803: 1008803
+   8804: 1008804
+   8805: 1008805
+   8806: 1008806
+   8807: 1008807
+   8808: 1008808
+   8809: 1008809
+   8810: 1008810
+   8811: 1008811
+   8812: 1008812
+   8813: 1008813
+   8814: 1008814
+   8815: 1008815
+   8816: 1008816
+   8817: 1008817
+   8818: 1008818
+   8819: 1008819
+   8820: 1008820
+   8821: 1008821
+   8822: 1008822
+   8823: 1008823
+   8824: 1008824
+   8825: 1008825
+   8826: 1008826
+   8827: 1008827
+   8828: 1008828
+   8829: 1008829
+   8830: 1008830
+   8831: 1008831
+   8832: 1008832
+   8833: 1008833
+   8834: 1008834
+   8835: 1008835
+   8836: 1008836
+   8837: 1008837
+   8838: 1008838
+   8839: 1008839
+   8840: 1008840
+   8841: 1008841
+   8842: 1008842
+   8843: 1008843
+   8844: 1008844
+   8845: 1008845
+   8846: 1008846
+   8847: 1008847
+   8848: 1008848
+   8849: 1008849
+   8850: 1008850
+   8851: 1008851
+   8852: 1008852
+   8853: 1008853
+   8854: 1008854
+   8855: 1008855
+   8856: 1008856
+   8857: 1008857
+   8858: 1008858
+   8859: 1008859
+   8860: 1008860
+   8861: 1008861
+   8862: 1008862
+   8863: 1008863
+   8864: 1008864
+   8865: 1008865
+   8866: 1008866
+   8867: 1008867
+   8868: 1008868
+   8869: 1008869
+   8870: 1008870
+   8871: 1008871
+   8872: 1008872
+   8873: 1008873
+   8874: 1008874
+   8875: 1008875
+   8876: 1008876
+   8877: 1008877
+   8878: 1008878
+   8879: 1008879
+   8880: 1008880
+   8881: 1008881
+   8882: 1008882
+   8883: 1008883
+   8884: 1008884
+   8885: 1008885
+   8886: 1008886
+   8887: 1008887
+   8888: 1008888
+   8889: 1008889
+   8890: 1008890
+   8891: 1008891
+   8892: 1008892
+   8893: 1008893
+   8894: 1008894
+   8895: 1008895
+   8896: 1008896
+   8897: 1008897
+   8898: 1008898
+   8899: 1008899
+   8900: 1008900
+   8901: 1008901
+   8902: 1008902
+   8903: 1008903
+   8904: 1008904
+   8905: 1008905
+   8906: 1008906
+   8907: 1008907
+   8908: 1008908
+   8909: 1008909
+   8910: 1008910
+   8911: 1008911
+   8912: 1008912
+   8913: 1008913
+   8914: 1008914
+   8915: 1008915
+   8916: 1008916
+   8917: 1008917
+   8918: 1008918
+   8919: 1008919
+   8920: 1008920
+   8921: 1008921
+   8922: 1008922
+   8923: 1008923
+   8924: 1008924
+   8925: 1008925
+   8926: 1008926
+   8927: 1008927
+   8928: 1008928
+   8929: 1008929
+   8930: 1008930
+   8931: 1008931
+   8932: 1008932
+   8933: 1008933
+   8934: 1008934
+   8935: 1008935
+   8936: 1008936
+   8937: 1008937
+   8938: 1008938
+   8939: 1008939
+   8940: 1008940
+   8941: 1008941
+   8942: 1008942
+   8943: 1008943
+   8944: 1008944
+   8945: 1008945
+   8946: 1008946
+   8947: 1008947
+   8948: 1008948
+   8949: 1008949
+   8950: 1008950
+   8951: 1008951
+   8952: 1008952
+   8953: 1008953
+   8954: 1008954
+   8955: 1008955
+   8956: 1008956
+   8957: 1008957
+   8958: 1008958
+   8959: 1008959
+   8960: 1008960
+   8961: 1008961
+   8962: 1008962
+   8963: 1008963
+   8964: 1008964
+   8965: 1008965
+   8966: 1008966
+   8967: 1008967
+   8968: 1008968
+   8969: 1008969
+   8970: 1008970
+   8971: 1008971
+   8972: 1008972
+   8973: 1008973
+   8974: 1008974
+   8975: 1008975
+   8976: 1008976
+   8977: 1008977
+   8978: 1008978
+   8979: 1008979
+   8980: 1008980
+   8981: 1008981
+   8982: 1008982
+   8983: 1008983
+   8984: 1008984
+   8985: 1008985
+   8986: 1008986
+   8987: 1008987
+   8988: 1008988
+   8989: 1008989
+   8990: 1008990
+   8991: 1008991
+   8992: 1008992
+   8993: 1008993
+   8994: 1008994
+   8995: 1008995
+   8996: 1008996
+   8997: 1008997
+   8998: 1008998
+   8999: 1008999
diff --git a/8.x/mk/tests/ok/l02.txt b/8.x/mk/tests/ok/l02.txt
new file mode 100644 (file)
index 0000000..a1bd366
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Over 64 Kb of strings
+<<< done.
diff --git a/8.x/mk/tests/ok/l02a.txt b/8.x/mk/tests/ok/l02a.txt
new file mode 100755 (executable)
index 0000000..1336623
--- /dev/null
@@ -0,0 +1,3503 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW  3500 rows = p1:S
+      0: 'Alice in Wonderland'
+      1: 'The wizard of Oz'
+      2: 'I'm singin' in the rain'
+      3: 'Alice in Wonderland'
+      4: 'The wizard of Oz'
+      5: 'I'm singin' in the rain'
+      6: 'Alice in Wonderland'
+      7: 'The wizard of Oz'
+      8: 'I'm singin' in the rain'
+      9: 'Alice in Wonderland'
+     10: 'The wizard of Oz'
+     11: 'I'm singin' in the rain'
+     12: 'Alice in Wonderland'
+     13: 'The wizard of Oz'
+     14: 'I'm singin' in the rain'
+     15: 'Alice in Wonderland'
+     16: 'The wizard of Oz'
+     17: 'I'm singin' in the rain'
+     18: 'Alice in Wonderland'
+     19: 'The wizard of Oz'
+     20: 'I'm singin' in the rain'
+     21: 'Alice in Wonderland'
+     22: 'The wizard of Oz'
+     23: 'I'm singin' in the rain'
+     24: 'Alice in Wonderland'
+     25: 'The wizard of Oz'
+     26: 'I'm singin' in the rain'
+     27: 'Alice in Wonderland'
+     28: 'The wizard of Oz'
+     29: 'I'm singin' in the rain'
+     30: 'Alice in Wonderland'
+     31: 'The wizard of Oz'
+     32: 'I'm singin' in the rain'
+     33: 'Alice in Wonderland'
+     34: 'The wizard of Oz'
+     35: 'I'm singin' in the rain'
+     36: 'Alice in Wonderland'
+     37: 'The wizard of Oz'
+     38: 'I'm singin' in the rain'
+     39: 'Alice in Wonderland'
+     40: 'The wizard of Oz'
+     41: 'I'm singin' in the rain'
+     42: 'Alice in Wonderland'
+     43: 'The wizard of Oz'
+     44: 'I'm singin' in the rain'
+     45: 'Alice in Wonderland'
+     46: 'The wizard of Oz'
+     47: 'I'm singin' in the rain'
+     48: 'Alice in Wonderland'
+     49: 'The wizard of Oz'
+     50: 'I'm singin' in the rain'
+     51: 'Alice in Wonderland'
+     52: 'The wizard of Oz'
+     53: 'I'm singin' in the rain'
+     54: 'Alice in Wonderland'
+     55: 'The wizard of Oz'
+     56: 'I'm singin' in the rain'
+     57: 'Alice in Wonderland'
+     58: 'The wizard of Oz'
+     59: 'I'm singin' in the rain'
+     60: 'Alice in Wonderland'
+     61: 'The wizard of Oz'
+     62: 'I'm singin' in the rain'
+     63: 'Alice in Wonderland'
+     64: 'The wizard of Oz'
+     65: 'I'm singin' in the rain'
+     66: 'Alice in Wonderland'
+     67: 'The wizard of Oz'
+     68: 'I'm singin' in the rain'
+     69: 'Alice in Wonderland'
+     70: 'The wizard of Oz'
+     71: 'I'm singin' in the rain'
+     72: 'Alice in Wonderland'
+     73: 'The wizard of Oz'
+     74: 'I'm singin' in the rain'
+     75: 'Alice in Wonderland'
+     76: 'The wizard of Oz'
+     77: 'I'm singin' in the rain'
+     78: 'Alice in Wonderland'
+     79: 'The wizard of Oz'
+     80: 'I'm singin' in the rain'
+     81: 'Alice in Wonderland'
+     82: 'The wizard of Oz'
+     83: 'I'm singin' in the rain'
+     84: 'Alice in Wonderland'
+     85: 'The wizard of Oz'
+     86: 'I'm singin' in the rain'
+     87: 'Alice in Wonderland'
+     88: 'The wizard of Oz'
+     89: 'I'm singin' in the rain'
+     90: 'Alice in Wonderland'
+     91: 'The wizard of Oz'
+     92: 'I'm singin' in the rain'
+     93: 'Alice in Wonderland'
+     94: 'The wizard of Oz'
+     95: 'I'm singin' in the rain'
+     96: 'Alice in Wonderland'
+     97: 'The wizard of Oz'
+     98: 'I'm singin' in the rain'
+     99: 'Alice in Wonderland'
+    100: 'The wizard of Oz'
+    101: 'I'm singin' in the rain'
+    102: 'Alice in Wonderland'
+    103: 'The wizard of Oz'
+    104: 'I'm singin' in the rain'
+    105: 'Alice in Wonderland'
+    106: 'The wizard of Oz'
+    107: 'I'm singin' in the rain'
+    108: 'Alice in Wonderland'
+    109: 'The wizard of Oz'
+    110: 'I'm singin' in the rain'
+    111: 'Alice in Wonderland'
+    112: 'The wizard of Oz'
+    113: 'I'm singin' in the rain'
+    114: 'Alice in Wonderland'
+    115: 'The wizard of Oz'
+    116: 'I'm singin' in the rain'
+    117: 'Alice in Wonderland'
+    118: 'The wizard of Oz'
+    119: 'I'm singin' in the rain'
+    120: 'Alice in Wonderland'
+    121: 'The wizard of Oz'
+    122: 'I'm singin' in the rain'
+    123: 'Alice in Wonderland'
+    124: 'The wizard of Oz'
+    125: 'I'm singin' in the rain'
+    126: 'Alice in Wonderland'
+    127: 'The wizard of Oz'
+    128: 'I'm singin' in the rain'
+    129: 'Alice in Wonderland'
+    130: 'The wizard of Oz'
+    131: 'I'm singin' in the rain'
+    132: 'Alice in Wonderland'
+    133: 'The wizard of Oz'
+    134: 'I'm singin' in the rain'
+    135: 'Alice in Wonderland'
+    136: 'The wizard of Oz'
+    137: 'I'm singin' in the rain'
+    138: 'Alice in Wonderland'
+    139: 'The wizard of Oz'
+    140: 'I'm singin' in the rain'
+    141: 'Alice in Wonderland'
+    142: 'The wizard of Oz'
+    143: 'I'm singin' in the rain'
+    144: 'Alice in Wonderland'
+    145: 'The wizard of Oz'
+    146: 'I'm singin' in the rain'
+    147: 'Alice in Wonderland'
+    148: 'The wizard of Oz'
+    149: 'I'm singin' in the rain'
+    150: 'Alice in Wonderland'
+    151: 'The wizard of Oz'
+    152: 'I'm singin' in the rain'
+    153: 'Alice in Wonderland'
+    154: 'The wizard of Oz'
+    155: 'I'm singin' in the rain'
+    156: 'Alice in Wonderland'
+    157: 'The wizard of Oz'
+    158: 'I'm singin' in the rain'
+    159: 'Alice in Wonderland'
+    160: 'The wizard of Oz'
+    161: 'I'm singin' in the rain'
+    162: 'Alice in Wonderland'
+    163: 'The wizard of Oz'
+    164: 'I'm singin' in the rain'
+    165: 'Alice in Wonderland'
+    166: 'The wizard of Oz'
+    167: 'I'm singin' in the rain'
+    168: 'Alice in Wonderland'
+    169: 'The wizard of Oz'
+    170: 'I'm singin' in the rain'
+    171: 'Alice in Wonderland'
+    172: 'The wizard of Oz'
+    173: 'I'm singin' in the rain'
+    174: 'Alice in Wonderland'
+    175: 'The wizard of Oz'
+    176: 'I'm singin' in the rain'
+    177: 'Alice in Wonderland'
+    178: 'The wizard of Oz'
+    179: 'I'm singin' in the rain'
+    180: 'Alice in Wonderland'
+    181: 'The wizard of Oz'
+    182: 'I'm singin' in the rain'
+    183: 'Alice in Wonderland'
+    184: 'The wizard of Oz'
+    185: 'I'm singin' in the rain'
+    186: 'Alice in Wonderland'
+    187: 'The wizard of Oz'
+    188: 'I'm singin' in the rain'
+    189: 'Alice in Wonderland'
+    190: 'The wizard of Oz'
+    191: 'I'm singin' in the rain'
+    192: 'Alice in Wonderland'
+    193: 'The wizard of Oz'
+    194: 'I'm singin' in the rain'
+    195: 'Alice in Wonderland'
+    196: 'The wizard of Oz'
+    197: 'I'm singin' in the rain'
+    198: 'Alice in Wonderland'
+    199: 'The wizard of Oz'
+    200: 'I'm singin' in the rain'
+    201: 'Alice in Wonderland'
+    202: 'The wizard of Oz'
+    203: 'I'm singin' in the rain'
+    204: 'Alice in Wonderland'
+    205: 'The wizard of Oz'
+    206: 'I'm singin' in the rain'
+    207: 'Alice in Wonderland'
+    208: 'The wizard of Oz'
+    209: 'I'm singin' in the rain'
+    210: 'Alice in Wonderland'
+    211: 'The wizard of Oz'
+    212: 'I'm singin' in the rain'
+    213: 'Alice in Wonderland'
+    214: 'The wizard of Oz'
+    215: 'I'm singin' in the rain'
+    216: 'Alice in Wonderland'
+    217: 'The wizard of Oz'
+    218: 'I'm singin' in the rain'
+    219: 'Alice in Wonderland'
+    220: 'The wizard of Oz'
+    221: 'I'm singin' in the rain'
+    222: 'Alice in Wonderland'
+    223: 'The wizard of Oz'
+    224: 'I'm singin' in the rain'
+    225: 'Alice in Wonderland'
+    226: 'The wizard of Oz'
+    227: 'I'm singin' in the rain'
+    228: 'Alice in Wonderland'
+    229: 'The wizard of Oz'
+    230: 'I'm singin' in the rain'
+    231: 'Alice in Wonderland'
+    232: 'The wizard of Oz'
+    233: 'I'm singin' in the rain'
+    234: 'Alice in Wonderland'
+    235: 'The wizard of Oz'
+    236: 'I'm singin' in the rain'
+    237: 'Alice in Wonderland'
+    238: 'The wizard of Oz'
+    239: 'I'm singin' in the rain'
+    240: 'Alice in Wonderland'
+    241: 'The wizard of Oz'
+    242: 'I'm singin' in the rain'
+    243: 'Alice in Wonderland'
+    244: 'The wizard of Oz'
+    245: 'I'm singin' in the rain'
+    246: 'Alice in Wonderland'
+    247: 'The wizard of Oz'
+    248: 'I'm singin' in the rain'
+    249: 'Alice in Wonderland'
+    250: 'The wizard of Oz'
+    251: 'I'm singin' in the rain'
+    252: 'Alice in Wonderland'
+    253: 'The wizard of Oz'
+    254: 'I'm singin' in the rain'
+    255: 'Alice in Wonderland'
+    256: 'The wizard of Oz'
+    257: 'I'm singin' in the rain'
+    258: 'Alice in Wonderland'
+    259: 'The wizard of Oz'
+    260: 'I'm singin' in the rain'
+    261: 'Alice in Wonderland'
+    262: 'The wizard of Oz'
+    263: 'I'm singin' in the rain'
+    264: 'Alice in Wonderland'
+    265: 'The wizard of Oz'
+    266: 'I'm singin' in the rain'
+    267: 'Alice in Wonderland'
+    268: 'The wizard of Oz'
+    269: 'I'm singin' in the rain'
+    270: 'Alice in Wonderland'
+    271: 'The wizard of Oz'
+    272: 'I'm singin' in the rain'
+    273: 'Alice in Wonderland'
+    274: 'The wizard of Oz'
+    275: 'I'm singin' in the rain'
+    276: 'Alice in Wonderland'
+    277: 'The wizard of Oz'
+    278: 'I'm singin' in the rain'
+    279: 'Alice in Wonderland'
+    280: 'The wizard of Oz'
+    281: 'I'm singin' in the rain'
+    282: 'Alice in Wonderland'
+    283: 'The wizard of Oz'
+    284: 'I'm singin' in the rain'
+    285: 'Alice in Wonderland'
+    286: 'The wizard of Oz'
+    287: 'I'm singin' in the rain'
+    288: 'Alice in Wonderland'
+    289: 'The wizard of Oz'
+    290: 'I'm singin' in the rain'
+    291: 'Alice in Wonderland'
+    292: 'The wizard of Oz'
+    293: 'I'm singin' in the rain'
+    294: 'Alice in Wonderland'
+    295: 'The wizard of Oz'
+    296: 'I'm singin' in the rain'
+    297: 'Alice in Wonderland'
+    298: 'The wizard of Oz'
+    299: 'I'm singin' in the rain'
+    300: 'Alice in Wonderland'
+    301: 'The wizard of Oz'
+    302: 'I'm singin' in the rain'
+    303: 'Alice in Wonderland'
+    304: 'The wizard of Oz'
+    305: 'I'm singin' in the rain'
+    306: 'Alice in Wonderland'
+    307: 'The wizard of Oz'
+    308: 'I'm singin' in the rain'
+    309: 'Alice in Wonderland'
+    310: 'The wizard of Oz'
+    311: 'I'm singin' in the rain'
+    312: 'Alice in Wonderland'
+    313: 'The wizard of Oz'
+    314: 'I'm singin' in the rain'
+    315: 'Alice in Wonderland'
+    316: 'The wizard of Oz'
+    317: 'I'm singin' in the rain'
+    318: 'Alice in Wonderland'
+    319: 'The wizard of Oz'
+    320: 'I'm singin' in the rain'
+    321: 'Alice in Wonderland'
+    322: 'The wizard of Oz'
+    323: 'I'm singin' in the rain'
+    324: 'Alice in Wonderland'
+    325: 'The wizard of Oz'
+    326: 'I'm singin' in the rain'
+    327: 'Alice in Wonderland'
+    328: 'The wizard of Oz'
+    329: 'I'm singin' in the rain'
+    330: 'Alice in Wonderland'
+    331: 'The wizard of Oz'
+    332: 'I'm singin' in the rain'
+    333: 'Alice in Wonderland'
+    334: 'The wizard of Oz'
+    335: 'I'm singin' in the rain'
+    336: 'Alice in Wonderland'
+    337: 'The wizard of Oz'
+    338: 'I'm singin' in the rain'
+    339: 'Alice in Wonderland'
+    340: 'The wizard of Oz'
+    341: 'I'm singin' in the rain'
+    342: 'Alice in Wonderland'
+    343: 'The wizard of Oz'
+    344: 'I'm singin' in the rain'
+    345: 'Alice in Wonderland'
+    346: 'The wizard of Oz'
+    347: 'I'm singin' in the rain'
+    348: 'Alice in Wonderland'
+    349: 'The wizard of Oz'
+    350: 'I'm singin' in the rain'
+    351: 'Alice in Wonderland'
+    352: 'The wizard of Oz'
+    353: 'I'm singin' in the rain'
+    354: 'Alice in Wonderland'
+    355: 'The wizard of Oz'
+    356: 'I'm singin' in the rain'
+    357: 'Alice in Wonderland'
+    358: 'The wizard of Oz'
+    359: 'I'm singin' in the rain'
+    360: 'Alice in Wonderland'
+    361: 'The wizard of Oz'
+    362: 'I'm singin' in the rain'
+    363: 'Alice in Wonderland'
+    364: 'The wizard of Oz'
+    365: 'I'm singin' in the rain'
+    366: 'Alice in Wonderland'
+    367: 'The wizard of Oz'
+    368: 'I'm singin' in the rain'
+    369: 'Alice in Wonderland'
+    370: 'The wizard of Oz'
+    371: 'I'm singin' in the rain'
+    372: 'Alice in Wonderland'
+    373: 'The wizard of Oz'
+    374: 'I'm singin' in the rain'
+    375: 'Alice in Wonderland'
+    376: 'The wizard of Oz'
+    377: 'I'm singin' in the rain'
+    378: 'Alice in Wonderland'
+    379: 'The wizard of Oz'
+    380: 'I'm singin' in the rain'
+    381: 'Alice in Wonderland'
+    382: 'The wizard of Oz'
+    383: 'I'm singin' in the rain'
+    384: 'Alice in Wonderland'
+    385: 'The wizard of Oz'
+    386: 'I'm singin' in the rain'
+    387: 'Alice in Wonderland'
+    388: 'The wizard of Oz'
+    389: 'I'm singin' in the rain'
+    390: 'Alice in Wonderland'
+    391: 'The wizard of Oz'
+    392: 'I'm singin' in the rain'
+    393: 'Alice in Wonderland'
+    394: 'The wizard of Oz'
+    395: 'I'm singin' in the rain'
+    396: 'Alice in Wonderland'
+    397: 'The wizard of Oz'
+    398: 'I'm singin' in the rain'
+    399: 'Alice in Wonderland'
+    400: 'The wizard of Oz'
+    401: 'I'm singin' in the rain'
+    402: 'Alice in Wonderland'
+    403: 'The wizard of Oz'
+    404: 'I'm singin' in the rain'
+    405: 'Alice in Wonderland'
+    406: 'The wizard of Oz'
+    407: 'I'm singin' in the rain'
+    408: 'Alice in Wonderland'
+    409: 'The wizard of Oz'
+    410: 'I'm singin' in the rain'
+    411: 'Alice in Wonderland'
+    412: 'The wizard of Oz'
+    413: 'I'm singin' in the rain'
+    414: 'Alice in Wonderland'
+    415: 'The wizard of Oz'
+    416: 'I'm singin' in the rain'
+    417: 'Alice in Wonderland'
+    418: 'The wizard of Oz'
+    419: 'I'm singin' in the rain'
+    420: 'Alice in Wonderland'
+    421: 'The wizard of Oz'
+    422: 'I'm singin' in the rain'
+    423: 'Alice in Wonderland'
+    424: 'The wizard of Oz'
+    425: 'I'm singin' in the rain'
+    426: 'Alice in Wonderland'
+    427: 'The wizard of Oz'
+    428: 'I'm singin' in the rain'
+    429: 'Alice in Wonderland'
+    430: 'The wizard of Oz'
+    431: 'I'm singin' in the rain'
+    432: 'Alice in Wonderland'
+    433: 'The wizard of Oz'
+    434: 'I'm singin' in the rain'
+    435: 'Alice in Wonderland'
+    436: 'The wizard of Oz'
+    437: 'I'm singin' in the rain'
+    438: 'Alice in Wonderland'
+    439: 'The wizard of Oz'
+    440: 'I'm singin' in the rain'
+    441: 'Alice in Wonderland'
+    442: 'The wizard of Oz'
+    443: 'I'm singin' in the rain'
+    444: 'Alice in Wonderland'
+    445: 'The wizard of Oz'
+    446: 'I'm singin' in the rain'
+    447: 'Alice in Wonderland'
+    448: 'The wizard of Oz'
+    449: 'I'm singin' in the rain'
+    450: 'Alice in Wonderland'
+    451: 'The wizard of Oz'
+    452: 'I'm singin' in the rain'
+    453: 'Alice in Wonderland'
+    454: 'The wizard of Oz'
+    455: 'I'm singin' in the rain'
+    456: 'Alice in Wonderland'
+    457: 'The wizard of Oz'
+    458: 'I'm singin' in the rain'
+    459: 'Alice in Wonderland'
+    460: 'The wizard of Oz'
+    461: 'I'm singin' in the rain'
+    462: 'Alice in Wonderland'
+    463: 'The wizard of Oz'
+    464: 'I'm singin' in the rain'
+    465: 'Alice in Wonderland'
+    466: 'The wizard of Oz'
+    467: 'I'm singin' in the rain'
+    468: 'Alice in Wonderland'
+    469: 'The wizard of Oz'
+    470: 'I'm singin' in the rain'
+    471: 'Alice in Wonderland'
+    472: 'The wizard of Oz'
+    473: 'I'm singin' in the rain'
+    474: 'Alice in Wonderland'
+    475: 'The wizard of Oz'
+    476: 'I'm singin' in the rain'
+    477: 'Alice in Wonderland'
+    478: 'The wizard of Oz'
+    479: 'I'm singin' in the rain'
+    480: 'Alice in Wonderland'
+    481: 'The wizard of Oz'
+    482: 'I'm singin' in the rain'
+    483: 'Alice in Wonderland'
+    484: 'The wizard of Oz'
+    485: 'I'm singin' in the rain'
+    486: 'Alice in Wonderland'
+    487: 'The wizard of Oz'
+    488: 'I'm singin' in the rain'
+    489: 'Alice in Wonderland'
+    490: 'The wizard of Oz'
+    491: 'I'm singin' in the rain'
+    492: 'Alice in Wonderland'
+    493: 'The wizard of Oz'
+    494: 'I'm singin' in the rain'
+    495: 'Alice in Wonderland'
+    496: 'The wizard of Oz'
+    497: 'I'm singin' in the rain'
+    498: 'Alice in Wonderland'
+    499: 'The wizard of Oz'
+    500: 'I'm singin' in the rain'
+    501: 'Alice in Wonderland'
+    502: 'The wizard of Oz'
+    503: 'I'm singin' in the rain'
+    504: 'Alice in Wonderland'
+    505: 'The wizard of Oz'
+    506: 'I'm singin' in the rain'
+    507: 'Alice in Wonderland'
+    508: 'The wizard of Oz'
+    509: 'I'm singin' in the rain'
+    510: 'Alice in Wonderland'
+    511: 'The wizard of Oz'
+    512: 'I'm singin' in the rain'
+    513: 'Alice in Wonderland'
+    514: 'The wizard of Oz'
+    515: 'I'm singin' in the rain'
+    516: 'Alice in Wonderland'
+    517: 'The wizard of Oz'
+    518: 'I'm singin' in the rain'
+    519: 'Alice in Wonderland'
+    520: 'The wizard of Oz'
+    521: 'I'm singin' in the rain'
+    522: 'Alice in Wonderland'
+    523: 'The wizard of Oz'
+    524: 'I'm singin' in the rain'
+    525: 'Alice in Wonderland'
+    526: 'The wizard of Oz'
+    527: 'I'm singin' in the rain'
+    528: 'Alice in Wonderland'
+    529: 'The wizard of Oz'
+    530: 'I'm singin' in the rain'
+    531: 'Alice in Wonderland'
+    532: 'The wizard of Oz'
+    533: 'I'm singin' in the rain'
+    534: 'Alice in Wonderland'
+    535: 'The wizard of Oz'
+    536: 'I'm singin' in the rain'
+    537: 'Alice in Wonderland'
+    538: 'The wizard of Oz'
+    539: 'I'm singin' in the rain'
+    540: 'Alice in Wonderland'
+    541: 'The wizard of Oz'
+    542: 'I'm singin' in the rain'
+    543: 'Alice in Wonderland'
+    544: 'The wizard of Oz'
+    545: 'I'm singin' in the rain'
+    546: 'Alice in Wonderland'
+    547: 'The wizard of Oz'
+    548: 'I'm singin' in the rain'
+    549: 'Alice in Wonderland'
+    550: 'The wizard of Oz'
+    551: 'I'm singin' in the rain'
+    552: 'Alice in Wonderland'
+    553: 'The wizard of Oz'
+    554: 'I'm singin' in the rain'
+    555: 'Alice in Wonderland'
+    556: 'The wizard of Oz'
+    557: 'I'm singin' in the rain'
+    558: 'Alice in Wonderland'
+    559: 'The wizard of Oz'
+    560: 'I'm singin' in the rain'
+    561: 'Alice in Wonderland'
+    562: 'The wizard of Oz'
+    563: 'I'm singin' in the rain'
+    564: 'Alice in Wonderland'
+    565: 'The wizard of Oz'
+    566: 'I'm singin' in the rain'
+    567: 'Alice in Wonderland'
+    568: 'The wizard of Oz'
+    569: 'I'm singin' in the rain'
+    570: 'Alice in Wonderland'
+    571: 'The wizard of Oz'
+    572: 'I'm singin' in the rain'
+    573: 'Alice in Wonderland'
+    574: 'The wizard of Oz'
+    575: 'I'm singin' in the rain'
+    576: 'Alice in Wonderland'
+    577: 'The wizard of Oz'
+    578: 'I'm singin' in the rain'
+    579: 'Alice in Wonderland'
+    580: 'The wizard of Oz'
+    581: 'I'm singin' in the rain'
+    582: 'Alice in Wonderland'
+    583: 'The wizard of Oz'
+    584: 'I'm singin' in the rain'
+    585: 'Alice in Wonderland'
+    586: 'The wizard of Oz'
+    587: 'I'm singin' in the rain'
+    588: 'Alice in Wonderland'
+    589: 'The wizard of Oz'
+    590: 'I'm singin' in the rain'
+    591: 'Alice in Wonderland'
+    592: 'The wizard of Oz'
+    593: 'I'm singin' in the rain'
+    594: 'Alice in Wonderland'
+    595: 'The wizard of Oz'
+    596: 'I'm singin' in the rain'
+    597: 'Alice in Wonderland'
+    598: 'The wizard of Oz'
+    599: 'I'm singin' in the rain'
+    600: 'Alice in Wonderland'
+    601: 'The wizard of Oz'
+    602: 'I'm singin' in the rain'
+    603: 'Alice in Wonderland'
+    604: 'The wizard of Oz'
+    605: 'I'm singin' in the rain'
+    606: 'Alice in Wonderland'
+    607: 'The wizard of Oz'
+    608: 'I'm singin' in the rain'
+    609: 'Alice in Wonderland'
+    610: 'The wizard of Oz'
+    611: 'I'm singin' in the rain'
+    612: 'Alice in Wonderland'
+    613: 'The wizard of Oz'
+    614: 'I'm singin' in the rain'
+    615: 'Alice in Wonderland'
+    616: 'The wizard of Oz'
+    617: 'I'm singin' in the rain'
+    618: 'Alice in Wonderland'
+    619: 'The wizard of Oz'
+    620: 'I'm singin' in the rain'
+    621: 'Alice in Wonderland'
+    622: 'The wizard of Oz'
+    623: 'I'm singin' in the rain'
+    624: 'Alice in Wonderland'
+    625: 'The wizard of Oz'
+    626: 'I'm singin' in the rain'
+    627: 'Alice in Wonderland'
+    628: 'The wizard of Oz'
+    629: 'I'm singin' in the rain'
+    630: 'Alice in Wonderland'
+    631: 'The wizard of Oz'
+    632: 'I'm singin' in the rain'
+    633: 'Alice in Wonderland'
+    634: 'The wizard of Oz'
+    635: 'I'm singin' in the rain'
+    636: 'Alice in Wonderland'
+    637: 'The wizard of Oz'
+    638: 'I'm singin' in the rain'
+    639: 'Alice in Wonderland'
+    640: 'The wizard of Oz'
+    641: 'I'm singin' in the rain'
+    642: 'Alice in Wonderland'
+    643: 'The wizard of Oz'
+    644: 'I'm singin' in the rain'
+    645: 'Alice in Wonderland'
+    646: 'The wizard of Oz'
+    647: 'I'm singin' in the rain'
+    648: 'Alice in Wonderland'
+    649: 'The wizard of Oz'
+    650: 'I'm singin' in the rain'
+    651: 'Alice in Wonderland'
+    652: 'The wizard of Oz'
+    653: 'I'm singin' in the rain'
+    654: 'Alice in Wonderland'
+    655: 'The wizard of Oz'
+    656: 'I'm singin' in the rain'
+    657: 'Alice in Wonderland'
+    658: 'The wizard of Oz'
+    659: 'I'm singin' in the rain'
+    660: 'Alice in Wonderland'
+    661: 'The wizard of Oz'
+    662: 'I'm singin' in the rain'
+    663: 'Alice in Wonderland'
+    664: 'The wizard of Oz'
+    665: 'I'm singin' in the rain'
+    666: 'Alice in Wonderland'
+    667: 'The wizard of Oz'
+    668: 'I'm singin' in the rain'
+    669: 'Alice in Wonderland'
+    670: 'The wizard of Oz'
+    671: 'I'm singin' in the rain'
+    672: 'Alice in Wonderland'
+    673: 'The wizard of Oz'
+    674: 'I'm singin' in the rain'
+    675: 'Alice in Wonderland'
+    676: 'The wizard of Oz'
+    677: 'I'm singin' in the rain'
+    678: 'Alice in Wonderland'
+    679: 'The wizard of Oz'
+    680: 'I'm singin' in the rain'
+    681: 'Alice in Wonderland'
+    682: 'The wizard of Oz'
+    683: 'I'm singin' in the rain'
+    684: 'Alice in Wonderland'
+    685: 'The wizard of Oz'
+    686: 'I'm singin' in the rain'
+    687: 'Alice in Wonderland'
+    688: 'The wizard of Oz'
+    689: 'I'm singin' in the rain'
+    690: 'Alice in Wonderland'
+    691: 'The wizard of Oz'
+    692: 'I'm singin' in the rain'
+    693: 'Alice in Wonderland'
+    694: 'The wizard of Oz'
+    695: 'I'm singin' in the rain'
+    696: 'Alice in Wonderland'
+    697: 'The wizard of Oz'
+    698: 'I'm singin' in the rain'
+    699: 'Alice in Wonderland'
+    700: 'The wizard of Oz'
+    701: 'I'm singin' in the rain'
+    702: 'Alice in Wonderland'
+    703: 'The wizard of Oz'
+    704: 'I'm singin' in the rain'
+    705: 'Alice in Wonderland'
+    706: 'The wizard of Oz'
+    707: 'I'm singin' in the rain'
+    708: 'Alice in Wonderland'
+    709: 'The wizard of Oz'
+    710: 'I'm singin' in the rain'
+    711: 'Alice in Wonderland'
+    712: 'The wizard of Oz'
+    713: 'I'm singin' in the rain'
+    714: 'Alice in Wonderland'
+    715: 'The wizard of Oz'
+    716: 'I'm singin' in the rain'
+    717: 'Alice in Wonderland'
+    718: 'The wizard of Oz'
+    719: 'I'm singin' in the rain'
+    720: 'Alice in Wonderland'
+    721: 'The wizard of Oz'
+    722: 'I'm singin' in the rain'
+    723: 'Alice in Wonderland'
+    724: 'The wizard of Oz'
+    725: 'I'm singin' in the rain'
+    726: 'Alice in Wonderland'
+    727: 'The wizard of Oz'
+    728: 'I'm singin' in the rain'
+    729: 'Alice in Wonderland'
+    730: 'The wizard of Oz'
+    731: 'I'm singin' in the rain'
+    732: 'Alice in Wonderland'
+    733: 'The wizard of Oz'
+    734: 'I'm singin' in the rain'
+    735: 'Alice in Wonderland'
+    736: 'The wizard of Oz'
+    737: 'I'm singin' in the rain'
+    738: 'Alice in Wonderland'
+    739: 'The wizard of Oz'
+    740: 'I'm singin' in the rain'
+    741: 'Alice in Wonderland'
+    742: 'The wizard of Oz'
+    743: 'I'm singin' in the rain'
+    744: 'Alice in Wonderland'
+    745: 'The wizard of Oz'
+    746: 'I'm singin' in the rain'
+    747: 'Alice in Wonderland'
+    748: 'The wizard of Oz'
+    749: 'I'm singin' in the rain'
+    750: 'Alice in Wonderland'
+    751: 'The wizard of Oz'
+    752: 'I'm singin' in the rain'
+    753: 'Alice in Wonderland'
+    754: 'The wizard of Oz'
+    755: 'I'm singin' in the rain'
+    756: 'Alice in Wonderland'
+    757: 'The wizard of Oz'
+    758: 'I'm singin' in the rain'
+    759: 'Alice in Wonderland'
+    760: 'The wizard of Oz'
+    761: 'I'm singin' in the rain'
+    762: 'Alice in Wonderland'
+    763: 'The wizard of Oz'
+    764: 'I'm singin' in the rain'
+    765: 'Alice in Wonderland'
+    766: 'The wizard of Oz'
+    767: 'I'm singin' in the rain'
+    768: 'Alice in Wonderland'
+    769: 'The wizard of Oz'
+    770: 'I'm singin' in the rain'
+    771: 'Alice in Wonderland'
+    772: 'The wizard of Oz'
+    773: 'I'm singin' in the rain'
+    774: 'Alice in Wonderland'
+    775: 'The wizard of Oz'
+    776: 'I'm singin' in the rain'
+    777: 'Alice in Wonderland'
+    778: 'The wizard of Oz'
+    779: 'I'm singin' in the rain'
+    780: 'Alice in Wonderland'
+    781: 'The wizard of Oz'
+    782: 'I'm singin' in the rain'
+    783: 'Alice in Wonderland'
+    784: 'The wizard of Oz'
+    785: 'I'm singin' in the rain'
+    786: 'Alice in Wonderland'
+    787: 'The wizard of Oz'
+    788: 'I'm singin' in the rain'
+    789: 'Alice in Wonderland'
+    790: 'The wizard of Oz'
+    791: 'I'm singin' in the rain'
+    792: 'Alice in Wonderland'
+    793: 'The wizard of Oz'
+    794: 'I'm singin' in the rain'
+    795: 'Alice in Wonderland'
+    796: 'The wizard of Oz'
+    797: 'I'm singin' in the rain'
+    798: 'Alice in Wonderland'
+    799: 'The wizard of Oz'
+    800: 'I'm singin' in the rain'
+    801: 'Alice in Wonderland'
+    802: 'The wizard of Oz'
+    803: 'I'm singin' in the rain'
+    804: 'Alice in Wonderland'
+    805: 'The wizard of Oz'
+    806: 'I'm singin' in the rain'
+    807: 'Alice in Wonderland'
+    808: 'The wizard of Oz'
+    809: 'I'm singin' in the rain'
+    810: 'Alice in Wonderland'
+    811: 'The wizard of Oz'
+    812: 'I'm singin' in the rain'
+    813: 'Alice in Wonderland'
+    814: 'The wizard of Oz'
+    815: 'I'm singin' in the rain'
+    816: 'Alice in Wonderland'
+    817: 'The wizard of Oz'
+    818: 'I'm singin' in the rain'
+    819: 'Alice in Wonderland'
+    820: 'The wizard of Oz'
+    821: 'I'm singin' in the rain'
+    822: 'Alice in Wonderland'
+    823: 'The wizard of Oz'
+    824: 'I'm singin' in the rain'
+    825: 'Alice in Wonderland'
+    826: 'The wizard of Oz'
+    827: 'I'm singin' in the rain'
+    828: 'Alice in Wonderland'
+    829: 'The wizard of Oz'
+    830: 'I'm singin' in the rain'
+    831: 'Alice in Wonderland'
+    832: 'The wizard of Oz'
+    833: 'I'm singin' in the rain'
+    834: 'Alice in Wonderland'
+    835: 'The wizard of Oz'
+    836: 'I'm singin' in the rain'
+    837: 'Alice in Wonderland'
+    838: 'The wizard of Oz'
+    839: 'I'm singin' in the rain'
+    840: 'Alice in Wonderland'
+    841: 'The wizard of Oz'
+    842: 'I'm singin' in the rain'
+    843: 'Alice in Wonderland'
+    844: 'The wizard of Oz'
+    845: 'I'm singin' in the rain'
+    846: 'Alice in Wonderland'
+    847: 'The wizard of Oz'
+    848: 'I'm singin' in the rain'
+    849: 'Alice in Wonderland'
+    850: 'The wizard of Oz'
+    851: 'I'm singin' in the rain'
+    852: 'Alice in Wonderland'
+    853: 'The wizard of Oz'
+    854: 'I'm singin' in the rain'
+    855: 'Alice in Wonderland'
+    856: 'The wizard of Oz'
+    857: 'I'm singin' in the rain'
+    858: 'Alice in Wonderland'
+    859: 'The wizard of Oz'
+    860: 'I'm singin' in the rain'
+    861: 'Alice in Wonderland'
+    862: 'The wizard of Oz'
+    863: 'I'm singin' in the rain'
+    864: 'Alice in Wonderland'
+    865: 'The wizard of Oz'
+    866: 'I'm singin' in the rain'
+    867: 'Alice in Wonderland'
+    868: 'The wizard of Oz'
+    869: 'I'm singin' in the rain'
+    870: 'Alice in Wonderland'
+    871: 'The wizard of Oz'
+    872: 'I'm singin' in the rain'
+    873: 'Alice in Wonderland'
+    874: 'The wizard of Oz'
+    875: 'I'm singin' in the rain'
+    876: 'Alice in Wonderland'
+    877: 'The wizard of Oz'
+    878: 'I'm singin' in the rain'
+    879: 'Alice in Wonderland'
+    880: 'The wizard of Oz'
+    881: 'I'm singin' in the rain'
+    882: 'Alice in Wonderland'
+    883: 'The wizard of Oz'
+    884: 'I'm singin' in the rain'
+    885: 'Alice in Wonderland'
+    886: 'The wizard of Oz'
+    887: 'I'm singin' in the rain'
+    888: 'Alice in Wonderland'
+    889: 'The wizard of Oz'
+    890: 'I'm singin' in the rain'
+    891: 'Alice in Wonderland'
+    892: 'The wizard of Oz'
+    893: 'I'm singin' in the rain'
+    894: 'Alice in Wonderland'
+    895: 'The wizard of Oz'
+    896: 'I'm singin' in the rain'
+    897: 'Alice in Wonderland'
+    898: 'The wizard of Oz'
+    899: 'I'm singin' in the rain'
+    900: 'Alice in Wonderland'
+    901: 'The wizard of Oz'
+    902: 'I'm singin' in the rain'
+    903: 'Alice in Wonderland'
+    904: 'The wizard of Oz'
+    905: 'I'm singin' in the rain'
+    906: 'Alice in Wonderland'
+    907: 'The wizard of Oz'
+    908: 'I'm singin' in the rain'
+    909: 'Alice in Wonderland'
+    910: 'The wizard of Oz'
+    911: 'I'm singin' in the rain'
+    912: 'Alice in Wonderland'
+    913: 'The wizard of Oz'
+    914: 'I'm singin' in the rain'
+    915: 'Alice in Wonderland'
+    916: 'The wizard of Oz'
+    917: 'I'm singin' in the rain'
+    918: 'Alice in Wonderland'
+    919: 'The wizard of Oz'
+    920: 'I'm singin' in the rain'
+    921: 'Alice in Wonderland'
+    922: 'The wizard of Oz'
+    923: 'I'm singin' in the rain'
+    924: 'Alice in Wonderland'
+    925: 'The wizard of Oz'
+    926: 'I'm singin' in the rain'
+    927: 'Alice in Wonderland'
+    928: 'The wizard of Oz'
+    929: 'I'm singin' in the rain'
+    930: 'Alice in Wonderland'
+    931: 'The wizard of Oz'
+    932: 'I'm singin' in the rain'
+    933: 'Alice in Wonderland'
+    934: 'The wizard of Oz'
+    935: 'I'm singin' in the rain'
+    936: 'Alice in Wonderland'
+    937: 'The wizard of Oz'
+    938: 'I'm singin' in the rain'
+    939: 'Alice in Wonderland'
+    940: 'The wizard of Oz'
+    941: 'I'm singin' in the rain'
+    942: 'Alice in Wonderland'
+    943: 'The wizard of Oz'
+    944: 'I'm singin' in the rain'
+    945: 'Alice in Wonderland'
+    946: 'The wizard of Oz'
+    947: 'I'm singin' in the rain'
+    948: 'Alice in Wonderland'
+    949: 'The wizard of Oz'
+    950: 'I'm singin' in the rain'
+    951: 'Alice in Wonderland'
+    952: 'The wizard of Oz'
+    953: 'I'm singin' in the rain'
+    954: 'Alice in Wonderland'
+    955: 'The wizard of Oz'
+    956: 'I'm singin' in the rain'
+    957: 'Alice in Wonderland'
+    958: 'The wizard of Oz'
+    959: 'I'm singin' in the rain'
+    960: 'Alice in Wonderland'
+    961: 'The wizard of Oz'
+    962: 'I'm singin' in the rain'
+    963: 'Alice in Wonderland'
+    964: 'The wizard of Oz'
+    965: 'I'm singin' in the rain'
+    966: 'Alice in Wonderland'
+    967: 'The wizard of Oz'
+    968: 'I'm singin' in the rain'
+    969: 'Alice in Wonderland'
+    970: 'The wizard of Oz'
+    971: 'I'm singin' in the rain'
+    972: 'Alice in Wonderland'
+    973: 'The wizard of Oz'
+    974: 'I'm singin' in the rain'
+    975: 'Alice in Wonderland'
+    976: 'The wizard of Oz'
+    977: 'I'm singin' in the rain'
+    978: 'Alice in Wonderland'
+    979: 'The wizard of Oz'
+    980: 'I'm singin' in the rain'
+    981: 'Alice in Wonderland'
+    982: 'The wizard of Oz'
+    983: 'I'm singin' in the rain'
+    984: 'Alice in Wonderland'
+    985: 'The wizard of Oz'
+    986: 'I'm singin' in the rain'
+    987: 'Alice in Wonderland'
+    988: 'The wizard of Oz'
+    989: 'I'm singin' in the rain'
+    990: 'Alice in Wonderland'
+    991: 'The wizard of Oz'
+    992: 'I'm singin' in the rain'
+    993: 'Alice in Wonderland'
+    994: 'The wizard of Oz'
+    995: 'I'm singin' in the rain'
+    996: 'Alice in Wonderland'
+    997: 'The wizard of Oz'
+    998: 'I'm singin' in the rain'
+    999: 'Alice in Wonderland'
+   1000: 'The wizard of Oz'
+   1001: 'I'm singin' in the rain'
+   1002: 'Alice in Wonderland'
+   1003: 'The wizard of Oz'
+   1004: 'I'm singin' in the rain'
+   1005: 'Alice in Wonderland'
+   1006: 'The wizard of Oz'
+   1007: 'I'm singin' in the rain'
+   1008: 'Alice in Wonderland'
+   1009: 'The wizard of Oz'
+   1010: 'I'm singin' in the rain'
+   1011: 'Alice in Wonderland'
+   1012: 'The wizard of Oz'
+   1013: 'I'm singin' in the rain'
+   1014: 'Alice in Wonderland'
+   1015: 'The wizard of Oz'
+   1016: 'I'm singin' in the rain'
+   1017: 'Alice in Wonderland'
+   1018: 'The wizard of Oz'
+   1019: 'I'm singin' in the rain'
+   1020: 'Alice in Wonderland'
+   1021: 'The wizard of Oz'
+   1022: 'I'm singin' in the rain'
+   1023: 'Alice in Wonderland'
+   1024: 'The wizard of Oz'
+   1025: 'I'm singin' in the rain'
+   1026: 'Alice in Wonderland'
+   1027: 'The wizard of Oz'
+   1028: 'I'm singin' in the rain'
+   1029: 'Alice in Wonderland'
+   1030: 'The wizard of Oz'
+   1031: 'I'm singin' in the rain'
+   1032: 'Alice in Wonderland'
+   1033: 'The wizard of Oz'
+   1034: 'I'm singin' in the rain'
+   1035: 'Alice in Wonderland'
+   1036: 'The wizard of Oz'
+   1037: 'I'm singin' in the rain'
+   1038: 'Alice in Wonderland'
+   1039: 'The wizard of Oz'
+   1040: 'I'm singin' in the rain'
+   1041: 'Alice in Wonderland'
+   1042: 'The wizard of Oz'
+   1043: 'I'm singin' in the rain'
+   1044: 'Alice in Wonderland'
+   1045: 'The wizard of Oz'
+   1046: 'I'm singin' in the rain'
+   1047: 'Alice in Wonderland'
+   1048: 'The wizard of Oz'
+   1049: 'I'm singin' in the rain'
+   1050: 'Alice in Wonderland'
+   1051: 'The wizard of Oz'
+   1052: 'I'm singin' in the rain'
+   1053: 'Alice in Wonderland'
+   1054: 'The wizard of Oz'
+   1055: 'I'm singin' in the rain'
+   1056: 'Alice in Wonderland'
+   1057: 'The wizard of Oz'
+   1058: 'I'm singin' in the rain'
+   1059: 'Alice in Wonderland'
+   1060: 'The wizard of Oz'
+   1061: 'I'm singin' in the rain'
+   1062: 'Alice in Wonderland'
+   1063: 'The wizard of Oz'
+   1064: 'I'm singin' in the rain'
+   1065: 'Alice in Wonderland'
+   1066: 'The wizard of Oz'
+   1067: 'I'm singin' in the rain'
+   1068: 'Alice in Wonderland'
+   1069: 'The wizard of Oz'
+   1070: 'I'm singin' in the rain'
+   1071: 'Alice in Wonderland'
+   1072: 'The wizard of Oz'
+   1073: 'I'm singin' in the rain'
+   1074: 'Alice in Wonderland'
+   1075: 'The wizard of Oz'
+   1076: 'I'm singin' in the rain'
+   1077: 'Alice in Wonderland'
+   1078: 'The wizard of Oz'
+   1079: 'I'm singin' in the rain'
+   1080: 'Alice in Wonderland'
+   1081: 'The wizard of Oz'
+   1082: 'I'm singin' in the rain'
+   1083: 'Alice in Wonderland'
+   1084: 'The wizard of Oz'
+   1085: 'I'm singin' in the rain'
+   1086: 'Alice in Wonderland'
+   1087: 'The wizard of Oz'
+   1088: 'I'm singin' in the rain'
+   1089: 'Alice in Wonderland'
+   1090: 'The wizard of Oz'
+   1091: 'I'm singin' in the rain'
+   1092: 'Alice in Wonderland'
+   1093: 'The wizard of Oz'
+   1094: 'I'm singin' in the rain'
+   1095: 'Alice in Wonderland'
+   1096: 'The wizard of Oz'
+   1097: 'I'm singin' in the rain'
+   1098: 'Alice in Wonderland'
+   1099: 'The wizard of Oz'
+   1100: 'I'm singin' in the rain'
+   1101: 'Alice in Wonderland'
+   1102: 'The wizard of Oz'
+   1103: 'I'm singin' in the rain'
+   1104: 'Alice in Wonderland'
+   1105: 'The wizard of Oz'
+   1106: 'I'm singin' in the rain'
+   1107: 'Alice in Wonderland'
+   1108: 'The wizard of Oz'
+   1109: 'I'm singin' in the rain'
+   1110: 'Alice in Wonderland'
+   1111: 'The wizard of Oz'
+   1112: 'I'm singin' in the rain'
+   1113: 'Alice in Wonderland'
+   1114: 'The wizard of Oz'
+   1115: 'I'm singin' in the rain'
+   1116: 'Alice in Wonderland'
+   1117: 'The wizard of Oz'
+   1118: 'I'm singin' in the rain'
+   1119: 'Alice in Wonderland'
+   1120: 'The wizard of Oz'
+   1121: 'I'm singin' in the rain'
+   1122: 'Alice in Wonderland'
+   1123: 'The wizard of Oz'
+   1124: 'I'm singin' in the rain'
+   1125: 'Alice in Wonderland'
+   1126: 'The wizard of Oz'
+   1127: 'I'm singin' in the rain'
+   1128: 'Alice in Wonderland'
+   1129: 'The wizard of Oz'
+   1130: 'I'm singin' in the rain'
+   1131: 'Alice in Wonderland'
+   1132: 'The wizard of Oz'
+   1133: 'I'm singin' in the rain'
+   1134: 'Alice in Wonderland'
+   1135: 'The wizard of Oz'
+   1136: 'I'm singin' in the rain'
+   1137: 'Alice in Wonderland'
+   1138: 'The wizard of Oz'
+   1139: 'I'm singin' in the rain'
+   1140: 'Alice in Wonderland'
+   1141: 'The wizard of Oz'
+   1142: 'I'm singin' in the rain'
+   1143: 'Alice in Wonderland'
+   1144: 'The wizard of Oz'
+   1145: 'I'm singin' in the rain'
+   1146: 'Alice in Wonderland'
+   1147: 'The wizard of Oz'
+   1148: 'I'm singin' in the rain'
+   1149: 'Alice in Wonderland'
+   1150: 'The wizard of Oz'
+   1151: 'I'm singin' in the rain'
+   1152: 'Alice in Wonderland'
+   1153: 'The wizard of Oz'
+   1154: 'I'm singin' in the rain'
+   1155: 'Alice in Wonderland'
+   1156: 'The wizard of Oz'
+   1157: 'I'm singin' in the rain'
+   1158: 'Alice in Wonderland'
+   1159: 'The wizard of Oz'
+   1160: 'I'm singin' in the rain'
+   1161: 'Alice in Wonderland'
+   1162: 'The wizard of Oz'
+   1163: 'I'm singin' in the rain'
+   1164: 'Alice in Wonderland'
+   1165: 'The wizard of Oz'
+   1166: 'I'm singin' in the rain'
+   1167: 'Alice in Wonderland'
+   1168: 'The wizard of Oz'
+   1169: 'I'm singin' in the rain'
+   1170: 'Alice in Wonderland'
+   1171: 'The wizard of Oz'
+   1172: 'I'm singin' in the rain'
+   1173: 'Alice in Wonderland'
+   1174: 'The wizard of Oz'
+   1175: 'I'm singin' in the rain'
+   1176: 'Alice in Wonderland'
+   1177: 'The wizard of Oz'
+   1178: 'I'm singin' in the rain'
+   1179: 'Alice in Wonderland'
+   1180: 'The wizard of Oz'
+   1181: 'I'm singin' in the rain'
+   1182: 'Alice in Wonderland'
+   1183: 'The wizard of Oz'
+   1184: 'I'm singin' in the rain'
+   1185: 'Alice in Wonderland'
+   1186: 'The wizard of Oz'
+   1187: 'I'm singin' in the rain'
+   1188: 'Alice in Wonderland'
+   1189: 'The wizard of Oz'
+   1190: 'I'm singin' in the rain'
+   1191: 'Alice in Wonderland'
+   1192: 'The wizard of Oz'
+   1193: 'I'm singin' in the rain'
+   1194: 'Alice in Wonderland'
+   1195: 'The wizard of Oz'
+   1196: 'I'm singin' in the rain'
+   1197: 'Alice in Wonderland'
+   1198: 'The wizard of Oz'
+   1199: 'I'm singin' in the rain'
+   1200: 'Alice in Wonderland'
+   1201: 'The wizard of Oz'
+   1202: 'I'm singin' in the rain'
+   1203: 'Alice in Wonderland'
+   1204: 'The wizard of Oz'
+   1205: 'I'm singin' in the rain'
+   1206: 'Alice in Wonderland'
+   1207: 'The wizard of Oz'
+   1208: 'I'm singin' in the rain'
+   1209: 'Alice in Wonderland'
+   1210: 'The wizard of Oz'
+   1211: 'I'm singin' in the rain'
+   1212: 'Alice in Wonderland'
+   1213: 'The wizard of Oz'
+   1214: 'I'm singin' in the rain'
+   1215: 'Alice in Wonderland'
+   1216: 'The wizard of Oz'
+   1217: 'I'm singin' in the rain'
+   1218: 'Alice in Wonderland'
+   1219: 'The wizard of Oz'
+   1220: 'I'm singin' in the rain'
+   1221: 'Alice in Wonderland'
+   1222: 'The wizard of Oz'
+   1223: 'I'm singin' in the rain'
+   1224: 'Alice in Wonderland'
+   1225: 'The wizard of Oz'
+   1226: 'I'm singin' in the rain'
+   1227: 'Alice in Wonderland'
+   1228: 'The wizard of Oz'
+   1229: 'I'm singin' in the rain'
+   1230: 'Alice in Wonderland'
+   1231: 'The wizard of Oz'
+   1232: 'I'm singin' in the rain'
+   1233: 'Alice in Wonderland'
+   1234: 'The wizard of Oz'
+   1235: 'I'm singin' in the rain'
+   1236: 'Alice in Wonderland'
+   1237: 'The wizard of Oz'
+   1238: 'I'm singin' in the rain'
+   1239: 'Alice in Wonderland'
+   1240: 'The wizard of Oz'
+   1241: 'I'm singin' in the rain'
+   1242: 'Alice in Wonderland'
+   1243: 'The wizard of Oz'
+   1244: 'I'm singin' in the rain'
+   1245: 'Alice in Wonderland'
+   1246: 'The wizard of Oz'
+   1247: 'I'm singin' in the rain'
+   1248: 'Alice in Wonderland'
+   1249: 'The wizard of Oz'
+   1250: 'I'm singin' in the rain'
+   1251: 'Alice in Wonderland'
+   1252: 'The wizard of Oz'
+   1253: 'I'm singin' in the rain'
+   1254: 'Alice in Wonderland'
+   1255: 'The wizard of Oz'
+   1256: 'I'm singin' in the rain'
+   1257: 'Alice in Wonderland'
+   1258: 'The wizard of Oz'
+   1259: 'I'm singin' in the rain'
+   1260: 'Alice in Wonderland'
+   1261: 'The wizard of Oz'
+   1262: 'I'm singin' in the rain'
+   1263: 'Alice in Wonderland'
+   1264: 'The wizard of Oz'
+   1265: 'I'm singin' in the rain'
+   1266: 'Alice in Wonderland'
+   1267: 'The wizard of Oz'
+   1268: 'I'm singin' in the rain'
+   1269: 'Alice in Wonderland'
+   1270: 'The wizard of Oz'
+   1271: 'I'm singin' in the rain'
+   1272: 'Alice in Wonderland'
+   1273: 'The wizard of Oz'
+   1274: 'I'm singin' in the rain'
+   1275: 'Alice in Wonderland'
+   1276: 'The wizard of Oz'
+   1277: 'I'm singin' in the rain'
+   1278: 'Alice in Wonderland'
+   1279: 'The wizard of Oz'
+   1280: 'I'm singin' in the rain'
+   1281: 'Alice in Wonderland'
+   1282: 'The wizard of Oz'
+   1283: 'I'm singin' in the rain'
+   1284: 'Alice in Wonderland'
+   1285: 'The wizard of Oz'
+   1286: 'I'm singin' in the rain'
+   1287: 'Alice in Wonderland'
+   1288: 'The wizard of Oz'
+   1289: 'I'm singin' in the rain'
+   1290: 'Alice in Wonderland'
+   1291: 'The wizard of Oz'
+   1292: 'I'm singin' in the rain'
+   1293: 'Alice in Wonderland'
+   1294: 'The wizard of Oz'
+   1295: 'I'm singin' in the rain'
+   1296: 'Alice in Wonderland'
+   1297: 'The wizard of Oz'
+   1298: 'I'm singin' in the rain'
+   1299: 'Alice in Wonderland'
+   1300: 'The wizard of Oz'
+   1301: 'I'm singin' in the rain'
+   1302: 'Alice in Wonderland'
+   1303: 'The wizard of Oz'
+   1304: 'I'm singin' in the rain'
+   1305: 'Alice in Wonderland'
+   1306: 'The wizard of Oz'
+   1307: 'I'm singin' in the rain'
+   1308: 'Alice in Wonderland'
+   1309: 'The wizard of Oz'
+   1310: 'I'm singin' in the rain'
+   1311: 'Alice in Wonderland'
+   1312: 'The wizard of Oz'
+   1313: 'I'm singin' in the rain'
+   1314: 'Alice in Wonderland'
+   1315: 'The wizard of Oz'
+   1316: 'I'm singin' in the rain'
+   1317: 'Alice in Wonderland'
+   1318: 'The wizard of Oz'
+   1319: 'I'm singin' in the rain'
+   1320: 'Alice in Wonderland'
+   1321: 'The wizard of Oz'
+   1322: 'I'm singin' in the rain'
+   1323: 'Alice in Wonderland'
+   1324: 'The wizard of Oz'
+   1325: 'I'm singin' in the rain'
+   1326: 'Alice in Wonderland'
+   1327: 'The wizard of Oz'
+   1328: 'I'm singin' in the rain'
+   1329: 'Alice in Wonderland'
+   1330: 'The wizard of Oz'
+   1331: 'I'm singin' in the rain'
+   1332: 'Alice in Wonderland'
+   1333: 'The wizard of Oz'
+   1334: 'I'm singin' in the rain'
+   1335: 'Alice in Wonderland'
+   1336: 'The wizard of Oz'
+   1337: 'I'm singin' in the rain'
+   1338: 'Alice in Wonderland'
+   1339: 'The wizard of Oz'
+   1340: 'I'm singin' in the rain'
+   1341: 'Alice in Wonderland'
+   1342: 'The wizard of Oz'
+   1343: 'I'm singin' in the rain'
+   1344: 'Alice in Wonderland'
+   1345: 'The wizard of Oz'
+   1346: 'I'm singin' in the rain'
+   1347: 'Alice in Wonderland'
+   1348: 'The wizard of Oz'
+   1349: 'I'm singin' in the rain'
+   1350: 'Alice in Wonderland'
+   1351: 'The wizard of Oz'
+   1352: 'I'm singin' in the rain'
+   1353: 'Alice in Wonderland'
+   1354: 'The wizard of Oz'
+   1355: 'I'm singin' in the rain'
+   1356: 'Alice in Wonderland'
+   1357: 'The wizard of Oz'
+   1358: 'I'm singin' in the rain'
+   1359: 'Alice in Wonderland'
+   1360: 'The wizard of Oz'
+   1361: 'I'm singin' in the rain'
+   1362: 'Alice in Wonderland'
+   1363: 'The wizard of Oz'
+   1364: 'I'm singin' in the rain'
+   1365: 'Alice in Wonderland'
+   1366: 'The wizard of Oz'
+   1367: 'I'm singin' in the rain'
+   1368: 'Alice in Wonderland'
+   1369: 'The wizard of Oz'
+   1370: 'I'm singin' in the rain'
+   1371: 'Alice in Wonderland'
+   1372: 'The wizard of Oz'
+   1373: 'I'm singin' in the rain'
+   1374: 'Alice in Wonderland'
+   1375: 'The wizard of Oz'
+   1376: 'I'm singin' in the rain'
+   1377: 'Alice in Wonderland'
+   1378: 'The wizard of Oz'
+   1379: 'I'm singin' in the rain'
+   1380: 'Alice in Wonderland'
+   1381: 'The wizard of Oz'
+   1382: 'I'm singin' in the rain'
+   1383: 'Alice in Wonderland'
+   1384: 'The wizard of Oz'
+   1385: 'I'm singin' in the rain'
+   1386: 'Alice in Wonderland'
+   1387: 'The wizard of Oz'
+   1388: 'I'm singin' in the rain'
+   1389: 'Alice in Wonderland'
+   1390: 'The wizard of Oz'
+   1391: 'I'm singin' in the rain'
+   1392: 'Alice in Wonderland'
+   1393: 'The wizard of Oz'
+   1394: 'I'm singin' in the rain'
+   1395: 'Alice in Wonderland'
+   1396: 'The wizard of Oz'
+   1397: 'I'm singin' in the rain'
+   1398: 'Alice in Wonderland'
+   1399: 'The wizard of Oz'
+   1400: 'I'm singin' in the rain'
+   1401: 'Alice in Wonderland'
+   1402: 'The wizard of Oz'
+   1403: 'I'm singin' in the rain'
+   1404: 'Alice in Wonderland'
+   1405: 'The wizard of Oz'
+   1406: 'I'm singin' in the rain'
+   1407: 'Alice in Wonderland'
+   1408: 'The wizard of Oz'
+   1409: 'I'm singin' in the rain'
+   1410: 'Alice in Wonderland'
+   1411: 'The wizard of Oz'
+   1412: 'I'm singin' in the rain'
+   1413: 'Alice in Wonderland'
+   1414: 'The wizard of Oz'
+   1415: 'I'm singin' in the rain'
+   1416: 'Alice in Wonderland'
+   1417: 'The wizard of Oz'
+   1418: 'I'm singin' in the rain'
+   1419: 'Alice in Wonderland'
+   1420: 'The wizard of Oz'
+   1421: 'I'm singin' in the rain'
+   1422: 'Alice in Wonderland'
+   1423: 'The wizard of Oz'
+   1424: 'I'm singin' in the rain'
+   1425: 'Alice in Wonderland'
+   1426: 'The wizard of Oz'
+   1427: 'I'm singin' in the rain'
+   1428: 'Alice in Wonderland'
+   1429: 'The wizard of Oz'
+   1430: 'I'm singin' in the rain'
+   1431: 'Alice in Wonderland'
+   1432: 'The wizard of Oz'
+   1433: 'I'm singin' in the rain'
+   1434: 'Alice in Wonderland'
+   1435: 'The wizard of Oz'
+   1436: 'I'm singin' in the rain'
+   1437: 'Alice in Wonderland'
+   1438: 'The wizard of Oz'
+   1439: 'I'm singin' in the rain'
+   1440: 'Alice in Wonderland'
+   1441: 'The wizard of Oz'
+   1442: 'I'm singin' in the rain'
+   1443: 'Alice in Wonderland'
+   1444: 'The wizard of Oz'
+   1445: 'I'm singin' in the rain'
+   1446: 'Alice in Wonderland'
+   1447: 'The wizard of Oz'
+   1448: 'I'm singin' in the rain'
+   1449: 'Alice in Wonderland'
+   1450: 'The wizard of Oz'
+   1451: 'I'm singin' in the rain'
+   1452: 'Alice in Wonderland'
+   1453: 'The wizard of Oz'
+   1454: 'I'm singin' in the rain'
+   1455: 'Alice in Wonderland'
+   1456: 'The wizard of Oz'
+   1457: 'I'm singin' in the rain'
+   1458: 'Alice in Wonderland'
+   1459: 'The wizard of Oz'
+   1460: 'I'm singin' in the rain'
+   1461: 'Alice in Wonderland'
+   1462: 'The wizard of Oz'
+   1463: 'I'm singin' in the rain'
+   1464: 'Alice in Wonderland'
+   1465: 'The wizard of Oz'
+   1466: 'I'm singin' in the rain'
+   1467: 'Alice in Wonderland'
+   1468: 'The wizard of Oz'
+   1469: 'I'm singin' in the rain'
+   1470: 'Alice in Wonderland'
+   1471: 'The wizard of Oz'
+   1472: 'I'm singin' in the rain'
+   1473: 'Alice in Wonderland'
+   1474: 'The wizard of Oz'
+   1475: 'I'm singin' in the rain'
+   1476: 'Alice in Wonderland'
+   1477: 'The wizard of Oz'
+   1478: 'I'm singin' in the rain'
+   1479: 'Alice in Wonderland'
+   1480: 'The wizard of Oz'
+   1481: 'I'm singin' in the rain'
+   1482: 'Alice in Wonderland'
+   1483: 'The wizard of Oz'
+   1484: 'I'm singin' in the rain'
+   1485: 'Alice in Wonderland'
+   1486: 'The wizard of Oz'
+   1487: 'I'm singin' in the rain'
+   1488: 'Alice in Wonderland'
+   1489: 'The wizard of Oz'
+   1490: 'I'm singin' in the rain'
+   1491: 'Alice in Wonderland'
+   1492: 'The wizard of Oz'
+   1493: 'I'm singin' in the rain'
+   1494: 'Alice in Wonderland'
+   1495: 'The wizard of Oz'
+   1496: 'I'm singin' in the rain'
+   1497: 'Alice in Wonderland'
+   1498: 'The wizard of Oz'
+   1499: 'I'm singin' in the rain'
+   1500: 'Alice in Wonderland'
+   1501: 'The wizard of Oz'
+   1502: 'I'm singin' in the rain'
+   1503: 'Alice in Wonderland'
+   1504: 'The wizard of Oz'
+   1505: 'I'm singin' in the rain'
+   1506: 'Alice in Wonderland'
+   1507: 'The wizard of Oz'
+   1508: 'I'm singin' in the rain'
+   1509: 'Alice in Wonderland'
+   1510: 'The wizard of Oz'
+   1511: 'I'm singin' in the rain'
+   1512: 'Alice in Wonderland'
+   1513: 'The wizard of Oz'
+   1514: 'I'm singin' in the rain'
+   1515: 'Alice in Wonderland'
+   1516: 'The wizard of Oz'
+   1517: 'I'm singin' in the rain'
+   1518: 'Alice in Wonderland'
+   1519: 'The wizard of Oz'
+   1520: 'I'm singin' in the rain'
+   1521: 'Alice in Wonderland'
+   1522: 'The wizard of Oz'
+   1523: 'I'm singin' in the rain'
+   1524: 'Alice in Wonderland'
+   1525: 'The wizard of Oz'
+   1526: 'I'm singin' in the rain'
+   1527: 'Alice in Wonderland'
+   1528: 'The wizard of Oz'
+   1529: 'I'm singin' in the rain'
+   1530: 'Alice in Wonderland'
+   1531: 'The wizard of Oz'
+   1532: 'I'm singin' in the rain'
+   1533: 'Alice in Wonderland'
+   1534: 'The wizard of Oz'
+   1535: 'I'm singin' in the rain'
+   1536: 'Alice in Wonderland'
+   1537: 'The wizard of Oz'
+   1538: 'I'm singin' in the rain'
+   1539: 'Alice in Wonderland'
+   1540: 'The wizard of Oz'
+   1541: 'I'm singin' in the rain'
+   1542: 'Alice in Wonderland'
+   1543: 'The wizard of Oz'
+   1544: 'I'm singin' in the rain'
+   1545: 'Alice in Wonderland'
+   1546: 'The wizard of Oz'
+   1547: 'I'm singin' in the rain'
+   1548: 'Alice in Wonderland'
+   1549: 'The wizard of Oz'
+   1550: 'I'm singin' in the rain'
+   1551: 'Alice in Wonderland'
+   1552: 'The wizard of Oz'
+   1553: 'I'm singin' in the rain'
+   1554: 'Alice in Wonderland'
+   1555: 'The wizard of Oz'
+   1556: 'I'm singin' in the rain'
+   1557: 'Alice in Wonderland'
+   1558: 'The wizard of Oz'
+   1559: 'I'm singin' in the rain'
+   1560: 'Alice in Wonderland'
+   1561: 'The wizard of Oz'
+   1562: 'I'm singin' in the rain'
+   1563: 'Alice in Wonderland'
+   1564: 'The wizard of Oz'
+   1565: 'I'm singin' in the rain'
+   1566: 'Alice in Wonderland'
+   1567: 'The wizard of Oz'
+   1568: 'I'm singin' in the rain'
+   1569: 'Alice in Wonderland'
+   1570: 'The wizard of Oz'
+   1571: 'I'm singin' in the rain'
+   1572: 'Alice in Wonderland'
+   1573: 'The wizard of Oz'
+   1574: 'I'm singin' in the rain'
+   1575: 'Alice in Wonderland'
+   1576: 'The wizard of Oz'
+   1577: 'I'm singin' in the rain'
+   1578: 'Alice in Wonderland'
+   1579: 'The wizard of Oz'
+   1580: 'I'm singin' in the rain'
+   1581: 'Alice in Wonderland'
+   1582: 'The wizard of Oz'
+   1583: 'I'm singin' in the rain'
+   1584: 'Alice in Wonderland'
+   1585: 'The wizard of Oz'
+   1586: 'I'm singin' in the rain'
+   1587: 'Alice in Wonderland'
+   1588: 'The wizard of Oz'
+   1589: 'I'm singin' in the rain'
+   1590: 'Alice in Wonderland'
+   1591: 'The wizard of Oz'
+   1592: 'I'm singin' in the rain'
+   1593: 'Alice in Wonderland'
+   1594: 'The wizard of Oz'
+   1595: 'I'm singin' in the rain'
+   1596: 'Alice in Wonderland'
+   1597: 'The wizard of Oz'
+   1598: 'I'm singin' in the rain'
+   1599: 'Alice in Wonderland'
+   1600: 'The wizard of Oz'
+   1601: 'I'm singin' in the rain'
+   1602: 'Alice in Wonderland'
+   1603: 'The wizard of Oz'
+   1604: 'I'm singin' in the rain'
+   1605: 'Alice in Wonderland'
+   1606: 'The wizard of Oz'
+   1607: 'I'm singin' in the rain'
+   1608: 'Alice in Wonderland'
+   1609: 'The wizard of Oz'
+   1610: 'I'm singin' in the rain'
+   1611: 'Alice in Wonderland'
+   1612: 'The wizard of Oz'
+   1613: 'I'm singin' in the rain'
+   1614: 'Alice in Wonderland'
+   1615: 'The wizard of Oz'
+   1616: 'I'm singin' in the rain'
+   1617: 'Alice in Wonderland'
+   1618: 'The wizard of Oz'
+   1619: 'I'm singin' in the rain'
+   1620: 'Alice in Wonderland'
+   1621: 'The wizard of Oz'
+   1622: 'I'm singin' in the rain'
+   1623: 'Alice in Wonderland'
+   1624: 'The wizard of Oz'
+   1625: 'I'm singin' in the rain'
+   1626: 'Alice in Wonderland'
+   1627: 'The wizard of Oz'
+   1628: 'I'm singin' in the rain'
+   1629: 'Alice in Wonderland'
+   1630: 'The wizard of Oz'
+   1631: 'I'm singin' in the rain'
+   1632: 'Alice in Wonderland'
+   1633: 'The wizard of Oz'
+   1634: 'I'm singin' in the rain'
+   1635: 'Alice in Wonderland'
+   1636: 'The wizard of Oz'
+   1637: 'I'm singin' in the rain'
+   1638: 'Alice in Wonderland'
+   1639: 'The wizard of Oz'
+   1640: 'I'm singin' in the rain'
+   1641: 'Alice in Wonderland'
+   1642: 'The wizard of Oz'
+   1643: 'I'm singin' in the rain'
+   1644: 'Alice in Wonderland'
+   1645: 'The wizard of Oz'
+   1646: 'I'm singin' in the rain'
+   1647: 'Alice in Wonderland'
+   1648: 'The wizard of Oz'
+   1649: 'I'm singin' in the rain'
+   1650: 'Alice in Wonderland'
+   1651: 'The wizard of Oz'
+   1652: 'I'm singin' in the rain'
+   1653: 'Alice in Wonderland'
+   1654: 'The wizard of Oz'
+   1655: 'I'm singin' in the rain'
+   1656: 'Alice in Wonderland'
+   1657: 'The wizard of Oz'
+   1658: 'I'm singin' in the rain'
+   1659: 'Alice in Wonderland'
+   1660: 'The wizard of Oz'
+   1661: 'I'm singin' in the rain'
+   1662: 'Alice in Wonderland'
+   1663: 'The wizard of Oz'
+   1664: 'I'm singin' in the rain'
+   1665: 'Alice in Wonderland'
+   1666: 'The wizard of Oz'
+   1667: 'I'm singin' in the rain'
+   1668: 'Alice in Wonderland'
+   1669: 'The wizard of Oz'
+   1670: 'I'm singin' in the rain'
+   1671: 'Alice in Wonderland'
+   1672: 'The wizard of Oz'
+   1673: 'I'm singin' in the rain'
+   1674: 'Alice in Wonderland'
+   1675: 'The wizard of Oz'
+   1676: 'I'm singin' in the rain'
+   1677: 'Alice in Wonderland'
+   1678: 'The wizard of Oz'
+   1679: 'I'm singin' in the rain'
+   1680: 'Alice in Wonderland'
+   1681: 'The wizard of Oz'
+   1682: 'I'm singin' in the rain'
+   1683: 'Alice in Wonderland'
+   1684: 'The wizard of Oz'
+   1685: 'I'm singin' in the rain'
+   1686: 'Alice in Wonderland'
+   1687: 'The wizard of Oz'
+   1688: 'I'm singin' in the rain'
+   1689: 'Alice in Wonderland'
+   1690: 'The wizard of Oz'
+   1691: 'I'm singin' in the rain'
+   1692: 'Alice in Wonderland'
+   1693: 'The wizard of Oz'
+   1694: 'I'm singin' in the rain'
+   1695: 'Alice in Wonderland'
+   1696: 'The wizard of Oz'
+   1697: 'I'm singin' in the rain'
+   1698: 'Alice in Wonderland'
+   1699: 'The wizard of Oz'
+   1700: 'I'm singin' in the rain'
+   1701: 'Alice in Wonderland'
+   1702: 'The wizard of Oz'
+   1703: 'I'm singin' in the rain'
+   1704: 'Alice in Wonderland'
+   1705: 'The wizard of Oz'
+   1706: 'I'm singin' in the rain'
+   1707: 'Alice in Wonderland'
+   1708: 'The wizard of Oz'
+   1709: 'I'm singin' in the rain'
+   1710: 'Alice in Wonderland'
+   1711: 'The wizard of Oz'
+   1712: 'I'm singin' in the rain'
+   1713: 'Alice in Wonderland'
+   1714: 'The wizard of Oz'
+   1715: 'I'm singin' in the rain'
+   1716: 'Alice in Wonderland'
+   1717: 'The wizard of Oz'
+   1718: 'I'm singin' in the rain'
+   1719: 'Alice in Wonderland'
+   1720: 'The wizard of Oz'
+   1721: 'I'm singin' in the rain'
+   1722: 'Alice in Wonderland'
+   1723: 'The wizard of Oz'
+   1724: 'I'm singin' in the rain'
+   1725: 'Alice in Wonderland'
+   1726: 'The wizard of Oz'
+   1727: 'I'm singin' in the rain'
+   1728: 'Alice in Wonderland'
+   1729: 'The wizard of Oz'
+   1730: 'I'm singin' in the rain'
+   1731: 'Alice in Wonderland'
+   1732: 'The wizard of Oz'
+   1733: 'I'm singin' in the rain'
+   1734: 'Alice in Wonderland'
+   1735: 'The wizard of Oz'
+   1736: 'I'm singin' in the rain'
+   1737: 'Alice in Wonderland'
+   1738: 'The wizard of Oz'
+   1739: 'I'm singin' in the rain'
+   1740: 'Alice in Wonderland'
+   1741: 'The wizard of Oz'
+   1742: 'I'm singin' in the rain'
+   1743: 'Alice in Wonderland'
+   1744: 'The wizard of Oz'
+   1745: 'I'm singin' in the rain'
+   1746: 'Alice in Wonderland'
+   1747: 'The wizard of Oz'
+   1748: 'I'm singin' in the rain'
+   1749: 'Alice in Wonderland'
+   1750: 'The wizard of Oz'
+   1751: 'I'm singin' in the rain'
+   1752: 'Alice in Wonderland'
+   1753: 'The wizard of Oz'
+   1754: 'I'm singin' in the rain'
+   1755: 'Alice in Wonderland'
+   1756: 'The wizard of Oz'
+   1757: 'I'm singin' in the rain'
+   1758: 'Alice in Wonderland'
+   1759: 'The wizard of Oz'
+   1760: 'I'm singin' in the rain'
+   1761: 'Alice in Wonderland'
+   1762: 'The wizard of Oz'
+   1763: 'I'm singin' in the rain'
+   1764: 'Alice in Wonderland'
+   1765: 'The wizard of Oz'
+   1766: 'I'm singin' in the rain'
+   1767: 'Alice in Wonderland'
+   1768: 'The wizard of Oz'
+   1769: 'I'm singin' in the rain'
+   1770: 'Alice in Wonderland'
+   1771: 'The wizard of Oz'
+   1772: 'I'm singin' in the rain'
+   1773: 'Alice in Wonderland'
+   1774: 'The wizard of Oz'
+   1775: 'I'm singin' in the rain'
+   1776: 'Alice in Wonderland'
+   1777: 'The wizard of Oz'
+   1778: 'I'm singin' in the rain'
+   1779: 'Alice in Wonderland'
+   1780: 'The wizard of Oz'
+   1781: 'I'm singin' in the rain'
+   1782: 'Alice in Wonderland'
+   1783: 'The wizard of Oz'
+   1784: 'I'm singin' in the rain'
+   1785: 'Alice in Wonderland'
+   1786: 'The wizard of Oz'
+   1787: 'I'm singin' in the rain'
+   1788: 'Alice in Wonderland'
+   1789: 'The wizard of Oz'
+   1790: 'I'm singin' in the rain'
+   1791: 'Alice in Wonderland'
+   1792: 'The wizard of Oz'
+   1793: 'I'm singin' in the rain'
+   1794: 'Alice in Wonderland'
+   1795: 'The wizard of Oz'
+   1796: 'I'm singin' in the rain'
+   1797: 'Alice in Wonderland'
+   1798: 'The wizard of Oz'
+   1799: 'I'm singin' in the rain'
+   1800: 'Alice in Wonderland'
+   1801: 'The wizard of Oz'
+   1802: 'I'm singin' in the rain'
+   1803: 'Alice in Wonderland'
+   1804: 'The wizard of Oz'
+   1805: 'I'm singin' in the rain'
+   1806: 'Alice in Wonderland'
+   1807: 'The wizard of Oz'
+   1808: 'I'm singin' in the rain'
+   1809: 'Alice in Wonderland'
+   1810: 'The wizard of Oz'
+   1811: 'I'm singin' in the rain'
+   1812: 'Alice in Wonderland'
+   1813: 'The wizard of Oz'
+   1814: 'I'm singin' in the rain'
+   1815: 'Alice in Wonderland'
+   1816: 'The wizard of Oz'
+   1817: 'I'm singin' in the rain'
+   1818: 'Alice in Wonderland'
+   1819: 'The wizard of Oz'
+   1820: 'I'm singin' in the rain'
+   1821: 'Alice in Wonderland'
+   1822: 'The wizard of Oz'
+   1823: 'I'm singin' in the rain'
+   1824: 'Alice in Wonderland'
+   1825: 'The wizard of Oz'
+   1826: 'I'm singin' in the rain'
+   1827: 'Alice in Wonderland'
+   1828: 'The wizard of Oz'
+   1829: 'I'm singin' in the rain'
+   1830: 'Alice in Wonderland'
+   1831: 'The wizard of Oz'
+   1832: 'I'm singin' in the rain'
+   1833: 'Alice in Wonderland'
+   1834: 'The wizard of Oz'
+   1835: 'I'm singin' in the rain'
+   1836: 'Alice in Wonderland'
+   1837: 'The wizard of Oz'
+   1838: 'I'm singin' in the rain'
+   1839: 'Alice in Wonderland'
+   1840: 'The wizard of Oz'
+   1841: 'I'm singin' in the rain'
+   1842: 'Alice in Wonderland'
+   1843: 'The wizard of Oz'
+   1844: 'I'm singin' in the rain'
+   1845: 'Alice in Wonderland'
+   1846: 'The wizard of Oz'
+   1847: 'I'm singin' in the rain'
+   1848: 'Alice in Wonderland'
+   1849: 'The wizard of Oz'
+   1850: 'I'm singin' in the rain'
+   1851: 'Alice in Wonderland'
+   1852: 'The wizard of Oz'
+   1853: 'I'm singin' in the rain'
+   1854: 'Alice in Wonderland'
+   1855: 'The wizard of Oz'
+   1856: 'I'm singin' in the rain'
+   1857: 'Alice in Wonderland'
+   1858: 'The wizard of Oz'
+   1859: 'I'm singin' in the rain'
+   1860: 'Alice in Wonderland'
+   1861: 'The wizard of Oz'
+   1862: 'I'm singin' in the rain'
+   1863: 'Alice in Wonderland'
+   1864: 'The wizard of Oz'
+   1865: 'I'm singin' in the rain'
+   1866: 'Alice in Wonderland'
+   1867: 'The wizard of Oz'
+   1868: 'I'm singin' in the rain'
+   1869: 'Alice in Wonderland'
+   1870: 'The wizard of Oz'
+   1871: 'I'm singin' in the rain'
+   1872: 'Alice in Wonderland'
+   1873: 'The wizard of Oz'
+   1874: 'I'm singin' in the rain'
+   1875: 'Alice in Wonderland'
+   1876: 'The wizard of Oz'
+   1877: 'I'm singin' in the rain'
+   1878: 'Alice in Wonderland'
+   1879: 'The wizard of Oz'
+   1880: 'I'm singin' in the rain'
+   1881: 'Alice in Wonderland'
+   1882: 'The wizard of Oz'
+   1883: 'I'm singin' in the rain'
+   1884: 'Alice in Wonderland'
+   1885: 'The wizard of Oz'
+   1886: 'I'm singin' in the rain'
+   1887: 'Alice in Wonderland'
+   1888: 'The wizard of Oz'
+   1889: 'I'm singin' in the rain'
+   1890: 'Alice in Wonderland'
+   1891: 'The wizard of Oz'
+   1892: 'I'm singin' in the rain'
+   1893: 'Alice in Wonderland'
+   1894: 'The wizard of Oz'
+   1895: 'I'm singin' in the rain'
+   1896: 'Alice in Wonderland'
+   1897: 'The wizard of Oz'
+   1898: 'I'm singin' in the rain'
+   1899: 'Alice in Wonderland'
+   1900: 'The wizard of Oz'
+   1901: 'I'm singin' in the rain'
+   1902: 'Alice in Wonderland'
+   1903: 'The wizard of Oz'
+   1904: 'I'm singin' in the rain'
+   1905: 'Alice in Wonderland'
+   1906: 'The wizard of Oz'
+   1907: 'I'm singin' in the rain'
+   1908: 'Alice in Wonderland'
+   1909: 'The wizard of Oz'
+   1910: 'I'm singin' in the rain'
+   1911: 'Alice in Wonderland'
+   1912: 'The wizard of Oz'
+   1913: 'I'm singin' in the rain'
+   1914: 'Alice in Wonderland'
+   1915: 'The wizard of Oz'
+   1916: 'I'm singin' in the rain'
+   1917: 'Alice in Wonderland'
+   1918: 'The wizard of Oz'
+   1919: 'I'm singin' in the rain'
+   1920: 'Alice in Wonderland'
+   1921: 'The wizard of Oz'
+   1922: 'I'm singin' in the rain'
+   1923: 'Alice in Wonderland'
+   1924: 'The wizard of Oz'
+   1925: 'I'm singin' in the rain'
+   1926: 'Alice in Wonderland'
+   1927: 'The wizard of Oz'
+   1928: 'I'm singin' in the rain'
+   1929: 'Alice in Wonderland'
+   1930: 'The wizard of Oz'
+   1931: 'I'm singin' in the rain'
+   1932: 'Alice in Wonderland'
+   1933: 'The wizard of Oz'
+   1934: 'I'm singin' in the rain'
+   1935: 'Alice in Wonderland'
+   1936: 'The wizard of Oz'
+   1937: 'I'm singin' in the rain'
+   1938: 'Alice in Wonderland'
+   1939: 'The wizard of Oz'
+   1940: 'I'm singin' in the rain'
+   1941: 'Alice in Wonderland'
+   1942: 'The wizard of Oz'
+   1943: 'I'm singin' in the rain'
+   1944: 'Alice in Wonderland'
+   1945: 'The wizard of Oz'
+   1946: 'I'm singin' in the rain'
+   1947: 'Alice in Wonderland'
+   1948: 'The wizard of Oz'
+   1949: 'I'm singin' in the rain'
+   1950: 'Alice in Wonderland'
+   1951: 'The wizard of Oz'
+   1952: 'I'm singin' in the rain'
+   1953: 'Alice in Wonderland'
+   1954: 'The wizard of Oz'
+   1955: 'I'm singin' in the rain'
+   1956: 'Alice in Wonderland'
+   1957: 'The wizard of Oz'
+   1958: 'I'm singin' in the rain'
+   1959: 'Alice in Wonderland'
+   1960: 'The wizard of Oz'
+   1961: 'I'm singin' in the rain'
+   1962: 'Alice in Wonderland'
+   1963: 'The wizard of Oz'
+   1964: 'I'm singin' in the rain'
+   1965: 'Alice in Wonderland'
+   1966: 'The wizard of Oz'
+   1967: 'I'm singin' in the rain'
+   1968: 'Alice in Wonderland'
+   1969: 'The wizard of Oz'
+   1970: 'I'm singin' in the rain'
+   1971: 'Alice in Wonderland'
+   1972: 'The wizard of Oz'
+   1973: 'I'm singin' in the rain'
+   1974: 'Alice in Wonderland'
+   1975: 'The wizard of Oz'
+   1976: 'I'm singin' in the rain'
+   1977: 'Alice in Wonderland'
+   1978: 'The wizard of Oz'
+   1979: 'I'm singin' in the rain'
+   1980: 'Alice in Wonderland'
+   1981: 'The wizard of Oz'
+   1982: 'I'm singin' in the rain'
+   1983: 'Alice in Wonderland'
+   1984: 'The wizard of Oz'
+   1985: 'I'm singin' in the rain'
+   1986: 'Alice in Wonderland'
+   1987: 'The wizard of Oz'
+   1988: 'I'm singin' in the rain'
+   1989: 'Alice in Wonderland'
+   1990: 'The wizard of Oz'
+   1991: 'I'm singin' in the rain'
+   1992: 'Alice in Wonderland'
+   1993: 'The wizard of Oz'
+   1994: 'I'm singin' in the rain'
+   1995: 'Alice in Wonderland'
+   1996: 'The wizard of Oz'
+   1997: 'I'm singin' in the rain'
+   1998: 'Alice in Wonderland'
+   1999: 'The wizard of Oz'
+   2000: 'I'm singin' in the rain'
+   2001: 'Alice in Wonderland'
+   2002: 'The wizard of Oz'
+   2003: 'I'm singin' in the rain'
+   2004: 'Alice in Wonderland'
+   2005: 'The wizard of Oz'
+   2006: 'I'm singin' in the rain'
+   2007: 'Alice in Wonderland'
+   2008: 'The wizard of Oz'
+   2009: 'I'm singin' in the rain'
+   2010: 'Alice in Wonderland'
+   2011: 'The wizard of Oz'
+   2012: 'I'm singin' in the rain'
+   2013: 'Alice in Wonderland'
+   2014: 'The wizard of Oz'
+   2015: 'I'm singin' in the rain'
+   2016: 'Alice in Wonderland'
+   2017: 'The wizard of Oz'
+   2018: 'I'm singin' in the rain'
+   2019: 'Alice in Wonderland'
+   2020: 'The wizard of Oz'
+   2021: 'I'm singin' in the rain'
+   2022: 'Alice in Wonderland'
+   2023: 'The wizard of Oz'
+   2024: 'I'm singin' in the rain'
+   2025: 'Alice in Wonderland'
+   2026: 'The wizard of Oz'
+   2027: 'I'm singin' in the rain'
+   2028: 'Alice in Wonderland'
+   2029: 'The wizard of Oz'
+   2030: 'I'm singin' in the rain'
+   2031: 'Alice in Wonderland'
+   2032: 'The wizard of Oz'
+   2033: 'I'm singin' in the rain'
+   2034: 'Alice in Wonderland'
+   2035: 'The wizard of Oz'
+   2036: 'I'm singin' in the rain'
+   2037: 'Alice in Wonderland'
+   2038: 'The wizard of Oz'
+   2039: 'I'm singin' in the rain'
+   2040: 'Alice in Wonderland'
+   2041: 'The wizard of Oz'
+   2042: 'I'm singin' in the rain'
+   2043: 'Alice in Wonderland'
+   2044: 'The wizard of Oz'
+   2045: 'I'm singin' in the rain'
+   2046: 'Alice in Wonderland'
+   2047: 'The wizard of Oz'
+   2048: 'I'm singin' in the rain'
+   2049: 'Alice in Wonderland'
+   2050: 'The wizard of Oz'
+   2051: 'I'm singin' in the rain'
+   2052: 'Alice in Wonderland'
+   2053: 'The wizard of Oz'
+   2054: 'I'm singin' in the rain'
+   2055: 'Alice in Wonderland'
+   2056: 'The wizard of Oz'
+   2057: 'I'm singin' in the rain'
+   2058: 'Alice in Wonderland'
+   2059: 'The wizard of Oz'
+   2060: 'I'm singin' in the rain'
+   2061: 'Alice in Wonderland'
+   2062: 'The wizard of Oz'
+   2063: 'I'm singin' in the rain'
+   2064: 'Alice in Wonderland'
+   2065: 'The wizard of Oz'
+   2066: 'I'm singin' in the rain'
+   2067: 'Alice in Wonderland'
+   2068: 'The wizard of Oz'
+   2069: 'I'm singin' in the rain'
+   2070: 'Alice in Wonderland'
+   2071: 'The wizard of Oz'
+   2072: 'I'm singin' in the rain'
+   2073: 'Alice in Wonderland'
+   2074: 'The wizard of Oz'
+   2075: 'I'm singin' in the rain'
+   2076: 'Alice in Wonderland'
+   2077: 'The wizard of Oz'
+   2078: 'I'm singin' in the rain'
+   2079: 'Alice in Wonderland'
+   2080: 'The wizard of Oz'
+   2081: 'I'm singin' in the rain'
+   2082: 'Alice in Wonderland'
+   2083: 'The wizard of Oz'
+   2084: 'I'm singin' in the rain'
+   2085: 'Alice in Wonderland'
+   2086: 'The wizard of Oz'
+   2087: 'I'm singin' in the rain'
+   2088: 'Alice in Wonderland'
+   2089: 'The wizard of Oz'
+   2090: 'I'm singin' in the rain'
+   2091: 'Alice in Wonderland'
+   2092: 'The wizard of Oz'
+   2093: 'I'm singin' in the rain'
+   2094: 'Alice in Wonderland'
+   2095: 'The wizard of Oz'
+   2096: 'I'm singin' in the rain'
+   2097: 'Alice in Wonderland'
+   2098: 'The wizard of Oz'
+   2099: 'I'm singin' in the rain'
+   2100: 'Alice in Wonderland'
+   2101: 'The wizard of Oz'
+   2102: 'I'm singin' in the rain'
+   2103: 'Alice in Wonderland'
+   2104: 'The wizard of Oz'
+   2105: 'I'm singin' in the rain'
+   2106: 'Alice in Wonderland'
+   2107: 'The wizard of Oz'
+   2108: 'I'm singin' in the rain'
+   2109: 'Alice in Wonderland'
+   2110: 'The wizard of Oz'
+   2111: 'I'm singin' in the rain'
+   2112: 'Alice in Wonderland'
+   2113: 'The wizard of Oz'
+   2114: 'I'm singin' in the rain'
+   2115: 'Alice in Wonderland'
+   2116: 'The wizard of Oz'
+   2117: 'I'm singin' in the rain'
+   2118: 'Alice in Wonderland'
+   2119: 'The wizard of Oz'
+   2120: 'I'm singin' in the rain'
+   2121: 'Alice in Wonderland'
+   2122: 'The wizard of Oz'
+   2123: 'I'm singin' in the rain'
+   2124: 'Alice in Wonderland'
+   2125: 'The wizard of Oz'
+   2126: 'I'm singin' in the rain'
+   2127: 'Alice in Wonderland'
+   2128: 'The wizard of Oz'
+   2129: 'I'm singin' in the rain'
+   2130: 'Alice in Wonderland'
+   2131: 'The wizard of Oz'
+   2132: 'I'm singin' in the rain'
+   2133: 'Alice in Wonderland'
+   2134: 'The wizard of Oz'
+   2135: 'I'm singin' in the rain'
+   2136: 'Alice in Wonderland'
+   2137: 'The wizard of Oz'
+   2138: 'I'm singin' in the rain'
+   2139: 'Alice in Wonderland'
+   2140: 'The wizard of Oz'
+   2141: 'I'm singin' in the rain'
+   2142: 'Alice in Wonderland'
+   2143: 'The wizard of Oz'
+   2144: 'I'm singin' in the rain'
+   2145: 'Alice in Wonderland'
+   2146: 'The wizard of Oz'
+   2147: 'I'm singin' in the rain'
+   2148: 'Alice in Wonderland'
+   2149: 'The wizard of Oz'
+   2150: 'I'm singin' in the rain'
+   2151: 'Alice in Wonderland'
+   2152: 'The wizard of Oz'
+   2153: 'I'm singin' in the rain'
+   2154: 'Alice in Wonderland'
+   2155: 'The wizard of Oz'
+   2156: 'I'm singin' in the rain'
+   2157: 'Alice in Wonderland'
+   2158: 'The wizard of Oz'
+   2159: 'I'm singin' in the rain'
+   2160: 'Alice in Wonderland'
+   2161: 'The wizard of Oz'
+   2162: 'I'm singin' in the rain'
+   2163: 'Alice in Wonderland'
+   2164: 'The wizard of Oz'
+   2165: 'I'm singin' in the rain'
+   2166: 'Alice in Wonderland'
+   2167: 'The wizard of Oz'
+   2168: 'I'm singin' in the rain'
+   2169: 'Alice in Wonderland'
+   2170: 'The wizard of Oz'
+   2171: 'I'm singin' in the rain'
+   2172: 'Alice in Wonderland'
+   2173: 'The wizard of Oz'
+   2174: 'I'm singin' in the rain'
+   2175: 'Alice in Wonderland'
+   2176: 'The wizard of Oz'
+   2177: 'I'm singin' in the rain'
+   2178: 'Alice in Wonderland'
+   2179: 'The wizard of Oz'
+   2180: 'I'm singin' in the rain'
+   2181: 'Alice in Wonderland'
+   2182: 'The wizard of Oz'
+   2183: 'I'm singin' in the rain'
+   2184: 'Alice in Wonderland'
+   2185: 'The wizard of Oz'
+   2186: 'I'm singin' in the rain'
+   2187: 'Alice in Wonderland'
+   2188: 'The wizard of Oz'
+   2189: 'I'm singin' in the rain'
+   2190: 'Alice in Wonderland'
+   2191: 'The wizard of Oz'
+   2192: 'I'm singin' in the rain'
+   2193: 'Alice in Wonderland'
+   2194: 'The wizard of Oz'
+   2195: 'I'm singin' in the rain'
+   2196: 'Alice in Wonderland'
+   2197: 'The wizard of Oz'
+   2198: 'I'm singin' in the rain'
+   2199: 'Alice in Wonderland'
+   2200: 'The wizard of Oz'
+   2201: 'I'm singin' in the rain'
+   2202: 'Alice in Wonderland'
+   2203: 'The wizard of Oz'
+   2204: 'I'm singin' in the rain'
+   2205: 'Alice in Wonderland'
+   2206: 'The wizard of Oz'
+   2207: 'I'm singin' in the rain'
+   2208: 'Alice in Wonderland'
+   2209: 'The wizard of Oz'
+   2210: 'I'm singin' in the rain'
+   2211: 'Alice in Wonderland'
+   2212: 'The wizard of Oz'
+   2213: 'I'm singin' in the rain'
+   2214: 'Alice in Wonderland'
+   2215: 'The wizard of Oz'
+   2216: 'I'm singin' in the rain'
+   2217: 'Alice in Wonderland'
+   2218: 'The wizard of Oz'
+   2219: 'I'm singin' in the rain'
+   2220: 'Alice in Wonderland'
+   2221: 'The wizard of Oz'
+   2222: 'I'm singin' in the rain'
+   2223: 'Alice in Wonderland'
+   2224: 'The wizard of Oz'
+   2225: 'I'm singin' in the rain'
+   2226: 'Alice in Wonderland'
+   2227: 'The wizard of Oz'
+   2228: 'I'm singin' in the rain'
+   2229: 'Alice in Wonderland'
+   2230: 'The wizard of Oz'
+   2231: 'I'm singin' in the rain'
+   2232: 'Alice in Wonderland'
+   2233: 'The wizard of Oz'
+   2234: 'I'm singin' in the rain'
+   2235: 'Alice in Wonderland'
+   2236: 'The wizard of Oz'
+   2237: 'I'm singin' in the rain'
+   2238: 'Alice in Wonderland'
+   2239: 'The wizard of Oz'
+   2240: 'I'm singin' in the rain'
+   2241: 'Alice in Wonderland'
+   2242: 'The wizard of Oz'
+   2243: 'I'm singin' in the rain'
+   2244: 'Alice in Wonderland'
+   2245: 'The wizard of Oz'
+   2246: 'I'm singin' in the rain'
+   2247: 'Alice in Wonderland'
+   2248: 'The wizard of Oz'
+   2249: 'I'm singin' in the rain'
+   2250: 'Alice in Wonderland'
+   2251: 'The wizard of Oz'
+   2252: 'I'm singin' in the rain'
+   2253: 'Alice in Wonderland'
+   2254: 'The wizard of Oz'
+   2255: 'I'm singin' in the rain'
+   2256: 'Alice in Wonderland'
+   2257: 'The wizard of Oz'
+   2258: 'I'm singin' in the rain'
+   2259: 'Alice in Wonderland'
+   2260: 'The wizard of Oz'
+   2261: 'I'm singin' in the rain'
+   2262: 'Alice in Wonderland'
+   2263: 'The wizard of Oz'
+   2264: 'I'm singin' in the rain'
+   2265: 'Alice in Wonderland'
+   2266: 'The wizard of Oz'
+   2267: 'I'm singin' in the rain'
+   2268: 'Alice in Wonderland'
+   2269: 'The wizard of Oz'
+   2270: 'I'm singin' in the rain'
+   2271: 'Alice in Wonderland'
+   2272: 'The wizard of Oz'
+   2273: 'I'm singin' in the rain'
+   2274: 'Alice in Wonderland'
+   2275: 'The wizard of Oz'
+   2276: 'I'm singin' in the rain'
+   2277: 'Alice in Wonderland'
+   2278: 'The wizard of Oz'
+   2279: 'I'm singin' in the rain'
+   2280: 'Alice in Wonderland'
+   2281: 'The wizard of Oz'
+   2282: 'I'm singin' in the rain'
+   2283: 'Alice in Wonderland'
+   2284: 'The wizard of Oz'
+   2285: 'I'm singin' in the rain'
+   2286: 'Alice in Wonderland'
+   2287: 'The wizard of Oz'
+   2288: 'I'm singin' in the rain'
+   2289: 'Alice in Wonderland'
+   2290: 'The wizard of Oz'
+   2291: 'I'm singin' in the rain'
+   2292: 'Alice in Wonderland'
+   2293: 'The wizard of Oz'
+   2294: 'I'm singin' in the rain'
+   2295: 'Alice in Wonderland'
+   2296: 'The wizard of Oz'
+   2297: 'I'm singin' in the rain'
+   2298: 'Alice in Wonderland'
+   2299: 'The wizard of Oz'
+   2300: 'I'm singin' in the rain'
+   2301: 'Alice in Wonderland'
+   2302: 'The wizard of Oz'
+   2303: 'I'm singin' in the rain'
+   2304: 'Alice in Wonderland'
+   2305: 'The wizard of Oz'
+   2306: 'I'm singin' in the rain'
+   2307: 'Alice in Wonderland'
+   2308: 'The wizard of Oz'
+   2309: 'I'm singin' in the rain'
+   2310: 'Alice in Wonderland'
+   2311: 'The wizard of Oz'
+   2312: 'I'm singin' in the rain'
+   2313: 'Alice in Wonderland'
+   2314: 'The wizard of Oz'
+   2315: 'I'm singin' in the rain'
+   2316: 'Alice in Wonderland'
+   2317: 'The wizard of Oz'
+   2318: 'I'm singin' in the rain'
+   2319: 'Alice in Wonderland'
+   2320: 'The wizard of Oz'
+   2321: 'I'm singin' in the rain'
+   2322: 'Alice in Wonderland'
+   2323: 'The wizard of Oz'
+   2324: 'I'm singin' in the rain'
+   2325: 'Alice in Wonderland'
+   2326: 'The wizard of Oz'
+   2327: 'I'm singin' in the rain'
+   2328: 'Alice in Wonderland'
+   2329: 'The wizard of Oz'
+   2330: 'I'm singin' in the rain'
+   2331: 'Alice in Wonderland'
+   2332: 'The wizard of Oz'
+   2333: 'I'm singin' in the rain'
+   2334: 'Alice in Wonderland'
+   2335: 'The wizard of Oz'
+   2336: 'I'm singin' in the rain'
+   2337: 'Alice in Wonderland'
+   2338: 'The wizard of Oz'
+   2339: 'I'm singin' in the rain'
+   2340: 'Alice in Wonderland'
+   2341: 'The wizard of Oz'
+   2342: 'I'm singin' in the rain'
+   2343: 'Alice in Wonderland'
+   2344: 'The wizard of Oz'
+   2345: 'I'm singin' in the rain'
+   2346: 'Alice in Wonderland'
+   2347: 'The wizard of Oz'
+   2348: 'I'm singin' in the rain'
+   2349: 'Alice in Wonderland'
+   2350: 'The wizard of Oz'
+   2351: 'I'm singin' in the rain'
+   2352: 'Alice in Wonderland'
+   2353: 'The wizard of Oz'
+   2354: 'I'm singin' in the rain'
+   2355: 'Alice in Wonderland'
+   2356: 'The wizard of Oz'
+   2357: 'I'm singin' in the rain'
+   2358: 'Alice in Wonderland'
+   2359: 'The wizard of Oz'
+   2360: 'I'm singin' in the rain'
+   2361: 'Alice in Wonderland'
+   2362: 'The wizard of Oz'
+   2363: 'I'm singin' in the rain'
+   2364: 'Alice in Wonderland'
+   2365: 'The wizard of Oz'
+   2366: 'I'm singin' in the rain'
+   2367: 'Alice in Wonderland'
+   2368: 'The wizard of Oz'
+   2369: 'I'm singin' in the rain'
+   2370: 'Alice in Wonderland'
+   2371: 'The wizard of Oz'
+   2372: 'I'm singin' in the rain'
+   2373: 'Alice in Wonderland'
+   2374: 'The wizard of Oz'
+   2375: 'I'm singin' in the rain'
+   2376: 'Alice in Wonderland'
+   2377: 'The wizard of Oz'
+   2378: 'I'm singin' in the rain'
+   2379: 'Alice in Wonderland'
+   2380: 'The wizard of Oz'
+   2381: 'I'm singin' in the rain'
+   2382: 'Alice in Wonderland'
+   2383: 'The wizard of Oz'
+   2384: 'I'm singin' in the rain'
+   2385: 'Alice in Wonderland'
+   2386: 'The wizard of Oz'
+   2387: 'I'm singin' in the rain'
+   2388: 'Alice in Wonderland'
+   2389: 'The wizard of Oz'
+   2390: 'I'm singin' in the rain'
+   2391: 'Alice in Wonderland'
+   2392: 'The wizard of Oz'
+   2393: 'I'm singin' in the rain'
+   2394: 'Alice in Wonderland'
+   2395: 'The wizard of Oz'
+   2396: 'I'm singin' in the rain'
+   2397: 'Alice in Wonderland'
+   2398: 'The wizard of Oz'
+   2399: 'I'm singin' in the rain'
+   2400: 'Alice in Wonderland'
+   2401: 'The wizard of Oz'
+   2402: 'I'm singin' in the rain'
+   2403: 'Alice in Wonderland'
+   2404: 'The wizard of Oz'
+   2405: 'I'm singin' in the rain'
+   2406: 'Alice in Wonderland'
+   2407: 'The wizard of Oz'
+   2408: 'I'm singin' in the rain'
+   2409: 'Alice in Wonderland'
+   2410: 'The wizard of Oz'
+   2411: 'I'm singin' in the rain'
+   2412: 'Alice in Wonderland'
+   2413: 'The wizard of Oz'
+   2414: 'I'm singin' in the rain'
+   2415: 'Alice in Wonderland'
+   2416: 'The wizard of Oz'
+   2417: 'I'm singin' in the rain'
+   2418: 'Alice in Wonderland'
+   2419: 'The wizard of Oz'
+   2420: 'I'm singin' in the rain'
+   2421: 'Alice in Wonderland'
+   2422: 'The wizard of Oz'
+   2423: 'I'm singin' in the rain'
+   2424: 'Alice in Wonderland'
+   2425: 'The wizard of Oz'
+   2426: 'I'm singin' in the rain'
+   2427: 'Alice in Wonderland'
+   2428: 'The wizard of Oz'
+   2429: 'I'm singin' in the rain'
+   2430: 'Alice in Wonderland'
+   2431: 'The wizard of Oz'
+   2432: 'I'm singin' in the rain'
+   2433: 'Alice in Wonderland'
+   2434: 'The wizard of Oz'
+   2435: 'I'm singin' in the rain'
+   2436: 'Alice in Wonderland'
+   2437: 'The wizard of Oz'
+   2438: 'I'm singin' in the rain'
+   2439: 'Alice in Wonderland'
+   2440: 'The wizard of Oz'
+   2441: 'I'm singin' in the rain'
+   2442: 'Alice in Wonderland'
+   2443: 'The wizard of Oz'
+   2444: 'I'm singin' in the rain'
+   2445: 'Alice in Wonderland'
+   2446: 'The wizard of Oz'
+   2447: 'I'm singin' in the rain'
+   2448: 'Alice in Wonderland'
+   2449: 'The wizard of Oz'
+   2450: 'I'm singin' in the rain'
+   2451: 'Alice in Wonderland'
+   2452: 'The wizard of Oz'
+   2453: 'I'm singin' in the rain'
+   2454: 'Alice in Wonderland'
+   2455: 'The wizard of Oz'
+   2456: 'I'm singin' in the rain'
+   2457: 'Alice in Wonderland'
+   2458: 'The wizard of Oz'
+   2459: 'I'm singin' in the rain'
+   2460: 'Alice in Wonderland'
+   2461: 'The wizard of Oz'
+   2462: 'I'm singin' in the rain'
+   2463: 'Alice in Wonderland'
+   2464: 'The wizard of Oz'
+   2465: 'I'm singin' in the rain'
+   2466: 'Alice in Wonderland'
+   2467: 'The wizard of Oz'
+   2468: 'I'm singin' in the rain'
+   2469: 'Alice in Wonderland'
+   2470: 'The wizard of Oz'
+   2471: 'I'm singin' in the rain'
+   2472: 'Alice in Wonderland'
+   2473: 'The wizard of Oz'
+   2474: 'I'm singin' in the rain'
+   2475: 'Alice in Wonderland'
+   2476: 'The wizard of Oz'
+   2477: 'I'm singin' in the rain'
+   2478: 'Alice in Wonderland'
+   2479: 'The wizard of Oz'
+   2480: 'I'm singin' in the rain'
+   2481: 'Alice in Wonderland'
+   2482: 'The wizard of Oz'
+   2483: 'I'm singin' in the rain'
+   2484: 'Alice in Wonderland'
+   2485: 'The wizard of Oz'
+   2486: 'I'm singin' in the rain'
+   2487: 'Alice in Wonderland'
+   2488: 'The wizard of Oz'
+   2489: 'I'm singin' in the rain'
+   2490: 'Alice in Wonderland'
+   2491: 'The wizard of Oz'
+   2492: 'I'm singin' in the rain'
+   2493: 'Alice in Wonderland'
+   2494: 'The wizard of Oz'
+   2495: 'I'm singin' in the rain'
+   2496: 'Alice in Wonderland'
+   2497: 'The wizard of Oz'
+   2498: 'I'm singin' in the rain'
+   2499: 'Alice in Wonderland'
+   2500: 'The wizard of Oz'
+   2501: 'I'm singin' in the rain'
+   2502: 'Alice in Wonderland'
+   2503: 'The wizard of Oz'
+   2504: 'I'm singin' in the rain'
+   2505: 'Alice in Wonderland'
+   2506: 'The wizard of Oz'
+   2507: 'I'm singin' in the rain'
+   2508: 'Alice in Wonderland'
+   2509: 'The wizard of Oz'
+   2510: 'I'm singin' in the rain'
+   2511: 'Alice in Wonderland'
+   2512: 'The wizard of Oz'
+   2513: 'I'm singin' in the rain'
+   2514: 'Alice in Wonderland'
+   2515: 'The wizard of Oz'
+   2516: 'I'm singin' in the rain'
+   2517: 'Alice in Wonderland'
+   2518: 'The wizard of Oz'
+   2519: 'I'm singin' in the rain'
+   2520: 'Alice in Wonderland'
+   2521: 'The wizard of Oz'
+   2522: 'I'm singin' in the rain'
+   2523: 'Alice in Wonderland'
+   2524: 'The wizard of Oz'
+   2525: 'I'm singin' in the rain'
+   2526: 'Alice in Wonderland'
+   2527: 'The wizard of Oz'
+   2528: 'I'm singin' in the rain'
+   2529: 'Alice in Wonderland'
+   2530: 'The wizard of Oz'
+   2531: 'I'm singin' in the rain'
+   2532: 'Alice in Wonderland'
+   2533: 'The wizard of Oz'
+   2534: 'I'm singin' in the rain'
+   2535: 'Alice in Wonderland'
+   2536: 'The wizard of Oz'
+   2537: 'I'm singin' in the rain'
+   2538: 'Alice in Wonderland'
+   2539: 'The wizard of Oz'
+   2540: 'I'm singin' in the rain'
+   2541: 'Alice in Wonderland'
+   2542: 'The wizard of Oz'
+   2543: 'I'm singin' in the rain'
+   2544: 'Alice in Wonderland'
+   2545: 'The wizard of Oz'
+   2546: 'I'm singin' in the rain'
+   2547: 'Alice in Wonderland'
+   2548: 'The wizard of Oz'
+   2549: 'I'm singin' in the rain'
+   2550: 'Alice in Wonderland'
+   2551: 'The wizard of Oz'
+   2552: 'I'm singin' in the rain'
+   2553: 'Alice in Wonderland'
+   2554: 'The wizard of Oz'
+   2555: 'I'm singin' in the rain'
+   2556: 'Alice in Wonderland'
+   2557: 'The wizard of Oz'
+   2558: 'I'm singin' in the rain'
+   2559: 'Alice in Wonderland'
+   2560: 'The wizard of Oz'
+   2561: 'I'm singin' in the rain'
+   2562: 'Alice in Wonderland'
+   2563: 'The wizard of Oz'
+   2564: 'I'm singin' in the rain'
+   2565: 'Alice in Wonderland'
+   2566: 'The wizard of Oz'
+   2567: 'I'm singin' in the rain'
+   2568: 'Alice in Wonderland'
+   2569: 'The wizard of Oz'
+   2570: 'I'm singin' in the rain'
+   2571: 'Alice in Wonderland'
+   2572: 'The wizard of Oz'
+   2573: 'I'm singin' in the rain'
+   2574: 'Alice in Wonderland'
+   2575: 'The wizard of Oz'
+   2576: 'I'm singin' in the rain'
+   2577: 'Alice in Wonderland'
+   2578: 'The wizard of Oz'
+   2579: 'I'm singin' in the rain'
+   2580: 'Alice in Wonderland'
+   2581: 'The wizard of Oz'
+   2582: 'I'm singin' in the rain'
+   2583: 'Alice in Wonderland'
+   2584: 'The wizard of Oz'
+   2585: 'I'm singin' in the rain'
+   2586: 'Alice in Wonderland'
+   2587: 'The wizard of Oz'
+   2588: 'I'm singin' in the rain'
+   2589: 'Alice in Wonderland'
+   2590: 'The wizard of Oz'
+   2591: 'I'm singin' in the rain'
+   2592: 'Alice in Wonderland'
+   2593: 'The wizard of Oz'
+   2594: 'I'm singin' in the rain'
+   2595: 'Alice in Wonderland'
+   2596: 'The wizard of Oz'
+   2597: 'I'm singin' in the rain'
+   2598: 'Alice in Wonderland'
+   2599: 'The wizard of Oz'
+   2600: 'I'm singin' in the rain'
+   2601: 'Alice in Wonderland'
+   2602: 'The wizard of Oz'
+   2603: 'I'm singin' in the rain'
+   2604: 'Alice in Wonderland'
+   2605: 'The wizard of Oz'
+   2606: 'I'm singin' in the rain'
+   2607: 'Alice in Wonderland'
+   2608: 'The wizard of Oz'
+   2609: 'I'm singin' in the rain'
+   2610: 'Alice in Wonderland'
+   2611: 'The wizard of Oz'
+   2612: 'I'm singin' in the rain'
+   2613: 'Alice in Wonderland'
+   2614: 'The wizard of Oz'
+   2615: 'I'm singin' in the rain'
+   2616: 'Alice in Wonderland'
+   2617: 'The wizard of Oz'
+   2618: 'I'm singin' in the rain'
+   2619: 'Alice in Wonderland'
+   2620: 'The wizard of Oz'
+   2621: 'I'm singin' in the rain'
+   2622: 'Alice in Wonderland'
+   2623: 'The wizard of Oz'
+   2624: 'I'm singin' in the rain'
+   2625: 'Alice in Wonderland'
+   2626: 'The wizard of Oz'
+   2627: 'I'm singin' in the rain'
+   2628: 'Alice in Wonderland'
+   2629: 'The wizard of Oz'
+   2630: 'I'm singin' in the rain'
+   2631: 'Alice in Wonderland'
+   2632: 'The wizard of Oz'
+   2633: 'I'm singin' in the rain'
+   2634: 'Alice in Wonderland'
+   2635: 'The wizard of Oz'
+   2636: 'I'm singin' in the rain'
+   2637: 'Alice in Wonderland'
+   2638: 'The wizard of Oz'
+   2639: 'I'm singin' in the rain'
+   2640: 'Alice in Wonderland'
+   2641: 'The wizard of Oz'
+   2642: 'I'm singin' in the rain'
+   2643: 'Alice in Wonderland'
+   2644: 'The wizard of Oz'
+   2645: 'I'm singin' in the rain'
+   2646: 'Alice in Wonderland'
+   2647: 'The wizard of Oz'
+   2648: 'I'm singin' in the rain'
+   2649: 'Alice in Wonderland'
+   2650: 'The wizard of Oz'
+   2651: 'I'm singin' in the rain'
+   2652: 'Alice in Wonderland'
+   2653: 'The wizard of Oz'
+   2654: 'I'm singin' in the rain'
+   2655: 'Alice in Wonderland'
+   2656: 'The wizard of Oz'
+   2657: 'I'm singin' in the rain'
+   2658: 'Alice in Wonderland'
+   2659: 'The wizard of Oz'
+   2660: 'I'm singin' in the rain'
+   2661: 'Alice in Wonderland'
+   2662: 'The wizard of Oz'
+   2663: 'I'm singin' in the rain'
+   2664: 'Alice in Wonderland'
+   2665: 'The wizard of Oz'
+   2666: 'I'm singin' in the rain'
+   2667: 'Alice in Wonderland'
+   2668: 'The wizard of Oz'
+   2669: 'I'm singin' in the rain'
+   2670: 'Alice in Wonderland'
+   2671: 'The wizard of Oz'
+   2672: 'I'm singin' in the rain'
+   2673: 'Alice in Wonderland'
+   2674: 'The wizard of Oz'
+   2675: 'I'm singin' in the rain'
+   2676: 'Alice in Wonderland'
+   2677: 'The wizard of Oz'
+   2678: 'I'm singin' in the rain'
+   2679: 'Alice in Wonderland'
+   2680: 'The wizard of Oz'
+   2681: 'I'm singin' in the rain'
+   2682: 'Alice in Wonderland'
+   2683: 'The wizard of Oz'
+   2684: 'I'm singin' in the rain'
+   2685: 'Alice in Wonderland'
+   2686: 'The wizard of Oz'
+   2687: 'I'm singin' in the rain'
+   2688: 'Alice in Wonderland'
+   2689: 'The wizard of Oz'
+   2690: 'I'm singin' in the rain'
+   2691: 'Alice in Wonderland'
+   2692: 'The wizard of Oz'
+   2693: 'I'm singin' in the rain'
+   2694: 'Alice in Wonderland'
+   2695: 'The wizard of Oz'
+   2696: 'I'm singin' in the rain'
+   2697: 'Alice in Wonderland'
+   2698: 'The wizard of Oz'
+   2699: 'I'm singin' in the rain'
+   2700: 'Alice in Wonderland'
+   2701: 'The wizard of Oz'
+   2702: 'I'm singin' in the rain'
+   2703: 'Alice in Wonderland'
+   2704: 'The wizard of Oz'
+   2705: 'I'm singin' in the rain'
+   2706: 'Alice in Wonderland'
+   2707: 'The wizard of Oz'
+   2708: 'I'm singin' in the rain'
+   2709: 'Alice in Wonderland'
+   2710: 'The wizard of Oz'
+   2711: 'I'm singin' in the rain'
+   2712: 'Alice in Wonderland'
+   2713: 'The wizard of Oz'
+   2714: 'I'm singin' in the rain'
+   2715: 'Alice in Wonderland'
+   2716: 'The wizard of Oz'
+   2717: 'I'm singin' in the rain'
+   2718: 'Alice in Wonderland'
+   2719: 'The wizard of Oz'
+   2720: 'I'm singin' in the rain'
+   2721: 'Alice in Wonderland'
+   2722: 'The wizard of Oz'
+   2723: 'I'm singin' in the rain'
+   2724: 'Alice in Wonderland'
+   2725: 'The wizard of Oz'
+   2726: 'I'm singin' in the rain'
+   2727: 'Alice in Wonderland'
+   2728: 'The wizard of Oz'
+   2729: 'I'm singin' in the rain'
+   2730: 'Alice in Wonderland'
+   2731: 'The wizard of Oz'
+   2732: 'I'm singin' in the rain'
+   2733: 'Alice in Wonderland'
+   2734: 'The wizard of Oz'
+   2735: 'I'm singin' in the rain'
+   2736: 'Alice in Wonderland'
+   2737: 'The wizard of Oz'
+   2738: 'I'm singin' in the rain'
+   2739: 'Alice in Wonderland'
+   2740: 'The wizard of Oz'
+   2741: 'I'm singin' in the rain'
+   2742: 'Alice in Wonderland'
+   2743: 'The wizard of Oz'
+   2744: 'I'm singin' in the rain'
+   2745: 'Alice in Wonderland'
+   2746: 'The wizard of Oz'
+   2747: 'I'm singin' in the rain'
+   2748: 'Alice in Wonderland'
+   2749: 'The wizard of Oz'
+   2750: 'I'm singin' in the rain'
+   2751: 'Alice in Wonderland'
+   2752: 'The wizard of Oz'
+   2753: 'I'm singin' in the rain'
+   2754: 'Alice in Wonderland'
+   2755: 'The wizard of Oz'
+   2756: 'I'm singin' in the rain'
+   2757: 'Alice in Wonderland'
+   2758: 'The wizard of Oz'
+   2759: 'I'm singin' in the rain'
+   2760: 'Alice in Wonderland'
+   2761: 'The wizard of Oz'
+   2762: 'I'm singin' in the rain'
+   2763: 'Alice in Wonderland'
+   2764: 'The wizard of Oz'
+   2765: 'I'm singin' in the rain'
+   2766: 'Alice in Wonderland'
+   2767: 'The wizard of Oz'
+   2768: 'I'm singin' in the rain'
+   2769: 'Alice in Wonderland'
+   2770: 'The wizard of Oz'
+   2771: 'I'm singin' in the rain'
+   2772: 'Alice in Wonderland'
+   2773: 'The wizard of Oz'
+   2774: 'I'm singin' in the rain'
+   2775: 'Alice in Wonderland'
+   2776: 'The wizard of Oz'
+   2777: 'I'm singin' in the rain'
+   2778: 'Alice in Wonderland'
+   2779: 'The wizard of Oz'
+   2780: 'I'm singin' in the rain'
+   2781: 'Alice in Wonderland'
+   2782: 'The wizard of Oz'
+   2783: 'I'm singin' in the rain'
+   2784: 'Alice in Wonderland'
+   2785: 'The wizard of Oz'
+   2786: 'I'm singin' in the rain'
+   2787: 'Alice in Wonderland'
+   2788: 'The wizard of Oz'
+   2789: 'I'm singin' in the rain'
+   2790: 'Alice in Wonderland'
+   2791: 'The wizard of Oz'
+   2792: 'I'm singin' in the rain'
+   2793: 'Alice in Wonderland'
+   2794: 'The wizard of Oz'
+   2795: 'I'm singin' in the rain'
+   2796: 'Alice in Wonderland'
+   2797: 'The wizard of Oz'
+   2798: 'I'm singin' in the rain'
+   2799: 'Alice in Wonderland'
+   2800: 'The wizard of Oz'
+   2801: 'I'm singin' in the rain'
+   2802: 'Alice in Wonderland'
+   2803: 'The wizard of Oz'
+   2804: 'I'm singin' in the rain'
+   2805: 'Alice in Wonderland'
+   2806: 'The wizard of Oz'
+   2807: 'I'm singin' in the rain'
+   2808: 'Alice in Wonderland'
+   2809: 'The wizard of Oz'
+   2810: 'I'm singin' in the rain'
+   2811: 'Alice in Wonderland'
+   2812: 'The wizard of Oz'
+   2813: 'I'm singin' in the rain'
+   2814: 'Alice in Wonderland'
+   2815: 'The wizard of Oz'
+   2816: 'I'm singin' in the rain'
+   2817: 'Alice in Wonderland'
+   2818: 'The wizard of Oz'
+   2819: 'I'm singin' in the rain'
+   2820: 'Alice in Wonderland'
+   2821: 'The wizard of Oz'
+   2822: 'I'm singin' in the rain'
+   2823: 'Alice in Wonderland'
+   2824: 'The wizard of Oz'
+   2825: 'I'm singin' in the rain'
+   2826: 'Alice in Wonderland'
+   2827: 'The wizard of Oz'
+   2828: 'I'm singin' in the rain'
+   2829: 'Alice in Wonderland'
+   2830: 'The wizard of Oz'
+   2831: 'I'm singin' in the rain'
+   2832: 'Alice in Wonderland'
+   2833: 'The wizard of Oz'
+   2834: 'I'm singin' in the rain'
+   2835: 'Alice in Wonderland'
+   2836: 'The wizard of Oz'
+   2837: 'I'm singin' in the rain'
+   2838: 'Alice in Wonderland'
+   2839: 'The wizard of Oz'
+   2840: 'I'm singin' in the rain'
+   2841: 'Alice in Wonderland'
+   2842: 'The wizard of Oz'
+   2843: 'I'm singin' in the rain'
+   2844: 'Alice in Wonderland'
+   2845: 'The wizard of Oz'
+   2846: 'I'm singin' in the rain'
+   2847: 'Alice in Wonderland'
+   2848: 'The wizard of Oz'
+   2849: 'I'm singin' in the rain'
+   2850: 'Alice in Wonderland'
+   2851: 'The wizard of Oz'
+   2852: 'I'm singin' in the rain'
+   2853: 'Alice in Wonderland'
+   2854: 'The wizard of Oz'
+   2855: 'I'm singin' in the rain'
+   2856: 'Alice in Wonderland'
+   2857: 'The wizard of Oz'
+   2858: 'I'm singin' in the rain'
+   2859: 'Alice in Wonderland'
+   2860: 'The wizard of Oz'
+   2861: 'I'm singin' in the rain'
+   2862: 'Alice in Wonderland'
+   2863: 'The wizard of Oz'
+   2864: 'I'm singin' in the rain'
+   2865: 'Alice in Wonderland'
+   2866: 'The wizard of Oz'
+   2867: 'I'm singin' in the rain'
+   2868: 'Alice in Wonderland'
+   2869: 'The wizard of Oz'
+   2870: 'I'm singin' in the rain'
+   2871: 'Alice in Wonderland'
+   2872: 'The wizard of Oz'
+   2873: 'I'm singin' in the rain'
+   2874: 'Alice in Wonderland'
+   2875: 'The wizard of Oz'
+   2876: 'I'm singin' in the rain'
+   2877: 'Alice in Wonderland'
+   2878: 'The wizard of Oz'
+   2879: 'I'm singin' in the rain'
+   2880: 'Alice in Wonderland'
+   2881: 'The wizard of Oz'
+   2882: 'I'm singin' in the rain'
+   2883: 'Alice in Wonderland'
+   2884: 'The wizard of Oz'
+   2885: 'I'm singin' in the rain'
+   2886: 'Alice in Wonderland'
+   2887: 'The wizard of Oz'
+   2888: 'I'm singin' in the rain'
+   2889: 'Alice in Wonderland'
+   2890: 'The wizard of Oz'
+   2891: 'I'm singin' in the rain'
+   2892: 'Alice in Wonderland'
+   2893: 'The wizard of Oz'
+   2894: 'I'm singin' in the rain'
+   2895: 'Alice in Wonderland'
+   2896: 'The wizard of Oz'
+   2897: 'I'm singin' in the rain'
+   2898: 'Alice in Wonderland'
+   2899: 'The wizard of Oz'
+   2900: 'I'm singin' in the rain'
+   2901: 'Alice in Wonderland'
+   2902: 'The wizard of Oz'
+   2903: 'I'm singin' in the rain'
+   2904: 'Alice in Wonderland'
+   2905: 'The wizard of Oz'
+   2906: 'I'm singin' in the rain'
+   2907: 'Alice in Wonderland'
+   2908: 'The wizard of Oz'
+   2909: 'I'm singin' in the rain'
+   2910: 'Alice in Wonderland'
+   2911: 'The wizard of Oz'
+   2912: 'I'm singin' in the rain'
+   2913: 'Alice in Wonderland'
+   2914: 'The wizard of Oz'
+   2915: 'I'm singin' in the rain'
+   2916: 'Alice in Wonderland'
+   2917: 'The wizard of Oz'
+   2918: 'I'm singin' in the rain'
+   2919: 'Alice in Wonderland'
+   2920: 'The wizard of Oz'
+   2921: 'I'm singin' in the rain'
+   2922: 'Alice in Wonderland'
+   2923: 'The wizard of Oz'
+   2924: 'I'm singin' in the rain'
+   2925: 'Alice in Wonderland'
+   2926: 'The wizard of Oz'
+   2927: 'I'm singin' in the rain'
+   2928: 'Alice in Wonderland'
+   2929: 'The wizard of Oz'
+   2930: 'I'm singin' in the rain'
+   2931: 'Alice in Wonderland'
+   2932: 'The wizard of Oz'
+   2933: 'I'm singin' in the rain'
+   2934: 'Alice in Wonderland'
+   2935: 'The wizard of Oz'
+   2936: 'I'm singin' in the rain'
+   2937: 'Alice in Wonderland'
+   2938: 'The wizard of Oz'
+   2939: 'I'm singin' in the rain'
+   2940: 'Alice in Wonderland'
+   2941: 'The wizard of Oz'
+   2942: 'I'm singin' in the rain'
+   2943: 'Alice in Wonderland'
+   2944: 'The wizard of Oz'
+   2945: 'I'm singin' in the rain'
+   2946: 'Alice in Wonderland'
+   2947: 'The wizard of Oz'
+   2948: 'I'm singin' in the rain'
+   2949: 'Alice in Wonderland'
+   2950: 'The wizard of Oz'
+   2951: 'I'm singin' in the rain'
+   2952: 'Alice in Wonderland'
+   2953: 'The wizard of Oz'
+   2954: 'I'm singin' in the rain'
+   2955: 'Alice in Wonderland'
+   2956: 'The wizard of Oz'
+   2957: 'I'm singin' in the rain'
+   2958: 'Alice in Wonderland'
+   2959: 'The wizard of Oz'
+   2960: 'I'm singin' in the rain'
+   2961: 'Alice in Wonderland'
+   2962: 'The wizard of Oz'
+   2963: 'I'm singin' in the rain'
+   2964: 'Alice in Wonderland'
+   2965: 'The wizard of Oz'
+   2966: 'I'm singin' in the rain'
+   2967: 'Alice in Wonderland'
+   2968: 'The wizard of Oz'
+   2969: 'I'm singin' in the rain'
+   2970: 'Alice in Wonderland'
+   2971: 'The wizard of Oz'
+   2972: 'I'm singin' in the rain'
+   2973: 'Alice in Wonderland'
+   2974: 'The wizard of Oz'
+   2975: 'I'm singin' in the rain'
+   2976: 'Alice in Wonderland'
+   2977: 'The wizard of Oz'
+   2978: 'I'm singin' in the rain'
+   2979: 'Alice in Wonderland'
+   2980: 'The wizard of Oz'
+   2981: 'I'm singin' in the rain'
+   2982: 'Alice in Wonderland'
+   2983: 'The wizard of Oz'
+   2984: 'I'm singin' in the rain'
+   2985: 'Alice in Wonderland'
+   2986: 'The wizard of Oz'
+   2987: 'I'm singin' in the rain'
+   2988: 'Alice in Wonderland'
+   2989: 'The wizard of Oz'
+   2990: 'I'm singin' in the rain'
+   2991: 'Alice in Wonderland'
+   2992: 'The wizard of Oz'
+   2993: 'I'm singin' in the rain'
+   2994: 'Alice in Wonderland'
+   2995: 'The wizard of Oz'
+   2996: 'I'm singin' in the rain'
+   2997: 'Alice in Wonderland'
+   2998: 'The wizard of Oz'
+   2999: 'I'm singin' in the rain'
+   3000: 'Alice in Wonderland'
+   3001: 'The wizard of Oz'
+   3002: 'I'm singin' in the rain'
+   3003: 'Alice in Wonderland'
+   3004: 'The wizard of Oz'
+   3005: 'I'm singin' in the rain'
+   3006: 'Alice in Wonderland'
+   3007: 'The wizard of Oz'
+   3008: 'I'm singin' in the rain'
+   3009: 'Alice in Wonderland'
+   3010: 'The wizard of Oz'
+   3011: 'I'm singin' in the rain'
+   3012: 'Alice in Wonderland'
+   3013: 'The wizard of Oz'
+   3014: 'I'm singin' in the rain'
+   3015: 'Alice in Wonderland'
+   3016: 'The wizard of Oz'
+   3017: 'I'm singin' in the rain'
+   3018: 'Alice in Wonderland'
+   3019: 'The wizard of Oz'
+   3020: 'I'm singin' in the rain'
+   3021: 'Alice in Wonderland'
+   3022: 'The wizard of Oz'
+   3023: 'I'm singin' in the rain'
+   3024: 'Alice in Wonderland'
+   3025: 'The wizard of Oz'
+   3026: 'I'm singin' in the rain'
+   3027: 'Alice in Wonderland'
+   3028: 'The wizard of Oz'
+   3029: 'I'm singin' in the rain'
+   3030: 'Alice in Wonderland'
+   3031: 'The wizard of Oz'
+   3032: 'I'm singin' in the rain'
+   3033: 'Alice in Wonderland'
+   3034: 'The wizard of Oz'
+   3035: 'I'm singin' in the rain'
+   3036: 'Alice in Wonderland'
+   3037: 'The wizard of Oz'
+   3038: 'I'm singin' in the rain'
+   3039: 'Alice in Wonderland'
+   3040: 'The wizard of Oz'
+   3041: 'I'm singin' in the rain'
+   3042: 'Alice in Wonderland'
+   3043: 'The wizard of Oz'
+   3044: 'I'm singin' in the rain'
+   3045: 'Alice in Wonderland'
+   3046: 'The wizard of Oz'
+   3047: 'I'm singin' in the rain'
+   3048: 'Alice in Wonderland'
+   3049: 'The wizard of Oz'
+   3050: 'I'm singin' in the rain'
+   3051: 'Alice in Wonderland'
+   3052: 'The wizard of Oz'
+   3053: 'I'm singin' in the rain'
+   3054: 'Alice in Wonderland'
+   3055: 'The wizard of Oz'
+   3056: 'I'm singin' in the rain'
+   3057: 'Alice in Wonderland'
+   3058: 'The wizard of Oz'
+   3059: 'I'm singin' in the rain'
+   3060: 'Alice in Wonderland'
+   3061: 'The wizard of Oz'
+   3062: 'I'm singin' in the rain'
+   3063: 'Alice in Wonderland'
+   3064: 'The wizard of Oz'
+   3065: 'I'm singin' in the rain'
+   3066: 'Alice in Wonderland'
+   3067: 'The wizard of Oz'
+   3068: 'I'm singin' in the rain'
+   3069: 'Alice in Wonderland'
+   3070: 'The wizard of Oz'
+   3071: 'I'm singin' in the rain'
+   3072: 'Alice in Wonderland'
+   3073: 'The wizard of Oz'
+   3074: 'I'm singin' in the rain'
+   3075: 'Alice in Wonderland'
+   3076: 'The wizard of Oz'
+   3077: 'I'm singin' in the rain'
+   3078: 'Alice in Wonderland'
+   3079: 'The wizard of Oz'
+   3080: 'I'm singin' in the rain'
+   3081: 'Alice in Wonderland'
+   3082: 'The wizard of Oz'
+   3083: 'I'm singin' in the rain'
+   3084: 'Alice in Wonderland'
+   3085: 'The wizard of Oz'
+   3086: 'I'm singin' in the rain'
+   3087: 'Alice in Wonderland'
+   3088: 'The wizard of Oz'
+   3089: 'I'm singin' in the rain'
+   3090: 'Alice in Wonderland'
+   3091: 'The wizard of Oz'
+   3092: 'I'm singin' in the rain'
+   3093: 'Alice in Wonderland'
+   3094: 'The wizard of Oz'
+   3095: 'I'm singin' in the rain'
+   3096: 'Alice in Wonderland'
+   3097: 'The wizard of Oz'
+   3098: 'I'm singin' in the rain'
+   3099: 'Alice in Wonderland'
+   3100: 'The wizard of Oz'
+   3101: 'I'm singin' in the rain'
+   3102: 'Alice in Wonderland'
+   3103: 'The wizard of Oz'
+   3104: 'I'm singin' in the rain'
+   3105: 'Alice in Wonderland'
+   3106: 'The wizard of Oz'
+   3107: 'I'm singin' in the rain'
+   3108: 'Alice in Wonderland'
+   3109: 'The wizard of Oz'
+   3110: 'I'm singin' in the rain'
+   3111: 'Alice in Wonderland'
+   3112: 'The wizard of Oz'
+   3113: 'I'm singin' in the rain'
+   3114: 'Alice in Wonderland'
+   3115: 'The wizard of Oz'
+   3116: 'I'm singin' in the rain'
+   3117: 'Alice in Wonderland'
+   3118: 'The wizard of Oz'
+   3119: 'I'm singin' in the rain'
+   3120: 'Alice in Wonderland'
+   3121: 'The wizard of Oz'
+   3122: 'I'm singin' in the rain'
+   3123: 'Alice in Wonderland'
+   3124: 'The wizard of Oz'
+   3125: 'I'm singin' in the rain'
+   3126: 'Alice in Wonderland'
+   3127: 'The wizard of Oz'
+   3128: 'I'm singin' in the rain'
+   3129: 'Alice in Wonderland'
+   3130: 'The wizard of Oz'
+   3131: 'I'm singin' in the rain'
+   3132: 'Alice in Wonderland'
+   3133: 'The wizard of Oz'
+   3134: 'I'm singin' in the rain'
+   3135: 'Alice in Wonderland'
+   3136: 'The wizard of Oz'
+   3137: 'I'm singin' in the rain'
+   3138: 'Alice in Wonderland'
+   3139: 'The wizard of Oz'
+   3140: 'I'm singin' in the rain'
+   3141: 'Alice in Wonderland'
+   3142: 'The wizard of Oz'
+   3143: 'I'm singin' in the rain'
+   3144: 'Alice in Wonderland'
+   3145: 'The wizard of Oz'
+   3146: 'I'm singin' in the rain'
+   3147: 'Alice in Wonderland'
+   3148: 'The wizard of Oz'
+   3149: 'I'm singin' in the rain'
+   3150: 'Alice in Wonderland'
+   3151: 'The wizard of Oz'
+   3152: 'I'm singin' in the rain'
+   3153: 'Alice in Wonderland'
+   3154: 'The wizard of Oz'
+   3155: 'I'm singin' in the rain'
+   3156: 'Alice in Wonderland'
+   3157: 'The wizard of Oz'
+   3158: 'I'm singin' in the rain'
+   3159: 'Alice in Wonderland'
+   3160: 'The wizard of Oz'
+   3161: 'I'm singin' in the rain'
+   3162: 'Alice in Wonderland'
+   3163: 'The wizard of Oz'
+   3164: 'I'm singin' in the rain'
+   3165: 'Alice in Wonderland'
+   3166: 'The wizard of Oz'
+   3167: 'I'm singin' in the rain'
+   3168: 'Alice in Wonderland'
+   3169: 'The wizard of Oz'
+   3170: 'I'm singin' in the rain'
+   3171: 'Alice in Wonderland'
+   3172: 'The wizard of Oz'
+   3173: 'I'm singin' in the rain'
+   3174: 'Alice in Wonderland'
+   3175: 'The wizard of Oz'
+   3176: 'I'm singin' in the rain'
+   3177: 'Alice in Wonderland'
+   3178: 'The wizard of Oz'
+   3179: 'I'm singin' in the rain'
+   3180: 'Alice in Wonderland'
+   3181: 'The wizard of Oz'
+   3182: 'I'm singin' in the rain'
+   3183: 'Alice in Wonderland'
+   3184: 'The wizard of Oz'
+   3185: 'I'm singin' in the rain'
+   3186: 'Alice in Wonderland'
+   3187: 'The wizard of Oz'
+   3188: 'I'm singin' in the rain'
+   3189: 'Alice in Wonderland'
+   3190: 'The wizard of Oz'
+   3191: 'I'm singin' in the rain'
+   3192: 'Alice in Wonderland'
+   3193: 'The wizard of Oz'
+   3194: 'I'm singin' in the rain'
+   3195: 'Alice in Wonderland'
+   3196: 'The wizard of Oz'
+   3197: 'I'm singin' in the rain'
+   3198: 'Alice in Wonderland'
+   3199: 'The wizard of Oz'
+   3200: 'I'm singin' in the rain'
+   3201: 'Alice in Wonderland'
+   3202: 'The wizard of Oz'
+   3203: 'I'm singin' in the rain'
+   3204: 'Alice in Wonderland'
+   3205: 'The wizard of Oz'
+   3206: 'I'm singin' in the rain'
+   3207: 'Alice in Wonderland'
+   3208: 'The wizard of Oz'
+   3209: 'I'm singin' in the rain'
+   3210: 'Alice in Wonderland'
+   3211: 'The wizard of Oz'
+   3212: 'I'm singin' in the rain'
+   3213: 'Alice in Wonderland'
+   3214: 'The wizard of Oz'
+   3215: 'I'm singin' in the rain'
+   3216: 'Alice in Wonderland'
+   3217: 'The wizard of Oz'
+   3218: 'I'm singin' in the rain'
+   3219: 'Alice in Wonderland'
+   3220: 'The wizard of Oz'
+   3221: 'I'm singin' in the rain'
+   3222: 'Alice in Wonderland'
+   3223: 'The wizard of Oz'
+   3224: 'I'm singin' in the rain'
+   3225: 'Alice in Wonderland'
+   3226: 'The wizard of Oz'
+   3227: 'I'm singin' in the rain'
+   3228: 'Alice in Wonderland'
+   3229: 'The wizard of Oz'
+   3230: 'I'm singin' in the rain'
+   3231: 'Alice in Wonderland'
+   3232: 'The wizard of Oz'
+   3233: 'I'm singin' in the rain'
+   3234: 'Alice in Wonderland'
+   3235: 'The wizard of Oz'
+   3236: 'I'm singin' in the rain'
+   3237: 'Alice in Wonderland'
+   3238: 'The wizard of Oz'
+   3239: 'I'm singin' in the rain'
+   3240: 'Alice in Wonderland'
+   3241: 'The wizard of Oz'
+   3242: 'I'm singin' in the rain'
+   3243: 'Alice in Wonderland'
+   3244: 'The wizard of Oz'
+   3245: 'I'm singin' in the rain'
+   3246: 'Alice in Wonderland'
+   3247: 'The wizard of Oz'
+   3248: 'I'm singin' in the rain'
+   3249: 'Alice in Wonderland'
+   3250: 'The wizard of Oz'
+   3251: 'I'm singin' in the rain'
+   3252: 'Alice in Wonderland'
+   3253: 'The wizard of Oz'
+   3254: 'I'm singin' in the rain'
+   3255: 'Alice in Wonderland'
+   3256: 'The wizard of Oz'
+   3257: 'I'm singin' in the rain'
+   3258: 'Alice in Wonderland'
+   3259: 'The wizard of Oz'
+   3260: 'I'm singin' in the rain'
+   3261: 'Alice in Wonderland'
+   3262: 'The wizard of Oz'
+   3263: 'I'm singin' in the rain'
+   3264: 'Alice in Wonderland'
+   3265: 'The wizard of Oz'
+   3266: 'I'm singin' in the rain'
+   3267: 'Alice in Wonderland'
+   3268: 'The wizard of Oz'
+   3269: 'I'm singin' in the rain'
+   3270: 'Alice in Wonderland'
+   3271: 'The wizard of Oz'
+   3272: 'I'm singin' in the rain'
+   3273: 'Alice in Wonderland'
+   3274: 'The wizard of Oz'
+   3275: 'I'm singin' in the rain'
+   3276: 'Alice in Wonderland'
+   3277: 'The wizard of Oz'
+   3278: 'I'm singin' in the rain'
+   3279: 'Alice in Wonderland'
+   3280: 'The wizard of Oz'
+   3281: 'I'm singin' in the rain'
+   3282: 'Alice in Wonderland'
+   3283: 'The wizard of Oz'
+   3284: 'I'm singin' in the rain'
+   3285: 'Alice in Wonderland'
+   3286: 'The wizard of Oz'
+   3287: 'I'm singin' in the rain'
+   3288: 'Alice in Wonderland'
+   3289: 'The wizard of Oz'
+   3290: 'I'm singin' in the rain'
+   3291: 'Alice in Wonderland'
+   3292: 'The wizard of Oz'
+   3293: 'I'm singin' in the rain'
+   3294: 'Alice in Wonderland'
+   3295: 'The wizard of Oz'
+   3296: 'I'm singin' in the rain'
+   3297: 'Alice in Wonderland'
+   3298: 'The wizard of Oz'
+   3299: 'I'm singin' in the rain'
+   3300: 'Alice in Wonderland'
+   3301: 'The wizard of Oz'
+   3302: 'I'm singin' in the rain'
+   3303: 'Alice in Wonderland'
+   3304: 'The wizard of Oz'
+   3305: 'I'm singin' in the rain'
+   3306: 'Alice in Wonderland'
+   3307: 'The wizard of Oz'
+   3308: 'I'm singin' in the rain'
+   3309: 'Alice in Wonderland'
+   3310: 'The wizard of Oz'
+   3311: 'I'm singin' in the rain'
+   3312: 'Alice in Wonderland'
+   3313: 'The wizard of Oz'
+   3314: 'I'm singin' in the rain'
+   3315: 'Alice in Wonderland'
+   3316: 'The wizard of Oz'
+   3317: 'I'm singin' in the rain'
+   3318: 'Alice in Wonderland'
+   3319: 'The wizard of Oz'
+   3320: 'I'm singin' in the rain'
+   3321: 'Alice in Wonderland'
+   3322: 'The wizard of Oz'
+   3323: 'I'm singin' in the rain'
+   3324: 'Alice in Wonderland'
+   3325: 'The wizard of Oz'
+   3326: 'I'm singin' in the rain'
+   3327: 'Alice in Wonderland'
+   3328: 'The wizard of Oz'
+   3329: 'I'm singin' in the rain'
+   3330: 'Alice in Wonderland'
+   3331: 'The wizard of Oz'
+   3332: 'I'm singin' in the rain'
+   3333: 'Alice in Wonderland'
+   3334: 'The wizard of Oz'
+   3335: 'I'm singin' in the rain'
+   3336: 'Alice in Wonderland'
+   3337: 'The wizard of Oz'
+   3338: 'I'm singin' in the rain'
+   3339: 'Alice in Wonderland'
+   3340: 'The wizard of Oz'
+   3341: 'I'm singin' in the rain'
+   3342: 'Alice in Wonderland'
+   3343: 'The wizard of Oz'
+   3344: 'I'm singin' in the rain'
+   3345: 'Alice in Wonderland'
+   3346: 'The wizard of Oz'
+   3347: 'I'm singin' in the rain'
+   3348: 'Alice in Wonderland'
+   3349: 'The wizard of Oz'
+   3350: 'I'm singin' in the rain'
+   3351: 'Alice in Wonderland'
+   3352: 'The wizard of Oz'
+   3353: 'I'm singin' in the rain'
+   3354: 'Alice in Wonderland'
+   3355: 'The wizard of Oz'
+   3356: 'I'm singin' in the rain'
+   3357: 'Alice in Wonderland'
+   3358: 'The wizard of Oz'
+   3359: 'I'm singin' in the rain'
+   3360: 'Alice in Wonderland'
+   3361: 'The wizard of Oz'
+   3362: 'I'm singin' in the rain'
+   3363: 'Alice in Wonderland'
+   3364: 'The wizard of Oz'
+   3365: 'I'm singin' in the rain'
+   3366: 'Alice in Wonderland'
+   3367: 'The wizard of Oz'
+   3368: 'I'm singin' in the rain'
+   3369: 'Alice in Wonderland'
+   3370: 'The wizard of Oz'
+   3371: 'I'm singin' in the rain'
+   3372: 'Alice in Wonderland'
+   3373: 'The wizard of Oz'
+   3374: 'I'm singin' in the rain'
+   3375: 'Alice in Wonderland'
+   3376: 'The wizard of Oz'
+   3377: 'I'm singin' in the rain'
+   3378: 'Alice in Wonderland'
+   3379: 'The wizard of Oz'
+   3380: 'I'm singin' in the rain'
+   3381: 'Alice in Wonderland'
+   3382: 'The wizard of Oz'
+   3383: 'I'm singin' in the rain'
+   3384: 'Alice in Wonderland'
+   3385: 'The wizard of Oz'
+   3386: 'I'm singin' in the rain'
+   3387: 'Alice in Wonderland'
+   3388: 'The wizard of Oz'
+   3389: 'I'm singin' in the rain'
+   3390: 'Alice in Wonderland'
+   3391: 'The wizard of Oz'
+   3392: 'I'm singin' in the rain'
+   3393: 'Alice in Wonderland'
+   3394: 'The wizard of Oz'
+   3395: 'I'm singin' in the rain'
+   3396: 'Alice in Wonderland'
+   3397: 'The wizard of Oz'
+   3398: 'I'm singin' in the rain'
+   3399: 'Alice in Wonderland'
+   3400: 'The wizard of Oz'
+   3401: 'I'm singin' in the rain'
+   3402: 'Alice in Wonderland'
+   3403: 'The wizard of Oz'
+   3404: 'I'm singin' in the rain'
+   3405: 'Alice in Wonderland'
+   3406: 'The wizard of Oz'
+   3407: 'I'm singin' in the rain'
+   3408: 'Alice in Wonderland'
+   3409: 'The wizard of Oz'
+   3410: 'I'm singin' in the rain'
+   3411: 'Alice in Wonderland'
+   3412: 'The wizard of Oz'
+   3413: 'I'm singin' in the rain'
+   3414: 'Alice in Wonderland'
+   3415: 'The wizard of Oz'
+   3416: 'I'm singin' in the rain'
+   3417: 'Alice in Wonderland'
+   3418: 'The wizard of Oz'
+   3419: 'I'm singin' in the rain'
+   3420: 'Alice in Wonderland'
+   3421: 'The wizard of Oz'
+   3422: 'I'm singin' in the rain'
+   3423: 'Alice in Wonderland'
+   3424: 'The wizard of Oz'
+   3425: 'I'm singin' in the rain'
+   3426: 'Alice in Wonderland'
+   3427: 'The wizard of Oz'
+   3428: 'I'm singin' in the rain'
+   3429: 'Alice in Wonderland'
+   3430: 'The wizard of Oz'
+   3431: 'I'm singin' in the rain'
+   3432: 'Alice in Wonderland'
+   3433: 'The wizard of Oz'
+   3434: 'I'm singin' in the rain'
+   3435: 'Alice in Wonderland'
+   3436: 'The wizard of Oz'
+   3437: 'I'm singin' in the rain'
+   3438: 'Alice in Wonderland'
+   3439: 'The wizard of Oz'
+   3440: 'I'm singin' in the rain'
+   3441: 'Alice in Wonderland'
+   3442: 'The wizard of Oz'
+   3443: 'I'm singin' in the rain'
+   3444: 'Alice in Wonderland'
+   3445: 'The wizard of Oz'
+   3446: 'I'm singin' in the rain'
+   3447: 'Alice in Wonderland'
+   3448: 'The wizard of Oz'
+   3449: 'I'm singin' in the rain'
+   3450: 'Alice in Wonderland'
+   3451: 'The wizard of Oz'
+   3452: 'I'm singin' in the rain'
+   3453: 'Alice in Wonderland'
+   3454: 'The wizard of Oz'
+   3455: 'I'm singin' in the rain'
+   3456: 'Alice in Wonderland'
+   3457: 'The wizard of Oz'
+   3458: 'I'm singin' in the rain'
+   3459: 'Alice in Wonderland'
+   3460: 'The wizard of Oz'
+   3461: 'I'm singin' in the rain'
+   3462: 'Alice in Wonderland'
+   3463: 'The wizard of Oz'
+   3464: 'I'm singin' in the rain'
+   3465: 'Alice in Wonderland'
+   3466: 'The wizard of Oz'
+   3467: 'I'm singin' in the rain'
+   3468: 'Alice in Wonderland'
+   3469: 'The wizard of Oz'
+   3470: 'I'm singin' in the rain'
+   3471: 'Alice in Wonderland'
+   3472: 'The wizard of Oz'
+   3473: 'I'm singin' in the rain'
+   3474: 'Alice in Wonderland'
+   3475: 'The wizard of Oz'
+   3476: 'I'm singin' in the rain'
+   3477: 'Alice in Wonderland'
+   3478: 'The wizard of Oz'
+   3479: 'I'm singin' in the rain'
+   3480: 'Alice in Wonderland'
+   3481: 'The wizard of Oz'
+   3482: 'I'm singin' in the rain'
+   3483: 'Alice in Wonderland'
+   3484: 'The wizard of Oz'
+   3485: 'I'm singin' in the rain'
+   3486: 'Alice in Wonderland'
+   3487: 'The wizard of Oz'
+   3488: 'I'm singin' in the rain'
+   3489: 'Alice in Wonderland'
+   3490: 'The wizard of Oz'
+   3491: 'I'm singin' in the rain'
+   3492: 'Alice in Wonderland'
+   3493: 'The wizard of Oz'
+   3494: 'I'm singin' in the rain'
+   3495: 'Alice in Wonderland'
+   3496: 'The wizard of Oz'
+   3497: 'I'm singin' in the rain'
+   3498: 'Alice in Wonderland'
+   3499: 'The wizard of Oz'
diff --git a/8.x/mk/tests/ok/l03.txt b/8.x/mk/tests/ok/l03.txt
new file mode 100644 (file)
index 0000000..82e3188
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Force sections in storage
+<<< done.
diff --git a/8.x/mk/tests/ok/l03a.txt b/8.x/mk/tests/ok/l03a.txt
new file mode 100755 (executable)
index 0000000..daff458
--- /dev/null
@@ -0,0 +1,1503 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW   500 rows = p1:V
+      0: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9000
+      1: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9001
+      2: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9002
+      3: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9003
+      4: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9004
+      5: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9005
+      6: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9006
+      7: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9007
+      8: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9008
+      9: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9009
+     10: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9010
+     11: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9011
+     12: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9012
+     13: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9013
+     14: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9014
+     15: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9015
+     16: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9016
+     17: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9017
+     18: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9018
+     19: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9019
+     20: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9020
+     21: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9021
+     22: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9022
+     23: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9023
+     24: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9024
+     25: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9025
+     26: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9026
+     27: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9027
+     28: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9028
+     29: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9029
+     30: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9030
+     31: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9031
+     32: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9032
+     33: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9033
+     34: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9034
+     35: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9035
+     36: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9036
+     37: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9037
+     38: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9038
+     39: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9039
+     40: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9040
+     41: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9041
+     42: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9042
+     43: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9043
+     44: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9044
+     45: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9045
+     46: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9046
+     47: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9047
+     48: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9048
+     49: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9049
+     50: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9050
+     51: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9051
+     52: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9052
+     53: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9053
+     54: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9054
+     55: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9055
+     56: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9056
+     57: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9057
+     58: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9058
+     59: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9059
+     60: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9060
+     61: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9061
+     62: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9062
+     63: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9063
+     64: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9064
+     65: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9065
+     66: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9066
+     67: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9067
+     68: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9068
+     69: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9069
+     70: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9070
+     71: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9071
+     72: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9072
+     73: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9073
+     74: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9074
+     75: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9075
+     76: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9076
+     77: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9077
+     78: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9078
+     79: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9079
+     80: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9080
+     81: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9081
+     82: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9082
+     83: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9083
+     84: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9084
+     85: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9085
+     86: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9086
+     87: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9087
+     88: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9088
+     89: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9089
+     90: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9090
+     91: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9091
+     92: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9092
+     93: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9093
+     94: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9094
+     95: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9095
+     96: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9096
+     97: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9097
+     98: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9098
+     99: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9099
+    100: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9100
+    101: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9101
+    102: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9102
+    103: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9103
+    104: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9104
+    105: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9105
+    106: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9106
+    107: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9107
+    108: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9108
+    109: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9109
+    110: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9110
+    111: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9111
+    112: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9112
+    113: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9113
+    114: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9114
+    115: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9115
+    116: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9116
+    117: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9117
+    118: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9118
+    119: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9119
+    120: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9120
+    121: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9121
+    122: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9122
+    123: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9123
+    124: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9124
+    125: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9125
+    126: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9126
+    127: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9127
+    128: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9128
+    129: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9129
+    130: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9130
+    131: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9131
+    132: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9132
+    133: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9133
+    134: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9134
+    135: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9135
+    136: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9136
+    137: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9137
+    138: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9138
+    139: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9139
+    140: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9140
+    141: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9141
+    142: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9142
+    143: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9143
+    144: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9144
+    145: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9145
+    146: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9146
+    147: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9147
+    148: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9148
+    149: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9149
+    150: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9150
+    151: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9151
+    152: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9152
+    153: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9153
+    154: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9154
+    155: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9155
+    156: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9156
+    157: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9157
+    158: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9158
+    159: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9159
+    160: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9160
+    161: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9161
+    162: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9162
+    163: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9163
+    164: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9164
+    165: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9165
+    166: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9166
+    167: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9167
+    168: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9168
+    169: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9169
+    170: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9170
+    171: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9171
+    172: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9172
+    173: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9173
+    174: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9174
+    175: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9175
+    176: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9176
+    177: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9177
+    178: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9178
+    179: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9179
+    180: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9180
+    181: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9181
+    182: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9182
+    183: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9183
+    184: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9184
+    185: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9185
+    186: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9186
+    187: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9187
+    188: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9188
+    189: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9189
+    190: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9190
+    191: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9191
+    192: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9192
+    193: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9193
+    194: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9194
+    195: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9195
+    196: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9196
+    197: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9197
+    198: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9198
+    199: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9199
+    200: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9200
+    201: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9201
+    202: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9202
+    203: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9203
+    204: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9204
+    205: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9205
+    206: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9206
+    207: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9207
+    208: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9208
+    209: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9209
+    210: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9210
+    211: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9211
+    212: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9212
+    213: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9213
+    214: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9214
+    215: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9215
+    216: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9216
+    217: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9217
+    218: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9218
+    219: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9219
+    220: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9220
+    221: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9221
+    222: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9222
+    223: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9223
+    224: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9224
+    225: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9225
+    226: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9226
+    227: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9227
+    228: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9228
+    229: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9229
+    230: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9230
+    231: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9231
+    232: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9232
+    233: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9233
+    234: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9234
+    235: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9235
+    236: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9236
+    237: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9237
+    238: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9238
+    239: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9239
+    240: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9240
+    241: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9241
+    242: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9242
+    243: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9243
+    244: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9244
+    245: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9245
+    246: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9246
+    247: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9247
+    248: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9248
+    249: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9249
+    250: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9250
+    251: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9251
+    252: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9252
+    253: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9253
+    254: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9254
+    255: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9255
+    256: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9256
+    257: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9257
+    258: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9258
+    259: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9259
+    260: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9260
+    261: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9261
+    262: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9262
+    263: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9263
+    264: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9264
+    265: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9265
+    266: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9266
+    267: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9267
+    268: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9268
+    269: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9269
+    270: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9270
+    271: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9271
+    272: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9272
+    273: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9273
+    274: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9274
+    275: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9275
+    276: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9276
+    277: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9277
+    278: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9278
+    279: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9279
+    280: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9280
+    281: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9281
+    282: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9282
+    283: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9283
+    284: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9284
+    285: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9285
+    286: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9286
+    287: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9287
+    288: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9288
+    289: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9289
+    290: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9290
+    291: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9291
+    292: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9292
+    293: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9293
+    294: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9294
+    295: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9295
+    296: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9296
+    297: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9297
+    298: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9298
+    299: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9299
+    300: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9300
+    301: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9301
+    302: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9302
+    303: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9303
+    304: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9304
+    305: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9305
+    306: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9306
+    307: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9307
+    308: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9308
+    309: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9309
+    310: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9310
+    311: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9311
+    312: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9312
+    313: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9313
+    314: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9314
+    315: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9315
+    316: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9316
+    317: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9317
+    318: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9318
+    319: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9319
+    320: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9320
+    321: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9321
+    322: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9322
+    323: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9323
+    324: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9324
+    325: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9325
+    326: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9326
+    327: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9327
+    328: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9328
+    329: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9329
+    330: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9330
+    331: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9331
+    332: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9332
+    333: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9333
+    334: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9334
+    335: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9335
+    336: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9336
+    337: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9337
+    338: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9338
+    339: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9339
+    340: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9340
+    341: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9341
+    342: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9342
+    343: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9343
+    344: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9344
+    345: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9345
+    346: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9346
+    347: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9347
+    348: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9348
+    349: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9349
+    350: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9350
+    351: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9351
+    352: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9352
+    353: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9353
+    354: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9354
+    355: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9355
+    356: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9356
+    357: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9357
+    358: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9358
+    359: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9359
+    360: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9360
+    361: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9361
+    362: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9362
+    363: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9363
+    364: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9364
+    365: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9365
+    366: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9366
+    367: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9367
+    368: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9368
+    369: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9369
+    370: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9370
+    371: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9371
+    372: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9372
+    373: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9373
+    374: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9374
+    375: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9375
+    376: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9376
+    377: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9377
+    378: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9378
+    379: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9379
+    380: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9380
+    381: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9381
+    382: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9382
+    383: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9383
+    384: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9384
+    385: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9385
+    386: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9386
+    387: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9387
+    388: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9388
+    389: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9389
+    390: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9390
+    391: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9391
+    392: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9392
+    393: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9393
+    394: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9394
+    395: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9395
+    396: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9396
+    397: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9397
+    398: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9398
+    399: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9399
+    400: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9400
+    401: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9401
+    402: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9402
+    403: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9403
+    404: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9404
+    405: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9405
+    406: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9406
+    407: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9407
+    408: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9408
+    409: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9409
+    410: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9410
+    411: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9411
+    412: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9412
+    413: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9413
+    414: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9414
+    415: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9415
+    416: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9416
+    417: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9417
+    418: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9418
+    419: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9419
+    420: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9420
+    421: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9421
+    422: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9422
+    423: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9423
+    424: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9424
+    425: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9425
+    426: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9426
+    427: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9427
+    428: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9428
+    429: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9429
+    430: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9430
+    431: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9431
+    432: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9432
+    433: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9433
+    434: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9434
+    435: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9435
+    436: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9436
+    437: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9437
+    438: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9438
+    439: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9439
+    440: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9440
+    441: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9441
+    442: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9442
+    443: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9443
+    444: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9444
+    445: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9445
+    446: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9446
+    447: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9447
+    448: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9448
+    449: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9449
+    450: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9450
+    451: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9451
+    452: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9452
+    453: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9453
+    454: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9454
+    455: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9455
+    456: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9456
+    457: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9457
+    458: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9458
+    459: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9459
+    460: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9460
+    461: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9461
+    462: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9462
+    463: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9463
+    464: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9464
+    465: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9465
+    466: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9466
+    467: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9467
+    468: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9468
+    469: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9469
+    470: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9470
+    471: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9471
+    472: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9472
+    473: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9473
+    474: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9474
+    475: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9475
+    476: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9476
+    477: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9477
+    478: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9478
+    479: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9479
+    480: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9480
+    481: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9481
+    482: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9482
+    483: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9483
+    484: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9484
+    485: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9485
+    486: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9486
+    487: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9487
+    488: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9488
+    489: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9489
+    490: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9490
+    491: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9491
+    492: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9492
+    493: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9493
+    494: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9494
+    495: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9495
+    496: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9496
+    497: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9497
+    498: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9498
+    499: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9499
diff --git a/8.x/mk/tests/ok/l03b.txt b/8.x/mk/tests/ok/l03b.txt
new file mode 100755 (executable)
index 0000000..daff458
--- /dev/null
@@ -0,0 +1,1503 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW   500 rows = p1:V
+      0: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9000
+      1: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9001
+      2: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9002
+      3: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9003
+      4: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9004
+      5: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9005
+      6: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9006
+      7: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9007
+      8: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9008
+      9: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9009
+     10: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9010
+     11: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9011
+     12: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9012
+     13: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9013
+     14: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9014
+     15: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9015
+     16: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9016
+     17: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9017
+     18: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9018
+     19: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9019
+     20: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9020
+     21: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9021
+     22: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9022
+     23: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9023
+     24: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9024
+     25: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9025
+     26: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9026
+     27: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9027
+     28: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9028
+     29: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9029
+     30: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9030
+     31: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9031
+     32: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9032
+     33: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9033
+     34: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9034
+     35: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9035
+     36: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9036
+     37: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9037
+     38: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9038
+     39: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9039
+     40: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9040
+     41: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9041
+     42: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9042
+     43: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9043
+     44: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9044
+     45: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9045
+     46: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9046
+     47: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9047
+     48: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9048
+     49: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9049
+     50: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9050
+     51: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9051
+     52: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9052
+     53: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9053
+     54: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9054
+     55: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9055
+     56: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9056
+     57: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9057
+     58: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9058
+     59: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9059
+     60: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9060
+     61: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9061
+     62: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9062
+     63: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9063
+     64: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9064
+     65: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9065
+     66: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9066
+     67: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9067
+     68: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9068
+     69: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9069
+     70: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9070
+     71: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9071
+     72: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9072
+     73: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9073
+     74: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9074
+     75: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9075
+     76: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9076
+     77: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9077
+     78: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9078
+     79: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9079
+     80: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9080
+     81: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9081
+     82: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9082
+     83: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9083
+     84: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9084
+     85: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9085
+     86: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9086
+     87: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9087
+     88: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9088
+     89: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9089
+     90: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9090
+     91: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9091
+     92: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9092
+     93: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9093
+     94: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9094
+     95: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9095
+     96: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9096
+     97: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9097
+     98: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9098
+     99: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9099
+    100: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9100
+    101: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9101
+    102: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9102
+    103: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9103
+    104: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9104
+    105: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9105
+    106: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9106
+    107: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9107
+    108: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9108
+    109: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9109
+    110: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9110
+    111: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9111
+    112: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9112
+    113: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9113
+    114: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9114
+    115: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9115
+    116: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9116
+    117: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9117
+    118: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9118
+    119: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9119
+    120: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9120
+    121: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9121
+    122: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9122
+    123: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9123
+    124: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9124
+    125: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9125
+    126: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9126
+    127: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9127
+    128: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9128
+    129: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9129
+    130: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9130
+    131: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9131
+    132: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9132
+    133: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9133
+    134: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9134
+    135: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9135
+    136: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9136
+    137: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9137
+    138: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9138
+    139: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9139
+    140: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9140
+    141: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9141
+    142: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9142
+    143: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9143
+    144: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9144
+    145: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9145
+    146: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9146
+    147: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9147
+    148: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9148
+    149: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9149
+    150: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9150
+    151: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9151
+    152: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9152
+    153: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9153
+    154: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9154
+    155: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9155
+    156: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9156
+    157: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9157
+    158: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9158
+    159: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9159
+    160: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9160
+    161: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9161
+    162: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9162
+    163: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9163
+    164: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9164
+    165: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9165
+    166: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9166
+    167: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9167
+    168: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9168
+    169: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9169
+    170: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9170
+    171: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9171
+    172: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9172
+    173: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9173
+    174: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9174
+    175: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9175
+    176: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9176
+    177: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9177
+    178: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9178
+    179: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9179
+    180: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9180
+    181: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9181
+    182: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9182
+    183: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9183
+    184: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9184
+    185: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9185
+    186: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9186
+    187: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9187
+    188: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9188
+    189: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9189
+    190: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9190
+    191: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9191
+    192: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9192
+    193: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9193
+    194: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9194
+    195: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9195
+    196: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9196
+    197: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9197
+    198: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9198
+    199: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9199
+    200: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9200
+    201: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9201
+    202: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9202
+    203: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9203
+    204: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9204
+    205: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9205
+    206: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9206
+    207: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9207
+    208: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9208
+    209: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9209
+    210: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9210
+    211: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9211
+    212: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9212
+    213: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9213
+    214: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9214
+    215: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9215
+    216: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9216
+    217: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9217
+    218: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9218
+    219: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9219
+    220: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9220
+    221: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9221
+    222: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9222
+    223: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9223
+    224: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9224
+    225: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9225
+    226: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9226
+    227: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9227
+    228: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9228
+    229: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9229
+    230: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9230
+    231: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9231
+    232: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9232
+    233: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9233
+    234: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9234
+    235: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9235
+    236: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9236
+    237: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9237
+    238: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9238
+    239: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9239
+    240: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9240
+    241: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9241
+    242: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9242
+    243: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9243
+    244: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9244
+    245: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9245
+    246: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9246
+    247: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9247
+    248: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9248
+    249: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9249
+    250: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9250
+    251: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9251
+    252: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9252
+    253: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9253
+    254: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9254
+    255: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9255
+    256: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9256
+    257: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9257
+    258: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9258
+    259: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9259
+    260: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9260
+    261: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9261
+    262: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9262
+    263: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9263
+    264: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9264
+    265: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9265
+    266: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9266
+    267: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9267
+    268: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9268
+    269: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9269
+    270: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9270
+    271: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9271
+    272: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9272
+    273: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9273
+    274: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9274
+    275: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9275
+    276: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9276
+    277: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9277
+    278: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9278
+    279: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9279
+    280: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9280
+    281: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9281
+    282: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9282
+    283: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9283
+    284: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9284
+    285: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9285
+    286: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9286
+    287: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9287
+    288: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9288
+    289: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9289
+    290: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9290
+    291: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9291
+    292: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9292
+    293: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9293
+    294: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9294
+    295: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9295
+    296: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9296
+    297: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9297
+    298: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9298
+    299: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9299
+    300: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9300
+    301: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9301
+    302: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9302
+    303: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9303
+    304: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9304
+    305: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9305
+    306: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9306
+    307: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9307
+    308: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9308
+    309: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9309
+    310: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9310
+    311: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9311
+    312: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9312
+    313: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9313
+    314: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9314
+    315: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9315
+    316: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9316
+    317: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9317
+    318: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9318
+    319: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9319
+    320: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9320
+    321: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9321
+    322: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9322
+    323: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9323
+    324: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9324
+    325: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9325
+    326: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9326
+    327: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9327
+    328: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9328
+    329: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9329
+    330: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9330
+    331: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9331
+    332: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9332
+    333: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9333
+    334: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9334
+    335: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9335
+    336: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9336
+    337: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9337
+    338: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9338
+    339: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9339
+    340: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9340
+    341: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9341
+    342: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9342
+    343: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9343
+    344: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9344
+    345: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9345
+    346: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9346
+    347: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9347
+    348: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9348
+    349: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9349
+    350: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9350
+    351: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9351
+    352: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9352
+    353: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9353
+    354: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9354
+    355: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9355
+    356: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9356
+    357: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9357
+    358: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9358
+    359: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9359
+    360: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9360
+    361: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9361
+    362: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9362
+    363: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9363
+    364: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9364
+    365: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9365
+    366: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9366
+    367: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9367
+    368: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9368
+    369: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9369
+    370: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9370
+    371: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9371
+    372: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9372
+    373: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9373
+    374: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9374
+    375: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9375
+    376: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9376
+    377: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9377
+    378: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9378
+    379: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9379
+    380: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9380
+    381: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9381
+    382: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9382
+    383: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9383
+    384: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9384
+    385: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9385
+    386: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9386
+    387: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9387
+    388: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9388
+    389: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9389
+    390: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9390
+    391: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9391
+    392: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9392
+    393: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9393
+    394: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9394
+    395: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9395
+    396: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9396
+    397: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9397
+    398: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9398
+    399: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9399
+    400: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9400
+    401: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9401
+    402: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9402
+    403: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9403
+    404: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9404
+    405: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9405
+    406: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9406
+    407: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9407
+    408: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9408
+    409: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9409
+    410: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9410
+    411: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9411
+    412: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9412
+    413: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9413
+    414: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9414
+    415: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9415
+    416: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9416
+    417: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9417
+    418: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9418
+    419: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9419
+    420: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9420
+    421: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9421
+    422: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9422
+    423: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9423
+    424: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9424
+    425: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9425
+    426: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9426
+    427: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9427
+    428: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9428
+    429: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9429
+    430: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9430
+    431: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9431
+    432: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9432
+    433: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9433
+    434: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9434
+    435: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9435
+    436: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9436
+    437: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9437
+    438: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9438
+    439: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9439
+    440: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9440
+    441: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9441
+    442: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9442
+    443: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9443
+    444: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9444
+    445: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9445
+    446: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9446
+    447: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9447
+    448: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9448
+    449: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9449
+    450: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9450
+    451: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9451
+    452: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9452
+    453: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9453
+    454: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9454
+    455: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9455
+    456: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9456
+    457: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9457
+    458: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9458
+    459: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9459
+    460: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9460
+    461: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9461
+    462: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9462
+    463: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9463
+    464: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9464
+    465: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9465
+    466: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9466
+    467: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9467
+    468: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9468
+    469: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9469
+    470: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9470
+    471: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9471
+    472: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9472
+    473: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9473
+    474: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9474
+    475: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9475
+    476: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9476
+    477: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9477
+    478: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9478
+    479: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9479
+    480: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9480
+    481: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9481
+    482: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9482
+    483: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9483
+    484: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9484
+    485: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9485
+    486: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9486
+    487: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9487
+    488: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9488
+    489: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9489
+    490: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9490
+    491: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9491
+    492: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9492
+    493: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9493
+    494: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9494
+    495: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9495
+    496: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9496
+    497: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9497
+    498: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9498
+    499: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9499
diff --git a/8.x/mk/tests/ok/l04.txt b/8.x/mk/tests/ok/l04.txt
new file mode 100644 (file)
index 0000000..2392000
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Modify sections in storage
+<<< done.
diff --git a/8.x/mk/tests/ok/l04a.txt b/8.x/mk/tests/ok/l04a.txt
new file mode 100755 (executable)
index 0000000..2eed1fc
--- /dev/null
@@ -0,0 +1,1503 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW   500 rows = p1:V
+      0: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 1
+      1: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9001
+      2: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9002
+      3: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9003
+      4: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9004
+      5: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9005
+      6: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9006
+      7: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9007
+      8: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9008
+      9: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9009
+     10: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9010
+     11: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9011
+     12: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9012
+     13: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9013
+     14: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9014
+     15: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9015
+     16: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9016
+     17: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9017
+     18: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9018
+     19: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9019
+     20: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9020
+     21: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9021
+     22: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9022
+     23: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9023
+     24: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9024
+     25: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9025
+     26: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9026
+     27: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9027
+     28: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9028
+     29: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9029
+     30: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9030
+     31: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9031
+     32: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9032
+     33: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9033
+     34: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9034
+     35: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9035
+     36: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9036
+     37: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9037
+     38: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9038
+     39: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9039
+     40: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9040
+     41: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9041
+     42: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9042
+     43: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9043
+     44: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9044
+     45: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9045
+     46: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9046
+     47: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9047
+     48: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9048
+     49: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9049
+     50: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9050
+     51: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9051
+     52: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9052
+     53: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9053
+     54: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9054
+     55: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9055
+     56: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9056
+     57: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9057
+     58: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9058
+     59: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9059
+     60: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9060
+     61: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9061
+     62: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9062
+     63: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9063
+     64: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9064
+     65: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9065
+     66: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9066
+     67: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9067
+     68: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9068
+     69: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9069
+     70: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9070
+     71: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9071
+     72: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9072
+     73: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9073
+     74: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9074
+     75: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9075
+     76: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9076
+     77: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9077
+     78: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9078
+     79: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9079
+     80: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9080
+     81: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9081
+     82: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9082
+     83: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9083
+     84: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9084
+     85: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9085
+     86: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9086
+     87: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9087
+     88: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9088
+     89: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9089
+     90: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9090
+     91: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9091
+     92: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9092
+     93: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9093
+     94: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9094
+     95: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9095
+     96: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9096
+     97: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9097
+     98: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9098
+     99: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9099
+    100: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9100
+    101: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9101
+    102: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9102
+    103: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9103
+    104: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9104
+    105: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9105
+    106: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9106
+    107: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9107
+    108: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9108
+    109: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9109
+    110: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9110
+    111: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9111
+    112: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9112
+    113: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9113
+    114: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9114
+    115: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9115
+    116: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9116
+    117: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9117
+    118: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9118
+    119: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9119
+    120: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9120
+    121: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9121
+    122: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9122
+    123: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9123
+    124: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9124
+    125: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9125
+    126: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9126
+    127: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9127
+    128: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9128
+    129: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9129
+    130: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9130
+    131: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9131
+    132: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9132
+    133: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9133
+    134: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9134
+    135: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9135
+    136: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9136
+    137: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9137
+    138: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9138
+    139: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9139
+    140: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9140
+    141: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9141
+    142: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9142
+    143: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9143
+    144: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9144
+    145: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9145
+    146: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9146
+    147: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9147
+    148: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9148
+    149: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9149
+    150: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9150
+    151: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9151
+    152: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9152
+    153: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9153
+    154: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9154
+    155: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9155
+    156: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9156
+    157: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9157
+    158: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9158
+    159: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9159
+    160: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9160
+    161: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9161
+    162: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9162
+    163: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9163
+    164: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9164
+    165: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9165
+    166: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9166
+    167: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9167
+    168: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9168
+    169: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9169
+    170: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9170
+    171: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9171
+    172: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9172
+    173: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9173
+    174: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9174
+    175: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9175
+    176: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9176
+    177: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9177
+    178: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9178
+    179: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9179
+    180: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9180
+    181: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9181
+    182: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9182
+    183: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9183
+    184: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9184
+    185: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9185
+    186: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9186
+    187: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9187
+    188: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9188
+    189: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9189
+    190: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9190
+    191: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9191
+    192: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9192
+    193: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9193
+    194: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9194
+    195: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9195
+    196: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9196
+    197: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9197
+    198: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9198
+    199: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9199
+    200: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9200
+    201: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9201
+    202: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9202
+    203: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9203
+    204: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9204
+    205: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9205
+    206: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9206
+    207: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9207
+    208: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9208
+    209: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9209
+    210: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9210
+    211: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9211
+    212: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9212
+    213: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9213
+    214: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9214
+    215: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9215
+    216: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9216
+    217: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9217
+    218: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9218
+    219: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9219
+    220: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9220
+    221: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9221
+    222: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9222
+    223: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9223
+    224: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9224
+    225: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9225
+    226: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9226
+    227: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9227
+    228: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9228
+    229: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9229
+    230: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9230
+    231: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9231
+    232: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9232
+    233: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9233
+    234: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9234
+    235: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9235
+    236: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9236
+    237: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9237
+    238: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9238
+    239: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9239
+    240: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9240
+    241: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9241
+    242: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9242
+    243: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9243
+    244: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9244
+    245: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9245
+    246: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9246
+    247: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9247
+    248: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9248
+    249: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9249
+    250: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9250
+    251: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9251
+    252: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9252
+    253: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9253
+    254: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9254
+    255: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9255
+    256: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9256
+    257: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9257
+    258: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9258
+    259: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9259
+    260: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9260
+    261: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9261
+    262: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9262
+    263: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9263
+    264: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9264
+    265: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9265
+    266: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9266
+    267: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9267
+    268: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9268
+    269: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9269
+    270: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9270
+    271: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9271
+    272: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9272
+    273: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9273
+    274: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9274
+    275: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9275
+    276: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9276
+    277: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9277
+    278: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9278
+    279: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9279
+    280: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9280
+    281: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9281
+    282: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9282
+    283: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9283
+    284: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9284
+    285: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9285
+    286: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9286
+    287: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9287
+    288: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9288
+    289: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9289
+    290: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9290
+    291: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9291
+    292: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9292
+    293: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9293
+    294: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9294
+    295: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9295
+    296: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9296
+    297: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9297
+    298: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9298
+    299: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9299
+    300: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9300
+    301: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9301
+    302: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9302
+    303: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9303
+    304: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9304
+    305: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9305
+    306: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9306
+    307: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9307
+    308: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9308
+    309: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9309
+    310: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9310
+    311: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9311
+    312: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9312
+    313: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9313
+    314: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9314
+    315: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9315
+    316: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9316
+    317: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9317
+    318: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9318
+    319: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9319
+    320: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9320
+    321: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9321
+    322: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9322
+    323: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9323
+    324: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9324
+    325: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9325
+    326: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9326
+    327: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9327
+    328: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9328
+    329: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9329
+    330: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9330
+    331: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9331
+    332: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9332
+    333: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9333
+    334: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9334
+    335: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9335
+    336: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9336
+    337: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9337
+    338: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9338
+    339: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9339
+    340: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9340
+    341: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9341
+    342: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9342
+    343: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9343
+    344: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9344
+    345: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9345
+    346: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9346
+    347: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9347
+    348: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9348
+    349: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9349
+    350: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9350
+    351: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9351
+    352: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9352
+    353: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9353
+    354: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9354
+    355: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9355
+    356: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9356
+    357: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9357
+    358: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9358
+    359: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9359
+    360: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9360
+    361: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9361
+    362: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9362
+    363: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9363
+    364: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9364
+    365: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9365
+    366: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9366
+    367: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9367
+    368: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9368
+    369: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9369
+    370: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9370
+    371: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9371
+    372: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9372
+    373: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9373
+    374: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9374
+    375: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9375
+    376: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9376
+    377: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9377
+    378: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9378
+    379: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9379
+    380: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9380
+    381: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9381
+    382: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9382
+    383: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9383
+    384: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9384
+    385: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9385
+    386: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9386
+    387: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9387
+    388: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9388
+    389: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9389
+    390: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9390
+    391: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9391
+    392: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9392
+    393: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9393
+    394: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9394
+    395: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9395
+    396: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9396
+    397: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9397
+    398: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9398
+    399: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9399
+    400: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9400
+    401: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9401
+    402: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9402
+    403: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9403
+    404: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9404
+    405: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9405
+    406: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9406
+    407: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9407
+    408: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9408
+    409: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9409
+    410: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9410
+    411: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9411
+    412: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9412
+    413: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9413
+    414: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9414
+    415: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9415
+    416: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9416
+    417: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9417
+    418: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9418
+    419: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9419
+    420: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9420
+    421: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9421
+    422: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9422
+    423: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9423
+    424: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9424
+    425: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9425
+    426: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9426
+    427: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9427
+    428: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9428
+    429: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9429
+    430: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9430
+    431: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9431
+    432: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9432
+    433: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9433
+    434: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9434
+    435: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9435
+    436: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9436
+    437: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9437
+    438: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9438
+    439: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9439
+    440: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9440
+    441: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9441
+    442: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9442
+    443: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9443
+    444: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9444
+    445: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9445
+    446: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9446
+    447: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9447
+    448: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9448
+    449: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9449
+    450: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9450
+    451: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9451
+    452: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9452
+    453: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9453
+    454: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9454
+    455: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9455
+    456: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9456
+    457: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9457
+    458: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9458
+    459: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9459
+    460: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9460
+    461: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9461
+    462: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9462
+    463: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9463
+    464: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9464
+    465: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9465
+    466: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9466
+    467: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9467
+    468: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9468
+    469: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9469
+    470: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9470
+    471: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9471
+    472: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9472
+    473: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9473
+    474: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9474
+    475: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9475
+    476: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9476
+    477: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9477
+    478: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9478
+    479: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9479
+    480: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9480
+    481: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9481
+    482: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9482
+    483: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9483
+    484: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9484
+    485: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9485
+    486: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9486
+    487: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9487
+    488: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9488
+    489: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9489
+    490: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9490
+    491: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9491
+    492: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9492
+    493: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9493
+    494: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9494
+    495: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9495
+    496: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9496
+    497: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9497
+    498: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9498
+    499: subview 'p1'
+     VIEW     1 rows = p2:I
+        0: 9499
diff --git a/8.x/mk/tests/ok/l05.txt b/8.x/mk/tests/ok/l05.txt
new file mode 100644 (file)
index 0000000..64d8af7
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Delete from 32 Kb of strings
+<<< done.
diff --git a/8.x/mk/tests/ok/l05a.txt b/8.x/mk/tests/ok/l05a.txt
new file mode 100755 (executable)
index 0000000..d01cb2d
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I p2:S p3:S
+      0: 1747 'The wizard of Oz' 'The wizard of Oz'
diff --git a/8.x/mk/tests/ok/l06.txt b/8.x/mk/tests/ok/l06.txt
new file mode 100644 (file)
index 0000000..d5e421d
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Bit field manipulations
+<<< done.
diff --git a/8.x/mk/tests/ok/l06a.txt b/8.x/mk/tests/ok/l06a.txt
new file mode 100755 (executable)
index 0000000..05757a4
--- /dev/null
@@ -0,0 +1,1371 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW  1368 rows = p1:I
+      0: 0
+      1: 1
+      2: 2
+      3: 3
+      4: 4
+      5: 5
+      6: 6
+      7: 7
+      8: 8
+      9: 9
+     10: 10
+     11: 11
+     12: 12
+     13: 13
+     14: 14
+     15: 15
+     16: 16
+     17: 17
+     18: 17
+     19: 17
+     20: 17
+     21: 17
+     22: 17
+     23: 17
+     24: 17
+     25: 17
+     26: 17
+     27: 17
+     28: 17
+     29: 17
+     30: 17
+     31: 17
+     32: 17
+     33: 17
+     34: 17
+     35: 16
+     36: 16
+     37: 16
+     38: 16
+     39: 16
+     40: 16
+     41: 16
+     42: 16
+     43: 16
+     44: 16
+     45: 16
+     46: 16
+     47: 16
+     48: 16
+     49: 16
+     50: 16
+     51: 15
+     52: 15
+     53: 15
+     54: 15
+     55: 15
+     56: 15
+     57: 15
+     58: 15
+     59: 15
+     60: 15
+     61: 15
+     62: 15
+     63: 15
+     64: 15
+     65: 15
+     66: 14
+     67: 14
+     68: 14
+     69: 14
+     70: 14
+     71: 14
+     72: 14
+     73: 14
+     74: 14
+     75: 14
+     76: 14
+     77: 14
+     78: 14
+     79: 14
+     80: 13
+     81: 13
+     82: 13
+     83: 13
+     84: 13
+     85: 13
+     86: 13
+     87: 13
+     88: 13
+     89: 13
+     90: 13
+     91: 13
+     92: 13
+     93: 12
+     94: 12
+     95: 12
+     96: 12
+     97: 12
+     98: 12
+     99: 12
+    100: 12
+    101: 12
+    102: 12
+    103: 12
+    104: 12
+    105: 11
+    106: 11
+    107: 11
+    108: 11
+    109: 11
+    110: 11
+    111: 11
+    112: 11
+    113: 11
+    114: 11
+    115: 11
+    116: 10
+    117: 10
+    118: 10
+    119: 10
+    120: 10
+    121: 10
+    122: 10
+    123: 10
+    124: 10
+    125: 10
+    126: 9
+    127: 9
+    128: 9
+    129: 9
+    130: 9
+    131: 9
+    132: 9
+    133: 9
+    134: 9
+    135: 8
+    136: 8
+    137: 8
+    138: 8
+    139: 8
+    140: 8
+    141: 8
+    142: 8
+    143: 7
+    144: 7
+    145: 7
+    146: 7
+    147: 7
+    148: 7
+    149: 7
+    150: 6
+    151: 6
+    152: 6
+    153: 6
+    154: 6
+    155: 6
+    156: 5
+    157: 5
+    158: 5
+    159: 5
+    160: 5
+    161: 4
+    162: 4
+    163: 4
+    164: 4
+    165: 3
+    166: 3
+    167: 3
+    168: 2
+    169: 2
+    170: 1
+    171: 0
+    172: 1
+    173: 2
+    174: 3
+    175: 4
+    176: 5
+    177: 6
+    178: 7
+    179: 8
+    180: 9
+    181: 10
+    182: 11
+    183: 12
+    184: 13
+    185: 14
+    186: 15
+    187: 16
+    188: 17
+    189: 17
+    190: 17
+    191: 17
+    192: 17
+    193: 17
+    194: 17
+    195: 17
+    196: 17
+    197: 17
+    198: 17
+    199: 17
+    200: 17
+    201: 17
+    202: 17
+    203: 17
+    204: 17
+    205: 17
+    206: 16
+    207: 16
+    208: 16
+    209: 16
+    210: 16
+    211: 16
+    212: 16
+    213: 16
+    214: 16
+    215: 16
+    216: 16
+    217: 16
+    218: 16
+    219: 16
+    220: 16
+    221: 16
+    222: 15
+    223: 15
+    224: 15
+    225: 15
+    226: 15
+    227: 15
+    228: 15
+    229: 15
+    230: 15
+    231: 15
+    232: 15
+    233: 15
+    234: 15
+    235: 15
+    236: 15
+    237: 14
+    238: 14
+    239: 14
+    240: 14
+    241: 14
+    242: 14
+    243: 14
+    244: 14
+    245: 14
+    246: 14
+    247: 14
+    248: 14
+    249: 14
+    250: 14
+    251: 13
+    252: 13
+    253: 13
+    254: 13
+    255: 13
+    256: 13
+    257: 13
+    258: 13
+    259: 13
+    260: 13
+    261: 13
+    262: 13
+    263: 13
+    264: 12
+    265: 12
+    266: 12
+    267: 12
+    268: 12
+    269: 12
+    270: 12
+    271: 12
+    272: 12
+    273: 12
+    274: 12
+    275: 12
+    276: 11
+    277: 11
+    278: 11
+    279: 11
+    280: 11
+    281: 11
+    282: 11
+    283: 11
+    284: 11
+    285: 11
+    286: 11
+    287: 10
+    288: 10
+    289: 10
+    290: 10
+    291: 10
+    292: 10
+    293: 10
+    294: 10
+    295: 10
+    296: 10
+    297: 9
+    298: 9
+    299: 9
+    300: 9
+    301: 9
+    302: 9
+    303: 9
+    304: 9
+    305: 9
+    306: 8
+    307: 8
+    308: 8
+    309: 8
+    310: 8
+    311: 8
+    312: 8
+    313: 8
+    314: 7
+    315: 7
+    316: 7
+    317: 7
+    318: 7
+    319: 7
+    320: 7
+    321: 6
+    322: 6
+    323: 6
+    324: 6
+    325: 6
+    326: 6
+    327: 5
+    328: 5
+    329: 5
+    330: 5
+    331: 5
+    332: 4
+    333: 4
+    334: 4
+    335: 4
+    336: 3
+    337: 3
+    338: 3
+    339: 2
+    340: 2
+    341: 1
+    342: 0
+    343: 1
+    344: 2
+    345: 3
+    346: 4
+    347: 5
+    348: 6
+    349: 7
+    350: 8
+    351: 9
+    352: 10
+    353: 11
+    354: 12
+    355: 13
+    356: 14
+    357: 15
+    358: 16
+    359: 17
+    360: 17
+    361: 17
+    362: 17
+    363: 17
+    364: 17
+    365: 17
+    366: 17
+    367: 17
+    368: 17
+    369: 17
+    370: 17
+    371: 17
+    372: 17
+    373: 17
+    374: 17
+    375: 17
+    376: 17
+    377: 16
+    378: 16
+    379: 16
+    380: 16
+    381: 16
+    382: 16
+    383: 16
+    384: 16
+    385: 16
+    386: 16
+    387: 16
+    388: 16
+    389: 16
+    390: 16
+    391: 16
+    392: 16
+    393: 15
+    394: 15
+    395: 15
+    396: 15
+    397: 15
+    398: 15
+    399: 15
+    400: 15
+    401: 15
+    402: 15
+    403: 15
+    404: 15
+    405: 15
+    406: 15
+    407: 15
+    408: 14
+    409: 14
+    410: 14
+    411: 14
+    412: 14
+    413: 14
+    414: 14
+    415: 14
+    416: 14
+    417: 14
+    418: 14
+    419: 14
+    420: 14
+    421: 14
+    422: 13
+    423: 13
+    424: 13
+    425: 13
+    426: 13
+    427: 13
+    428: 13
+    429: 13
+    430: 13
+    431: 13
+    432: 13
+    433: 13
+    434: 13
+    435: 12
+    436: 12
+    437: 12
+    438: 12
+    439: 12
+    440: 12
+    441: 12
+    442: 12
+    443: 12
+    444: 12
+    445: 12
+    446: 12
+    447: 11
+    448: 11
+    449: 11
+    450: 11
+    451: 11
+    452: 11
+    453: 11
+    454: 11
+    455: 11
+    456: 11
+    457: 11
+    458: 10
+    459: 10
+    460: 10
+    461: 10
+    462: 10
+    463: 10
+    464: 10
+    465: 10
+    466: 10
+    467: 10
+    468: 9
+    469: 9
+    470: 9
+    471: 9
+    472: 9
+    473: 9
+    474: 9
+    475: 9
+    476: 9
+    477: 8
+    478: 8
+    479: 8
+    480: 8
+    481: 8
+    482: 8
+    483: 8
+    484: 8
+    485: 7
+    486: 7
+    487: 7
+    488: 7
+    489: 7
+    490: 7
+    491: 7
+    492: 6
+    493: 6
+    494: 6
+    495: 6
+    496: 6
+    497: 6
+    498: 5
+    499: 5
+    500: 5
+    501: 5
+    502: 5
+    503: 4
+    504: 4
+    505: 4
+    506: 4
+    507: 3
+    508: 3
+    509: 3
+    510: 2
+    511: 2
+    512: 1
+    513: 0
+    514: 1
+    515: 2
+    516: 3
+    517: 4
+    518: 5
+    519: 6
+    520: 7
+    521: 8
+    522: 9
+    523: 10
+    524: 11
+    525: 12
+    526: 13
+    527: 14
+    528: 15
+    529: 16
+    530: 17
+    531: 17
+    532: 17
+    533: 17
+    534: 17
+    535: 17
+    536: 17
+    537: 17
+    538: 17
+    539: 17
+    540: 17
+    541: 17
+    542: 17
+    543: 17
+    544: 17
+    545: 17
+    546: 17
+    547: 17
+    548: 16
+    549: 16
+    550: 16
+    551: 16
+    552: 16
+    553: 16
+    554: 16
+    555: 16
+    556: 16
+    557: 16
+    558: 16
+    559: 16
+    560: 16
+    561: 16
+    562: 16
+    563: 16
+    564: 15
+    565: 15
+    566: 15
+    567: 15
+    568: 15
+    569: 15
+    570: 15
+    571: 15
+    572: 15
+    573: 15
+    574: 15
+    575: 15
+    576: 15
+    577: 15
+    578: 15
+    579: 14
+    580: 14
+    581: 14
+    582: 14
+    583: 14
+    584: 14
+    585: 14
+    586: 14
+    587: 14
+    588: 14
+    589: 14
+    590: 14
+    591: 14
+    592: 14
+    593: 13
+    594: 13
+    595: 13
+    596: 13
+    597: 13
+    598: 13
+    599: 13
+    600: 13
+    601: 13
+    602: 13
+    603: 13
+    604: 13
+    605: 13
+    606: 12
+    607: 12
+    608: 12
+    609: 12
+    610: 12
+    611: 12
+    612: 12
+    613: 12
+    614: 12
+    615: 12
+    616: 12
+    617: 12
+    618: 11
+    619: 11
+    620: 11
+    621: 11
+    622: 11
+    623: 11
+    624: 11
+    625: 11
+    626: 11
+    627: 11
+    628: 11
+    629: 10
+    630: 10
+    631: 10
+    632: 10
+    633: 10
+    634: 10
+    635: 10
+    636: 10
+    637: 10
+    638: 10
+    639: 9
+    640: 9
+    641: 9
+    642: 9
+    643: 9
+    644: 9
+    645: 9
+    646: 9
+    647: 9
+    648: 8
+    649: 8
+    650: 8
+    651: 8
+    652: 8
+    653: 8
+    654: 8
+    655: 8
+    656: 7
+    657: 7
+    658: 7
+    659: 7
+    660: 7
+    661: 7
+    662: 7
+    663: 6
+    664: 6
+    665: 6
+    666: 6
+    667: 6
+    668: 6
+    669: 5
+    670: 5
+    671: 5
+    672: 5
+    673: 5
+    674: 4
+    675: 4
+    676: 4
+    677: 4
+    678: 3
+    679: 3
+    680: 3
+    681: 2
+    682: 2
+    683: 1
+    684: 0
+    685: 1
+    686: 2
+    687: 3
+    688: 4
+    689: 5
+    690: 6
+    691: 7
+    692: 8
+    693: 9
+    694: 10
+    695: 11
+    696: 12
+    697: 13
+    698: 14
+    699: 15
+    700: 0
+    701: 1
+    702: 1
+    703: 1
+    704: 1
+    705: 1
+    706: 1
+    707: 1
+    708: 1
+    709: 1
+    710: 1
+    711: 1
+    712: 1
+    713: 1
+    714: 1
+    715: 1
+    716: 1
+    717: 1
+    718: 1
+    719: 0
+    720: 0
+    721: 0
+    722: 0
+    723: 0
+    724: 0
+    725: 0
+    726: 0
+    727: 0
+    728: 0
+    729: 0
+    730: 0
+    731: 0
+    732: 0
+    733: 0
+    734: 0
+    735: 15
+    736: 15
+    737: 15
+    738: 15
+    739: 15
+    740: 15
+    741: 15
+    742: 15
+    743: 15
+    744: 15
+    745: 15
+    746: 15
+    747: 15
+    748: 15
+    749: 15
+    750: 14
+    751: 14
+    752: 14
+    753: 14
+    754: 14
+    755: 14
+    756: 14
+    757: 14
+    758: 14
+    759: 14
+    760: 14
+    761: 14
+    762: 14
+    763: 14
+    764: 13
+    765: 13
+    766: 13
+    767: 13
+    768: 13
+    769: 13
+    770: 13
+    771: 13
+    772: 13
+    773: 13
+    774: 13
+    775: 13
+    776: 13
+    777: 12
+    778: 12
+    779: 12
+    780: 12
+    781: 12
+    782: 12
+    783: 12
+    784: 12
+    785: 12
+    786: 12
+    787: 12
+    788: 12
+    789: 11
+    790: 11
+    791: 11
+    792: 11
+    793: 11
+    794: 11
+    795: 11
+    796: 11
+    797: 11
+    798: 11
+    799: 11
+    800: 10
+    801: 10
+    802: 10
+    803: 10
+    804: 10
+    805: 10
+    806: 10
+    807: 10
+    808: 10
+    809: 10
+    810: 9
+    811: 9
+    812: 9
+    813: 9
+    814: 9
+    815: 9
+    816: 9
+    817: 9
+    818: 9
+    819: 8
+    820: 8
+    821: 8
+    822: 8
+    823: 8
+    824: 8
+    825: 8
+    826: 8
+    827: 7
+    828: 7
+    829: 7
+    830: 7
+    831: 7
+    832: 7
+    833: 7
+    834: 6
+    835: 6
+    836: 6
+    837: 6
+    838: 6
+    839: 6
+    840: 5
+    841: 5
+    842: 5
+    843: 5
+    844: 5
+    845: 4
+    846: 4
+    847: 4
+    848: 4
+    849: 3
+    850: 3
+    851: 3
+    852: 2
+    853: 2
+    854: 1
+    855: 0
+    856: 1
+    857: 2
+    858: 3
+    859: 4
+    860: 5
+    861: 6
+    862: 7
+    863: 0
+    864: 1
+    865: 2
+    866: 3
+    867: 4
+    868: 5
+    869: 6
+    870: 7
+    871: 0
+    872: 1
+    873: 1
+    874: 1
+    875: 1
+    876: 1
+    877: 1
+    878: 1
+    879: 1
+    880: 1
+    881: 1
+    882: 1
+    883: 1
+    884: 1
+    885: 1
+    886: 1
+    887: 1
+    888: 1
+    889: 1
+    890: 0
+    891: 0
+    892: 0
+    893: 0
+    894: 0
+    895: 0
+    896: 0
+    897: 0
+    898: 0
+    899: 0
+    900: 0
+    901: 0
+    902: 0
+    903: 0
+    904: 0
+    905: 0
+    906: 7
+    907: 7
+    908: 7
+    909: 7
+    910: 7
+    911: 7
+    912: 7
+    913: 7
+    914: 7
+    915: 7
+    916: 7
+    917: 7
+    918: 7
+    919: 7
+    920: 7
+    921: 6
+    922: 6
+    923: 6
+    924: 6
+    925: 6
+    926: 6
+    927: 6
+    928: 6
+    929: 6
+    930: 6
+    931: 6
+    932: 6
+    933: 6
+    934: 6
+    935: 5
+    936: 5
+    937: 5
+    938: 5
+    939: 5
+    940: 5
+    941: 5
+    942: 5
+    943: 5
+    944: 5
+    945: 5
+    946: 5
+    947: 5
+    948: 4
+    949: 4
+    950: 4
+    951: 4
+    952: 4
+    953: 4
+    954: 4
+    955: 4
+    956: 4
+    957: 4
+    958: 4
+    959: 4
+    960: 3
+    961: 3
+    962: 3
+    963: 3
+    964: 3
+    965: 3
+    966: 3
+    967: 3
+    968: 3
+    969: 3
+    970: 3
+    971: 2
+    972: 2
+    973: 2
+    974: 2
+    975: 2
+    976: 2
+    977: 2
+    978: 2
+    979: 2
+    980: 2
+    981: 1
+    982: 1
+    983: 1
+    984: 1
+    985: 1
+    986: 1
+    987: 1
+    988: 1
+    989: 1
+    990: 0
+    991: 0
+    992: 0
+    993: 0
+    994: 0
+    995: 0
+    996: 0
+    997: 0
+    998: 7
+    999: 7
+   1000: 7
+   1001: 7
+   1002: 7
+   1003: 7
+   1004: 7
+   1005: 6
+   1006: 6
+   1007: 6
+   1008: 6
+   1009: 6
+   1010: 6
+   1011: 5
+   1012: 5
+   1013: 5
+   1014: 5
+   1015: 5
+   1016: 4
+   1017: 4
+   1018: 4
+   1019: 4
+   1020: 3
+   1021: 3
+   1022: 3
+   1023: 2
+   1024: 2
+   1025: 1
+   1026: 0
+   1027: 1
+   1028: 2
+   1029: 3
+   1030: 0
+   1031: 1
+   1032: 2
+   1033: 3
+   1034: 0
+   1035: 1
+   1036: 2
+   1037: 3
+   1038: 0
+   1039: 1
+   1040: 2
+   1041: 3
+   1042: 0
+   1043: 1
+   1044: 1
+   1045: 1
+   1046: 1
+   1047: 1
+   1048: 1
+   1049: 1
+   1050: 1
+   1051: 1
+   1052: 1
+   1053: 1
+   1054: 1
+   1055: 1
+   1056: 1
+   1057: 1
+   1058: 1
+   1059: 1
+   1060: 1
+   1061: 0
+   1062: 0
+   1063: 0
+   1064: 0
+   1065: 0
+   1066: 0
+   1067: 0
+   1068: 0
+   1069: 0
+   1070: 0
+   1071: 0
+   1072: 0
+   1073: 0
+   1074: 0
+   1075: 0
+   1076: 0
+   1077: 3
+   1078: 3
+   1079: 3
+   1080: 3
+   1081: 3
+   1082: 3
+   1083: 3
+   1084: 3
+   1085: 3
+   1086: 3
+   1087: 3
+   1088: 3
+   1089: 3
+   1090: 3
+   1091: 3
+   1092: 2
+   1093: 2
+   1094: 2
+   1095: 2
+   1096: 2
+   1097: 2
+   1098: 2
+   1099: 2
+   1100: 2
+   1101: 2
+   1102: 2
+   1103: 2
+   1104: 2
+   1105: 2
+   1106: 1
+   1107: 1
+   1108: 1
+   1109: 1
+   1110: 1
+   1111: 1
+   1112: 1
+   1113: 1
+   1114: 1
+   1115: 1
+   1116: 1
+   1117: 1
+   1118: 1
+   1119: 0
+   1120: 0
+   1121: 0
+   1122: 0
+   1123: 0
+   1124: 0
+   1125: 0
+   1126: 0
+   1127: 0
+   1128: 0
+   1129: 0
+   1130: 0
+   1131: 3
+   1132: 3
+   1133: 3
+   1134: 3
+   1135: 3
+   1136: 3
+   1137: 3
+   1138: 3
+   1139: 3
+   1140: 3
+   1141: 3
+   1142: 2
+   1143: 2
+   1144: 2
+   1145: 2
+   1146: 2
+   1147: 2
+   1148: 2
+   1149: 2
+   1150: 2
+   1151: 2
+   1152: 1
+   1153: 1
+   1154: 1
+   1155: 1
+   1156: 1
+   1157: 1
+   1158: 1
+   1159: 1
+   1160: 1
+   1161: 0
+   1162: 0
+   1163: 0
+   1164: 0
+   1165: 0
+   1166: 0
+   1167: 0
+   1168: 0
+   1169: 3
+   1170: 3
+   1171: 3
+   1172: 3
+   1173: 3
+   1174: 3
+   1175: 3
+   1176: 2
+   1177: 2
+   1178: 2
+   1179: 2
+   1180: 2
+   1181: 2
+   1182: 1
+   1183: 1
+   1184: 1
+   1185: 1
+   1186: 1
+   1187: 0
+   1188: 0
+   1189: 0
+   1190: 0
+   1191: 3
+   1192: 3
+   1193: 3
+   1194: 2
+   1195: 2
+   1196: 1
+   1197: 0
+   1198: 1
+   1199: 0
+   1200: 1
+   1201: 0
+   1202: 1
+   1203: 0
+   1204: 1
+   1205: 0
+   1206: 1
+   1207: 0
+   1208: 1
+   1209: 0
+   1210: 1
+   1211: 0
+   1212: 1
+   1213: 0
+   1214: 1
+   1215: 1
+   1216: 1
+   1217: 1
+   1218: 1
+   1219: 1
+   1220: 1
+   1221: 1
+   1222: 1
+   1223: 1
+   1224: 1
+   1225: 1
+   1226: 1
+   1227: 1
+   1228: 1
+   1229: 1
+   1230: 1
+   1231: 1
+   1232: 0
+   1233: 0
+   1234: 0
+   1235: 0
+   1236: 0
+   1237: 0
+   1238: 0
+   1239: 0
+   1240: 0
+   1241: 0
+   1242: 0
+   1243: 0
+   1244: 0
+   1245: 0
+   1246: 0
+   1247: 0
+   1248: 1
+   1249: 1
+   1250: 1
+   1251: 1
+   1252: 1
+   1253: 1
+   1254: 1
+   1255: 1
+   1256: 1
+   1257: 1
+   1258: 1
+   1259: 1
+   1260: 1
+   1261: 1
+   1262: 1
+   1263: 0
+   1264: 0
+   1265: 0
+   1266: 0
+   1267: 0
+   1268: 0
+   1269: 0
+   1270: 0
+   1271: 0
+   1272: 0
+   1273: 0
+   1274: 0
+   1275: 0
+   1276: 0
+   1277: 1
+   1278: 1
+   1279: 1
+   1280: 1
+   1281: 1
+   1282: 1
+   1283: 1
+   1284: 1
+   1285: 1
+   1286: 1
+   1287: 1
+   1288: 1
+   1289: 1
+   1290: 0
+   1291: 0
+   1292: 0
+   1293: 0
+   1294: 0
+   1295: 0
+   1296: 0
+   1297: 0
+   1298: 0
+   1299: 0
+   1300: 0
+   1301: 0
+   1302: 1
+   1303: 1
+   1304: 1
+   1305: 1
+   1306: 1
+   1307: 1
+   1308: 1
+   1309: 1
+   1310: 1
+   1311: 1
+   1312: 1
+   1313: 0
+   1314: 0
+   1315: 0
+   1316: 0
+   1317: 0
+   1318: 0
+   1319: 0
+   1320: 0
+   1321: 0
+   1322: 0
+   1323: 1
+   1324: 1
+   1325: 1
+   1326: 1
+   1327: 1
+   1328: 1
+   1329: 1
+   1330: 1
+   1331: 1
+   1332: 0
+   1333: 0
+   1334: 0
+   1335: 0
+   1336: 0
+   1337: 0
+   1338: 0
+   1339: 0
+   1340: 1
+   1341: 1
+   1342: 1
+   1343: 1
+   1344: 1
+   1345: 1
+   1346: 1
+   1347: 0
+   1348: 0
+   1349: 0
+   1350: 0
+   1351: 0
+   1352: 0
+   1353: 1
+   1354: 1
+   1355: 1
+   1356: 1
+   1357: 1
+   1358: 0
+   1359: 0
+   1360: 0
+   1361: 0
+   1362: 1
+   1363: 1
+   1364: 1
+   1365: 0
+   1366: 0
+   1367: 1
diff --git a/8.x/mk/tests/ok/l07.txt b/8.x/mk/tests/ok/l07.txt
new file mode 100755 (executable)
index 0000000..fa6b10c
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Huge description
+<<< done.
diff --git a/8.x/mk/tests/ok/l07a.txt b/8.x/mk/tests/ok/l07a.txt
new file mode 100755 (executable)
index 0000000..11c0137
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = a123456789a123456789a123456789p1:I a123456789a123456789a123456789p2:I a123456789a123456789a123456789p3:I a123456789a123456789a123456789p4:I a123456789a123456789a123456789p5:I a123456789a123456789a123456789p6:I a123456789a123456789a123456789p7:I a123456789a123456789a123456789p8:I a123456789a123456789a123456789p9:I a123456789a123456789a123456789p10:I a123456789a123456789a123456789p11:I a123456789a123456789a123456789p12:I a123456789a123456789a123456789p13:I a123456789a123456789a123456789p14:I a123456789a123456789a123456789p15:I a123456789a123456789a123456789p16:I a123456789a123456789a123456789p17:I a123456789a123456789a123456789p18:I a123456789a123456789a123456789p19:I a123456789a123456789a123456789p20:I a123456789a123456789a123456789p21:I a123456789a123456789a123456789p22:I a123456789a123456789a123456789p23:I a123456789a123456789a123456789p24:I a123456789a123456789a123456789p25:I a123456789a123456789a123456789p26:I a123456789a123456789a123456789p27:I a123456789a123456789a123456789p28:I a123456789a123456789a123456789p29:I a123456789a123456789a123456789p30:I a123456789a123456789a123456789p31:I a123456789a123456789a123456789p32:I a123456789a123456789a123456789p33:I a123456789a123456789a123456789p34:I a123456789a123456789a123456789p35:I a123456789a123456789a123456789p36:I a123456789a123456789a123456789p37:I a123456789a123456789a123456789p38:I a123456789a123456789a123456789p39:I a123456789a123456789a123456789p40:I a123456789a123456789a123456789p41:I a123456789a123456789a123456789p42:I a123456789a123456789a123456789p43:I a123456789a123456789a123456789p44:I a123456789a123456789a123456789p45:I a123456789a123456789a123456789p46:I a123456789a123456789a123456789p47:I a123456789a123456789a123456789p48:I a123456789a123456789a123456789p49:I a123456789a123456789a123456789p50:I a123456789a123456789a123456789p51:I a123456789a123456789a123456789p52:I a123456789a123456789a123456789p53:I a123456789a123456789a123456789p54:I a123456789a123456789a123456789p55:I a123456789a123456789a123456789p56:I a123456789a123456789a123456789p57:I a123456789a123456789a123456789p58:I a123456789a123456789a123456789p59:I a123456789a123456789a123456789p60:I a123456789a123456789a123456789p61:I a123456789a123456789a123456789p62:I a123456789a123456789a123456789p63:I a123456789a123456789a123456789p64:I a123456789a123456789a123456789p65:I a123456789a123456789a123456789p66:I a123456789a123456789a123456789p67:I a123456789a123456789a123456789p68:I a123456789a123456789a123456789p69:I a123456789a123456789a123456789p70:I a123456789a123456789a123456789p71:I a123456789a123456789a123456789p72:I a123456789a123456789a123456789p73:I a123456789a123456789a123456789p74:I a123456789a123456789a123456789p75:I a123456789a123456789a123456789p76:I a123456789a123456789a123456789p77:I a123456789a123456789a123456789p78:I a123456789a123456789a123456789p79:I a123456789a123456789a123456789p80:I a123456789a123456789a123456789p81:I a123456789a123456789a123456789p82:I a123456789a123456789a123456789p83:I a123456789a123456789a123456789p84:I a123456789a123456789a123456789p85:I a123456789a123456789a123456789p86:I a123456789a123456789a123456789p87:I a123456789a123456789a123456789p88:I a123456789a123456789a123456789p89:I a123456789a123456789a123456789p90:I a123456789a123456789a123456789p91:I a123456789a123456789a123456789p92:I a123456789a123456789a123456789p93:I a123456789a123456789a123456789p94:I a123456789a123456789a123456789p95:I a123456789a123456789a123456789p96:I a123456789a123456789a123456789p97:I a123456789a123456789a123456789p98:I a123456789a123456789a123456789p99:I a123456789a123456789a123456789p100:I a123456789a123456789a123456789p101:I a123456789a123456789a123456789p102:I a123456789a123456789a123456789p103:I a123456789a123456789a123456789p104:I a123456789a123456789a123456789p105:I a123456789a123456789a123456789p106:I a123456789a123456789a123456789p107:I a123456789a123456789a123456789p108:I a123456789a123456789a123456789p109:I a123456789a123456789a123456789p110:I a123456789a123456789a123456789p111:I a123456789a123456789a123456789p112:I a123456789a123456789a123456789p113:I a123456789a123456789a123456789p114:I a123456789a123456789a123456789p115:I a123456789a123456789a123456789p116:I a123456789a123456789a123456789p117:I a123456789a123456789a123456789p118:I a123456789a123456789a123456789p119:I a123456789a123456789a123456789p120:I a123456789a123456789a123456789p121:I a123456789a123456789a123456789p122:I a123456789a123456789a123456789p123:I a123456789a123456789a123456789p124:I a123456789a123456789a123456789p125:I a123456789a123456789a123456789p126:I a123456789a123456789a123456789p127:I a123456789a123456789a123456789p128:I a123456789a123456789a123456789p129:I a123456789a123456789a123456789p130:I a123456789a123456789a123456789p131:I a123456789a123456789a123456789p132:I a123456789a123456789a123456789p133:I a123456789a123456789a123456789p134:I a123456789a123456789a123456789p135:I a123456789a123456789a123456789p136:I a123456789a123456789a123456789p137:I a123456789a123456789a123456789p138:I a123456789a123456789a123456789p139:I a123456789a123456789a123456789p140:I a123456789a123456789a123456789p141:I a123456789a123456789a123456789p142:I a123456789a123456789a123456789p143:I a123456789a123456789a123456789p144:I a123456789a123456789a123456789p145:I a123456789a123456789a123456789p146:I a123456789a123456789a123456789p147:I a123456789a123456789a123456789p148:I a123456789a123456789a123456789p149:I
+      0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/8.x/mk/tests/ok/m01.txt b/8.x/mk/tests/ok/m01.txt
new file mode 100644 (file)
index 0000000..0c3bb84
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Hash mapping
+<<< done.
diff --git a/8.x/mk/tests/ok/m02.txt b/8.x/mk/tests/ok/m02.txt
new file mode 100644 (file)
index 0000000..703e30b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Blocked view bug
+<<< done.
diff --git a/8.x/mk/tests/ok/m02a.txt b/8.x/mk/tests/ok/m02a.txt
new file mode 100644 (file)
index 0000000..c51c6f2
--- /dev/null
@@ -0,0 +1,22 @@
+ VIEW     1 rows = v1:V
+    0: subview 'v1'
+   VIEW     2 rows = _B:V
+      0: subview '_B'
+     VIEW    15 rows = p1:B
+        0: (3490b)
+        1: (3491b)
+        2: (3492b)
+        3: (3493b)
+        4: (3494b)
+        5: (3495b)
+        6: (3496b)
+        7: (3497b)
+        8: (3498b)
+        9: (3499b)
+       10: (3500b)
+       11: (3501b)
+       12: (3502b)
+       13: (3503b)
+       14: (3504b)
+      1: subview '_B'
+     VIEW     0 rows = p1:B
diff --git a/8.x/mk/tests/ok/m03.txt b/8.x/mk/tests/ok/m03.txt
new file mode 100644 (file)
index 0000000..f80527b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Hash adds
+<<< done.
diff --git a/8.x/mk/tests/ok/m03a.txt b/8.x/mk/tests/ok/m03a.txt
new file mode 100644 (file)
index 0000000..dc96ffa
--- /dev/null
@@ -0,0 +1,55 @@
+ VIEW     1 rows = d1:V m1:V d2:V m2:V d3:V m3:V d4:V m4:V
+    0: subview 'd1'
+   VIEW     4 rows = p1:S
+      0: 'one'
+      1: 'two'
+      2: 'three'
+      3: 'four'
+    0: subview 'm1'
+   VIEW     9 rows = _H:I _R:I
+      0: 0 -1
+      1: -1413211378 1
+      2: -153687682 2
+      3: 0 -1
+      4: 0 -1
+      5: 0 -1
+      6: -1614533319 3
+      7: -245760992 0
+      8: 11 0
+    0: subview 'd2'
+   VIEW     3 rows = p1:S
+      0: 'two'
+      1: 'three'
+      2: 'four'
+    0: subview 'm2'
+   VIEW     9 rows = _H:I _R:I
+      0: 0 -1
+      1: -1413211378 0
+      2: -153687682 1
+      3: 0 -1
+      4: 0 -1
+      5: 0 -1
+      6: -1614533319 2
+      7: 0 -1
+      8: 11 0
+    0: subview 'd3'
+   VIEW     2 rows = p1:S
+      0: 'three'
+      1: 'four'
+    0: subview 'm3'
+   VIEW     5 rows = _H:I _R:I
+      0: 0 -1
+      1: -153687682 0
+      2: -1614533319 1
+      3: 0 -1
+      4: 7 0
+    0: subview 'd4'
+   VIEW     1 rows = p1:S
+      0: 'four'
+    0: subview 'm4'
+   VIEW     5 rows = _H:I _R:I
+      0: 0 -1
+      1: 0 -1
+      2: -1614533319 0
+      3: 0 -1
+      4: 7 0
diff --git a/8.x/mk/tests/ok/m04.txt b/8.x/mk/tests/ok/m04.txt
new file mode 100644 (file)
index 0000000..036ca99
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Locate bug
+<<< done.
diff --git a/8.x/mk/tests/ok/m04a.txt b/8.x/mk/tests/ok/m04a.txt
new file mode 100644 (file)
index 0000000..fb38c39
--- /dev/null
@@ -0,0 +1,9 @@
+ VIEW     1 rows = v1:V
+    0: subview 'v1'
+   VIEW     6 rows = p1:I p2:S
+      0: 1 'one'
+      1: 2 'two'
+      2: 3 'three'
+      3: 4 'four'
+      4: 5 'five'
+      5: 6 'six'
diff --git a/8.x/mk/tests/ok/m05.txt b/8.x/mk/tests/ok/m05.txt
new file mode 100644 (file)
index 0000000..7b4e60c
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Blocked view with subviews
+<<< done.
diff --git a/8.x/mk/tests/ok/m05a.txt b/8.x/mk/tests/ok/m05a.txt
new file mode 100644 (file)
index 0000000..a9f3411
--- /dev/null
@@ -0,0 +1,4012 @@
+ VIEW     1 rows = v1:V
+    0: subview 'v1'
+   VIEW     3 rows = _B:V
+      0: subview '_B'
+     VIEW   500 rows = p1:S sv:V
+        0: 'id-0'
+        0: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 0
+        1: 'id-1'
+        1: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 1
+        2: 'id-2'
+        2: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 2
+        3: 'id-3'
+        3: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 3
+        4: 'id-4'
+        4: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 4
+        5: 'id-5'
+        5: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 5
+        6: 'id-6'
+        6: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 6
+        7: 'id-7'
+        7: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 7
+        8: 'id-8'
+        8: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 8
+        9: 'id-9'
+        9: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 9
+       10: 'id-10'
+       10: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 10
+       11: 'id-11'
+       11: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 11
+       12: 'id-12'
+       12: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 12
+       13: 'id-13'
+       13: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 13
+       14: 'id-14'
+       14: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 14
+       15: 'id-15'
+       15: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 15
+       16: 'id-16'
+       16: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 16
+       17: 'id-17'
+       17: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 17
+       18: 'id-18'
+       18: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 18
+       19: 'id-19'
+       19: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 19
+       20: 'id-20'
+       20: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 20
+       21: 'id-21'
+       21: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 21
+       22: 'id-22'
+       22: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 22
+       23: 'id-23'
+       23: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 23
+       24: 'id-24'
+       24: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 24
+       25: 'id-25'
+       25: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 25
+       26: 'id-26'
+       26: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 26
+       27: 'id-27'
+       27: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 27
+       28: 'id-28'
+       28: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 28
+       29: 'id-29'
+       29: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 29
+       30: 'id-30'
+       30: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 30
+       31: 'id-31'
+       31: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 31
+       32: 'id-32'
+       32: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 32
+       33: 'id-33'
+       33: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 33
+       34: 'id-34'
+       34: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 34
+       35: 'id-35'
+       35: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 35
+       36: 'id-36'
+       36: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 36
+       37: 'id-37'
+       37: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 37
+       38: 'id-38'
+       38: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 38
+       39: 'id-39'
+       39: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 39
+       40: 'id-40'
+       40: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 40
+       41: 'id-41'
+       41: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 41
+       42: 'id-42'
+       42: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 42
+       43: 'id-43'
+       43: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 43
+       44: 'id-44'
+       44: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 44
+       45: 'id-45'
+       45: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 45
+       46: 'id-46'
+       46: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 46
+       47: 'id-47'
+       47: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 47
+       48: 'id-48'
+       48: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 48
+       49: 'id-49'
+       49: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 49
+       50: 'id-50'
+       50: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 50
+       51: 'id-51'
+       51: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 51
+       52: 'id-52'
+       52: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 52
+       53: 'id-53'
+       53: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 53
+       54: 'id-54'
+       54: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 54
+       55: 'id-55'
+       55: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 55
+       56: 'id-56'
+       56: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 56
+       57: 'id-57'
+       57: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 57
+       58: 'id-58'
+       58: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 58
+       59: 'id-59'
+       59: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 59
+       60: 'id-60'
+       60: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 60
+       61: 'id-61'
+       61: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 61
+       62: 'id-62'
+       62: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 62
+       63: 'id-63'
+       63: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 63
+       64: 'id-64'
+       64: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 64
+       65: 'id-65'
+       65: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 65
+       66: 'id-66'
+       66: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 66
+       67: 'id-67'
+       67: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 67
+       68: 'id-68'
+       68: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 68
+       69: 'id-69'
+       69: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 69
+       70: 'id-70'
+       70: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 70
+       71: 'id-71'
+       71: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 71
+       72: 'id-72'
+       72: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 72
+       73: 'id-73'
+       73: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 73
+       74: 'id-74'
+       74: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 74
+       75: 'id-75'
+       75: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 75
+       76: 'id-76'
+       76: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 76
+       77: 'id-77'
+       77: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 77
+       78: 'id-78'
+       78: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 78
+       79: 'id-79'
+       79: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 79
+       80: 'id-80'
+       80: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 80
+       81: 'id-81'
+       81: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 81
+       82: 'id-82'
+       82: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 82
+       83: 'id-83'
+       83: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 83
+       84: 'id-84'
+       84: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 84
+       85: 'id-85'
+       85: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 85
+       86: 'id-86'
+       86: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 86
+       87: 'id-87'
+       87: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 87
+       88: 'id-88'
+       88: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 88
+       89: 'id-89'
+       89: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 89
+       90: 'id-90'
+       90: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 90
+       91: 'id-91'
+       91: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 91
+       92: 'id-92'
+       92: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 92
+       93: 'id-93'
+       93: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 93
+       94: 'id-94'
+       94: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 94
+       95: 'id-95'
+       95: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 95
+       96: 'id-96'
+       96: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 96
+       97: 'id-97'
+       97: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 97
+       98: 'id-98'
+       98: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 98
+       99: 'id-99'
+       99: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 99
+      100: 'id-100'
+      100: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 100
+      101: 'id-101'
+      101: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 101
+      102: 'id-102'
+      102: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 102
+      103: 'id-103'
+      103: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 103
+      104: 'id-104'
+      104: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 104
+      105: 'id-105'
+      105: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 105
+      106: 'id-106'
+      106: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 106
+      107: 'id-107'
+      107: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 107
+      108: 'id-108'
+      108: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 108
+      109: 'id-109'
+      109: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 109
+      110: 'id-110'
+      110: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 110
+      111: 'id-111'
+      111: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 111
+      112: 'id-112'
+      112: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 112
+      113: 'id-113'
+      113: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 113
+      114: 'id-114'
+      114: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 114
+      115: 'id-115'
+      115: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 115
+      116: 'id-116'
+      116: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 116
+      117: 'id-117'
+      117: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 117
+      118: 'id-118'
+      118: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 118
+      119: 'id-119'
+      119: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 119
+      120: 'id-120'
+      120: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 120
+      121: 'id-121'
+      121: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 121
+      122: 'id-122'
+      122: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 122
+      123: 'id-123'
+      123: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 123
+      124: 'id-124'
+      124: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 124
+      125: 'id-125'
+      125: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 125
+      126: 'id-126'
+      126: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 126
+      127: 'id-127'
+      127: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 127
+      128: 'id-128'
+      128: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 128
+      129: 'id-129'
+      129: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 129
+      130: 'id-130'
+      130: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 130
+      131: 'id-131'
+      131: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 131
+      132: 'id-132'
+      132: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 132
+      133: 'id-133'
+      133: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 133
+      134: 'id-134'
+      134: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 134
+      135: 'id-135'
+      135: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 135
+      136: 'id-136'
+      136: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 136
+      137: 'id-137'
+      137: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 137
+      138: 'id-138'
+      138: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 138
+      139: 'id-139'
+      139: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 139
+      140: 'id-140'
+      140: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 140
+      141: 'id-141'
+      141: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 141
+      142: 'id-142'
+      142: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 142
+      143: 'id-143'
+      143: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 143
+      144: 'id-144'
+      144: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 144
+      145: 'id-145'
+      145: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 145
+      146: 'id-146'
+      146: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 146
+      147: 'id-147'
+      147: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 147
+      148: 'id-148'
+      148: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 148
+      149: 'id-149'
+      149: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 149
+      150: 'id-150'
+      150: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 150
+      151: 'id-151'
+      151: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 151
+      152: 'id-152'
+      152: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 152
+      153: 'id-153'
+      153: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 153
+      154: 'id-154'
+      154: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 154
+      155: 'id-155'
+      155: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 155
+      156: 'id-156'
+      156: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 156
+      157: 'id-157'
+      157: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 157
+      158: 'id-158'
+      158: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 158
+      159: 'id-159'
+      159: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 159
+      160: 'id-160'
+      160: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 160
+      161: 'id-161'
+      161: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 161
+      162: 'id-162'
+      162: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 162
+      163: 'id-163'
+      163: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 163
+      164: 'id-164'
+      164: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 164
+      165: 'id-165'
+      165: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 165
+      166: 'id-166'
+      166: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 166
+      167: 'id-167'
+      167: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 167
+      168: 'id-168'
+      168: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 168
+      169: 'id-169'
+      169: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 169
+      170: 'id-170'
+      170: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 170
+      171: 'id-171'
+      171: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 171
+      172: 'id-172'
+      172: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 172
+      173: 'id-173'
+      173: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 173
+      174: 'id-174'
+      174: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 174
+      175: 'id-175'
+      175: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 175
+      176: 'id-176'
+      176: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 176
+      177: 'id-177'
+      177: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 177
+      178: 'id-178'
+      178: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 178
+      179: 'id-179'
+      179: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 179
+      180: 'id-180'
+      180: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 180
+      181: 'id-181'
+      181: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 181
+      182: 'id-182'
+      182: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 182
+      183: 'id-183'
+      183: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 183
+      184: 'id-184'
+      184: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 184
+      185: 'id-185'
+      185: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 185
+      186: 'id-186'
+      186: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 186
+      187: 'id-187'
+      187: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 187
+      188: 'id-188'
+      188: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 188
+      189: 'id-189'
+      189: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 189
+      190: 'id-190'
+      190: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 190
+      191: 'id-191'
+      191: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 191
+      192: 'id-192'
+      192: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 192
+      193: 'id-193'
+      193: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 193
+      194: 'id-194'
+      194: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 194
+      195: 'id-195'
+      195: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 195
+      196: 'id-196'
+      196: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 196
+      197: 'id-197'
+      197: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 197
+      198: 'id-198'
+      198: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 198
+      199: 'id-199'
+      199: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 199
+      200: 'id-200'
+      200: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 200
+      201: 'id-201'
+      201: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 201
+      202: 'id-202'
+      202: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 202
+      203: 'id-203'
+      203: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 203
+      204: 'id-204'
+      204: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 204
+      205: 'id-205'
+      205: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 205
+      206: 'id-206'
+      206: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 206
+      207: 'id-207'
+      207: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 207
+      208: 'id-208'
+      208: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 208
+      209: 'id-209'
+      209: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 209
+      210: 'id-210'
+      210: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 210
+      211: 'id-211'
+      211: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 211
+      212: 'id-212'
+      212: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 212
+      213: 'id-213'
+      213: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 213
+      214: 'id-214'
+      214: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 214
+      215: 'id-215'
+      215: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 215
+      216: 'id-216'
+      216: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 216
+      217: 'id-217'
+      217: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 217
+      218: 'id-218'
+      218: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 218
+      219: 'id-219'
+      219: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 219
+      220: 'id-220'
+      220: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 220
+      221: 'id-221'
+      221: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 221
+      222: 'id-222'
+      222: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 222
+      223: 'id-223'
+      223: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 223
+      224: 'id-224'
+      224: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 224
+      225: 'id-225'
+      225: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 225
+      226: 'id-226'
+      226: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 226
+      227: 'id-227'
+      227: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 227
+      228: 'id-228'
+      228: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 228
+      229: 'id-229'
+      229: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 229
+      230: 'id-230'
+      230: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 230
+      231: 'id-231'
+      231: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 231
+      232: 'id-232'
+      232: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 232
+      233: 'id-233'
+      233: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 233
+      234: 'id-234'
+      234: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 234
+      235: 'id-235'
+      235: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 235
+      236: 'id-236'
+      236: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 236
+      237: 'id-237'
+      237: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 237
+      238: 'id-238'
+      238: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 238
+      239: 'id-239'
+      239: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 239
+      240: 'id-240'
+      240: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 240
+      241: 'id-241'
+      241: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 241
+      242: 'id-242'
+      242: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 242
+      243: 'id-243'
+      243: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 243
+      244: 'id-244'
+      244: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 244
+      245: 'id-245'
+      245: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 245
+      246: 'id-246'
+      246: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 246
+      247: 'id-247'
+      247: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 247
+      248: 'id-248'
+      248: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 248
+      249: 'id-249'
+      249: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 249
+      250: 'id-250'
+      250: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 250
+      251: 'id-251'
+      251: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 251
+      252: 'id-252'
+      252: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 252
+      253: 'id-253'
+      253: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 253
+      254: 'id-254'
+      254: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 254
+      255: 'id-255'
+      255: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 255
+      256: 'id-256'
+      256: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 256
+      257: 'id-257'
+      257: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 257
+      258: 'id-258'
+      258: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 258
+      259: 'id-259'
+      259: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 259
+      260: 'id-260'
+      260: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 260
+      261: 'id-261'
+      261: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 261
+      262: 'id-262'
+      262: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 262
+      263: 'id-263'
+      263: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 263
+      264: 'id-264'
+      264: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 264
+      265: 'id-265'
+      265: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 265
+      266: 'id-266'
+      266: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 266
+      267: 'id-267'
+      267: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 267
+      268: 'id-268'
+      268: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 268
+      269: 'id-269'
+      269: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 269
+      270: 'id-270'
+      270: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 270
+      271: 'id-271'
+      271: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 271
+      272: 'id-272'
+      272: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 272
+      273: 'id-273'
+      273: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 273
+      274: 'id-274'
+      274: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 274
+      275: 'id-275'
+      275: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 275
+      276: 'id-276'
+      276: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 276
+      277: 'id-277'
+      277: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 277
+      278: 'id-278'
+      278: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 278
+      279: 'id-279'
+      279: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 279
+      280: 'id-280'
+      280: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 280
+      281: 'id-281'
+      281: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 281
+      282: 'id-282'
+      282: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 282
+      283: 'id-283'
+      283: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 283
+      284: 'id-284'
+      284: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 284
+      285: 'id-285'
+      285: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 285
+      286: 'id-286'
+      286: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 286
+      287: 'id-287'
+      287: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 287
+      288: 'id-288'
+      288: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 288
+      289: 'id-289'
+      289: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 289
+      290: 'id-290'
+      290: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 290
+      291: 'id-291'
+      291: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 291
+      292: 'id-292'
+      292: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 292
+      293: 'id-293'
+      293: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 293
+      294: 'id-294'
+      294: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 294
+      295: 'id-295'
+      295: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 295
+      296: 'id-296'
+      296: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 296
+      297: 'id-297'
+      297: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 297
+      298: 'id-298'
+      298: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 298
+      299: 'id-299'
+      299: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 299
+      300: 'id-300'
+      300: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 300
+      301: 'id-301'
+      301: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 301
+      302: 'id-302'
+      302: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 302
+      303: 'id-303'
+      303: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 303
+      304: 'id-304'
+      304: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 304
+      305: 'id-305'
+      305: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 305
+      306: 'id-306'
+      306: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 306
+      307: 'id-307'
+      307: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 307
+      308: 'id-308'
+      308: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 308
+      309: 'id-309'
+      309: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 309
+      310: 'id-310'
+      310: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 310
+      311: 'id-311'
+      311: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 311
+      312: 'id-312'
+      312: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 312
+      313: 'id-313'
+      313: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 313
+      314: 'id-314'
+      314: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 314
+      315: 'id-315'
+      315: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 315
+      316: 'id-316'
+      316: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 316
+      317: 'id-317'
+      317: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 317
+      318: 'id-318'
+      318: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 318
+      319: 'id-319'
+      319: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 319
+      320: 'id-320'
+      320: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 320
+      321: 'id-321'
+      321: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 321
+      322: 'id-322'
+      322: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 322
+      323: 'id-323'
+      323: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 323
+      324: 'id-324'
+      324: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 324
+      325: 'id-325'
+      325: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 325
+      326: 'id-326'
+      326: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 326
+      327: 'id-327'
+      327: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 327
+      328: 'id-328'
+      328: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 328
+      329: 'id-329'
+      329: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 329
+      330: 'id-330'
+      330: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 330
+      331: 'id-331'
+      331: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 331
+      332: 'id-332'
+      332: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 332
+      333: 'id-333'
+      333: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 333
+      334: 'id-334'
+      334: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 334
+      335: 'id-335'
+      335: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 335
+      336: 'id-336'
+      336: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 336
+      337: 'id-337'
+      337: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 337
+      338: 'id-338'
+      338: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 338
+      339: 'id-339'
+      339: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 339
+      340: 'id-340'
+      340: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 340
+      341: 'id-341'
+      341: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 341
+      342: 'id-342'
+      342: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 342
+      343: 'id-343'
+      343: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 343
+      344: 'id-344'
+      344: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 344
+      345: 'id-345'
+      345: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 345
+      346: 'id-346'
+      346: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 346
+      347: 'id-347'
+      347: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 347
+      348: 'id-348'
+      348: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 348
+      349: 'id-349'
+      349: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 349
+      350: 'id-350'
+      350: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 350
+      351: 'id-351'
+      351: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 351
+      352: 'id-352'
+      352: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 352
+      353: 'id-353'
+      353: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 353
+      354: 'id-354'
+      354: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 354
+      355: 'id-355'
+      355: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 355
+      356: 'id-356'
+      356: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 356
+      357: 'id-357'
+      357: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 357
+      358: 'id-358'
+      358: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 358
+      359: 'id-359'
+      359: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 359
+      360: 'id-360'
+      360: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 360
+      361: 'id-361'
+      361: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 361
+      362: 'id-362'
+      362: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 362
+      363: 'id-363'
+      363: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 363
+      364: 'id-364'
+      364: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 364
+      365: 'id-365'
+      365: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 365
+      366: 'id-366'
+      366: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 366
+      367: 'id-367'
+      367: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 367
+      368: 'id-368'
+      368: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 368
+      369: 'id-369'
+      369: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 369
+      370: 'id-370'
+      370: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 370
+      371: 'id-371'
+      371: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 371
+      372: 'id-372'
+      372: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 372
+      373: 'id-373'
+      373: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 373
+      374: 'id-374'
+      374: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 374
+      375: 'id-375'
+      375: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 375
+      376: 'id-376'
+      376: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 376
+      377: 'id-377'
+      377: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 377
+      378: 'id-378'
+      378: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 378
+      379: 'id-379'
+      379: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 379
+      380: 'id-380'
+      380: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 380
+      381: 'id-381'
+      381: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 381
+      382: 'id-382'
+      382: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 382
+      383: 'id-383'
+      383: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 383
+      384: 'id-384'
+      384: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 384
+      385: 'id-385'
+      385: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 385
+      386: 'id-386'
+      386: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 386
+      387: 'id-387'
+      387: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 387
+      388: 'id-388'
+      388: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 388
+      389: 'id-389'
+      389: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 389
+      390: 'id-390'
+      390: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 390
+      391: 'id-391'
+      391: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 391
+      392: 'id-392'
+      392: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 392
+      393: 'id-393'
+      393: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 393
+      394: 'id-394'
+      394: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 394
+      395: 'id-395'
+      395: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 395
+      396: 'id-396'
+      396: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 396
+      397: 'id-397'
+      397: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 397
+      398: 'id-398'
+      398: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 398
+      399: 'id-399'
+      399: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 399
+      400: 'id-400'
+      400: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 400
+      401: 'id-401'
+      401: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 401
+      402: 'id-402'
+      402: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 402
+      403: 'id-403'
+      403: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 403
+      404: 'id-404'
+      404: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 404
+      405: 'id-405'
+      405: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 405
+      406: 'id-406'
+      406: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 406
+      407: 'id-407'
+      407: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 407
+      408: 'id-408'
+      408: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 408
+      409: 'id-409'
+      409: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 409
+      410: 'id-410'
+      410: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 410
+      411: 'id-411'
+      411: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 411
+      412: 'id-412'
+      412: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 412
+      413: 'id-413'
+      413: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 413
+      414: 'id-414'
+      414: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 414
+      415: 'id-415'
+      415: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 415
+      416: 'id-416'
+      416: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 416
+      417: 'id-417'
+      417: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 417
+      418: 'id-418'
+      418: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 418
+      419: 'id-419'
+      419: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 419
+      420: 'id-420'
+      420: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 420
+      421: 'id-421'
+      421: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 421
+      422: 'id-422'
+      422: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 422
+      423: 'id-423'
+      423: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 423
+      424: 'id-424'
+      424: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 424
+      425: 'id-425'
+      425: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 425
+      426: 'id-426'
+      426: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 426
+      427: 'id-427'
+      427: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 427
+      428: 'id-428'
+      428: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 428
+      429: 'id-429'
+      429: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 429
+      430: 'id-430'
+      430: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 430
+      431: 'id-431'
+      431: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 431
+      432: 'id-432'
+      432: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 432
+      433: 'id-433'
+      433: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 433
+      434: 'id-434'
+      434: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 434
+      435: 'id-435'
+      435: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 435
+      436: 'id-436'
+      436: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 436
+      437: 'id-437'
+      437: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 437
+      438: 'id-438'
+      438: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 438
+      439: 'id-439'
+      439: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 439
+      440: 'id-440'
+      440: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 440
+      441: 'id-441'
+      441: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 441
+      442: 'id-442'
+      442: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 442
+      443: 'id-443'
+      443: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 443
+      444: 'id-444'
+      444: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 444
+      445: 'id-445'
+      445: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 445
+      446: 'id-446'
+      446: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 446
+      447: 'id-447'
+      447: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 447
+      448: 'id-448'
+      448: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 448
+      449: 'id-449'
+      449: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 449
+      450: 'id-450'
+      450: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 450
+      451: 'id-451'
+      451: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 451
+      452: 'id-452'
+      452: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 452
+      453: 'id-453'
+      453: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 453
+      454: 'id-454'
+      454: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 454
+      455: 'id-455'
+      455: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 455
+      456: 'id-456'
+      456: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 456
+      457: 'id-457'
+      457: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 457
+      458: 'id-458'
+      458: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 458
+      459: 'id-459'
+      459: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 459
+      460: 'id-460'
+      460: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 460
+      461: 'id-461'
+      461: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 461
+      462: 'id-462'
+      462: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 462
+      463: 'id-463'
+      463: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 463
+      464: 'id-464'
+      464: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 464
+      465: 'id-465'
+      465: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 465
+      466: 'id-466'
+      466: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 466
+      467: 'id-467'
+      467: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 467
+      468: 'id-468'
+      468: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 468
+      469: 'id-469'
+      469: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 469
+      470: 'id-470'
+      470: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 470
+      471: 'id-471'
+      471: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 471
+      472: 'id-472'
+      472: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 472
+      473: 'id-473'
+      473: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 473
+      474: 'id-474'
+      474: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 474
+      475: 'id-475'
+      475: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 475
+      476: 'id-476'
+      476: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 476
+      477: 'id-477'
+      477: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 477
+      478: 'id-478'
+      478: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 478
+      479: 'id-479'
+      479: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 479
+      480: 'id-480'
+      480: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 480
+      481: 'id-481'
+      481: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 481
+      482: 'id-482'
+      482: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 482
+      483: 'id-483'
+      483: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 483
+      484: 'id-484'
+      484: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 484
+      485: 'id-485'
+      485: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 485
+      486: 'id-486'
+      486: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 486
+      487: 'id-487'
+      487: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 487
+      488: 'id-488'
+      488: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 488
+      489: 'id-489'
+      489: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 489
+      490: 'id-490'
+      490: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 490
+      491: 'id-491'
+      491: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 491
+      492: 'id-492'
+      492: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 492
+      493: 'id-493'
+      493: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 493
+      494: 'id-494'
+      494: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 494
+      495: 'id-495'
+      495: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 495
+      496: 'id-496'
+      496: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 496
+      497: 'id-497'
+      497: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 497
+      498: 'id-498'
+      498: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 498
+      499: 'id-499'
+      499: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 499
+      1: subview '_B'
+     VIEW   500 rows = p1:S sv:V
+        0: 'id-500'
+        0: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 500
+        1: 'id-501'
+        1: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 501
+        2: 'id-502'
+        2: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 502
+        3: 'id-503'
+        3: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 503
+        4: 'id-504'
+        4: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 504
+        5: 'id-505'
+        5: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 505
+        6: 'id-506'
+        6: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 506
+        7: 'id-507'
+        7: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 507
+        8: 'id-508'
+        8: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 508
+        9: 'id-509'
+        9: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 509
+       10: 'id-510'
+       10: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 510
+       11: 'id-511'
+       11: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 511
+       12: 'id-512'
+       12: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 512
+       13: 'id-513'
+       13: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 513
+       14: 'id-514'
+       14: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 514
+       15: 'id-515'
+       15: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 515
+       16: 'id-516'
+       16: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 516
+       17: 'id-517'
+       17: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 517
+       18: 'id-518'
+       18: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 518
+       19: 'id-519'
+       19: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 519
+       20: 'id-520'
+       20: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 520
+       21: 'id-521'
+       21: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 521
+       22: 'id-522'
+       22: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 522
+       23: 'id-523'
+       23: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 523
+       24: 'id-524'
+       24: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 524
+       25: 'id-525'
+       25: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 525
+       26: 'id-526'
+       26: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 526
+       27: 'id-527'
+       27: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 527
+       28: 'id-528'
+       28: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 528
+       29: 'id-529'
+       29: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 529
+       30: 'id-530'
+       30: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 530
+       31: 'id-531'
+       31: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 531
+       32: 'id-532'
+       32: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 532
+       33: 'id-533'
+       33: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 533
+       34: 'id-534'
+       34: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 534
+       35: 'id-535'
+       35: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 535
+       36: 'id-536'
+       36: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 536
+       37: 'id-537'
+       37: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 537
+       38: 'id-538'
+       38: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 538
+       39: 'id-539'
+       39: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 539
+       40: 'id-540'
+       40: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 540
+       41: 'id-541'
+       41: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 541
+       42: 'id-542'
+       42: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 542
+       43: 'id-543'
+       43: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 543
+       44: 'id-544'
+       44: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 544
+       45: 'id-545'
+       45: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 545
+       46: 'id-546'
+       46: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 546
+       47: 'id-547'
+       47: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 547
+       48: 'id-548'
+       48: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 548
+       49: 'id-549'
+       49: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 549
+       50: 'id-550'
+       50: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 550
+       51: 'id-551'
+       51: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 551
+       52: 'id-552'
+       52: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 552
+       53: 'id-553'
+       53: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 553
+       54: 'id-554'
+       54: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 554
+       55: 'id-555'
+       55: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 555
+       56: 'id-556'
+       56: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 556
+       57: 'id-557'
+       57: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 557
+       58: 'id-558'
+       58: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 558
+       59: 'id-559'
+       59: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 559
+       60: 'id-560'
+       60: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 560
+       61: 'id-561'
+       61: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 561
+       62: 'id-562'
+       62: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 562
+       63: 'id-563'
+       63: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 563
+       64: 'id-564'
+       64: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 564
+       65: 'id-565'
+       65: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 565
+       66: 'id-566'
+       66: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 566
+       67: 'id-567'
+       67: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 567
+       68: 'id-568'
+       68: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 568
+       69: 'id-569'
+       69: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 569
+       70: 'id-570'
+       70: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 570
+       71: 'id-571'
+       71: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 571
+       72: 'id-572'
+       72: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 572
+       73: 'id-573'
+       73: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 573
+       74: 'id-574'
+       74: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 574
+       75: 'id-575'
+       75: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 575
+       76: 'id-576'
+       76: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 576
+       77: 'id-577'
+       77: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 577
+       78: 'id-578'
+       78: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 578
+       79: 'id-579'
+       79: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 579
+       80: 'id-580'
+       80: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 580
+       81: 'id-581'
+       81: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 581
+       82: 'id-582'
+       82: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 582
+       83: 'id-583'
+       83: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 583
+       84: 'id-584'
+       84: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 584
+       85: 'id-585'
+       85: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 585
+       86: 'id-586'
+       86: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 586
+       87: 'id-587'
+       87: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 587
+       88: 'id-588'
+       88: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 588
+       89: 'id-589'
+       89: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 589
+       90: 'id-590'
+       90: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 590
+       91: 'id-591'
+       91: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 591
+       92: 'id-592'
+       92: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 592
+       93: 'id-593'
+       93: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 593
+       94: 'id-594'
+       94: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 594
+       95: 'id-595'
+       95: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 595
+       96: 'id-596'
+       96: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 596
+       97: 'id-597'
+       97: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 597
+       98: 'id-598'
+       98: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 598
+       99: 'id-599'
+       99: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 599
+      100: 'id-600'
+      100: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 600
+      101: 'id-601'
+      101: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 601
+      102: 'id-602'
+      102: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 602
+      103: 'id-603'
+      103: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 603
+      104: 'id-604'
+      104: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 604
+      105: 'id-605'
+      105: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 605
+      106: 'id-606'
+      106: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 606
+      107: 'id-607'
+      107: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 607
+      108: 'id-608'
+      108: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 608
+      109: 'id-609'
+      109: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 609
+      110: 'id-610'
+      110: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 610
+      111: 'id-611'
+      111: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 611
+      112: 'id-612'
+      112: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 612
+      113: 'id-613'
+      113: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 613
+      114: 'id-614'
+      114: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 614
+      115: 'id-615'
+      115: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 615
+      116: 'id-616'
+      116: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 616
+      117: 'id-617'
+      117: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 617
+      118: 'id-618'
+      118: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 618
+      119: 'id-619'
+      119: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 619
+      120: 'id-620'
+      120: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 620
+      121: 'id-621'
+      121: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 621
+      122: 'id-622'
+      122: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 622
+      123: 'id-623'
+      123: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 623
+      124: 'id-624'
+      124: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 624
+      125: 'id-625'
+      125: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 625
+      126: 'id-626'
+      126: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 626
+      127: 'id-627'
+      127: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 627
+      128: 'id-628'
+      128: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 628
+      129: 'id-629'
+      129: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 629
+      130: 'id-630'
+      130: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 630
+      131: 'id-631'
+      131: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 631
+      132: 'id-632'
+      132: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 632
+      133: 'id-633'
+      133: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 633
+      134: 'id-634'
+      134: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 634
+      135: 'id-635'
+      135: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 635
+      136: 'id-636'
+      136: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 636
+      137: 'id-637'
+      137: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 637
+      138: 'id-638'
+      138: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 638
+      139: 'id-639'
+      139: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 639
+      140: 'id-640'
+      140: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 640
+      141: 'id-641'
+      141: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 641
+      142: 'id-642'
+      142: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 642
+      143: 'id-643'
+      143: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 643
+      144: 'id-644'
+      144: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 644
+      145: 'id-645'
+      145: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 645
+      146: 'id-646'
+      146: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 646
+      147: 'id-647'
+      147: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 647
+      148: 'id-648'
+      148: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 648
+      149: 'id-649'
+      149: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 649
+      150: 'id-650'
+      150: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 650
+      151: 'id-651'
+      151: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 651
+      152: 'id-652'
+      152: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 652
+      153: 'id-653'
+      153: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 653
+      154: 'id-654'
+      154: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 654
+      155: 'id-655'
+      155: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 655
+      156: 'id-656'
+      156: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 656
+      157: 'id-657'
+      157: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 657
+      158: 'id-658'
+      158: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 658
+      159: 'id-659'
+      159: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 659
+      160: 'id-660'
+      160: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 660
+      161: 'id-661'
+      161: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 661
+      162: 'id-662'
+      162: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 662
+      163: 'id-663'
+      163: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 663
+      164: 'id-664'
+      164: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 664
+      165: 'id-665'
+      165: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 665
+      166: 'id-666'
+      166: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 666
+      167: 'id-667'
+      167: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 667
+      168: 'id-668'
+      168: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 668
+      169: 'id-669'
+      169: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 669
+      170: 'id-670'
+      170: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 670
+      171: 'id-671'
+      171: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 671
+      172: 'id-672'
+      172: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 672
+      173: 'id-673'
+      173: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 673
+      174: 'id-674'
+      174: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 674
+      175: 'id-675'
+      175: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 675
+      176: 'id-676'
+      176: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 676
+      177: 'id-677'
+      177: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 677
+      178: 'id-678'
+      178: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 678
+      179: 'id-679'
+      179: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 679
+      180: 'id-680'
+      180: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 680
+      181: 'id-681'
+      181: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 681
+      182: 'id-682'
+      182: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 682
+      183: 'id-683'
+      183: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 683
+      184: 'id-684'
+      184: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 684
+      185: 'id-685'
+      185: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 685
+      186: 'id-686'
+      186: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 686
+      187: 'id-687'
+      187: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 687
+      188: 'id-688'
+      188: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 688
+      189: 'id-689'
+      189: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 689
+      190: 'id-690'
+      190: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 690
+      191: 'id-691'
+      191: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 691
+      192: 'id-692'
+      192: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 692
+      193: 'id-693'
+      193: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 693
+      194: 'id-694'
+      194: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 694
+      195: 'id-695'
+      195: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 695
+      196: 'id-696'
+      196: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 696
+      197: 'id-697'
+      197: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 697
+      198: 'id-698'
+      198: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 698
+      199: 'id-699'
+      199: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 699
+      200: 'id-700'
+      200: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 700
+      201: 'id-701'
+      201: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 701
+      202: 'id-702'
+      202: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 702
+      203: 'id-703'
+      203: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 703
+      204: 'id-704'
+      204: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 704
+      205: 'id-705'
+      205: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 705
+      206: 'id-706'
+      206: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 706
+      207: 'id-707'
+      207: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 707
+      208: 'id-708'
+      208: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 708
+      209: 'id-709'
+      209: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 709
+      210: 'id-710'
+      210: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 710
+      211: 'id-711'
+      211: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 711
+      212: 'id-712'
+      212: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 712
+      213: 'id-713'
+      213: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 713
+      214: 'id-714'
+      214: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 714
+      215: 'id-715'
+      215: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 715
+      216: 'id-716'
+      216: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 716
+      217: 'id-717'
+      217: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 717
+      218: 'id-718'
+      218: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 718
+      219: 'id-719'
+      219: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 719
+      220: 'id-720'
+      220: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 720
+      221: 'id-721'
+      221: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 721
+      222: 'id-722'
+      222: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 722
+      223: 'id-723'
+      223: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 723
+      224: 'id-724'
+      224: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 724
+      225: 'id-725'
+      225: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 725
+      226: 'id-726'
+      226: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 726
+      227: 'id-727'
+      227: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 727
+      228: 'id-728'
+      228: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 728
+      229: 'id-729'
+      229: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 729
+      230: 'id-730'
+      230: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 730
+      231: 'id-731'
+      231: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 731
+      232: 'id-732'
+      232: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 732
+      233: 'id-733'
+      233: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 733
+      234: 'id-734'
+      234: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 734
+      235: 'id-735'
+      235: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 735
+      236: 'id-736'
+      236: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 736
+      237: 'id-737'
+      237: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 737
+      238: 'id-738'
+      238: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 738
+      239: 'id-739'
+      239: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 739
+      240: 'id-740'
+      240: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 740
+      241: 'id-741'
+      241: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 741
+      242: 'id-742'
+      242: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 742
+      243: 'id-743'
+      243: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 743
+      244: 'id-744'
+      244: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 744
+      245: 'id-745'
+      245: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 745
+      246: 'id-746'
+      246: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 746
+      247: 'id-747'
+      247: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 747
+      248: 'id-748'
+      248: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 748
+      249: 'id-749'
+      249: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 749
+      250: 'id-750'
+      250: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 750
+      251: 'id-751'
+      251: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 751
+      252: 'id-752'
+      252: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 752
+      253: 'id-753'
+      253: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 753
+      254: 'id-754'
+      254: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 754
+      255: 'id-755'
+      255: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 755
+      256: 'id-756'
+      256: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 756
+      257: 'id-757'
+      257: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 757
+      258: 'id-758'
+      258: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 758
+      259: 'id-759'
+      259: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 759
+      260: 'id-760'
+      260: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 760
+      261: 'id-761'
+      261: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 761
+      262: 'id-762'
+      262: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 762
+      263: 'id-763'
+      263: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 763
+      264: 'id-764'
+      264: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 764
+      265: 'id-765'
+      265: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 765
+      266: 'id-766'
+      266: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 766
+      267: 'id-767'
+      267: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 767
+      268: 'id-768'
+      268: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 768
+      269: 'id-769'
+      269: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 769
+      270: 'id-770'
+      270: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 770
+      271: 'id-771'
+      271: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 771
+      272: 'id-772'
+      272: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 772
+      273: 'id-773'
+      273: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 773
+      274: 'id-774'
+      274: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 774
+      275: 'id-775'
+      275: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 775
+      276: 'id-776'
+      276: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 776
+      277: 'id-777'
+      277: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 777
+      278: 'id-778'
+      278: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 778
+      279: 'id-779'
+      279: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 779
+      280: 'id-780'
+      280: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 780
+      281: 'id-781'
+      281: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 781
+      282: 'id-782'
+      282: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 782
+      283: 'id-783'
+      283: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 783
+      284: 'id-784'
+      284: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 784
+      285: 'id-785'
+      285: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 785
+      286: 'id-786'
+      286: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 786
+      287: 'id-787'
+      287: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 787
+      288: 'id-788'
+      288: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 788
+      289: 'id-789'
+      289: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 789
+      290: 'id-790'
+      290: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 790
+      291: 'id-791'
+      291: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 791
+      292: 'id-792'
+      292: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 792
+      293: 'id-793'
+      293: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 793
+      294: 'id-794'
+      294: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 794
+      295: 'id-795'
+      295: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 795
+      296: 'id-796'
+      296: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 796
+      297: 'id-797'
+      297: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 797
+      298: 'id-798'
+      298: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 798
+      299: 'id-799'
+      299: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 799
+      300: 'id-800'
+      300: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 800
+      301: 'id-801'
+      301: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 801
+      302: 'id-802'
+      302: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 802
+      303: 'id-803'
+      303: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 803
+      304: 'id-804'
+      304: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 804
+      305: 'id-805'
+      305: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 805
+      306: 'id-806'
+      306: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 806
+      307: 'id-807'
+      307: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 807
+      308: 'id-808'
+      308: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 808
+      309: 'id-809'
+      309: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 809
+      310: 'id-810'
+      310: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 810
+      311: 'id-811'
+      311: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 811
+      312: 'id-812'
+      312: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 812
+      313: 'id-813'
+      313: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 813
+      314: 'id-814'
+      314: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 814
+      315: 'id-815'
+      315: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 815
+      316: 'id-816'
+      316: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 816
+      317: 'id-817'
+      317: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 817
+      318: 'id-818'
+      318: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 818
+      319: 'id-819'
+      319: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 819
+      320: 'id-820'
+      320: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 820
+      321: 'id-821'
+      321: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 821
+      322: 'id-822'
+      322: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 822
+      323: 'id-823'
+      323: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 823
+      324: 'id-824'
+      324: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 824
+      325: 'id-825'
+      325: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 825
+      326: 'id-826'
+      326: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 826
+      327: 'id-827'
+      327: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 827
+      328: 'id-828'
+      328: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 828
+      329: 'id-829'
+      329: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 829
+      330: 'id-830'
+      330: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 830
+      331: 'id-831'
+      331: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 831
+      332: 'id-832'
+      332: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 832
+      333: 'id-833'
+      333: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 833
+      334: 'id-834'
+      334: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 834
+      335: 'id-835'
+      335: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 835
+      336: 'id-836'
+      336: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 836
+      337: 'id-837'
+      337: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 837
+      338: 'id-838'
+      338: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 838
+      339: 'id-839'
+      339: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 839
+      340: 'id-840'
+      340: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 840
+      341: 'id-841'
+      341: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 841
+      342: 'id-842'
+      342: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 842
+      343: 'id-843'
+      343: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 843
+      344: 'id-844'
+      344: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 844
+      345: 'id-845'
+      345: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 845
+      346: 'id-846'
+      346: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 846
+      347: 'id-847'
+      347: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 847
+      348: 'id-848'
+      348: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 848
+      349: 'id-849'
+      349: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 849
+      350: 'id-850'
+      350: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 850
+      351: 'id-851'
+      351: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 851
+      352: 'id-852'
+      352: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 852
+      353: 'id-853'
+      353: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 853
+      354: 'id-854'
+      354: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 854
+      355: 'id-855'
+      355: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 855
+      356: 'id-856'
+      356: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 856
+      357: 'id-857'
+      357: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 857
+      358: 'id-858'
+      358: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 858
+      359: 'id-859'
+      359: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 859
+      360: 'id-860'
+      360: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 860
+      361: 'id-861'
+      361: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 861
+      362: 'id-862'
+      362: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 862
+      363: 'id-863'
+      363: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 863
+      364: 'id-864'
+      364: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 864
+      365: 'id-865'
+      365: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 865
+      366: 'id-866'
+      366: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 866
+      367: 'id-867'
+      367: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 867
+      368: 'id-868'
+      368: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 868
+      369: 'id-869'
+      369: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 869
+      370: 'id-870'
+      370: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 870
+      371: 'id-871'
+      371: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 871
+      372: 'id-872'
+      372: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 872
+      373: 'id-873'
+      373: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 873
+      374: 'id-874'
+      374: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 874
+      375: 'id-875'
+      375: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 875
+      376: 'id-876'
+      376: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 876
+      377: 'id-877'
+      377: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 877
+      378: 'id-878'
+      378: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 878
+      379: 'id-879'
+      379: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 879
+      380: 'id-880'
+      380: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 880
+      381: 'id-881'
+      381: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 881
+      382: 'id-882'
+      382: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 882
+      383: 'id-883'
+      383: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 883
+      384: 'id-884'
+      384: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 884
+      385: 'id-885'
+      385: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 885
+      386: 'id-886'
+      386: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 886
+      387: 'id-887'
+      387: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 887
+      388: 'id-888'
+      388: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 888
+      389: 'id-889'
+      389: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 889
+      390: 'id-890'
+      390: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 890
+      391: 'id-891'
+      391: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 891
+      392: 'id-892'
+      392: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 892
+      393: 'id-893'
+      393: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 893
+      394: 'id-894'
+      394: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 894
+      395: 'id-895'
+      395: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 895
+      396: 'id-896'
+      396: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 896
+      397: 'id-897'
+      397: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 897
+      398: 'id-898'
+      398: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 898
+      399: 'id-899'
+      399: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 899
+      400: 'id-900'
+      400: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 900
+      401: 'id-901'
+      401: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 901
+      402: 'id-902'
+      402: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 902
+      403: 'id-903'
+      403: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 903
+      404: 'id-904'
+      404: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 904
+      405: 'id-905'
+      405: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 905
+      406: 'id-906'
+      406: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 906
+      407: 'id-907'
+      407: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 907
+      408: 'id-908'
+      408: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 908
+      409: 'id-909'
+      409: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 909
+      410: 'id-910'
+      410: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 910
+      411: 'id-911'
+      411: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 911
+      412: 'id-912'
+      412: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 912
+      413: 'id-913'
+      413: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 913
+      414: 'id-914'
+      414: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 914
+      415: 'id-915'
+      415: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 915
+      416: 'id-916'
+      416: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 916
+      417: 'id-917'
+      417: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 917
+      418: 'id-918'
+      418: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 918
+      419: 'id-919'
+      419: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 919
+      420: 'id-920'
+      420: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 920
+      421: 'id-921'
+      421: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 921
+      422: 'id-922'
+      422: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 922
+      423: 'id-923'
+      423: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 923
+      424: 'id-924'
+      424: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 924
+      425: 'id-925'
+      425: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 925
+      426: 'id-926'
+      426: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 926
+      427: 'id-927'
+      427: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 927
+      428: 'id-928'
+      428: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 928
+      429: 'id-929'
+      429: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 929
+      430: 'id-930'
+      430: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 930
+      431: 'id-931'
+      431: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 931
+      432: 'id-932'
+      432: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 932
+      433: 'id-933'
+      433: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 933
+      434: 'id-934'
+      434: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 934
+      435: 'id-935'
+      435: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 935
+      436: 'id-936'
+      436: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 936
+      437: 'id-937'
+      437: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 937
+      438: 'id-938'
+      438: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 938
+      439: 'id-939'
+      439: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 939
+      440: 'id-940'
+      440: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 940
+      441: 'id-941'
+      441: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 941
+      442: 'id-942'
+      442: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 942
+      443: 'id-943'
+      443: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 943
+      444: 'id-944'
+      444: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 944
+      445: 'id-945'
+      445: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 945
+      446: 'id-946'
+      446: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 946
+      447: 'id-947'
+      447: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 947
+      448: 'id-948'
+      448: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 948
+      449: 'id-949'
+      449: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 949
+      450: 'id-950'
+      450: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 950
+      451: 'id-951'
+      451: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 951
+      452: 'id-952'
+      452: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 952
+      453: 'id-953'
+      453: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 953
+      454: 'id-954'
+      454: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 954
+      455: 'id-955'
+      455: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 955
+      456: 'id-956'
+      456: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 956
+      457: 'id-957'
+      457: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 957
+      458: 'id-958'
+      458: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 958
+      459: 'id-959'
+      459: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 959
+      460: 'id-960'
+      460: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 960
+      461: 'id-961'
+      461: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 961
+      462: 'id-962'
+      462: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 962
+      463: 'id-963'
+      463: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 963
+      464: 'id-964'
+      464: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 964
+      465: 'id-965'
+      465: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 965
+      466: 'id-966'
+      466: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 966
+      467: 'id-967'
+      467: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 967
+      468: 'id-968'
+      468: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 968
+      469: 'id-969'
+      469: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 969
+      470: 'id-970'
+      470: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 970
+      471: 'id-971'
+      471: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 971
+      472: 'id-972'
+      472: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 972
+      473: 'id-973'
+      473: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 973
+      474: 'id-974'
+      474: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 974
+      475: 'id-975'
+      475: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 975
+      476: 'id-976'
+      476: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 976
+      477: 'id-977'
+      477: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 977
+      478: 'id-978'
+      478: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 978
+      479: 'id-979'
+      479: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 979
+      480: 'id-980'
+      480: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 980
+      481: 'id-981'
+      481: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 981
+      482: 'id-982'
+      482: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 982
+      483: 'id-983'
+      483: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 983
+      484: 'id-984'
+      484: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 984
+      485: 'id-985'
+      485: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 985
+      486: 'id-986'
+      486: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 986
+      487: 'id-987'
+      487: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 987
+      488: 'id-988'
+      488: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 988
+      489: 'id-989'
+      489: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 989
+      490: 'id-990'
+      490: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 990
+      491: 'id-991'
+      491: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 991
+      492: 'id-992'
+      492: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 992
+      493: 'id-993'
+      493: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 993
+      494: 'id-994'
+      494: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 994
+      495: 'id-995'
+      495: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 995
+      496: 'id-996'
+      496: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 996
+      497: 'id-997'
+      497: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 997
+      498: 'id-998'
+      498: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 998
+      499: 'id-999'
+      499: subview 'sv'
+       VIEW     1 rows = p2:I
+          0: 999
+      2: subview '_B'
+     VIEW     1 rows = p1:S sv:V
+        0: 'insert-0'
+        0: subview 'sv'
+       VIEW     0 rows = p2:I
diff --git a/8.x/mk/tests/ok/m06.txt b/8.x/mk/tests/ok/m06.txt
new file mode 100644 (file)
index 0000000..ef0cb46
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Blocked view multi-row deletion
+<<< done.
diff --git a/8.x/mk/tests/ok/m06a.txt b/8.x/mk/tests/ok/m06a.txt
new file mode 100644 (file)
index 0000000..d72b2e6
--- /dev/null
@@ -0,0 +1,2963 @@
+ VIEW     1 rows = v1:V v2:V
+    0: subview 'v1'
+   VIEW   901 rows = p1:I
+      0: 1
+      1: 100
+      2: 101
+      3: 102
+      4: 103
+      5: 104
+      6: 105
+      7: 106
+      8: 107
+      9: 108
+     10: 109
+     11: 110
+     12: 111
+     13: 112
+     14: 113
+     15: 114
+     16: 115
+     17: 116
+     18: 117
+     19: 118
+     20: 119
+     21: 120
+     22: 121
+     23: 122
+     24: 123
+     25: 124
+     26: 125
+     27: 126
+     28: 127
+     29: 128
+     30: 129
+     31: 130
+     32: 131
+     33: 132
+     34: 133
+     35: 134
+     36: 135
+     37: 136
+     38: 137
+     39: 138
+     40: 139
+     41: 140
+     42: 141
+     43: 142
+     44: 143
+     45: 144
+     46: 145
+     47: 146
+     48: 147
+     49: 148
+     50: 149
+     51: 150
+     52: 151
+     53: 152
+     54: 153
+     55: 154
+     56: 155
+     57: 156
+     58: 157
+     59: 158
+     60: 159
+     61: 160
+     62: 161
+     63: 162
+     64: 163
+     65: 164
+     66: 165
+     67: 166
+     68: 167
+     69: 168
+     70: 169
+     71: 170
+     72: 171
+     73: 172
+     74: 173
+     75: 174
+     76: 175
+     77: 176
+     78: 177
+     79: 178
+     80: 179
+     81: 180
+     82: 181
+     83: 182
+     84: 183
+     85: 184
+     86: 185
+     87: 186
+     88: 187
+     89: 188
+     90: 189
+     91: 190
+     92: 191
+     93: 192
+     94: 193
+     95: 194
+     96: 195
+     97: 196
+     98: 197
+     99: 198
+    100: 199
+    101: 200
+    102: 201
+    103: 202
+    104: 203
+    105: 204
+    106: 205
+    107: 206
+    108: 207
+    109: 208
+    110: 209
+    111: 210
+    112: 211
+    113: 212
+    114: 213
+    115: 214
+    116: 215
+    117: 216
+    118: 217
+    119: 218
+    120: 219
+    121: 220
+    122: 221
+    123: 222
+    124: 223
+    125: 224
+    126: 225
+    127: 226
+    128: 227
+    129: 228
+    130: 229
+    131: 230
+    132: 231
+    133: 232
+    134: 233
+    135: 234
+    136: 235
+    137: 236
+    138: 237
+    139: 238
+    140: 239
+    141: 240
+    142: 241
+    143: 242
+    144: 243
+    145: 244
+    146: 245
+    147: 246
+    148: 247
+    149: 248
+    150: 249
+    151: 250
+    152: 251
+    153: 252
+    154: 253
+    155: 254
+    156: 255
+    157: 256
+    158: 257
+    159: 258
+    160: 259
+    161: 260
+    162: 261
+    163: 262
+    164: 263
+    165: 264
+    166: 265
+    167: 266
+    168: 267
+    169: 268
+    170: 269
+    171: 270
+    172: 271
+    173: 272
+    174: 273
+    175: 274
+    176: 275
+    177: 276
+    178: 277
+    179: 278
+    180: 279
+    181: 280
+    182: 281
+    183: 282
+    184: 283
+    185: 284
+    186: 285
+    187: 286
+    188: 287
+    189: 288
+    190: 289
+    191: 290
+    192: 291
+    193: 292
+    194: 293
+    195: 294
+    196: 295
+    197: 296
+    198: 297
+    199: 298
+    200: 299
+    201: 300
+    202: 301
+    203: 302
+    204: 303
+    205: 304
+    206: 305
+    207: 306
+    208: 307
+    209: 308
+    210: 309
+    211: 310
+    212: 311
+    213: 312
+    214: 313
+    215: 314
+    216: 315
+    217: 316
+    218: 317
+    219: 318
+    220: 319
+    221: 320
+    222: 321
+    223: 322
+    224: 323
+    225: 324
+    226: 325
+    227: 326
+    228: 327
+    229: 328
+    230: 329
+    231: 330
+    232: 331
+    233: 332
+    234: 333
+    235: 334
+    236: 335
+    237: 336
+    238: 337
+    239: 338
+    240: 339
+    241: 340
+    242: 341
+    243: 342
+    244: 343
+    245: 344
+    246: 345
+    247: 346
+    248: 347
+    249: 348
+    250: 349
+    251: 350
+    252: 351
+    253: 352
+    254: 353
+    255: 354
+    256: 355
+    257: 356
+    258: 357
+    259: 358
+    260: 359
+    261: 360
+    262: 361
+    263: 362
+    264: 363
+    265: 364
+    266: 365
+    267: 366
+    268: 367
+    269: 368
+    270: 369
+    271: 370
+    272: 371
+    273: 372
+    274: 373
+    275: 374
+    276: 375
+    277: 376
+    278: 377
+    279: 378
+    280: 379
+    281: 380
+    282: 381
+    283: 382
+    284: 383
+    285: 384
+    286: 385
+    287: 386
+    288: 387
+    289: 388
+    290: 389
+    291: 390
+    292: 391
+    293: 392
+    294: 393
+    295: 394
+    296: 395
+    297: 396
+    298: 397
+    299: 398
+    300: 399
+    301: 400
+    302: 401
+    303: 402
+    304: 403
+    305: 404
+    306: 405
+    307: 406
+    308: 407
+    309: 408
+    310: 409
+    311: 410
+    312: 411
+    313: 412
+    314: 413
+    315: 414
+    316: 415
+    317: 416
+    318: 417
+    319: 418
+    320: 419
+    321: 420
+    322: 421
+    323: 422
+    324: 423
+    325: 424
+    326: 425
+    327: 426
+    328: 427
+    329: 428
+    330: 429
+    331: 430
+    332: 431
+    333: 432
+    334: 433
+    335: 434
+    336: 435
+    337: 436
+    338: 437
+    339: 438
+    340: 439
+    341: 440
+    342: 441
+    343: 442
+    344: 443
+    345: 444
+    346: 445
+    347: 446
+    348: 447
+    349: 448
+    350: 449
+    351: 450
+    352: 451
+    353: 452
+    354: 453
+    355: 454
+    356: 455
+    357: 456
+    358: 457
+    359: 458
+    360: 459
+    361: 460
+    362: 461
+    363: 462
+    364: 463
+    365: 464
+    366: 465
+    367: 466
+    368: 467
+    369: 468
+    370: 469
+    371: 470
+    372: 471
+    373: 472
+    374: 473
+    375: 474
+    376: 475
+    377: 476
+    378: 477
+    379: 478
+    380: 479
+    381: 480
+    382: 481
+    383: 482
+    384: 483
+    385: 484
+    386: 485
+    387: 486
+    388: 487
+    389: 488
+    390: 489
+    391: 490
+    392: 491
+    393: 492
+    394: 493
+    395: 494
+    396: 495
+    397: 496
+    398: 497
+    399: 498
+    400: 499
+    401: 500
+    402: 501
+    403: 502
+    404: 503
+    405: 504
+    406: 505
+    407: 506
+    408: 507
+    409: 508
+    410: 509
+    411: 510
+    412: 511
+    413: 512
+    414: 513
+    415: 514
+    416: 515
+    417: 516
+    418: 517
+    419: 518
+    420: 519
+    421: 520
+    422: 521
+    423: 522
+    424: 523
+    425: 524
+    426: 525
+    427: 526
+    428: 527
+    429: 528
+    430: 529
+    431: 530
+    432: 531
+    433: 532
+    434: 533
+    435: 534
+    436: 535
+    437: 536
+    438: 537
+    439: 538
+    440: 539
+    441: 540
+    442: 541
+    443: 542
+    444: 543
+    445: 544
+    446: 545
+    447: 546
+    448: 547
+    449: 548
+    450: 549
+    451: 550
+    452: 551
+    453: 552
+    454: 553
+    455: 554
+    456: 555
+    457: 556
+    458: 557
+    459: 558
+    460: 559
+    461: 560
+    462: 561
+    463: 562
+    464: 563
+    465: 564
+    466: 565
+    467: 566
+    468: 567
+    469: 568
+    470: 569
+    471: 570
+    472: 571
+    473: 572
+    474: 573
+    475: 574
+    476: 575
+    477: 576
+    478: 577
+    479: 578
+    480: 579
+    481: 580
+    482: 581
+    483: 582
+    484: 583
+    485: 584
+    486: 585
+    487: 586
+    488: 587
+    489: 588
+    490: 589
+    491: 590
+    492: 591
+    493: 592
+    494: 593
+    495: 594
+    496: 595
+    497: 596
+    498: 597
+    499: 598
+    500: 599
+    501: 600
+    502: 601
+    503: 602
+    504: 603
+    505: 604
+    506: 605
+    507: 606
+    508: 607
+    509: 608
+    510: 609
+    511: 610
+    512: 611
+    513: 612
+    514: 613
+    515: 614
+    516: 615
+    517: 616
+    518: 617
+    519: 618
+    520: 619
+    521: 620
+    522: 621
+    523: 622
+    524: 623
+    525: 624
+    526: 625
+    527: 626
+    528: 627
+    529: 628
+    530: 629
+    531: 630
+    532: 631
+    533: 632
+    534: 633
+    535: 634
+    536: 635
+    537: 636
+    538: 637
+    539: 638
+    540: 639
+    541: 640
+    542: 641
+    543: 642
+    544: 643
+    545: 644
+    546: 645
+    547: 646
+    548: 647
+    549: 648
+    550: 649
+    551: 650
+    552: 651
+    553: 652
+    554: 653
+    555: 654
+    556: 655
+    557: 656
+    558: 657
+    559: 658
+    560: 659
+    561: 660
+    562: 661
+    563: 662
+    564: 663
+    565: 664
+    566: 665
+    567: 666
+    568: 667
+    569: 668
+    570: 669
+    571: 670
+    572: 671
+    573: 672
+    574: 673
+    575: 674
+    576: 675
+    577: 676
+    578: 677
+    579: 678
+    580: 679
+    581: 680
+    582: 681
+    583: 682
+    584: 683
+    585: 684
+    586: 685
+    587: 686
+    588: 687
+    589: 688
+    590: 689
+    591: 690
+    592: 691
+    593: 692
+    594: 693
+    595: 694
+    596: 695
+    597: 696
+    598: 697
+    599: 698
+    600: 699
+    601: 700
+    602: 701
+    603: 702
+    604: 703
+    605: 704
+    606: 705
+    607: 706
+    608: 707
+    609: 708
+    610: 709
+    611: 710
+    612: 711
+    613: 712
+    614: 713
+    615: 714
+    616: 715
+    617: 716
+    618: 717
+    619: 718
+    620: 719
+    621: 720
+    622: 721
+    623: 722
+    624: 723
+    625: 724
+    626: 725
+    627: 726
+    628: 727
+    629: 728
+    630: 729
+    631: 730
+    632: 731
+    633: 732
+    634: 733
+    635: 734
+    636: 735
+    637: 736
+    638: 737
+    639: 738
+    640: 739
+    641: 740
+    642: 741
+    643: 742
+    644: 743
+    645: 744
+    646: 745
+    647: 746
+    648: 747
+    649: 748
+    650: 749
+    651: 750
+    652: 751
+    653: 752
+    654: 753
+    655: 754
+    656: 755
+    657: 756
+    658: 757
+    659: 758
+    660: 759
+    661: 760
+    662: 761
+    663: 762
+    664: 763
+    665: 764
+    666: 765
+    667: 766
+    668: 767
+    669: 768
+    670: 769
+    671: 770
+    672: 771
+    673: 772
+    674: 773
+    675: 774
+    676: 775
+    677: 776
+    678: 777
+    679: 778
+    680: 779
+    681: 780
+    682: 781
+    683: 782
+    684: 783
+    685: 784
+    686: 785
+    687: 786
+    688: 787
+    689: 788
+    690: 789
+    691: 790
+    692: 791
+    693: 792
+    694: 793
+    695: 794
+    696: 795
+    697: 796
+    698: 797
+    699: 798
+    700: 799
+    701: 800
+    702: 801
+    703: 802
+    704: 803
+    705: 804
+    706: 805
+    707: 806
+    708: 807
+    709: 808
+    710: 809
+    711: 810
+    712: 811
+    713: 812
+    714: 813
+    715: 814
+    716: 815
+    717: 816
+    718: 817
+    719: 818
+    720: 819
+    721: 820
+    722: 821
+    723: 822
+    724: 823
+    725: 824
+    726: 825
+    727: 826
+    728: 827
+    729: 828
+    730: 829
+    731: 830
+    732: 831
+    733: 832
+    734: 833
+    735: 834
+    736: 835
+    737: 836
+    738: 837
+    739: 838
+    740: 839
+    741: 840
+    742: 841
+    743: 842
+    744: 843
+    745: 844
+    746: 845
+    747: 846
+    748: 847
+    749: 848
+    750: 849
+    751: 850
+    752: 851
+    753: 852
+    754: 853
+    755: 854
+    756: 855
+    757: 856
+    758: 857
+    759: 858
+    760: 859
+    761: 860
+    762: 861
+    763: 862
+    764: 863
+    765: 864
+    766: 865
+    767: 866
+    768: 867
+    769: 868
+    770: 869
+    771: 870
+    772: 871
+    773: 872
+    774: 873
+    775: 874
+    776: 875
+    777: 876
+    778: 877
+    779: 878
+    780: 879
+    781: 880
+    782: 881
+    783: 882
+    784: 883
+    785: 884
+    786: 885
+    787: 886
+    788: 887
+    789: 888
+    790: 889
+    791: 890
+    792: 891
+    793: 892
+    794: 893
+    795: 894
+    796: 895
+    797: 896
+    798: 897
+    799: 898
+    800: 899
+    801: 900
+    802: 901
+    803: 902
+    804: 903
+    805: 904
+    806: 905
+    807: 906
+    808: 907
+    809: 908
+    810: 909
+    811: 910
+    812: 911
+    813: 912
+    814: 913
+    815: 914
+    816: 915
+    817: 916
+    818: 917
+    819: 918
+    820: 919
+    821: 920
+    822: 921
+    823: 922
+    824: 923
+    825: 924
+    826: 925
+    827: 926
+    828: 927
+    829: 928
+    830: 929
+    831: 930
+    832: 931
+    833: 932
+    834: 933
+    835: 934
+    836: 935
+    837: 936
+    838: 937
+    839: 938
+    840: 939
+    841: 940
+    842: 941
+    843: 942
+    844: 943
+    845: 944
+    846: 945
+    847: 946
+    848: 947
+    849: 948
+    850: 949
+    851: 950
+    852: 951
+    853: 952
+    854: 953
+    855: 954
+    856: 955
+    857: 956
+    858: 957
+    859: 958
+    860: 959
+    861: 960
+    862: 961
+    863: 962
+    864: 963
+    865: 964
+    866: 965
+    867: 966
+    868: 967
+    869: 968
+    870: 969
+    871: 970
+    872: 971
+    873: 972
+    874: 973
+    875: 974
+    876: 975
+    877: 976
+    878: 977
+    879: 978
+    880: 979
+    881: 980
+    882: 981
+    883: 982
+    884: 983
+    885: 984
+    886: 985
+    887: 986
+    888: 987
+    889: 988
+    890: 989
+    891: 990
+    892: 991
+    893: 992
+    894: 993
+    895: 994
+    896: 995
+    897: 996
+    898: 997
+    899: 998
+    900: 999
+    0: subview 'v2'
+   VIEW     4 rows = _B:V
+      0: subview '_B'
+     VIEW   999 rows = _H:I _R:I
+        0: 0 -1
+        1: 0 -1
+        2: -1461104643 430
+        3: 0 -1
+        4: 0 -1
+        5: 1034993658 780
+        6: 777013241 36
+        7: 608274424 551
+        8: 0 -1
+        9: -1460496394 19
+       10: 0 -1
+       11: 0 -1
+       12: 1035601907 881
+       13: 0 -1
+       14: 0 -1
+       15: 1799477232 164
+       16: 0 -1
+       17: 0 -1
+       18: 0 -1
+       19: -696012820 427
+       20: -683483157 154
+       21: 0 -1
+       22: 1800085481 265
+       23: 0 -1
+       24: -268685337 757
+       25: 0 -1
+       26: -695404571 16
+       27: -953384988 296
+       28: 0 -1
+       29: 338980834 282
+       30: 81000417 562
+       31: 1373974496 137
+       32: -1987770401 30
+       33: -694796322 629
+       34: 0 -1
+       35: 0 -1
+       36: 339589083 383
+       37: 0 -1
+       38: 0 -1
+       39: 1103464408 690
+       40: 0 -1
+       41: -965306410 158
+       42: 0 -1
+       43: 69687252 13
+       44: 1530791891 508
+       45: 0 -1
+       46: 1104072657 791
+       47: 0 -1
+       48: -964698161 259
+       49: 0 -1
+       50: 0 -1
+       51: -1649397812 822
+       52: 0 -1
+       53: 0 -1
+       54: 846700489 148
+       55: 677961672 663
+       56: -1222070329 640
+       57: -1390809146 131
+       58: 0 -1
+       59: 0 -1
+       60: 0 -1
+       61: -1999083582 505
+       62: 0 -1
+       63: 1869164480 276
+       64: 0 -1
+       65: -199606338 768
+       66: 0 -1
+       67: -626325572 539
+       68: 834779067 10
+       69: 576798650 290
+       70: 1869772729 377
+       71: 0 -1
+       72: -198998089 869
+       73: 0 -1
+       74: 0 -1
+       75: -883697740 408
+       76: 0 -1
+       77: 0 -1
+       78: 1599262641 418
+       79: 0 -1
+       80: -1918083153 142
+       81: 0 -1
+       82: 565485485 253
+       83: 0 -1
+       84: 0 -1
+       85: 1599870890 7
+       86: 0 -1
+       87: 0 -1
+       88: 0 -1
+       89: -895619162 270
+       90: -1153599579 550
+       91: 139374500 125
+       92: 0 -1
+       93: 1342498722 900
+       94: 0 -1
+       95: -1930612832 415
+       96: -895010913 371
+       97: 0 -1
+       98: 0 -1
+       99: -131135588 678
+      100: -1503285349 745
+      101: 0 -1
+      102: -1930004583 4
+      103: 0 -1
+      104: 296191895 496
+      105: 0 -1
+      106: -130527339 779
+      107: 0 -1
+      108: 0 -1
+      109: -1929396334 617
+      110: 0 -1
+      111: 0 -1
+      112: 0 -1
+      113: 0 -1
+      114: -387899507 136
+      115: -556638324 651
+      116: 0 -1
+      117: 646485898 402
+      118: 0 -1
+      119: -1164912760 1
+      120: 0 -1
+      121: 1061283718 493
+      122: 0 -1
+      123: 634564484 264
+      124: 2095669123 247
+      125: 0 -1
+      126: 1668949889 530
+      127: 1410969472 810
+      128: 0 -1
+      129: 0 -1
+      130: 635172733 365
+      131: 0 -1
+      132: 1838296955 628
+      133: 1669558138 119
+      134: 0 -1
+      135: 0 -1
+      136: 0 -1
+      137: 0 -1
+      138: -1083912331 662
+      139: 0 -1
+      140: 0 -1
+      141: -1434206350 756
+      142: 0 -1
+      143: -1860925584 527
+      144: 0 -1
+      145: 0 -1
+      146: 0 -1
+      147: -61448340 790
+      148: -1433598101 857
+      149: 0 -1
+      150: 0 -1
+      151: -2118297752 396
+      152: 0 -1
+      153: 107898726 888
+      154: -60840091 891
+      155: 0 -1
+      156: 1142284131 130
+      157: 0 -1
+      158: -669114527 241
+      159: 0 -1
+      160: 1557081951 733
+      161: 0 -1
+      162: 0 -1
+      163: 0 -1
+      164: 0 -1
+      165: -2130219174 258
+      166: 0 -1
+      167: -1095225512 113
+      168: 0 -1
+      169: 1130970966 605
+      170: 0 -1
+      171: 0 -1
+      172: -2129610925 359
+      173: 0 -1
+      174: 0 -1
+      175: 0 -1
+      176: 0 -1
+      177: -588114098 390
+      178: 0 -1
+      179: 0 -1
+      180: -938408117 484
+      181: 0 -1
+      182: -1365127351 767
+      183: 0 -1
+      184: 861069127 235
+      185: 0 -1
+      186: 434349893 518
+      187: 176369476 798
+      188: 0 -1
+      189: 0 -1
+      190: -1622499519 124
+      191: -1791238336 639
+      192: 603696959 616
+      193: 434958142 107
+      194: 0 -1
+      195: 0 -1
+      196: 0 -1
+      197: -173316294 481
+      198: 0 -1
+      199: -600035528 252
+      200: 0 -1
+      201: 1626160950 744
+      202: 0 -1
+      203: 1199441716 515
+      204: 0 -1
+      205: 0 -1
+      206: -599427279 353
+      207: 0 -1
+      208: 1626769199 845
+      209: 0 -1
+      210: 0 -1
+      211: 942069548 384
+      212: 0 -1
+      213: 0 -1
+      214: 1976454953 650
+      215: 0 -1
+      216: -92315865 118
+      217: 0 -1
+      218: -1903714523 229
+      219: 0 -1
+      220: 0 -1
+      221: 0 -1
+      222: 0 -1
+      223: -1296048352 778
+      224: 0 -1
+      225: 930148126 246
+      226: 0 -1
+      227: 1965141788 101
+      228: 0 -1
+      229: -1126701286 876
+      230: -1295440103 879
+      231: 0 -1
+      232: 930756375 347
+      233: 0 -1
+      234: 0 -1
+      235: 0 -1
+      236: 322481939 721
+      237: 0 -1
+      238: 0 -1
+      239: 0 -1
+      240: 2121959183 472
+      241: 0 -1
+      242: 1695239949 755
+      243: 0 -1
+      244: 0 -1
+      245: -103629046 593
+      246: 0 -1
+      247: 0 -1
+      248: 0 -1
+      249: 0 -1
+      250: 1437867781 112
+      251: 1269128964 627
+      252: 0 -1
+      253: -1822714110 378
+      254: 0 -1
+      255: 0 -1
+      256: 0 -1
+      257: -1407916290 469
+      258: 0 -1
+      259: -1834635524 240
+      260: -373530885 223
+      261: 0 -1
+      262: -800250119 506
+      263: 0 -1
+      264: 0 -1
+      265: 0 -1
+      266: -1834027275 341
+      267: 0 -1
+      268: -630903053 604
+      269: -799641870 95
+      270: 0 -1
+      271: 0 -1
+      272: 0 -1
+      273: 0 -1
+      274: 741854957 638
+      275: 0 -1
+      276: 0 -1
+      277: 391560938 732
+      278: 0 -1
+      279: -35158296 503
+      280: 0 -1
+      281: 0 -1
+      282: 0 -1
+      283: 1764318948 766
+      284: 392169187 833
+      285: 0 -1
+      286: 0 -1
+      287: -292530464 372
+      288: 0 -1
+      289: 1933666014 864
+      290: 1764927197 867
+      291: 0 -1
+      292: -1326915877 106
+      293: 0 -1
+      294: 1156652761 217
+      295: 0 -1
+      296: -912118057 709
+      297: 0 -1
+      298: 0 -1
+      299: 0 -1
+      300: 0 -1
+      301: -304451886 234
+      302: 0 -1
+      303: 730541776 89
+      304: 0 -1
+      305: -1338229042 581
+      306: 0 -1
+      307: 0 -1
+      308: -303843637 335
+      309: 0 -1
+      310: 0 -1
+      311: -988543288 898
+      312: 0 -1
+      313: 1237653190 366
+      314: 0 -1
+      315: 0 -1
+      316: 887359171 460
+      317: 0 -1
+      318: 460639937 743
+      319: 0 -1
+      320: -1608130881 211
+      321: 0 -1
+      322: -2034850115 494
+      323: 0 -1
+      324: 0 -1
+      325: 0 -1
+      326: 203267769 100
+      327: 34528952 615
+      328: -1865503049 592
+      329: -2034241866 83
+      330: 0 -1
+      331: 0 -1
+      332: 0 -1
+      333: 1652450994 457
+      334: 0 -1
+      335: 1225731760 228
+      336: 0 -1
+      337: -843039058 720
+      338: 0 -1
+      339: -1269758292 491
+      340: 0 -1
+      341: 0 -1
+      342: 1226340009 329
+      343: 0 -1
+      344: -842430809 821
+      345: 0 -1
+      346: 0 -1
+      347: -1527130460 360
+      348: 0 -1
+      349: 0 -1
+      350: -492745055 626
+      351: 0 -1
+      352: 1733451423 94
+      353: 0 -1
+      354: -77947235 205
+      355: 0 -1
+      356: 0 -1
+      357: 0 -1
+      358: 0 -1
+      359: 529718936 754
+      360: 0 -1
+      361: -1539051882 222
+      362: 0 -1
+      363: -504058220 77
+      364: 0 -1
+      365: 699066002 852
+      366: 530327185 855
+      367: 0 -1
+      368: -1538443633 323
+      369: 0 -1
+      370: 0 -1
+      371: 2071824012 886
+      372: -2146718069 697
+      373: 0 -1
+      374: 0 -1
+      375: 0 -1
+      376: -347240825 448
+      377: 0 -1
+      378: -773960059 731
+      379: 0 -1
+      380: 0 -1
+      381: 1722138242 569
+      382: 0 -1
+      383: 0 -1
+      384: 0 -1
+      385: 0 -1
+      386: -1031332227 88
+      387: -1200071044 603
+      388: 0 -1
+      389: 3053178 354
+      390: 0 -1
+      391: 0 -1
+      392: 0 -1
+      393: 417850998 445
+      394: 0 -1
+      395: -8868236 216
+      396: 1452236403 199
+      397: 0 -1
+      398: 1025517169 482
+      399: 0 -1
+      400: 0 -1
+      401: 0 -1
+      402: -8259987 317
+      403: 0 -1
+      404: 1194864235 580
+      405: 1026125418 71
+      406: 0 -1
+      407: 0 -1
+      408: 0 -1
+      409: 0 -1
+      410: -1727345051 614
+      411: 0 -1
+      412: 0 -1
+      413: -2077639070 708
+      414: 0 -1
+      415: 1790608992 479
+      416: 0 -1
+      417: 0 -1
+      418: 0 -1
+      419: -704881060 742
+      420: -2077030821 809
+      421: 0 -1
+      422: 0 -1
+      423: 1533236824 348
+      424: 0 -1
+      425: -535533994 840
+      426: -704272811 843
+      427: 0 -1
+      428: 498851411 82
+      429: 0 -1
+      430: -1312547247 193
+      431: 0 -1
+      432: 913649231 685
+      433: 0 -1
+      434: 0 -1
+      435: 0 -1
+      436: 0 -1
+      437: 1521315402 210
+      438: 0 -1
+      439: -1738658232 65
+      440: 0 -1
+      441: 487538246 557
+      442: 0 -1
+      443: 0 -1
+      444: 1521923651 311
+      445: 0 -1
+      446: 0 -1
+      447: 837224000 874
+      448: 0 -1
+      449: -1231546818 342
+      450: 0 -1
+      451: 0 -1
+      452: -1581840837 436
+      453: 0 -1
+      454: -2008560071 719
+      455: 0 -1
+      456: 217636407 187
+      457: 0 -1
+      458: -209082827 470
+      459: 0 -1
+      460: 0 -1
+      461: 0 -1
+      462: 2029035057 76
+      463: 1860296240 591
+      464: -39735761 568
+      465: -208474578 59
+      466: 0 -1
+      467: 0 -1
+      468: 0 -1
+      469: -816749014 433
+      470: 0 -1
+      471: -1243468248 204
+      472: 0 -1
+      473: 982728230 696
+      474: 0 -1
+      475: 556008996 467
+      476: 0 -1
+      477: 0 -1
+      478: -1242859999 305
+      479: 0 -1
+      480: 983336479 797
+      481: 0 -1
+      482: 0 -1
+      483: 298636828 336
+      484: 0 -1
+      485: 0 -1
+      486: 1333022233 602
+      487: 0 -1
+      488: -735748585 70
+      489: 0 -1
+      490: 1747820053 181
+      491: 0 -1
+      492: 0 -1
+      493: 0 -1
+      494: 0 -1
+      495: -1939481072 730
+      496: 0 -1
+      497: 286715406 198
+      498: 0 -1
+      499: 1321709068 53
+      500: 0 -1
+      501: -1770134006 828
+      502: -1938872823 831
+      503: 0 -1
+      504: 287323655 299
+      505: 0 -1
+      506: 0 -1
+      507: -397375996 862
+      508: -320950781 673
+      509: 0 -1
+      510: 0 -1
+      511: 0 -1
+      512: 1478526463 424
+      513: 0 -1
+      514: 1051807229 707
+      515: 0 -1
+      516: 0 -1
+      517: -747061766 545
+      518: 0 -1
+      519: 0 -1
+      520: 0 -1
+      521: 0 -1
+      522: 794435061 64
+      523: 625696244 579
+      524: 0 -1
+      525: 1828820466 330
+      526: 0 -1
+      527: 0 -1
+      528: 0 -1
+      529: -2051349010 421
+      530: 0 -1
+      531: 1816899052 192
+      532: -1016963605 175
+      533: 0 -1
+      534: -1443682839 458
+      535: 0 -1
+      536: 0 -1
+      537: 0 -1
+      538: 1817507301 293
+      539: 0 -1
+      540: -1274335773 556
+      541: -1443074590 47
+      542: 0 -1
+      543: 0 -1
+      544: 0 -1
+      545: 0 -1
+      546: 98422237 590
+      547: 0 -1
+      548: 0 -1
+      549: -251871782 684
+      550: 0 -1
+      551: -678591016 455
+      552: 357010903 411
+      553: 0 -1
+      554: 0 -1
+      555: 1120886228 718
+      556: -251263533 785
+      557: 0 -1
+      558: 0 -1
+      559: -935963184 324
+      560: 1548213711 536
+      561: 1290233294 816
+      562: 1121494477 819
+      563: 0 -1
+      564: -1970348597 58
+      565: -677374518 657
+      566: 513220041 169
+      567: 0 -1
+      568: 0 -1
+      569: 0 -1
+      570: 0 -1
+      571: 0 -1
+      572: 0 -1
+      573: -947884606 186
+      574: 0 -1
+      575: 87109056 41
+      576: 0 -1
+      577: -1981661762 533
+      578: 0 -1
+      579: 0 -1
+      580: -947276357 287
+      581: 0 -1
+      582: 0 -1
+      583: -1631976008 850
+      584: 0 -1
+      585: 594220470 318
+      586: 1887194549 405
+      587: 0 -1
+      588: -1204648525 668
+      589: 0 -1
+      590: -182792783 695
+      591: 0 -1
+      592: 2043403695 163
+      593: 0 -1
+      594: 1616684461 446
+      595: 0 -1
+      596: 0 -1
+      597: -182184534 796
+      598: -440164951 52
+      599: -608903768 567
+      600: 1786031527 544
+      601: 1617292710 35
+      602: 0 -1
+      603: 0 -1
+      604: -181576285 897
+      605: 0 -1
+      606: 0 -1
+      607: 582299040 180
+      608: 0 -1
+      609: -1486471778 672
+      610: 0 -1
+      611: -1913191012 443
+      612: 0 -1
+      613: 0 -1
+      614: 582907289 281
+      615: 0 -1
+      616: -1485863529 773
+      617: 0 -1
+      618: 0 -1
+      619: 2124404116 312
+      620: 0 -1
+      621: 0 -1
+      622: -1136177775 578
+      623: 156796304 153
+      624: 1090018703 46
+      625: -1911974514 645
+      626: -721379955 157
+      627: 0 -1
+      628: -877589109 399
+      629: 0 -1
+      630: 0 -1
+      631: -113713784 706
+      632: 0 -1
+      633: 2112482694 174
+      634: 0 -1
+      635: -1147490940 29
+      636: 313613699 524
+      637: 55633282 804
+      638: -113105535 807
+      639: 0 -1
+      640: 2113090943 275
+      641: 0 -1
+      642: 0 -1
+      643: 1428391292 838
+      644: 0 -1
+      645: 0 -1
+      646: 0 -1
+      647: 0 -1
+      648: 1855718775 656
+      649: 1686979958 147
+      650: -1417392779 683
+      651: 0 -1
+      652: 0 -1
+      653: 1078705522 521
+      654: 0 -1
+      655: 0 -1
+      656: 0 -1
+      657: -1416784530 784
+      658: -1674764947 40
+      659: -1843503764 555
+      660: -382399125 26
+      661: -640379542 306
+      662: 652594537 393
+      663: 0 -1
+      664: -1416176281 885
+      665: 0 -1
+      666: 0 -1
+      667: -652300956 168
+      668: 0 -1
+      669: 0 -1
+      670: 382084449 434
+      671: 0 -1
+      672: -1686686369 0
+      673: 0 -1
+      674: -651692707 269
+      675: 0 -1
+      676: 0 -1
+      677: 382692698 23
+      678: 0 -1
+      679: 0 -1
+      680: 0 -1
+      681: 0 -1
+      682: 1924189525 566
+      683: -1077803692 141
+      684: 0 -1
+      685: 0 -1
+      686: 0 -1
+      687: 1147176272 431
+      688: -2112189105 387
+      689: 0 -1
+      690: 0 -1
+      691: -1348313780 694
+      692: 1574503755 761
+      693: 0 -1
+      694: 1147784521 20
+      695: 889804104 300
+      696: -920986297 512
+      697: 0 -1
+      698: -1347705531 795
+      699: 0 -1
+      700: -144581309 34
+      701: 1148392770 633
+      702: 0 -1
+      703: 0 -1
+      704: 0 -1
+      705: 0 -1
+      706: -1605077699 152
+      707: -1773816516 667
+      708: 0 -1
+      709: 877882682 162
+      710: 0 -1
+      711: 1912876344 17
+      712: 0 -1
+      713: -155894474 509
+      714: 0 -1
+      715: -582613708 280
+      716: 878490931 263
+      717: 0 -1
+      718: 0 -1
+      719: 193791280 826
+      720: -1616999121 14
+      721: -1874979538 294
+      722: -582005459 381
+      723: 0 -1
+      724: 621118763 644
+      725: 452379946 135
+      726: 1642974505 671
+      727: 0 -1
+      728: 0 -1
+      729: 0 -1
+      730: -852515547 422
+      731: 0 -1
+      732: 0 -1
+      733: 1643582754 772
+      734: 0 -1
+      735: 1216863520 543
+      736: 0 -1
+      737: -851907298 11
+      738: 0 -1
+      739: 0 -1
+      740: 1644191003 873
+      741: 0 -1
+      742: 0 -1
+      743: 959491352 412
+      744: 0 -1
+      745: 0 -1
+      746: 0 -1
+      747: -87423724 419
+      748: -74894061 146
+      749: 0 -1
+      750: -1886292719 257
+      751: 0 -1
+      752: 339903759 749
+      753: 0 -1
+      754: -86815475 8
+      755: -344795892 288
+      756: 0 -1
+      757: 947569930 274
+      758: 689589513 554
+      759: 1982563592 129
+      760: 0 -1
+      761: -86207226 621
+      762: 0 -1
+      763: 0 -1
+      764: 948178179 375
+      765: 0 -1
+      766: 0 -1
+      767: 1712053504 682
+      768: 0 -1
+      769: -1805292290 406
+      770: 0 -1
+      771: 678276348 5
+      772: 2139380987 500
+      773: 0 -1
+      774: 1712661753 783
+      775: 0 -1
+      776: -356109065 251
+      777: 0 -1
+      778: -782828299 534
+      779: -1040808716 814
+      780: 0 -1
+      781: 0 -1
+      782: 1455289585 140
+      783: 1286550768 655
+      784: -613481233 632
+      785: -782220050 123
+      786: 0 -1
+      787: 0 -1
+      788: 0 -1
+      789: -1390494486 497
+      790: 0 -1
+      791: -1817213720 268
+      792: 0 -1
+      793: 408982758 760
+      794: 0 -1
+      795: -17736476 531
+      796: 1443368163 2
+      797: 0 -1
+      798: -1816605471 369
+      799: 0 -1
+      800: 409591007 861
+      801: 0 -1
+      802: 0 -1
+      803: -275108644 400
+      804: 0 -1
+      805: 0 -1
+      806: 759276761 666
+      807: 0 -1
+      808: -1309494057 134
+      809: 0 -1
+      810: 1174074581 245
+      811: 0 -1
+      812: 0 -1
+      813: 0 -1
+      814: 0 -1
+      815: 1781740752 794
+      816: 0 -1
+      817: -287030066 262
+      818: -545010483 542
+      819: 747963596 117
+      820: 0 -1
+      821: 1951087818 892
+      822: 1782349001 895
+      823: 0 -1
+      824: -286421817 363
+      825: 0 -1
+      826: 0 -1
+      827: 477453508 670
+      828: -894696253 737
+      829: 0 -1
+      830: 0 -1
+      831: 0 -1
+      832: 904780991 488
+      833: 0 -1
+      834: 478061757 771
+      835: 0 -1
+      836: 0 -1
+      837: -1320807238 609
+      838: 0 -1
+      839: 0 -1
+      840: 0 -1
+      841: 0 -1
+      842: 220689589 128
+      843: 51950772 643
+      844: 0 -1
+      845: 1255074994 394
+      846: 0 -1
+      847: 0 -1
+      848: 0 -1
+      849: 1669872814 485
+      850: 0 -1
+      851: 1243153580 256
+      852: -1590709077 239
+      853: 0 -1
+      854: -2017428311 522
+      855: 2019558568 802
+      856: 0 -1
+      857: 0 -1
+      858: 1243761829 357
+      859: 0 -1
+      860: -1848081245 620
+      861: -2016820062 111
+      862: 0 -1
+      863: 0 -1
+      864: 0 -1
+      865: 0 -1
+      866: -475323235 654
+      867: 0 -1
+      868: 0 -1
+      869: -825617254 748
+      870: 0 -1
+      871: -1252336488 519
+      872: 0 -1
+      873: 0 -1
+      874: 0 -1
+      875: 547140756 782
+      876: -825009005 849
+      877: 0 -1
+      878: 0 -1
+      879: -1509708656 388
+      880: 0 -1
+      881: 716487822 880
+      882: 547749005 883
+      883: 0 -1
+      884: 1750873227 122
+      885: 0 -1
+      886: -60525431 233
+      887: 0 -1
+      888: -2129296249 725
+      889: 0 -1
+      890: 0 -1
+      891: 0 -1
+      892: 0 -1
+      893: -1521630078 250
+      894: 0 -1
+      895: -486636416 105
+      896: 0 -1
+      897: 1739560062 597
+      898: 0 -1
+      899: 0 -1
+      900: -1521021829 351
+      901: 0 -1
+      902: 0 -1
+      903: 0 -1
+      904: 0 -1
+      905: 20474998 382
+      906: 0 -1
+      907: 0 -1
+      908: -329819021 476
+      909: 0 -1
+      910: -756538255 759
+      911: 0 -1
+      912: 1469658223 227
+      913: 0 -1
+      914: 1042938989 510
+      915: 0 -1
+      916: 0 -1
+      917: 0 -1
+      918: -1013910423 116
+      919: -1182649240 631
+      920: 1212286055 608
+      921: 1043547238 99
+      922: 0 -1
+      923: 0 -1
+      924: 0 -1
+      925: 435272802 473
+      926: 0 -1
+      927: 8553568 244
+      928: 0 -1
+      929: -2060217250 736
+      930: 0 -1
+      931: 1808030812 507
+      932: 0 -1
+      933: 0 -1
+      934: 9161817 345
+      935: 0 -1
+      936: -2059609001 837
+      937: 0 -1
+      938: 0 -1
+      939: 1550658644 376
+      940: 0 -1
+      941: 0 -1
+      942: -1709923247 642
+      943: 0 -1
+      944: 516273231 110
+      945: 0 -1
+      946: -1295125427 221
+      947: 0 -1
+      948: 0 -1
+      949: 0 -1
+      950: 0 -1
+      951: -687459256 770
+      952: 0 -1
+      953: 1538737222 238
+      954: 0 -1
+      955: -1721236412 93
+      956: 0 -1
+      957: -518112190 868
+      958: -686851007 871
+      959: 0 -1
+      960: 1539345471 339
+      961: 0 -1
+      962: 0 -1
+      963: 0 -1
+      964: 931071035 713
+      965: 0 -1
+      966: 0 -1
+      967: 0 -1
+      968: -1564419017 464
+      969: 0 -1
+      970: -1991138251 747
+      971: 0 -1
+      972: 0 -1
+      973: 504960050 585
+      974: 0 -1
+      975: 0 -1
+      976: 0 -1
+      977: 0 -1
+      978: 2046456877 104
+      979: 1877718060 619
+      980: 0 -1
+      981: -1214125014 370
+      982: 0 -1
+      983: 0 -1
+      984: 0 -1
+      985: -799327194 461
+      986: 0 -1
+      987: -1226046428 232
+      988: 235058211 215
+      989: 0 -1
+      990: -191661023 498
+      991: 0 -1
+      992: 0 -1
+      993: 0 -1
+      994: -1225438179 333
+      995: 0 -1
+      996: -22313957 596
+      997: -191052774 87
+      998: 0 -1
+      1: subview '_B'
+     VIEW    47 rows = _H:I _R:I
+        0: 0 -1
+        1: 0 -1
+        2: 1350444053 630
+        3: 0 -1
+        4: 0 -1
+        5: 1000150034 724
+        6: 0 -1
+        7: 573430800 495
+        8: 0 -1
+        9: 0 -1
+       10: 0 -1
+       11: -1922059252 758
+       12: 1000758283 825
+       13: 0 -1
+       14: 0 -1
+       15: 316058632 364
+       16: 0 -1
+       17: -1752712186 856
+       18: -1921451003 859
+       19: 0 -1
+       20: -718326781 98
+       21: 0 -1
+       22: 1765241857 209
+       23: 0 -1
+       24: -303528961 701
+       25: 0 -1
+       26: 0 -1
+       27: 0 -1
+       28: 0 -1
+       29: 304137210 226
+       30: 0 -1
+       31: 1339130872 81
+       32: 0 -1
+       33: -729639946 573
+       34: 0 -1
+       35: 0 -1
+       36: 304745459 327
+       37: 0 -1
+       38: 0 -1
+       39: -379954192 890
+       40: 0 -1
+       41: 1846242286 358
+       42: 0 -1
+       43: 0 -1
+       44: 1495948267 452
+       45: 0 -1
+       46: 1069229033 735
+      2: subview '_B'
+     VIEW  1001 rows = _H:I _R:I
+        0: -999541785 203
+        1: 0 -1
+        2: -1426261019 486
+        3: 0 -1
+        4: 0 -1
+        5: 0 -1
+        6: 811856865 92
+        7: 643118048 607
+        8: -1256913953 584
+        9: -1425652770 75
+       10: 0 -1
+       11: 0 -1
+       12: 0 -1
+       13: -2033927206 449
+       14: 0 -1
+       15: 1834320856 220
+       16: 0 -1
+       17: -234449962 712
+       18: 0 -1
+       19: -661169196 483
+       20: 0 -1
+       21: 0 -1
+       22: 1834929105 321
+       23: 0 -1
+       24: -233841713 813
+       25: 0 -1
+       26: 0 -1
+       27: -918541364 352
+       28: 0 -1
+       29: 0 -1
+       30: 115844041 618
+       31: 0 -1
+       32: -1952926777 86
+       33: 0 -1
+       34: 530641861 197
+       35: 0 -1
+       36: 0 -1
+       37: 0 -1
+       38: 0 -1
+       39: 1138308032 746
+       40: 0 -1
+       41: -930462786 214
+       42: 0 -1
+       43: 104530876 69
+       44: 0 -1
+       45: 1307655098 844
+       46: 1138916281 847
+       47: 0 -1
+       48: -929854537 315
+       49: 0 -1
+       50: 0 -1
+       51: -1614554188 878
+       52: -1538128973 689
+       53: 0 -1
+       54: 0 -1
+       55: 0 -1
+       56: 261348271 440
+       57: 0 -1
+       58: -165370963 723
+       59: 0 -1
+       60: 0 -1
+       61: -1964239958 561
+       62: 0 -1
+       63: 0 -1
+       64: 0 -1
+       65: 0 -1
+       66: -422743131 80
+       67: -591481948 595
+       68: 0 -1
+       69: 611642274 346
+       70: 0 -1
+       71: 0 -1
+       72: 0 -1
+       73: 1026440094 437
+       74: 0 -1
+       75: 599720860 208
+       76: 2060825499 191
+       77: 0 -1
+       78: 1634106265 474
+       79: 0 -1
+       80: 0 -1
+       81: 0 -1
+       82: 600329109 309
+       83: 0 -1
+       84: 1803453331 572
+       85: 1634714514 63
+       86: 0 -1
+       87: 0 -1
+       88: 0 -1
+       89: 0 -1
+       90: -1118755955 606
+       91: 0 -1
+       92: 0 -1
+       93: -1469049974 700
+       94: 0 -1
+       95: -1895769208 471
+       96: 0 -1
+       97: 0 -1
+       98: 0 -1
+       99: -96291964 734
+      100: -1468441725 801
+      101: 0 -1
+      102: 0 -1
+      103: 2141825920 340
+      104: 0 -1
+      105: 73055102 832
+      106: -95683715 835
+      107: 0 -1
+      108: 1107440507 74
+      109: 0 -1
+      110: -703958151 185
+      111: 0 -1
+      112: 1522238327 677
+      113: 0 -1
+      114: 0 -1
+      115: 0 -1
+      116: 0 -1
+      117: 2129904498 202
+      118: 0 -1
+      119: -1130069136 57
+      120: 0 -1
+      121: 1096127342 549
+      122: 0 -1
+      123: 0 -1
+      124: 2130512747 303
+      125: 0 -1
+      126: 0 -1
+      127: 1445813096 866
+      128: 0 -1
+      129: -622957722 334
+      130: 0 -1
+      131: 0 -1
+      132: -973251741 428
+      133: 0 -1
+      134: -1399970975 711
+      135: 0 -1
+      136: 826225503 179
+      137: 0 -1
+      138: 399506269 462
+      139: 0 -1
+      140: 0 -1
+      141: 0 -1
+      142: -1657343143 68
+      143: -1826081960 583
+      144: 568853335 560
+      145: 400114518 51
+      146: 0 -1
+      147: 0 -1
+      148: 0 -1
+      149: -208159918 425
+      150: 0 -1
+      151: -634879152 196
+      152: 0 -1
+      153: 1591317326 688
+      154: 0 -1
+      155: 1164598092 459
+      156: 0 -1
+      157: 0 -1
+      158: -634270903 297
+      159: 0 -1
+      160: 1591925575 789
+      161: 0 -1
+      162: 0 -1
+      163: 907225924 328
+      164: 0 -1
+      165: 0 -1
+      166: 1941611329 594
+      167: 0 -1
+      168: -127159489 62
+      169: 1165814590 661
+      170: -1938558147 173
+      171: 0 -1
+      172: 0 -1
+      173: 0 -1
+      174: 0 -1
+      175: -1330891976 722
+      176: 0 -1
+      177: 895304502 190
+      178: 0 -1
+      179: 1930298164 45
+      180: -903564493 540
+      181: -1161544910 820
+      182: -1330283727 823
+      183: 0 -1
+      184: 895912751 291
+      185: 0 -1
+      186: 0 -1
+      187: 211213100 854
+      188: 0 -1
+      189: 0 -1
+      190: 0 -1
+      191: 0 -1
+      192: 2087115559 416
+      193: 0 -1
+      194: 1660396325 699
+      195: 0 -1
+      196: 0 -1
+      197: -138472670 537
+      198: 0 -1
+      199: 0 -1
+      200: 0 -1
+      201: 0 -1
+      202: 1403024157 56
+      203: 1234285340 571
+      204: 0 -1
+      205: -1857557734 322
+      206: -564583655 409
+      207: 0 -1
+      208: 0 -1
+      209: -1442759914 413
+      210: 0 -1
+      211: -1869479148 184
+      212: -408374509 167
+      213: 0 -1
+      214: -835093743 450
+      215: 0 -1
+      216: 0 -1
+      217: 0 -1
+      218: -1868870899 285
+      219: 0 -1
+      220: -665746677 548
+      221: -834485494 39
+      222: 0 -1
+      223: 0 -1
+      224: 0 -1
+      225: 0 -1
+      226: 707011333 582
+      227: 0 -1
+      228: 0 -1
+      229: 356717314 676
+      230: 0 -1
+      231: -70001920 447
+      232: 965599999 403
+      233: 0 -1
+      234: 0 -1
+      235: 1729475324 710
+      236: 357325563 777
+      237: 0 -1
+      238: 0 -1
+      239: -327374088 316
+      240: -2138164489 528
+      241: 1898822390 808
+      242: 1730083573 811
+      243: 0 -1
+      244: -1361759501 50
+      245: -68785422 649
+      246: 1121809137 161
+      247: 0 -1
+      248: 0 -1
+      249: 0 -1
+      250: 0 -1
+      251: 0 -1
+      252: 0 -1
+      253: -339295510 178
+      254: 0 -1
+      255: 695698152 33
+      256: 0 -1
+      257: -1373072666 525
+      258: 0 -1
+      259: 0 -1
+      260: -338687261 279
+      261: 0 -1
+      262: 0 -1
+      263: -1023386912 842
+      264: 0 -1
+      265: 1202809566 310
+      266: -1799183651 397
+      267: 0 -1
+      268: -596059429 660
+      269: -764798246 151
+      270: 425796313 687
+      271: 0 -1
+      272: 0 -1
+      273: 0 -1
+      274: -2069693739 438
+      275: 0 -1
+      276: 0 -1
+      277: 426404562 788
+      278: 168424145 44
+      279: -314672 559
+      280: 0 -1
+      281: -2069085490 27
+      282: 0 -1
+      283: 0 -1
+      284: 427012811 889
+      285: 0 -1
+      286: 0 -1
+      287: 1190888136 172
+      288: 0 -1
+      289: 0 -1
+      290: 0 -1
+      291: -1304601916 435
+      292: 0 -1
+      293: 0 -1
+      294: 1191496385 273
+      295: 0 -1
+      296: -877274433 765
+      297: 0 -1
+      298: -1303993667 24
+      299: -1561974084 304
+      300: 0 -1
+      301: 0 -1
+      302: -527588679 570
+      303: 765385400 145
+      304: 1698607799 38
+      305: -1303385418 637
+      306: 0 -1
+      307: 0 -1
+      308: -269000013 391
+      309: 0 -1
+      310: 0 -1
+      311: 494875312 698
+      312: 0 -1
+      313: -1573895506 166
+      314: 0 -1
+      315: -538901844 21
+      316: 922202795 516
+      317: 0 -1
+      318: 495483561 799
+      319: 0 -1
+      320: -1573287257 267
+      321: 0 -1
+      322: 0 -1
+      323: 2036980388 830
+      324: 0 -1
+      325: 0 -1
+      326: 238111393 156
+      327: 0 -1
+      328: -1830659425 648
+      329: -1999398242 139
+      330: -808803683 675
+      331: 0 -1
+      332: 0 -1
+      333: 1687294618 513
+      334: 0 -1
+      335: 1260575384 284
+      336: 0 -1
+      337: -808195434 776
+      338: -1066175851 32
+      339: -1234914668 547
+      340: 226189971 18
+      341: -31790446 298
+      342: 1261183633 385
+      343: 0 -1
+      344: -807587185 877
+      345: 0 -1
+      346: 0 -1
+      347: -43711860 160
+      348: 0 -1
+      349: 0 -1
+      350: 990673545 426
+      351: 0 -1
+      352: 1768295047 150
+      353: 0 -1
+      354: -43103611 261
+      355: 0 -1
+      356: 0 -1
+      357: 991281794 15
+      358: 0 -1
+      359: 0 -1
+      360: 0 -1
+      361: -1504208258 278
+      362: -1762188675 558
+      363: -469214596 133
+      364: 0 -1
+      365: 0 -1
+      366: 0 -1
+      367: 1755765368 423
+      368: -1503600009 379
+      369: 0 -1
+      370: 0 -1
+      371: -739724684 686
+      372: -2111874445 753
+      373: 0 -1
+      374: 1756373617 12
+      375: 1498393200 292
+      376: -312397201 504
+      377: 0 -1
+      378: -739116435 787
+      379: 0 -1
+      380: 0 -1
+      381: 1756981866 625
+      382: 0 -1
+      383: 0 -1
+      384: 0 -1
+      385: 0 -1
+      386: -996488603 144
+      387: -1165227420 659
+      388: 0 -1
+      389: 37896802 410
+      390: 0 -1
+      391: -1773501856 9
+      392: 0 -1
+      393: 452694622 501
+      394: 0 -1
+      395: 25975388 272
+      396: 1487080027 255
+      397: 0 -1
+      398: 1060360793 538
+      399: 802380376 818
+      400: -1008410025 6
+      401: -1266390442 286
+      402: 26583637 373
+      403: 0 -1
+      404: 1229707859 636
+      405: 1060969042 127
+      406: 0 -1
+      407: 0 -1
+      408: 0 -1
+      409: 0 -1
+      410: -243926451 414
+      411: 0 -1
+      412: 0 -1
+      413: -2042795446 764
+      414: 0 -1
+      415: 1825452616 535
+      416: 0 -1
+      417: -243318202 3
+      418: 0 -1
+      419: 0 -1
+      420: -2042187197 865
+      421: 0 -1
+      422: 0 -1
+      423: 1568080448 404
+      424: 0 -1
+      425: -500690370 896
+      426: -669429187 899
+      427: 0 -1
+      428: 533695035 138
+      429: 0 -1
+      430: -1277703623 249
+      431: 0 -1
+      432: 948492855 741
+      433: 0 -1
+      434: 0 -1
+      435: 0 -1
+      436: 0 -1
+      437: 1556159026 266
+      438: 1298178609 546
+      439: -1703814608 121
+      440: 0 -1
+      441: 522381870 613
+      442: 0 -1
+      443: 0 -1
+      444: 1556767275 367
+      445: 0 -1
+      446: 0 -1
+      447: -1974324696 674
+      448: 0 -1
+      449: -1196703194 398
+      450: 0 -1
+      451: 0 -1
+      452: -1546997213 492
+      453: 0 -1
+      454: -1973716447 775
+      455: 0 -1
+      456: 252480031 243
+      457: 0 -1
+      458: -174239203 526
+      459: -432219620 806
+      460: 0 -1
+      461: 0 -1
+      462: 2063878681 132
+      463: 1895139864 647
+      464: -4892137 624
+      465: -173630954 115
+      466: 0 -1
+      467: 0 -1
+      468: 0 -1
+      469: -781905390 489
+      470: 0 -1
+      471: -1208624624 260
+      472: 0 -1
+      473: 1017571854 752
+      474: 0 -1
+      475: 590852620 523
+      476: 0 -1
+      477: 0 -1
+      478: -1208016375 361
+      479: 0 -1
+      480: 1018180103 853
+      481: 0 -1
+      482: 0 -1
+      483: 333480452 392
+      484: 0 -1
+      485: 0 -1
+      486: 1367865857 658
+      487: 0 -1
+      488: -700904961 126
+      489: 0 -1
+      490: 1782663677 237
+      491: 0 -1
+      492: 0 -1
+      493: 0 -1
+      494: 0 -1
+      495: -1904637448 786
+      496: 0 -1
+      497: 321559030 254
+      498: 0 -1
+      499: 1356552692 109
+      500: 0 -1
+      501: -1735290382 884
+      502: -1904029199 887
+      503: 0 -1
+      504: 322167279 355
+      505: 0 -1
+      506: 0 -1
+      507: 0 -1
+      508: -286107157 729
+      509: 0 -1
+      510: 0 -1
+      511: 0 -1
+      512: 1513370087 480
+      513: 0 -1
+      514: 1086650853 763
+      515: 0 -1
+      516: 0 -1
+      517: -712218142 601
+      518: 0 -1
+      519: 0 -1
+      520: 0 -1
+      521: 0 -1
+      522: 829278685 120
+      523: 660539868 635
+      524: 0 -1
+      525: 1863664090 386
+      526: 0 -1
+      527: 0 -1
+      528: 0 -1
+      529: -2016505386 477
+      530: 0 -1
+      531: 1851742676 248
+      532: -982119981 231
+      533: 0 -1
+      534: -1408839215 514
+      535: 0 -1
+      536: 0 -1
+      537: 0 -1
+      538: 1852350925 349
+      539: 0 -1
+      540: -1239492149 612
+      541: -1408230966 103
+      542: 0 -1
+      543: 0 -1
+      544: 0 -1
+      545: 0 -1
+      546: 133265861 646
+      547: 0 -1
+      548: 0 -1
+      549: -217028158 740
+      550: 0 -1
+      551: -643747392 511
+      552: 0 -1
+      553: 0 -1
+      554: 0 -1
+      555: 1155729852 774
+      556: -216419909 841
+      557: 0 -1
+      558: 0 -1
+      559: -901119560 380
+      560: 0 -1
+      561: 1325076918 872
+      562: 1156338101 875
+      563: 0 -1
+      564: -1935504973 114
+      565: 0 -1
+      566: 548063665 225
+      567: 0 -1
+      568: -1520707153 717
+      569: 0 -1
+      570: 0 -1
+      571: 0 -1
+      572: 0 -1
+      573: -913040982 242
+      574: 0 -1
+      575: 121952680 97
+      576: 0 -1
+      577: -1946818138 589
+      578: 0 -1
+      579: 0 -1
+      580: -912432733 343
+      581: 0 -1
+      582: 0 -1
+      583: 0 -1
+      584: 0 -1
+      585: 629064094 374
+      586: 0 -1
+      587: 0 -1
+      588: 278770075 468
+      589: 0 -1
+      590: -147949159 751
+      591: 0 -1
+      592: 2078247319 219
+      593: 0 -1
+      594: 1651528085 502
+      595: 0 -1
+      596: 0 -1
+      597: 0 -1
+      598: -405321327 108
+      599: -574060144 623
+      600: 1820875151 600
+      601: 1652136334 91
+      602: 0 -1
+      603: 0 -1
+      604: 0 -1
+      605: 1043861898 465
+      606: 0 -1
+      607: 617142664 236
+      608: 0 -1
+      609: -1451628154 728
+      610: 0 -1
+      611: -1878347388 499
+      612: 0 -1
+      613: 0 -1
+      614: 617750913 337
+      615: 0 -1
+      616: -1451019905 829
+      617: 0 -1
+      618: 0 -1
+      619: -2135719556 368
+      620: 0 -1
+      621: 0 -1
+      622: -1101334151 634
+      623: 0 -1
+      624: 1124862327 102
+      625: 0 -1
+      626: -686536331 213
+      627: 0 -1
+      628: 0 -1
+      629: 0 -1
+      630: 0 -1
+      631: -78870160 762
+      632: 0 -1
+      633: 2147326318 230
+      634: 0 -1
+      635: -1112647316 85
+      636: 0 -1
+      637: 90476906 860
+      638: -78261911 863
+      639: 0 -1
+      640: -2147032729 331
+      641: 0 -1
+      642: 0 -1
+      643: 1463234916 894
+      644: 1539660131 705
+      645: 0 -1
+      646: 0 -1
+      647: 0 -1
+      648: -955829921 456
+      649: 0 -1
+      650: -1382549155 739
+      651: 0 -1
+      652: 0 -1
+      653: 1113549146 577
+      654: 0 -1
+      655: 0 -1
+      656: 0 -1
+      657: 0 -1
+      658: -1639921323 96
+      659: -1808660140 611
+      660: 0 -1
+      661: -605535918 362
+      662: 0 -1
+      663: 0 -1
+      664: 0 -1
+      665: -190738098 453
+      666: 0 -1
+      667: -617457332 224
+      668: 843647307 207
+      669: 0 -1
+      670: 416928073 490
+      671: 0 -1
+      672: 0 -1
+      673: 0 -1
+      674: -616849083 325
+      675: 0 -1
+      676: 586275139 588
+      677: 417536322 79
+      678: 0 -1
+      679: 0 -1
+      680: 0 -1
+      681: 0 -1
+      682: 1959033149 622
+      683: 0 -1
+      684: 0 -1
+      685: 1608739130 716
+      686: 0 -1
+      687: 1182019896 487
+      688: 0 -1
+      689: 0 -1
+      690: 0 -1
+      691: -1313470156 750
+      692: 1609347379 817
+      693: 0 -1
+      694: 0 -1
+      695: 924647728 356
+      696: 0 -1
+      697: -1144123090 848
+      698: -1312861907 851
+      699: 0 -1
+      700: -109737685 90
+      701: 0 -1
+      702: -1921136343 201
+      703: 0 -1
+      704: 305060135 693
+      705: 0 -1
+      706: 0 -1
+      707: 0 -1
+      708: 0 -1
+      709: 912726306 218
+      710: 0 -1
+      711: 1947719968 73
+      712: 0 -1
+      713: -121050850 565
+      714: 0 -1
+      715: 0 -1
+      716: 913334555 319
+      717: 0 -1
+      718: 0 -1
+      719: 228634904 882
+      720: 0 -1
+      721: -1840135914 350
+      722: 0 -1
+      723: 0 -1
+      724: 2104537363 444
+      725: 0 -1
+      726: 1677818129 727
+      727: 0 -1
+      728: -390952689 195
+      729: 0 -1
+      730: -817671923 478
+      731: 0 -1
+      732: 0 -1
+      733: 0 -1
+      734: 1420445961 84
+      735: 1251707144 599
+      736: -648324857 576
+      737: -817063674 67
+      738: 0 -1
+      739: 0 -1
+      740: 0 -1
+      741: -1425338110 441
+      742: 0 -1
+      743: -1852057344 212
+      744: 0 -1
+      745: 374139134 704
+      746: 0 -1
+      747: -52580100 475
+      748: 0 -1
+      749: 0 -1
+      750: -1851449095 313
+      751: 0 -1
+      752: 374747383 805
+      753: 0 -1
+      754: 0 -1
+      755: -309952268 344
+      756: 0 -1
+      757: 0 -1
+      758: 724433137 610
+      759: 0 -1
+      760: -1344337681 78
+      761: 0 -1
+      762: 1139230957 189
+      763: 0 -1
+      764: 0 -1
+      765: 0 -1
+      766: 0 -1
+      767: 1746897128 738
+      768: 0 -1
+      769: -321873690 206
+      770: 0 -1
+      771: 713119972 61
+      772: 0 -1
+      773: 1916244194 836
+      774: 1747505377 839
+      775: 0 -1
+      776: -321265441 307
+      777: 0 -1
+      778: 0 -1
+      779: -1005965092 870
+      780: -929539877 681
+      781: 0 -1
+      782: 0 -1
+      783: 0 -1
+      784: 869937367 432
+      785: 0 -1
+      786: 443218133 715
+      787: 0 -1
+      788: 0 -1
+      789: -1355650862 553
+      790: 0 -1
+      791: 0 -1
+      792: 0 -1
+      793: 0 -1
+      794: 185845965 72
+      795: 17107148 587
+      796: 0 -1
+      797: 1220231370 338
+      798: 0 -1
+      799: 0 -1
+      800: 0 -1
+      801: 1635029190 429
+      802: 0 -1
+      803: 1208309956 200
+      804: -1625552701 183
+      805: 0 -1
+      806: -2052271935 466
+      807: 0 -1
+      808: 0 -1
+      809: 0 -1
+      810: 1208918205 301
+      811: 0 -1
+      812: -1882924869 564
+      813: -2051663686 55
+      814: 0 -1
+      815: 0 -1
+      816: 0 -1
+      817: 0 -1
+      818: -510166859 598
+      819: 0 -1
+      820: 0 -1
+      821: -860460878 692
+      822: 0 -1
+      823: -1287180112 463
+      824: 0 -1
+      825: 0 -1
+      826: 0 -1
+      827: 512297132 726
+      828: -859852629 793
+      829: 0 -1
+      830: 0 -1
+      831: -1544552280 332
+      832: 0 -1
+      833: 681644198 824
+      834: 512905381 827
+      835: 0 -1
+      836: 1716029603 66
+      837: -1285963614 665
+      838: -95369055 177
+      839: 0 -1
+      840: 2130827423 669
+      841: 0 -1
+      842: 0 -1
+      843: 0 -1
+      844: 0 -1
+      845: -1556473702 194
+      846: 0 -1
+      847: -521480040 49
+      848: 0 -1
+      849: 1704716438 541
+      850: 0 -1
+      851: 0 -1
+      852: -1555865453 295
+      853: 0 -1
+      854: 0 -1
+      855: 2054402192 858
+      856: 0 -1
+      857: -14368626 326
+      858: 0 -1
+      859: 0 -1
+      860: -364662645 420
+      861: 0 -1
+      862: -791381879 703
+      863: 0 -1
+      864: 1434814599 171
+      865: 0 -1
+      866: 1008095365 454
+      867: 0 -1
+      868: 0 -1
+      869: 0 -1
+      870: -1048754047 60
+      871: -1217492864 575
+      872: 1177442431 552
+      873: 1008703614 43
+      874: 0 -1
+      875: 0 -1
+      876: 0 -1
+      877: 400429178 417
+      878: 0 -1
+      879: -26290056 188
+      880: 0 -1
+      881: -2095060874 680
+      882: 0 -1
+      883: 1773187188 451
+      884: 0 -1
+      885: 0 -1
+      886: -25681807 289
+      887: 0 -1
+      888: -2094452625 781
+      889: 0 -1
+      890: 0 -1
+      891: 1515815020 320
+      892: 0 -1
+      893: 0 -1
+      894: -1744766871 586
+      895: 0 -1
+      896: 481429607 54
+      897: 1774403686 653
+      898: -1329969051 165
+      899: 0 -1
+      900: -1486178205 407
+      901: 0 -1
+      902: 0 -1
+      903: -722302880 714
+      904: 0 -1
+      905: 1503893598 182
+      906: 0 -1
+      907: -1756080036 37
+      908: -294975397 532
+      909: -552955814 812
+      910: -721694631 815
+      911: 0 -1
+      912: 1504501847 283
+      913: 0 -1
+      914: 0 -1
+      915: 819802196 846
+      916: 0 -1
+      917: 0 -1
+      918: 0 -1
+      919: 0 -1
+      920: 1247129679 664
+      921: 1078390862 155
+      922: -2025981875 691
+      923: 0 -1
+      924: 0 -1
+      925: 470116426 529
+      926: 0 -1
+      927: 0 -1
+      928: 0 -1
+      929: -2025373626 792
+      930: 2011613253 48
+      931: 1842874436 563
+      932: 0 -1
+      933: -1248968638 314
+      934: 44005441 401
+      935: 0 -1
+      936: -2024765377 893
+      937: 0 -1
+      938: 0 -1
+      939: -1260890052 176
+      940: 200214587 159
+      941: 0 -1
+      942: -226504647 442
+      943: 0 -1
+      944: 0 -1
+      945: 0 -1
+      946: -1260281803 277
+      947: 0 -1
+      948: 0 -1
+      949: -225896398 31
+      950: 0 -1
+      951: 0 -1
+      952: 0 -1
+      953: 0 -1
+      954: 1315600429 574
+      955: -1686392788 149
+      956: 0 -1
+      957: 0 -1
+      958: 0 -1
+      959: 538587176 439
+      960: 1574189095 395
+      961: 0 -1
+      962: 0 -1
+      963: -1956902876 702
+      964: 965914659 769
+      965: 0 -1
+      966: 539195425 28
+      967: 281215008 308
+      968: -1529575393 520
+      969: -1787555810 800
+      970: -1956294627 803
+      971: 0 -1
+      972: -753170405 42
+      973: 539803674 641
+      974: 0 -1
+      975: 0 -1
+      976: 0 -1
+      977: 0 -1
+      978: 0 -1
+      979: 0 -1
+      980: 0 -1
+      981: 269293586 170
+      982: 0 -1
+      983: 1304287248 25
+      984: 0 -1
+      985: -764483570 517
+      986: 0 -1
+      987: 0 -1
+      988: 269901835 271
+      989: 0 -1
+      990: 0 -1
+      991: -414797816 834
+      992: 2069379079 22
+      993: 1811398662 302
+      994: -1190594555 389
+      995: 0 -1
+      996: 12529667 652
+      997: -156209150 143
+      998: 1034385409 679
+      999: 0 -1
+     1000: 2053 0
+      3: subview '_B'
+     VIEW     2 rows = _H:I _R:I
+        0: 0 -1
+        1: 0 -1
diff --git a/8.x/mk/tests/ok/m07.txt b/8.x/mk/tests/ok/m07.txt
new file mode 100644 (file)
index 0000000..aac9208
--- /dev/null
@@ -0,0 +1,63 @@
+>>> All blocked view multi-deletion cases
+blockdel pos 0 len 1
+blockdel pos 0 len 2
+blockdel pos 0 len 3
+blockdel pos 0 len 998
+blockdel pos 0 len 999
+blockdel pos 0 len 1000
+blockdel pos 0 len 1001
+blockdel pos 0 len 1998
+blockdel pos 0 len 1999
+blockdel pos 0 len 2000
+blockdel pos 0 len 2001
+blockdel pos 1 len 1
+blockdel pos 1 len 2
+blockdel pos 1 len 3
+blockdel pos 1 len 998
+blockdel pos 1 len 999
+blockdel pos 1 len 1000
+blockdel pos 1 len 1001
+blockdel pos 1 len 1998
+blockdel pos 1 len 1999
+blockdel pos 1 len 2000
+blockdel pos 1 len 2001
+blockdel pos 998 len 1
+blockdel pos 998 len 2
+blockdel pos 998 len 3
+blockdel pos 998 len 998
+blockdel pos 998 len 999
+blockdel pos 998 len 1000
+blockdel pos 998 len 1001
+blockdel pos 999 len 1
+blockdel pos 999 len 2
+blockdel pos 999 len 3
+blockdel pos 999 len 998
+blockdel pos 999 len 999
+blockdel pos 999 len 1000
+blockdel pos 999 len 1001
+blockdel pos 1000 len 1
+blockdel pos 1000 len 2
+blockdel pos 1000 len 3
+blockdel pos 1000 len 998
+blockdel pos 1000 len 999
+blockdel pos 1000 len 1000
+blockdel pos 1000 len 1001
+blockdel pos 1001 len 1
+blockdel pos 1001 len 2
+blockdel pos 1001 len 3
+blockdel pos 1001 len 998
+blockdel pos 1001 len 999
+blockdel pos 1001 len 1000
+blockdel pos 1001 len 1001
+blockdel pos 2998 len 1
+blockdel pos 2997 len 2
+blockdel pos 2996 len 3
+blockdel pos 2001 len 998
+blockdel pos 2000 len 999
+blockdel pos 1999 len 1000
+blockdel pos 1998 len 1001
+blockdel pos 1001 len 1998
+blockdel pos 1000 len 1999
+blockdel pos 999 len 2000
+blockdel pos 998 len 2001
+<<< done.
diff --git a/8.x/mk/tests/ok/n01.txt b/8.x/mk/tests/ok/n01.txt
new file mode 100644 (file)
index 0000000..28b1981
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Add to selection
+<<< done.
diff --git a/8.x/mk/tests/ok/n02.txt b/8.x/mk/tests/ok/n02.txt
new file mode 100644 (file)
index 0000000..a912aae
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Remove from selection
+<<< done.
diff --git a/8.x/mk/tests/ok/n03.txt b/8.x/mk/tests/ok/n03.txt
new file mode 100644 (file)
index 0000000..5934324
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Modify into selection
+<<< done.
diff --git a/8.x/mk/tests/ok/n04.txt b/8.x/mk/tests/ok/n04.txt
new file mode 100644 (file)
index 0000000..efb9601
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Modify out of selection
+<<< done.
diff --git a/8.x/mk/tests/ok/n05.txt b/8.x/mk/tests/ok/n05.txt
new file mode 100644 (file)
index 0000000..bc40bea
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Add to sorted
+<<< done.
diff --git a/8.x/mk/tests/ok/n06.txt b/8.x/mk/tests/ok/n06.txt
new file mode 100644 (file)
index 0000000..f8c499a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Remove from sorted
+<<< done.
diff --git a/8.x/mk/tests/ok/n07.txt b/8.x/mk/tests/ok/n07.txt
new file mode 100644 (file)
index 0000000..87ff412
--- /dev/null
@@ -0,0 +1,2 @@
+>>> New property through sort
+<<< done.
diff --git a/8.x/mk/tests/ok/n08.txt b/8.x/mk/tests/ok/n08.txt
new file mode 100644 (file)
index 0000000..0939301
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Nested project and select
+<<< done.
diff --git a/8.x/mk/tests/ok/n09.txt b/8.x/mk/tests/ok/n09.txt
new file mode 100644 (file)
index 0000000..0732f42
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Multiple dependencies
+<<< done.
diff --git a/8.x/mk/tests/ok/n10.txt b/8.x/mk/tests/ok/n10.txt
new file mode 100644 (file)
index 0000000..8c1f92d
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Modify sorted duplicates
+<<< done.
diff --git a/8.x/mk/tests/ok/n11.txt b/8.x/mk/tests/ok/n11.txt
new file mode 100644 (file)
index 0000000..07d6ebd
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Resize compound derived view
+<<< done.
diff --git a/8.x/mk/tests/ok/n12.txt b/8.x/mk/tests/ok/n12.txt
new file mode 100644 (file)
index 0000000..fa19439
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Alter multiply derived view
+<<< done.
diff --git a/8.x/mk/tests/ok/n13.txt b/8.x/mk/tests/ok/n13.txt
new file mode 100755 (executable)
index 0000000..e9ba290
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Project without
+<<< done.
diff --git a/8.x/mk/tests/ok/n14.txt b/8.x/mk/tests/ok/n14.txt
new file mode 100644 (file)
index 0000000..2522115
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Insert in non-mapped position
+<<< done.
diff --git a/8.x/mk/tests/ok/n14a.txt b/8.x/mk/tests/ok/n14a.txt
new file mode 100644 (file)
index 0000000..ef5e47a
--- /dev/null
@@ -0,0 +1,15 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW    12 rows = p1:I
+      0: 0
+      1: 1
+      2: 2
+      3: 6
+      4: 0
+      5: 1
+      6: 2
+      7: 1
+      8: 0
+      9: 1
+     10: 2
+     11: 0
diff --git a/8.x/mk/tests/ok/r00.txt b/8.x/mk/tests/ok/r00.txt
new file mode 100644 (file)
index 0000000..c2dd0e8
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Simple insert
+<<< done.
diff --git a/8.x/mk/tests/ok/r00a.txt b/8.x/mk/tests/ok/r00a.txt
new file mode 100755 (executable)
index 0000000..16475db
--- /dev/null
@@ -0,0 +1,253 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW   250 rows = p1:I
+      0: 1
+      1: 2
+      2: 3
+      3: 4
+      4: 5
+      5: 6
+      6: 7
+      7: 8
+      8: 9
+      9: 10
+     10: 11
+     11: 12
+     12: 13
+     13: 14
+     14: 15
+     15: 16
+     16: 17
+     17: 18
+     18: 19
+     19: 20
+     20: 21
+     21: 22
+     22: 23
+     23: 24
+     24: 25
+     25: 26
+     26: 27
+     27: 28
+     28: 29
+     29: 30
+     30: 31
+     31: 32
+     32: 33
+     33: 34
+     34: 35
+     35: 36
+     36: 37
+     37: 38
+     38: 39
+     39: 40
+     40: 41
+     41: 42
+     42: 43
+     43: 44
+     44: 45
+     45: 46
+     46: 47
+     47: 48
+     48: 49
+     49: 50
+     50: 51
+     51: 52
+     52: 53
+     53: 54
+     54: 55
+     55: 56
+     56: 57
+     57: 58
+     58: 59
+     59: 60
+     60: 61
+     61: 62
+     62: 63
+     63: 64
+     64: 65
+     65: 66
+     66: 67
+     67: 68
+     68: 69
+     69: 70
+     70: 71
+     71: 72
+     72: 73
+     73: 74
+     74: 75
+     75: 76
+     76: 77
+     77: 78
+     78: 79
+     79: 80
+     80: 81
+     81: 82
+     82: 83
+     83: 84
+     84: 85
+     85: 86
+     86: 87
+     87: 88
+     88: 89
+     89: 90
+     90: 91
+     91: 92
+     92: 93
+     93: 94
+     94: 95
+     95: 96
+     96: 97
+     97: 98
+     98: 99
+     99: 100
+    100: 101
+    101: 102
+    102: 103
+    103: 104
+    104: 105
+    105: 106
+    106: 107
+    107: 108
+    108: 109
+    109: 110
+    110: 111
+    111: 112
+    112: 113
+    113: 114
+    114: 115
+    115: 116
+    116: 117
+    117: 118
+    118: 119
+    119: 120
+    120: 121
+    121: 122
+    122: 123
+    123: 1
+    124: 2
+    125: 3
+    126: 4
+    127: 5
+    128: 6
+    129: 7
+    130: 8
+    131: 9
+    132: 10
+    133: 11
+    134: 12
+    135: 13
+    136: 14
+    137: 15
+    138: 16
+    139: 17
+    140: 18
+    141: 19
+    142: 20
+    143: 21
+    144: 22
+    145: 23
+    146: 24
+    147: 25
+    148: 26
+    149: 27
+    150: 28
+    151: 29
+    152: 30
+    153: 31
+    154: 32
+    155: 33
+    156: 34
+    157: 35
+    158: 36
+    159: 37
+    160: 38
+    161: 39
+    162: 40
+    163: 41
+    164: 42
+    165: 43
+    166: 44
+    167: 45
+    168: 46
+    169: 47
+    170: 48
+    171: 49
+    172: 50
+    173: 51
+    174: 52
+    175: 53
+    176: 54
+    177: 55
+    178: 56
+    179: 57
+    180: 58
+    181: 59
+    182: 60
+    183: 61
+    184: 62
+    185: 63
+    186: 64
+    187: 65
+    188: 66
+    189: 67
+    190: 68
+    191: 69
+    192: 70
+    193: 71
+    194: 72
+    195: 73
+    196: 74
+    197: 75
+    198: 76
+    199: 77
+    200: 78
+    201: 79
+    202: 80
+    203: 81
+    204: 82
+    205: 83
+    206: 84
+    207: 85
+    208: 86
+    209: 87
+    210: 88
+    211: 89
+    212: 90
+    213: 91
+    214: 92
+    215: 93
+    216: 94
+    217: 95
+    218: 96
+    219: 97
+    220: 98
+    221: 99
+    222: 100
+    223: 101
+    224: 102
+    225: 103
+    226: 104
+    227: 105
+    228: 106
+    229: 107
+    230: 108
+    231: 109
+    232: 110
+    233: 111
+    234: 112
+    235: 113
+    236: 114
+    237: 115
+    238: 116
+    239: 117
+    240: 118
+    241: 119
+    242: 120
+    243: 121
+    244: 122
+    245: 123
+    246: 1
+    247: 2
+    248: 3
+    249: 4
diff --git a/8.x/mk/tests/ok/r01.txt b/8.x/mk/tests/ok/r01.txt
new file mode 100644 (file)
index 0000000..092f02c
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Simple removes
+<<< done.
diff --git a/8.x/mk/tests/ok/r01a.txt b/8.x/mk/tests/ok/r01a.txt
new file mode 100755 (executable)
index 0000000..65a6851
--- /dev/null
@@ -0,0 +1,18 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW    15 rows = p1:I
+      0: 9
+      1: 10
+      2: 11
+      3: 12
+      4: 13
+      5: 14
+      6: 15
+      7: 16
+      8: 17
+      9: 18
+     10: 19
+     11: 20
+     12: 21
+     13: 22
+     14: 23
diff --git a/8.x/mk/tests/ok/r02.txt b/8.x/mk/tests/ok/r02.txt
new file mode 100644 (file)
index 0000000..9f5b549
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Large inserts and removes
+<<< done.
diff --git a/8.x/mk/tests/ok/r02a.txt b/8.x/mk/tests/ok/r02a.txt
new file mode 100755 (executable)
index 0000000..c86766a
--- /dev/null
@@ -0,0 +1,8 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     5 rows = p1:I
+      0: 37
+      1: 38
+      2: 39
+      3: 95
+      4: 96
diff --git a/8.x/mk/tests/ok/r03.txt b/8.x/mk/tests/ok/r03.txt
new file mode 100644 (file)
index 0000000..34f35e9
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Binary property insertions
+<<< done.
diff --git a/8.x/mk/tests/ok/r03a.txt b/8.x/mk/tests/ok/r03a.txt
new file mode 100755 (executable)
index 0000000..a99e46a
--- /dev/null
@@ -0,0 +1,8 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     5 rows = p1:B
+      0: (1024b)
+      1: (256b)
+      2: (1024b)
+      3: (1024b)
+      4: (341b)
diff --git a/8.x/mk/tests/ok/r04.txt b/8.x/mk/tests/ok/r04.txt
new file mode 100644 (file)
index 0000000..60404b7
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Scripted string property tests
+<<< done.
diff --git a/8.x/mk/tests/ok/r04a.txt b/8.x/mk/tests/ok/r04a.txt
new file mode 100755 (executable)
index 0000000..88ad826
--- /dev/null
@@ -0,0 +1,3 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     0 rows = p1:S
diff --git a/8.x/mk/tests/ok/reversed.txt b/8.x/mk/tests/ok/reversed.txt
new file mode 100755 (executable)
index 0000000..59ba292
--- /dev/null
@@ -0,0 +1,14 @@
+ VIEW     1 rows = address:V info:V
+    0: subview 'address'
+   VIEW     8 rows = name:S country:S age:I
+      0: 'John Williams' 'UK' 0
+      1: 'Paco Pena' 'Spain' 44
+      2: 'Julian Bream' '' 50
+      3: 'Julian Bream' '' 0
+      4: 'Julien Coco' 'Netherlands' 0
+      5: 'John Williams' 'UK' 0
+      6: 'Paco Pena' 'Spain' 0
+      7: 'Julien Coco' 'Netherlands' 0
+    0: subview 'info'
+   VIEW     1 rows = version:I
+      0: 100
diff --git a/8.x/mk/tests/ok/s00.txt b/8.x/mk/tests/ok/s00.txt
new file mode 100644 (file)
index 0000000..24df9e2
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Simple storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s00a.txt b/8.x/mk/tests/ok/s00a.txt
new file mode 100755 (executable)
index 0000000..0872f93
--- /dev/null
@@ -0,0 +1,3 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     0 rows = p1:I
diff --git a/8.x/mk/tests/ok/s01.txt b/8.x/mk/tests/ok/s01.txt
new file mode 100644 (file)
index 0000000..b5d4741
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Integer storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s01a.txt b/8.x/mk/tests/ok/s01a.txt
new file mode 100755 (executable)
index 0000000..b393bf2
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:I
+      0: 123
+      1: 789
+      2: 456
diff --git a/8.x/mk/tests/ok/s02.txt b/8.x/mk/tests/ok/s02.txt
new file mode 100644 (file)
index 0000000..7ec87fa
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Float storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s02a.txt b/8.x/mk/tests/ok/s02a.txt
new file mode 100755 (executable)
index 0000000..6a561a5
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:F
+      0: 12.3
+      1: 78.9
+      2: 45.6
diff --git a/8.x/mk/tests/ok/s03.txt b/8.x/mk/tests/ok/s03.txt
new file mode 100644 (file)
index 0000000..307fb2a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> String storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s03a.txt b/8.x/mk/tests/ok/s03a.txt
new file mode 100755 (executable)
index 0000000..83b6946
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:S
+      0: 'one'
+      1: 'three'
+      2: 'two'
diff --git a/8.x/mk/tests/ok/s04.txt b/8.x/mk/tests/ok/s04.txt
new file mode 100644 (file)
index 0000000..2a6472b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s04a.txt b/8.x/mk/tests/ok/s04a.txt
new file mode 100755 (executable)
index 0000000..2b6800f
--- /dev/null
@@ -0,0 +1,18 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:S p2:V
+      0: 'one'
+      0: subview 'p2'
+     VIEW     1 rows = p3:I
+        0: 1
+      1: 'three'
+      1: subview 'p2'
+     VIEW     3 rows = p3:I
+        0: 111
+        1: 222
+        2: 333
+      2: 'two'
+      2: subview 'p2'
+     VIEW     2 rows = p3:I
+        0: 11
+        1: 22
diff --git a/8.x/mk/tests/ok/s05.txt b/8.x/mk/tests/ok/s05.txt
new file mode 100644 (file)
index 0000000..625769c
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Store and reload
+<<< done.
diff --git a/8.x/mk/tests/ok/s05a.txt b/8.x/mk/tests/ok/s05a.txt
new file mode 100755 (executable)
index 0000000..fb8a3f1
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/s06.txt b/8.x/mk/tests/ok/s06.txt
new file mode 100644 (file)
index 0000000..6246a47
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Commit twice
+<<< done.
diff --git a/8.x/mk/tests/ok/s06a.txt b/8.x/mk/tests/ok/s06a.txt
new file mode 100755 (executable)
index 0000000..5688100
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = p1:I
+      0: 123
+      1: 234
diff --git a/8.x/mk/tests/ok/s07.txt b/8.x/mk/tests/ok/s07.txt
new file mode 100644 (file)
index 0000000..93559f6
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Commit modified
+<<< done.
diff --git a/8.x/mk/tests/ok/s07a.txt b/8.x/mk/tests/ok/s07a.txt
new file mode 100755 (executable)
index 0000000..80140cf
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 234
diff --git a/8.x/mk/tests/ok/s08.txt b/8.x/mk/tests/ok/s08.txt
new file mode 100644 (file)
index 0000000..cd8f897
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View after storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s08a.txt b/8.x/mk/tests/ok/s08a.txt
new file mode 100755 (executable)
index 0000000..fb8a3f1
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/s09.txt b/8.x/mk/tests/ok/s09.txt
new file mode 100644 (file)
index 0000000..9599ae1
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Copy storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s09a.txt b/8.x/mk/tests/ok/s09a.txt
new file mode 100755 (executable)
index 0000000..fb8a3f1
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/s09b.txt b/8.x/mk/tests/ok/s09b.txt
new file mode 100755 (executable)
index 0000000..fb8a3f1
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/s10.txt b/8.x/mk/tests/ok/s10.txt
new file mode 100644 (file)
index 0000000..03f9bed
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Stream storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s10a.txt b/8.x/mk/tests/ok/s10a.txt
new file mode 100755 (executable)
index 0000000..2b6800f
--- /dev/null
@@ -0,0 +1,18 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:S p2:V
+      0: 'one'
+      0: subview 'p2'
+     VIEW     1 rows = p3:I
+        0: 1
+      1: 'three'
+      1: subview 'p2'
+     VIEW     3 rows = p3:I
+        0: 111
+        1: 222
+        2: 333
+      2: 'two'
+      2: subview 'p2'
+     VIEW     2 rows = p3:I
+        0: 11
+        1: 22
diff --git a/8.x/mk/tests/ok/s10b.txt b/8.x/mk/tests/ok/s10b.txt
new file mode 100755 (executable)
index 0000000..2b6800f
--- /dev/null
@@ -0,0 +1,18 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:S p2:V
+      0: 'one'
+      0: subview 'p2'
+     VIEW     1 rows = p3:I
+        0: 1
+      1: 'three'
+      1: subview 'p2'
+     VIEW     3 rows = p3:I
+        0: 111
+        1: 222
+        2: 333
+      2: 'two'
+      2: subview 'p2'
+     VIEW     2 rows = p3:I
+        0: 11
+        1: 22
diff --git a/8.x/mk/tests/ok/s10c.txt b/8.x/mk/tests/ok/s10c.txt
new file mode 100755 (executable)
index 0000000..bb34ca0
--- /dev/null
@@ -0,0 +1,21 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     4 rows = p1:S p2:V
+      0: 'one'
+      0: subview 'p2'
+     VIEW     1 rows = p3:I
+        0: 1
+      1: 'three'
+      1: subview 'p2'
+     VIEW     3 rows = p3:I
+        0: 111
+        1: 222
+        2: 333
+      2: 'two'
+      2: subview 'p2'
+     VIEW     2 rows = p3:I
+        0: 11
+        1: 22
+      3: 'four'
+      3: subview 'p2'
+     VIEW     0 rows = p3:I
diff --git a/8.x/mk/tests/ok/s11.txt b/8.x/mk/tests/ok/s11.txt
new file mode 100644 (file)
index 0000000..fd82a16
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Commit and rollback
+<<< done.
diff --git a/8.x/mk/tests/ok/s11a.txt b/8.x/mk/tests/ok/s11a.txt
new file mode 100755 (executable)
index 0000000..fb8a3f1
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/s12.txt b/8.x/mk/tests/ok/s12.txt
new file mode 100644 (file)
index 0000000..be9ca7a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Remove subview
+<<< done.
diff --git a/8.x/mk/tests/ok/s12a.txt b/8.x/mk/tests/ok/s12a.txt
new file mode 100755 (executable)
index 0000000..9b6e95f
--- /dev/null
@@ -0,0 +1,3 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     0 rows = p1:I p2:V
diff --git a/8.x/mk/tests/ok/s13.txt b/8.x/mk/tests/ok/s13.txt
new file mode 100644 (file)
index 0000000..112c33c
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Remove middle subview
+<<< done.
diff --git a/8.x/mk/tests/ok/s13a.txt b/8.x/mk/tests/ok/s13a.txt
new file mode 100755 (executable)
index 0000000..2189bb0
--- /dev/null
@@ -0,0 +1,13 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = p1:I p2:V
+      0: 123
+      0: subview 'p2'
+     VIEW     1 rows = p3:I
+        0: 234
+      1: 125
+      1: subview 'p2'
+     VIEW     3 rows = p3:I
+        0: 456
+        1: 457
+        2: 458
diff --git a/8.x/mk/tests/ok/s14.txt b/8.x/mk/tests/ok/s14.txt
new file mode 100644 (file)
index 0000000..0e9348b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Replace attached subview
+<<< done.
diff --git a/8.x/mk/tests/ok/s14a.txt b/8.x/mk/tests/ok/s14a.txt
new file mode 100755 (executable)
index 0000000..e87913c
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I p2:V
+      0: 0
+      0: subview 'p2'
+     VIEW     0 rows = p3:I
diff --git a/8.x/mk/tests/ok/s15.txt b/8.x/mk/tests/ok/s15.txt
new file mode 100644 (file)
index 0000000..305baef
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Add after removed subviews
+<<< done.
diff --git a/8.x/mk/tests/ok/s15a.txt b/8.x/mk/tests/ok/s15a.txt
new file mode 100755 (executable)
index 0000000..9e07c88
--- /dev/null
@@ -0,0 +1,7 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I p2:V
+      0: 111
+      0: subview 'p2'
+     VIEW     1 rows = p3:I
+        0: 234
diff --git a/8.x/mk/tests/ok/s16.txt b/8.x/mk/tests/ok/s16.txt
new file mode 100644 (file)
index 0000000..27c69ca
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Add after removed ints
+<<< done.
diff --git a/8.x/mk/tests/ok/s16a.txt b/8.x/mk/tests/ok/s16a.txt
new file mode 100755 (executable)
index 0000000..fd274ae
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I p2:V
+      0: 4
+      0: subview 'p2'
+     VIEW     0 rows = p3:I
diff --git a/8.x/mk/tests/ok/s17.txt b/8.x/mk/tests/ok/s17.txt
new file mode 100644 (file)
index 0000000..9791395
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Add after removed strings
+<<< done.
diff --git a/8.x/mk/tests/ok/s17a.txt b/8.x/mk/tests/ok/s17a.txt
new file mode 100755 (executable)
index 0000000..40720e9
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:S p2:V
+      0: 'four'
+      0: subview 'p2'
+     VIEW     0 rows = p3:I
diff --git a/8.x/mk/tests/ok/s18.txt b/8.x/mk/tests/ok/s18.txt
new file mode 100644 (file)
index 0000000..5ff2d8e
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Empty storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s18a.txt b/8.x/mk/tests/ok/s18a.txt
new file mode 100755 (executable)
index 0000000..a28a7ca
--- /dev/null
@@ -0,0 +1 @@
+ VIEW     1 rows =
diff --git a/8.x/mk/tests/ok/s19.txt b/8.x/mk/tests/ok/s19.txt
new file mode 100644 (file)
index 0000000..0a9ff3a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Empty view outlives storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s19a.txt b/8.x/mk/tests/ok/s19a.txt
new file mode 100755 (executable)
index 0000000..a28a7ca
--- /dev/null
@@ -0,0 +1 @@
+ VIEW     1 rows =
diff --git a/8.x/mk/tests/ok/s20.txt b/8.x/mk/tests/ok/s20.txt
new file mode 100644 (file)
index 0000000..5124a59
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View outlives storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s20a.txt b/8.x/mk/tests/ok/s20a.txt
new file mode 100755 (executable)
index 0000000..a28a7ca
--- /dev/null
@@ -0,0 +1 @@
+ VIEW     1 rows =
diff --git a/8.x/mk/tests/ok/s21.txt b/8.x/mk/tests/ok/s21.txt
new file mode 100644 (file)
index 0000000..4b944bf
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Test demo scenario
+<<< done.
diff --git a/8.x/mk/tests/ok/s21a.txt b/8.x/mk/tests/ok/s21a.txt
new file mode 100755 (executable)
index 0000000..2da5bab
--- /dev/null
@@ -0,0 +1,10 @@
+ VIEW     1 rows = a:V b:V
+    0: subview 'a'
+   VIEW     4 rows = p1:S p2:S p3:I
+      0: 'One' 'Un' 0
+      1: 'Two' 'Deux' 123
+      2: 'Four' '' 0
+      3: 'Three' 'Trois' 0
+    0: subview 'b'
+   VIEW     1 rows = p4:I
+      0: 234
diff --git a/8.x/mk/tests/ok/s22.txt b/8.x/mk/tests/ok/s22.txt
new file mode 100644 (file)
index 0000000..8d5c2bc
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Double storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s22a.txt b/8.x/mk/tests/ok/s22a.txt
new file mode 100755 (executable)
index 0000000..03d83cf
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:D
+      0: 1234.5678
+      1: 3456.789
+      2: 2345.6789
diff --git a/8.x/mk/tests/ok/s23.txt b/8.x/mk/tests/ok/s23.txt
new file mode 100644 (file)
index 0000000..7f921bc
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Find absent record
+<<< done.
diff --git a/8.x/mk/tests/ok/s23a.txt b/8.x/mk/tests/ok/s23a.txt
new file mode 100755 (executable)
index 0000000..a28a7ca
--- /dev/null
@@ -0,0 +1 @@
+ VIEW     1 rows =
diff --git a/8.x/mk/tests/ok/s24.txt b/8.x/mk/tests/ok/s24.txt
new file mode 100644 (file)
index 0000000..91ef101
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Bitwise storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s24a.txt b/8.x/mk/tests/ok/s24a.txt
new file mode 100755 (executable)
index 0000000..37fc083
--- /dev/null
@@ -0,0 +1,45 @@
+ VIEW     1 rows = a1:V a2:V a3:V a4:V
+    0: subview 'a1'
+   VIEW     9 rows = p1:I
+      0: 1
+      1: 0
+      2: 1
+      3: 0
+      4: 1
+      5: 0
+      6: 1
+      7: 0
+      8: 1
+    0: subview 'a2'
+   VIEW     9 rows = p1:I
+      0: 3
+      1: 0
+      2: 1
+      3: 2
+      4: 3
+      5: 0
+      6: 1
+      7: 2
+      8: 3
+    0: subview 'a3'
+   VIEW     9 rows = p1:I
+      0: 7
+      1: 8
+      2: 9
+      3: 10
+      4: 11
+      5: 12
+      6: 13
+      7: 14
+      8: 15
+    0: subview 'a4'
+   VIEW     9 rows = p1:I
+      0: 119
+      1: 120
+      2: 121
+      3: 122
+      4: 123
+      5: 124
+      6: 125
+      7: 126
+      8: 127
diff --git a/8.x/mk/tests/ok/s25.txt b/8.x/mk/tests/ok/s25.txt
new file mode 100644 (file)
index 0000000..a9f5a36
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Bytes storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s25a.txt b/8.x/mk/tests/ok/s25a.txt
new file mode 100755 (executable)
index 0000000..ced17ab
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:B
+      0: (2b)
+      1: (4b)
+      2: (5b)
diff --git a/8.x/mk/tests/ok/s26.txt b/8.x/mk/tests/ok/s26.txt
new file mode 100644 (file)
index 0000000..4496d6e
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Bitwise autosizing
+<<< done.
diff --git a/8.x/mk/tests/ok/s26a.txt b/8.x/mk/tests/ok/s26a.txt
new file mode 100755 (executable)
index 0000000..2b644a8
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I p2:I p3:I p4:I
+      0: 100000 100000 100000 100000
diff --git a/8.x/mk/tests/ok/s27.txt b/8.x/mk/tests/ok/s27.txt
new file mode 100644 (file)
index 0000000..d35484e
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Bytes restructuring
+<<< done.
diff --git a/8.x/mk/tests/ok/s27a.txt b/8.x/mk/tests/ok/s27a.txt
new file mode 100755 (executable)
index 0000000..c39554b
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:B
+      0: (4b)
diff --git a/8.x/mk/tests/ok/s28.txt b/8.x/mk/tests/ok/s28.txt
new file mode 100644 (file)
index 0000000..4e7e1a1
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Doubles added later
+<<< done.
diff --git a/8.x/mk/tests/ok/s28a.txt b/8.x/mk/tests/ok/s28a.txt
new file mode 100755 (executable)
index 0000000..a731a6a
--- /dev/null
@@ -0,0 +1,7 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:F p2:D p3:V
+      0: 123 123
+      0: subview 'p3'
+     VIEW     1 rows = p1:F p2:D
+        0: 234 234
diff --git a/8.x/mk/tests/ok/s29.txt b/8.x/mk/tests/ok/s29.txt
new file mode 100644 (file)
index 0000000..982807a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Delete bytes property
+<<< done.
diff --git a/8.x/mk/tests/ok/s29a.txt b/8.x/mk/tests/ok/s29a.txt
new file mode 100755 (executable)
index 0000000..36e2113
--- /dev/null
@@ -0,0 +1,3 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     0 rows = p1:B
diff --git a/8.x/mk/tests/ok/s30.txt b/8.x/mk/tests/ok/s30.txt
new file mode 100644 (file)
index 0000000..e86ceee
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Memo storage
+<<< done.
diff --git a/8.x/mk/tests/ok/s30a.txt b/8.x/mk/tests/ok/s30a.txt
new file mode 100755 (executable)
index 0000000..ced17ab
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:B
+      0: (2b)
+      1: (4b)
+      2: (5b)
diff --git a/8.x/mk/tests/ok/s31.txt b/8.x/mk/tests/ok/s31.txt
new file mode 100755 (executable)
index 0000000..6610772
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Check sort buffer use
+<<< done.
diff --git a/8.x/mk/tests/ok/s31a.txt b/8.x/mk/tests/ok/s31a.txt
new file mode 100755 (executable)
index 0000000..bb0beb1
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:I
+      0: 3
+      1: 1
+      2: 2
diff --git a/8.x/mk/tests/ok/s32.txt b/8.x/mk/tests/ok/s32.txt
new file mode 100755 (executable)
index 0000000..342f61d
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Set memo empty or same size
+<<< done.
diff --git a/8.x/mk/tests/ok/s32a.txt b/8.x/mk/tests/ok/s32a.txt
new file mode 100755 (executable)
index 0000000..c39554b
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:B
+      0: (4b)
diff --git a/8.x/mk/tests/ok/s33.txt b/8.x/mk/tests/ok/s33.txt
new file mode 100755 (executable)
index 0000000..749e7d3
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Serialize memo fields
+<<< done.
diff --git a/8.x/mk/tests/ok/s33a.txt b/8.x/mk/tests/ok/s33a.txt
new file mode 100755 (executable)
index 0000000..ced17ab
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:B
+      0: (2b)
+      1: (4b)
+      2: (5b)
diff --git a/8.x/mk/tests/ok/s33b.txt b/8.x/mk/tests/ok/s33b.txt
new file mode 100755 (executable)
index 0000000..ced17ab
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:B
+      0: (2b)
+      1: (4b)
+      2: (5b)
diff --git a/8.x/mk/tests/ok/s33c.txt b/8.x/mk/tests/ok/s33c.txt
new file mode 100755 (executable)
index 0000000..ced17ab
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:B
+      0: (2b)
+      1: (4b)
+      2: (5b)
diff --git a/8.x/mk/tests/ok/s34.txt b/8.x/mk/tests/ok/s34.txt
new file mode 100644 (file)
index 0000000..63a225e
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Smart and failed commits
+<<< done.
diff --git a/8.x/mk/tests/ok/s34a.txt b/8.x/mk/tests/ok/s34a.txt
new file mode 100644 (file)
index 0000000..81e1847
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 111
diff --git a/8.x/mk/tests/ok/s35.txt b/8.x/mk/tests/ok/s35.txt
new file mode 100644 (file)
index 0000000..18835d3
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Datafile with preamble
+<<< done.
diff --git a/8.x/mk/tests/ok/s35a.txt b/8.x/mk/tests/ok/s35a.txt
new file mode 100644 (file)
index 0000000..81e1847
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 111
diff --git a/8.x/mk/tests/ok/s36.txt b/8.x/mk/tests/ok/s36.txt
new file mode 100644 (file)
index 0000000..63d15af
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Commit after load
+<<< done.
diff --git a/8.x/mk/tests/ok/s36a.txt b/8.x/mk/tests/ok/s36a.txt
new file mode 100644 (file)
index 0000000..81e1847
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 111
diff --git a/8.x/mk/tests/ok/s36b.txt b/8.x/mk/tests/ok/s36b.txt
new file mode 100644 (file)
index 0000000..81e1847
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 111
diff --git a/8.x/mk/tests/ok/s37.txt b/8.x/mk/tests/ok/s37.txt
new file mode 100644 (file)
index 0000000..8bf5f8b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Change short partial fields
+<<< done.
diff --git a/8.x/mk/tests/ok/s37a.txt b/8.x/mk/tests/ok/s37a.txt
new file mode 100644 (file)
index 0000000..21eab9c
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = v1:V
+    0: subview 'v1'
+   VIEW     1 rows = key:I p1:B
+      0: 0 (6b)
diff --git a/8.x/mk/tests/ok/s38.txt b/8.x/mk/tests/ok/s38.txt
new file mode 100644 (file)
index 0000000..acd0b20
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Lots of empty subviews
+<<< done.
diff --git a/8.x/mk/tests/ok/s38a.txt b/8.x/mk/tests/ok/s38a.txt
new file mode 100644 (file)
index 0000000..8ee8c34
--- /dev/null
@@ -0,0 +1,7 @@
+ VIEW     1 rows = v:V
+    0: subview 'v'
+   VIEW     2 rows = v1:V
+      0: subview 'v1'
+     VIEW     0 rows = p1:S
+      1: subview 'v1'
+     VIEW     0 rows = p1:S
diff --git a/8.x/mk/tests/ok/s39.txt b/8.x/mk/tests/ok/s39.txt
new file mode 100644 (file)
index 0000000..a907f11
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Do not detach empty top-level views
+<<< done.
diff --git a/8.x/mk/tests/ok/s39a.txt b/8.x/mk/tests/ok/s39a.txt
new file mode 100644 (file)
index 0000000..7799a27
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = v1:V
+    0: subview 'v1'
+   VIEW     1 rows = p1:I
+      0: 123
diff --git a/8.x/mk/tests/ok/s40.txt b/8.x/mk/tests/ok/s40.txt
new file mode 100644 (file)
index 0000000..b799ff9
--- /dev/null
@@ -0,0 +1,2 @@
+>>> LoadFrom after commit
+<<< done.
diff --git a/8.x/mk/tests/ok/s40a.txt b/8.x/mk/tests/ok/s40a.txt
new file mode 100644 (file)
index 0000000..d256fc7
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I
+      0: 456
diff --git a/8.x/mk/tests/ok/s41.txt b/8.x/mk/tests/ok/s41.txt
new file mode 100644 (file)
index 0000000..419edba
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Partial modify blocked
+<<< done.
diff --git a/8.x/mk/tests/ok/s41a.txt b/8.x/mk/tests/ok/s41a.txt
new file mode 100644 (file)
index 0000000..51bc32d
--- /dev/null
@@ -0,0 +1,8 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = _B:V
+      0: subview '_B'
+     VIEW     1 rows = p1:B
+        0: (8b)
+      1: subview '_B'
+     VIEW     0 rows = p1:B
diff --git a/8.x/mk/tests/ok/s42.txt b/8.x/mk/tests/ok/s42.txt
new file mode 100644 (file)
index 0000000..61c83f2
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Get descriptions
+<<< done.
diff --git a/8.x/mk/tests/ok/s43.txt b/8.x/mk/tests/ok/s43.txt
new file mode 100644 (file)
index 0000000..af2b071
--- /dev/null
@@ -0,0 +1,2 @@
+>>> View reuse after sub-byte ints
+<<< done.
diff --git a/8.x/mk/tests/ok/s43a.txt b/8.x/mk/tests/ok/s43a.txt
new file mode 100644 (file)
index 0000000..df0a22e
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     2 rows = p1:I
+      0: 0
+      1: 12345
diff --git a/8.x/mk/tests/ok/s44.txt b/8.x/mk/tests/ok/s44.txt
new file mode 100644 (file)
index 0000000..6404618
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Bad memo free space
+<<< done.
diff --git a/8.x/mk/tests/ok/s44a.txt b/8.x/mk/tests/ok/s44a.txt
new file mode 100644 (file)
index 0000000..02b49b5
--- /dev/null
@@ -0,0 +1,4 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I p2:B
+      0: 0 (12345b)
diff --git a/8.x/mk/tests/ok/s45.txt b/8.x/mk/tests/ok/s45.txt
new file mode 100644 (file)
index 0000000..066826a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Bad subview memo free space
+<<< done.
diff --git a/8.x/mk/tests/ok/s45a.txt b/8.x/mk/tests/ok/s45a.txt
new file mode 100644 (file)
index 0000000..920e28e
--- /dev/null
@@ -0,0 +1,7 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     1 rows = p1:I p2:V
+      0: 0
+      0: subview 'p2'
+     VIEW     1 rows = p3:B
+        0: (12345b)
diff --git a/8.x/mk/tests/ok/s46.txt b/8.x/mk/tests/ok/s46.txt
new file mode 100644 (file)
index 0000000..b799ff9
--- /dev/null
@@ -0,0 +1,2 @@
+>>> LoadFrom after commit
+<<< done.
diff --git a/8.x/mk/tests/ok/s46a.txt b/8.x/mk/tests/ok/s46a.txt
new file mode 100644 (file)
index 0000000..9fa0450
--- /dev/null
@@ -0,0 +1,15 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW    12 rows = p1:I
+      0: 11
+      1: 22
+      2: 33
+      3: 44
+      4: 0
+      5: 55
+      6: 66
+      7: 77
+      8: 0
+      9: 88
+     10: 99
+     11: 1000
diff --git a/8.x/mk/tests/ok/s47.txt b/8.x/mk/tests/ok/s47.txt
new file mode 100644 (file)
index 0000000..55827d0
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Defining bad property type
+<<< done.
diff --git a/8.x/mk/tests/ok/s48.txt b/8.x/mk/tests/ok/s48.txt
new file mode 100644 (file)
index 0000000..28fdd3a
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Resize subview to zero and back
+<<< done.
diff --git a/8.x/mk/tests/ok/s48a.txt b/8.x/mk/tests/ok/s48a.txt
new file mode 100644 (file)
index 0000000..5e39878
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = v1:V
+    0: subview 'v1'
+   VIEW     1 rows = v2:V
+      0: subview 'v2'
+     VIEW     0 rows = p1:I
diff --git a/8.x/mk/tests/ok/s48b.txt b/8.x/mk/tests/ok/s48b.txt
new file mode 100644 (file)
index 0000000..5e39878
--- /dev/null
@@ -0,0 +1,5 @@
+ VIEW     1 rows = v1:V
+    0: subview 'v1'
+   VIEW     1 rows = v2:V
+      0: subview 'v2'
+     VIEW     0 rows = p1:I
diff --git a/8.x/mk/tests/ok/s49.txt b/8.x/mk/tests/ok/s49.txt
new file mode 100644 (file)
index 0000000..b32d7ff
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Specify conflicting properties
+<<< done.
diff --git a/8.x/mk/tests/ok/s49a.txt b/8.x/mk/tests/ok/s49a.txt
new file mode 100644 (file)
index 0000000..992724c
--- /dev/null
@@ -0,0 +1,7 @@
+ VIEW     1 rows = v1:V v2:V v3:V
+    0: subview 'v1'
+   VIEW     0 rows = p1:I
+    0: subview 'v2'
+   VIEW     0 rows = p1:I
+    0: subview 'v3'
+   VIEW     0 rows = v3:V
diff --git a/8.x/mk/tests/ok/s50.txt b/8.x/mk/tests/ok/s50.txt
new file mode 100644 (file)
index 0000000..7a1ea9b
--- /dev/null
@@ -0,0 +1,2 @@
+>>> Free space usage
+<<< done.
diff --git a/8.x/mk/tests/ok/s50a.txt b/8.x/mk/tests/ok/s50a.txt
new file mode 100644 (file)
index 0000000..01163e3
--- /dev/null
@@ -0,0 +1,6 @@
+ VIEW     1 rows = a:V
+    0: subview 'a'
+   VIEW     3 rows = p1:I
+      0: 12345
+      1: 2345
+      2: 345
diff --git a/8.x/mk/tests/regress.cpp b/8.x/mk/tests/regress.cpp
new file mode 100755 (executable)
index 0000000..66449ad
--- /dev/null
@@ -0,0 +1,253 @@
+// regress.cpp -- Regression test program, main code
+// $Id: regress.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+#if defined (macintosh)  
+#include <SIOUX.h>
+#ifdef DEBUG_NEW
+#include <DebugNew.cp>
+//#include "ZoneRanger.c"
+#if DEBUG_NEW >= 2 && !defined (q4_MAC_LEAK_CHECK)
+#define q4_MAC_LEAK_CHECK 1
+#endif 
+#endif 
+#endif 
+
+#if __profile__
+#define q4_MWCW_PROFILER 1
+#include <profiler.h>
+#endif 
+
+#if q4_NOTHROW
+const char *msg;
+#endif 
+
+#if _WIN32_WCE
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+int remove(const char *fn_) {
+  c4_Bytes buffer;
+  int n = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fn_,  - 1, NULL, 0);
+  wchar_t *w = (wchar_t*)buffer.SetBufferClear((n + 1) *sizeof(wchar_t));
+  MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fn_,  - 1, w, n);
+  return DeleteFile((wchar_t*)buffer.Contents()) ? 0 :  - 1;
+}
+
+#endif 
+
+int 
+#if _WIN32_WCE
+_cdecl 
+#endif 
+main() {
+  //  afxMemDF |= allocMemDF | checkAlwaysMemDF;
+
+  // The M4STRING package sometimes keeps a spare empty string around.
+  // By allocating it here, we avoid a few bogus memory leak reports.
+  c4_String empty;
+
+#if q4_MAC_LEAK_CHECK
+  DebugNewForgetLeaks();
+#endif 
+
+#if q4_MWCW_PROFILER
+  if (!ProfilerInit(collectDetailed, bestTimeBase, 20, 5)) {
+#endif 
+    TestBasics1();
+    TestBasics2();
+    TestNotify();
+    TestCustom1();
+    TestCustom2();
+    TestResize();
+    TestStores1();
+    TestStores2();
+    TestStores3();
+    TestStores4();
+    TestStores5();
+    TestDiffer();
+    TestExtend();
+    TestFormat();
+    TestMapped();
+    TestLimits();
+
+#if q4_MWCW_PROFILER
+    ProfilerDump("\pRegress.prof");
+    ProfilerTerm();
+  }
+#endif 
+
+#if defined (_DEBUG)
+  fputs("\nPress return... ", stderr);
+  getchar();
+#endif 
+#if q4_MAC_LEAK_CHECK
+  if (DebugNewReportLeaks())
+    fputs("    *** Memory leaks found ***\n", stderr);
+#endif 
+#if defined (macintosh)  
+  SIOUXSettings.asktosaveonclose = false;
+#endif 
+
+  fputs("Done.\n", stderr);
+  return 0;
+}
+
+// Recursively display the entire view contents. The results shown do not
+// depend on file layout (free space, file positions, flat vs. on-demand).
+
+static void ViewDisplay(const c4_View &v_, FILE *fp, int l_ = 0) {
+  c4_String types;
+  bool hasData = false, hasSubs = false;
+
+  // display header info and collect all data types
+  fprintf(fp, "%*s VIEW %5d rows =", l_, "", v_.GetSize());
+  for (int n = 0; n < v_.NumProperties(); ++n) {
+    c4_Property prop = v_.NthProperty(n);
+    char t = prop.Type();
+
+    fprintf(fp, " %s:%c", (const char*)prop.Name(), t);
+
+    types += t;
+
+    if (t == 'V')
+      hasSubs = true;
+    else
+      hasData = true;
+  }
+  fprintf(fp, "\n");
+
+  for (int j = 0; j < v_.GetSize(); ++j) {
+    if (hasData)
+     { // data properties are all shown on the same line
+      fprintf(fp, "%*s %4d:", l_, "", j);
+      c4_RowRef r = v_[j];
+
+      for (int k = 0; k < types.GetLength(); ++k) {
+        c4_Property p = v_.NthProperty(k);
+
+        switch (types[k]) {
+          case 'I':
+            fprintf(fp, " %ld", (long)((c4_IntProp &)p)(r));
+            break;
+
+#if !q4_TINY
+          case 'F':
+            fprintf(fp, " %g", (double)((c4_FloatProp &)p)(r));
+            break;
+
+          case 'D':
+            fprintf(fp, " %.12g", (double)((c4_DoubleProp &)p)(r));
+            break;
+#endif 
+
+          case 'S':
+            fprintf(fp, " '%s'", (const char*)((c4_StringProp &)p)(r));
+            break;
+
+          case 'M':
+            // backward compatibility
+          case 'B':
+            fprintf(fp, " (%db)", (p(r)).GetSize());
+            break;
+
+          default:
+            if (types[k] != 'V')
+              fprintf(fp, " (%c?)", types[k]);
+        }
+      }
+
+      fprintf(fp, "\n");
+    }
+
+    if (hasSubs)
+     { // subviews are then shown, each as a separate block
+      for (int k = 0; k < types.GetLength(); ++k) {
+        if (types[k] == 'V') {
+          c4_Property prop = v_.NthProperty(k);
+
+          fprintf(fp, "%*s %4d: subview '%s'\n", l_, "", j, (const char*)
+            prop.Name());
+
+          c4_ViewProp &vp = (c4_ViewProp &)prop;
+
+          ViewDisplay(vp(v_[j]), fp, l_ + 2);
+        }
+      }
+    }
+  }
+}
+
+void DumpFile(const char *in_, const char *out_) {
+  FILE *fp = fopen(out_, TEXTOUT);
+  A(fp);
+
+  c4_Storage store(in_, 0);
+
+  ViewDisplay(store, fp);
+
+  fclose(fp);
+}
+
+void Fail(const char *msg) {
+#if q4_NOTHROW
+  fprintf(stderr, "\t%s\n", msg);
+  printf("*** %s ***\n", msg);
+#else 
+  throw msg;
+#endif 
+}
+
+void FailExpr(const char *expr) {
+  char buffer[100];
+  sprintf(buffer, "Failed: A(%s)", expr);
+  Fail(buffer);
+}
+
+int StartTest(int mask_, const char *name_, const char *desc_) {
+  if (mask_) {
+#if q4_MFC && defined(_DEBUG)
+    TRACE("%s - %-40s *** DISABLED ***\n", name_, desc_);
+#endif 
+#if !q4_MWCW_PROFILER
+    fprintf(stderr, "%s - %-40s   *** DISABLED ***\n", name_, desc_);
+#endif 
+    return false;
+  }
+
+#if q4_MFC && defined(_DEBUG)
+  TRACE("%s - %s\n", name_, desc_);
+#endif 
+#if !q4_MWCW_PROFILER
+  fprintf(stderr, "%s - %s\n", name_, desc_);
+#endif 
+
+  char buffer[50];
+  sprintf(buffer, "%s%s.txt", TESTDIR, name_);
+#if _WIN32_WCE
+  fclose(stdout);
+  fopen(buffer, TEXTOUT);
+#else 
+  freopen(buffer, TEXTOUT, stdout);
+#endif 
+  printf(">>> %s\n", desc_);
+
+  return true;
+}
+
+void CatchMsg(const char *msg) {
+#if !q4_MWCW_PROFILER
+  fprintf(stderr, "\t%s\n", msg);
+#endif 
+  printf("*** %s ***\n", msg);
+}
+
+void CatchOther() {
+#if !q4_MWCW_PROFILER
+  fputs("\tException!\n", stderr);
+#endif 
+  printf("*** Exception ***\n");
+}
diff --git a/8.x/mk/tests/regress.h b/8.x/mk/tests/regress.h
new file mode 100755 (executable)
index 0000000..ee37b7d
--- /dev/null
@@ -0,0 +1,146 @@
+// regress.h -- Regression test program, header file
+// $Id: regress.h 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "mk4.h"
+#include "mk4io.h"
+#include "mk4str.h"
+
+#define TraceAll  false
+
+// default for dos and unix is to assume they don't support exceptions
+#if defined (_DOS) || defined (unix) || defined (__unix__) || \
+defined(__GNUC__) || defined(_WIN32_WCE)
+#if !defined (q4_NOTHROW)
+#define q4_NOTHROW 1
+#endif 
+#endif 
+
+#ifdef _WIN32_WCE
+int remove(const char*);
+#endif 
+
+#if _MSC_VER == 800
+#pragma warning (disable: 4703) // function too large for global optimizations
+
+// also no exceptions in MSVC 1.52 when used with a QuickWin target
+#if defined (_QWINVER) && !defined (q4_NOTHROW)
+#define q4_NOTHROW 1    
+#endif 
+#endif 
+
+#if q4_NOTHROW
+#define try
+#define catch(x)  if (0)
+
+extern const char *msg;
+#endif 
+
+#if defined (macintosh)  
+#define TESTDIR ":tests:"
+#define TEXTOUT "wt"
+#define LINESEP "\r"
+#elif defined (__VMS)
+#define TESTDIR "[.tests]"
+#define TEXTOUT "w"
+#define LINESEP "\r\n" // is this correct?
+#elif defined (unix) || defined (__unix__) || defined (__GNUC__) || \
+defined(__hpux)
+#define TESTDIR "tests/"
+#define TEXTOUT "w"
+#define LINESEP "\n"
+#else 
+#define TESTDIR "tests\\"
+#define TEXTOUT "wt"
+#define LINESEP "\r\n"
+#endif 
+
+#include <stdio.h>
+
+#if q4_MFC && defined(_DEBUG)
+#define B(n_,d_,c_) \
+if (StartTest(c_, #n_, #d_)) \
+{ \
+CMemoryState oldState, newState, diffState; \
+oldState.Checkpoint(); \
+afxTraceEnabled = TraceAll; \
+try \
+{ \
+{
+#define E \
+} \
+puts("<<< done."); \
+} \
+catch (const char* msg) { CatchMsg(msg); } \
+catch (...) { CatchOther(); } \
+afxTraceEnabled = true; \
+fflush(stdout); \
+newState.Checkpoint(); \
+if (diffState.Difference(oldState, newState)) \
+{ \
+fputs("\tMemory leaked!\n", stderr); \
+puts("*** Memory leaked ***"); \
+TRACE("   *** Memory leaked, "); \
+diffState.DumpAllObjectsSince(); \
+} \
+fflush(stdout); \
+}
+#else 
+#define B(n_,d_,c_) \
+if (StartTest(c_, #n_, #d_)) \
+{ \
+try \
+{ \
+{
+#define E \
+} \
+puts("<<< done."); \
+} \
+catch (const char* msg) { CatchMsg(msg); } \
+catch (...) { CatchOther(); } \
+fflush(stdout); \
+}
+#endif 
+
+#define A(e_) if (e_) ; else FailExpr(#e_)
+
+#define W(f_) remove(#f_)
+#define R(f_) A(remove(#f_) == 0)
+#define D(f_) DumpFile(#f_, TESTDIR #f_ ".txt")
+
+typedef c4_BytesProp c4_MemoProp;
+
+extern void DumpFile(const char *in_, const char *out_);
+extern void Fail(const char *msg);
+extern void FailExpr(const char *expr);
+extern int StartTest(int, const char *, const char*);
+extern void CatchMsg(const char *msg);
+extern void CatchOther();
+
+extern void TestBasics1();
+extern void TestBasics2();
+extern void TestCustom1();
+extern void TestCustom2();
+extern void TestDiffer();
+extern void TestExtend();
+extern void TestFormat();
+extern void TestLimits();
+extern void TestMapped();
+extern void TestNotify();
+extern void TestResize();
+extern void TestStores1();
+extern void TestStores2();
+extern void TestStores3();
+extern void TestStores4();
+extern void TestStores5();
+
+//  The Borland C++ RTL does not want file handle objects to cross
+//  DLL boundaries, so we use special fopen/fclose hooks in the DLL.
+
+#if defined (__BORLANDC__) // this assumes Metakit is in a DLL!
+extern FILE *f4_FileOpenInDLL(const char *, const char*);
+extern int f4_FileCloseInDLL(FILE*);
+
+#define fopen f4_FileOpenInDLL
+#define fclose f4_FileCloseInDLL
+#endif
diff --git a/8.x/mk/tests/tbasic1.cpp b/8.x/mk/tests/tbasic1.cpp
new file mode 100644 (file)
index 0000000..787233e
--- /dev/null
@@ -0,0 +1,267 @@
+// tbasic1.cpp -- Regression test program, basic tests part 1
+// $Id: tbasic1.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestBasics1() {
+  B(b00, Should fail, 0) {
+    A(false);
+  }
+  E;
+
+  B(b01, Should succeed, 0) {
+    A(sizeof(t4_byte) == 1);
+    A(sizeof(short) == 2);
+    A(sizeof(t4_i32) == 4);
+    A(sizeof(float) == 4);
+    A(sizeof(double) == 8);
+  }
+  E;
+
+  B(b02, Int property, 0) {
+    c4_Row r1;
+    c4_IntProp p1("p1");
+    p1(r1) = 1234567890L;
+    long x1 = p1(r1);
+    A(x1 == 1234567890L);
+  }
+  E;
+
+#if !q4_TINY
+  B(b03, Float property, 0) {
+    c4_Row r1;
+    c4_FloatProp p1("p1");
+    p1(r1) = 123.456;
+    double x1 = p1(r1);
+    A((float)x1 == (float)123.456);
+  }
+  E;
+#endif 
+
+  B(b04, String property, 0) {
+    c4_Row r1;
+    c4_StringProp p1("p1");
+    p1(r1) = "abc";
+    const char *x1 = p1(r1);
+    A((c4_String)x1 == "abc");
+  }
+  E;
+
+  B(b05, View property, 0) {
+    c4_View v1;
+    c4_Row r1;
+    c4_ViewProp p1("p1");
+    p1(r1) = v1;
+    c4_View x1 = p1(r1);
+    // compare cursors to make sure this is the same sequence
+    A(x1[0] == v1[0]);
+  }
+  E;
+
+  B(b06, View construction, 0) {
+    c4_IntProp p1("p1"), p2("p2"), p3("p3");
+    c4_View v1 = (p1, p3, p2);
+    A(v1.FindProperty(p1.GetId()) == 0);
+    A(v1.FindProperty(p2.GetId()) == 2);
+    A(v1.FindProperty(p3.GetId()) == 1);
+  }
+  E;
+
+  B(b07, Row manipulation, 0) {
+    c4_StringProp p1("p1"), p2("p2");
+    c4_IntProp p3("p3");
+    c4_Row r1;
+    p1(r1) = "look at this";
+    const char *x1 = p1(r1);
+    A(x1 == (c4_String)"look at this");
+    r1 = p1["what's in a"] + p2["name..."];
+    c4_String t = (const char*)p2(r1);
+    p1(r1) = t + (const char*)(p1(r1));
+    p2(r1) = p1(r1);
+    c4_String x2 = (const char*)p1(r1); // 2000-03-16, store as c4_String
+    A(x2 == "name...what's in a");
+    // the above change avoids an evaluation order issue in assert below
+    A(x2 == p2(r1));
+    p3(r1) = 12345;
+    p3(r1) = p3(r1) + 123;
+    int x3 = p3(r1);
+    A(x3 == 12345+123);
+  }
+  E;
+
+  B(b08, Row expressions, 0) {
+    c4_StringProp p1("p1"), p2("p2");
+    c4_IntProp p3("p3");
+    c4_Row r1;
+    c4_View v1 = (p1, p2, p3);
+    v1.SetSize(5);
+    r1 = v1[1];
+    v1[2] = v1[1];
+    v1[3] = r1;
+    v1[4] = v1[4];
+    r1 = r1;
+  }
+  E;
+
+  B(b09, View manipulation, 0) {
+    c4_StringProp p1("p1"), p2("p2");
+    c4_Row r1 = p1["One"] + p2["Two"];
+    c4_Row r2;
+    c4_View v1;
+    v1.Add(r1);
+    v1.Add(r2);
+    v1.Add(r1);
+    A(v1.GetSize() == 3);
+    A(v1[0] == r1);
+    A(v1[1] == r2);
+    A(v1[2] == r1);
+    v1.RemoveAt(1, 1);
+    A(v1.GetSize() == 2);
+    A(v1[0] == r1);
+    A(v1[0] == v1[1]);
+  }
+  E;
+
+  B(b10, View sorting, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    c4_View v2 = v1.Sort();
+    A(v2.GetSize() == 6);
+    A(p1(v2[0]) == 111);
+    A(p1(v2[1]) == 123);
+    A(p1(v2[2]) == 222);
+    A(p1(v2[3]) == 234);
+    A(p1(v2[4]) == 333);
+    A(p1(v2[5]) == 345);
+  }
+  E;
+
+  B(b11, View selection, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    c4_View v2 = v1.SelectRange(p1[200], p1[333]);
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+  }
+  E;
+
+  B(b12, Add after remove, 0) {
+    c4_StringProp p1("p1");
+    c4_View v1;
+    v1.Add(p1["abc"]);
+    A(v1.GetSize() == 1);
+    v1.RemoveAt(0);
+    A(v1.GetSize() == 0);
+    v1.Add(p1["def"]);
+    A(v1.GetSize() == 1);
+  }
+  E;
+
+  B(b13, Clear view entry, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 1);
+    A(p1(v1[0]) == 123);
+
+    v1[0] = c4_Row();
+    A(v1.GetSize() == 1);
+    A(p1(v1[0]) == 0);
+  }
+  E;
+
+  B(b14, Empty view outlives temp storage, 0) {
+    c4_View v1;
+    c4_Storage s1;
+    v1 = s1.GetAs("a[p1:I,p2:S]");
+  }
+  E;
+
+  B(b15, View outlives temp storage, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+
+     {
+      c4_Storage s1;
+      v1 = s1.GetAs("a[p1:I,p2:S]");
+      v1.Add(p1[123]);
+    }
+
+    // 19990916 - semantics changed, view now 1 row, but 0 props
+    A(v1.GetSize() == 1);
+    A(v1.NumProperties() == 0);
+    //A(p1 (v1[0]) == 123);
+  }
+  E;
+
+  B(b16, View outlives cleared temp storage, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+
+     {
+      c4_Storage s1;
+      v1 = s1.GetAs("a[p1:I,p2:S]");
+      v1.Add(p1[123]);
+      v1.RemoveAll();
+    }
+
+    A(v1.GetSize() == 0);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 1);
+    A(p1(v1[0]) == 123);
+  }
+  E;
+
+#if !q4_TINY
+  B(b17, Double property, 0) {
+    c4_Row r1;
+    c4_DoubleProp p1("p1");
+    p1(r1) = 1234.5678;
+    double x1 = p1(r1);
+    A(x1 == (double)1234.5678);
+  }
+  E;
+#endif 
+
+  B(b18, SetAtGrow usage, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+
+    v1.SetAtGrow(3, p1[333]);
+    v1.SetAtGrow(1, p1[111]);
+    v1.SetAtGrow(5, p1[555]);
+
+    A(v1.GetSize() == 6);
+    A(p1(v1[1]) == 111);
+    A(p1(v1[3]) == 333);
+    A(p1(v1[5]) == 555);
+  }
+  E;
+
+  B(b19, Bytes property, 0) {
+    c4_Row r1;
+    c4_BytesProp p1("p1");
+    c4_Bytes x1("hi!", 3);
+
+    p1(r1) = x1;
+    c4_Bytes x2 = p1(r1);
+    A(x1 == x2);
+  }
+  E;
+}
diff --git a/8.x/mk/tests/tbasic2.cpp b/8.x/mk/tests/tbasic2.cpp
new file mode 100644 (file)
index 0000000..5a01ca4
--- /dev/null
@@ -0,0 +1,215 @@
+// tbasic2.cpp -- Regression test program, basic tests part 2
+// $Id: tbasic2.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+static int ViewSize(c4_View v) {
+  return v.GetSize();
+}
+
+void TestBasics2() {
+  B(b20, Search sorted view, 0) {
+    c4_IntProp p1("p1");
+    c4_StringProp p2("p2");
+    c4_View v1;
+    v1.Add(p1[111] + p2["one"]);
+    v1.Add(p1[222] + p2["two"]);
+    v1.Add(p1[333] + p2["three"]);
+    v1.Add(p1[345] + p2["four"]);
+    v1.Add(p1[234] + p2["five"]);
+    v1.Add(p1[123] + p2["six"]);
+    c4_View v2 = v1.Sort();
+    A(v2.GetSize() == 6);
+    A(p1(v2[0]) == 111);
+    A(p1(v2[1]) == 123);
+    A(p1(v2[2]) == 222);
+    A(p1(v2[3]) == 234);
+    A(p1(v2[4]) == 333);
+    A(p1(v2[5]) == 345);
+    A(v2.Search(p1[123]) == 1);
+    A(v2.Search(p1[100]) == 0);
+    A(v2.Search(p1[200]) == 2);
+    A(v2.Search(p1[400]) == 6);
+    c4_View v3 = v1.SortOn(p2);
+    A(v3.GetSize() == 6);
+    A(p1(v3[0]) == 234);
+    A(p1(v3[1]) == 345);
+    A(p1(v3[2]) == 111);
+    A(p1(v3[3]) == 123);
+    A(p1(v3[4]) == 333);
+    A(p1(v3[5]) == 222);
+    A(v3.Search(p2["six"]) == 3);
+    A(v3.Search(p2["aha"]) == 0);
+    A(v3.Search(p2["gee"]) == 2);
+    A(v3.Search(p2["wow"]) == 6);
+    c4_View v4 = v1.SortOnReverse(p2, p2);
+    A(v4.GetSize() == 6);
+    A(p1(v4[0]) == 222);
+    A(p1(v4[1]) == 333);
+    A(p1(v4[2]) == 123);
+    A(p1(v4[3]) == 111);
+    A(p1(v4[4]) == 345);
+    A(p1(v4[5]) == 234);
+    A(v4.Search(p2["six"]) == 2);
+    A(v4.Search(p2["aha"]) == 6);
+    A(v4.Search(p2["gee"]) == 4);
+    A(v4.Search(p2["wow"]) == 0);
+  }
+  E;
+
+  B(b21, Memo property, 0) {
+    c4_Row r1;
+    c4_MemoProp p1("p1");
+    c4_Bytes x1("hi!", 3);
+
+    p1(r1) = x1;
+    c4_Bytes x2 = p1(r1);
+    A(x1 == x2);
+  }
+  E;
+
+  B(b22, Stored view references, 0) {
+    c4_ViewProp p1("p1");
+    c4_View v1;
+
+     {
+      v1.Add(p1[c4_View()]);
+    }
+
+    // this works
+    int n = ViewSize(p1.Get(v1[0]));
+    A(n == 0);
+
+    // this fails in 1.8b2 using MSVC 1.52 (tq_wvus)
+    //
+    // The compiler destructs temp c4_View once too often, or
+    // what's more likely, fails to call the constructor once.
+    //
+    // So for MSVC 1.52: use prop.Get(rowref) for subviews,
+    // or immediately assign the result to a c4_View object,
+    // do not pass a "prop (rowref)" expression as argument.
+
+#if _MSC_VER != 800     
+    int m = ViewSize(p1(v1[0]));
+    A(m == 0);
+#endif 
+  }
+  E;
+
+  B(b23, Sort comparison fix, 0) { // 1.9e: compare buffering problem
+    c4_DoubleProp p1("p1");
+    c4_View v1;
+    for (int i = 0; i < 100; ++i)
+      v1.Add(p1[99-i]);
+    c4_View v2 = v1.Sort();
+    A(v2.GetSize() == 100);
+    for (int j = 0; j < 100; ++j) {
+      A(p1(v1[j]) == (double)99-j);
+      A(p1(v2[j]) == (double)j);
+    }
+  }
+  E;
+
+  B(b24, Custom view comparisons, 0) { // 1.9f: more compare cache problems
+    c4_IntProp p1("p1");
+    c4_FloatProp p2("p2");
+    c4_DoubleProp p3("p3");
+    c4_IntProp p4("p4");
+    c4_View v1;
+    v1.Add(p1[2] + p2[2] + p3[2]);
+    v1.Add(p1[1] + p2[1] + p3[1]);
+    v1.Add(p1[3] + p2[3] + p3[3]);
+    A(v1.GetSize() == 3);
+    A((int)p1(v1[0]) > (int)p1(v1[1]));
+    A((float)p2(v1[0]) > (float)p2(v1[1]));
+    A((double)p3(v1[0]) > (double)p3(v1[1]));
+    A((int)p1(v1[0]) < (int)p1(v1[2]));
+    A((float)p2(v1[0]) < (float)p2(v1[2]));
+    A((double)p3(v1[0]) < (double)p3(v1[2]));
+    c4_View v2 = v1.Unique();
+    A(v2.GetSize() == 3);
+    A((int)p1(v2[0]) != (int)p1(v2[1]));
+    A((float)p2(v2[0]) != (float)p2(v2[1]));
+    A((double)p3(v2[0]) != (double)p3(v2[1]));
+    A((int)p1(v2[0]) != (int)p1(v2[2]));
+    A((float)p2(v2[0]) != (float)p2(v2[2]));
+    A((double)p3(v2[0]) != (double)p3(v2[2]));
+    v1.Add(p1[2] + p2[2] + p3[2]);
+    v1.Add(p1[1] + p2[1] + p3[1]);
+    v1.Add(p1[3] + p2[3] + p3[3]);
+    c4_View v3 = v1.Unique();
+    A(v3.GetSize() == 3);
+    A((int)p1(v3[0]) != (int)p1(v3[1]));
+    A((float)p2(v3[0]) != (float)p2(v3[1]));
+    A((double)p3(v3[0]) != (double)p3(v3[1]));
+    A((int)p1(v3[0]) != (int)p1(v3[2]));
+    A((float)p2(v3[0]) != (float)p2(v3[2]));
+    A((double)p3(v3[0]) != (double)p3(v3[2]));
+    c4_View v4 = v1.Counts(p1, p4);
+    A(v4.GetSize() == 3);
+    c4_View v5 = v1.Counts(p2, p4);
+    A(v5.GetSize() == 3); // this failed in 1.9f
+    c4_View v6 = v1.Counts(p3, p4);
+    A(v6.GetSize() == 3); // this failed in 1.9f
+  }
+  E;
+
+  B(b25, Copy row from derived, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    c4_View v2 = v1.Select(p1[222]);
+    A(v2.GetSize() == 1);
+    A(p1(v2[0]) == 222);
+    c4_Row r = v2[0];
+    A(p1(r) == 222); // 1.9g: failed because SetAt did not remap
+  }
+  E;
+
+  B(b26, Partial memo field access, 0) {
+    c4_BytesProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[c4_Bytes("12345", 5)]);
+    A(v1.GetSize() == 1);
+    c4_Bytes buf = p1(v1[0]);
+    A(buf.Size() == 5);
+    A(buf == c4_Bytes("12345", 5));
+    buf = p1(v1[0]).Access(1, 3);
+    A(buf == c4_Bytes("234", 3));
+    p1(v1[0]).Modify(c4_Bytes("ab", 2), 2, 0);
+    buf = p1(v1[0]);
+    A(buf == c4_Bytes("12ab5", 5));
+    p1(v1[0]).Modify(c4_Bytes("ABC", 3), 1, 2);
+    buf = p1(v1[0]);
+    A(buf == c4_Bytes("1ABCab5", 7));
+    p1(v1[0]).Modify(c4_Bytes("xyz", 3), 2,  - 2);
+    buf = p1(v1[0]);
+    A(buf == c4_Bytes("1Axyz", 5));
+    p1(v1[0]).Modify(c4_Bytes("3456", 4), 4, 0);
+    buf = p1(v1[0]);
+    A(buf == c4_Bytes("1Axy3456", 8));
+  }
+  E;
+
+  B(b27, Copy value to another row, 0) {
+    c4_StringProp p1("p1");
+    c4_View v1;
+    v1.SetSize(2);
+    p1(v1[1]) = "abc";
+    // next assert fails in MacOS X 10.2.1 "Jaguar" with 2.4.7
+    // seems bug in gcc 3.1, -O i.s.o. -O2 works [jcw 21oct02]
+    A((const char*)(p1(v1[0])) == (c4_String)"");
+    A((const char*)(p1(v1[1])) == (c4_String)"abc");
+
+    // fails in 2.4.0, reported by Jerry McRae, August 2001
+    p1(v1[0]) = (const char*)p1(v1[1]);
+    // MacOS 10.2.3 gcc 3.1 dec 2002 is still weird, inserting the
+    // following code (which should be a noop) *fixes* the assert!
+    //const char* q = p1 (v1[1]);
+    A((c4_String)(const char*)(p1(v1[0])) == (c4_String)"abc");
+  }
+  E;
+}
diff --git a/8.x/mk/tests/tcusto1.cpp b/8.x/mk/tests/tcusto1.cpp
new file mode 100755 (executable)
index 0000000..2ffc793
--- /dev/null
@@ -0,0 +1,276 @@
+// tcusto1.cpp -- Regression test program, custom view tests
+// $Id: tcusto1.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestCustom1() {
+  B(c01, Slice forward, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1;
+    v1.Add(p1[123]);
+    v1.Add(p1[234]);
+    v1.Add(p1[345]);
+    v1.Add(p1[456]);
+    v1.Add(p1[567]);
+
+    c4_View v2 = v1.Slice(1,  - 1, 2);
+    A(v2.GetSize() == 2);
+    A(p1(v2[0]) == 234);
+    A(p1(v2[1]) == 456);
+
+    v1.Add(p1[678]);
+    A(v1.GetSize() == 6);
+    A(v2.GetSize() == 3);
+    A(p1(v2[2]) == 678);
+  }
+  E;
+
+  B(c02, Slice backward, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1;
+    v1.Add(p1[123]);
+    v1.Add(p1[234]);
+    v1.Add(p1[345]);
+    v1.Add(p1[456]);
+    v1.Add(p1[567]);
+
+    c4_View v2 = v1.Slice(1,  - 1,  - 2);
+    A(v2.GetSize() == 2);
+    A(p1(v2[0]) == 456);
+    A(p1(v2[1]) == 234);
+
+    v1.Add(p1[678]);
+    A(v1.GetSize() == 6);
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 678);
+    A(p1(v2[1]) == 456);
+    A(p1(v2[2]) == 234);
+  }
+  E;
+
+  B(c03, Slice reverse, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1;
+    v1.Add(p1[123]);
+    v1.Add(p1[234]);
+    v1.Add(p1[345]);
+    v1.Add(p1[456]);
+    v1.Add(p1[567]);
+
+    c4_View v2 = v1.Slice(1, 5,  - 1);
+    A(v2.GetSize() == 4);
+    A(p1(v2[0]) == 567);
+    A(p1(v2[1]) == 456);
+    A(p1(v2[2]) == 345);
+    A(p1(v2[3]) == 234);
+
+    v1.Add(p1[678]);
+    A(v1.GetSize() == 6);
+    A(v2.GetSize() == 4);
+  }
+  E;
+
+  B(c04, Cartesian product, 0) {
+    c4_IntProp p1("p1");
+    c4_IntProp p2("p2");
+
+    c4_View v1;
+    v1.Add(p1[123]);
+    v1.Add(p1[234]);
+    v1.Add(p1[345]);
+
+    c4_View v2;
+    v2.Add(p2[111]);
+    v2.Add(p2[222]);
+
+    c4_View v3 = v1.Product(v2);
+    A(v3.GetSize() == 6);
+    A(p1(v3[0]) == 123);
+    A(p2(v3[0]) == 111);
+    A(p1(v3[1]) == 123);
+    A(p2(v3[1]) == 222);
+    A(p1(v3[2]) == 234);
+    A(p2(v3[2]) == 111);
+    A(p1(v3[3]) == 234);
+    A(p2(v3[3]) == 222);
+    A(p1(v3[4]) == 345);
+    A(p2(v3[4]) == 111);
+    A(p1(v3[5]) == 345);
+    A(p2(v3[5]) == 222);
+
+    v1.Add(p1[456]);
+    A(v3.GetSize() == 8);
+    v2.Add(p2[333]);
+    A(v3.GetSize() == 12);
+  }
+  E;
+
+  B(c05, Remapping, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1;
+    v1.Add(p1[123]);
+    v1.Add(p1[234]);
+    v1.Add(p1[345]);
+
+    c4_View v2;
+    v2.Add(p1[2]);
+    v2.Add(p1[0]);
+    v2.Add(p1[1]);
+    v2.Add(p1[0]);
+
+    c4_View v3 = v1.RemapWith(v2);
+    A(v3.GetSize() == 4);
+    A(p1(v3[0]) == 345);
+    A(p1(v3[1]) == 123);
+    A(p1(v3[2]) == 234);
+    A(p1(v3[3]) == 123);
+  }
+  E;
+
+  B(c06, Pairwise combination, 0) {
+    c4_IntProp p1("p1");
+    c4_IntProp p2("p2");
+
+    c4_View v1;
+    v1.Add(p1[123]);
+    v1.Add(p1[234]);
+    v1.Add(p1[345]);
+
+    c4_View v2;
+    v2.Add(p2[111]);
+    v2.Add(p2[222]);
+    v2.Add(p2[333]);
+
+    c4_View v3 = v1.Pair(v2);
+    A(v3.GetSize() == 3);
+    A(p1(v3[0]) == 123);
+    A(p2(v3[0]) == 111);
+    A(p1(v3[1]) == 234);
+    A(p2(v3[1]) == 222);
+    A(p1(v3[2]) == 345);
+    A(p2(v3[2]) == 333);
+  }
+  E;
+
+  B(c07, Concatenate views, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1;
+    v1.Add(p1[123]);
+    v1.Add(p1[234]);
+    v1.Add(p1[345]);
+
+    c4_View v2;
+    v2.Add(p1[111]);
+    v2.Add(p1[222]);
+
+    c4_View v3 = v1.Concat(v2);
+    A(v3.GetSize() == 5);
+    A(p1(v3[0]) == 123);
+    A(p1(v3[1]) == 234);
+    A(p1(v3[2]) == 345);
+    A(p1(v3[3]) == 111);
+    A(p1(v3[4]) == 222);
+  }
+  E;
+
+  B(c08, Rename property, 0) {
+    c4_IntProp p1("p1");
+    c4_IntProp p2("p2");
+
+    c4_View v1;
+    v1.Add(p1[123]);
+    v1.Add(p1[234]);
+    v1.Add(p1[345]);
+
+    c4_View v2 = v1.Rename(p1, p2);
+    A(v2.GetSize() == 3);
+    A(p2(v2[0]) == 123);
+    A(p2(v2[1]) == 234);
+    A(p2(v2[2]) == 345);
+    A(p1(v2[0]) == 0);
+    A(p1(v2[1]) == 0);
+    A(p1(v2[2]) == 0);
+  }
+  E;
+
+  B(c09, GroupBy operation, 0) {
+    c4_StringProp p1("p1");
+    c4_IntProp p2("p2");
+    c4_ViewProp p3("p3");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[""]);
+    v1.Add(p1["1"] + p2[1]);
+    v1.Add(p1["12"] + p2[1]);
+    v1.Add(p1["12"] + p2[2]);
+    v1.Add(p1["123"] + p2[1]);
+    v1.Add(p1["123"] + p2[2]);
+    v1.Add(p1["123"] + p2[3]);
+
+    v2 = v1.GroupBy(p1, p3);
+    A(v2.GetSize() == 4);
+    A(p1(v2[0]) == (c4_String)"");
+    A(p1(v2[1]) == (c4_String)"1");
+    A(p1(v2[2]) == (c4_String)"12");
+    A(p1(v2[3]) == (c4_String)"123");
+
+    v3 = p3(v2[0]);
+    A(v3.GetSize() == 1);
+    A(p2(v3[0]) == 0);
+    v3 = p3(v2[1]);
+    A(v3.GetSize() == 1);
+    A(p2(v3[0]) == 1);
+    v3 = p3(v2[2]);
+    A(v3.GetSize() == 2);
+    A(p2(v3[0]) == 1);
+    A(p2(v3[1]) == 2);
+    v3 = p3(v2[3]);
+    A(v3.GetSize() == 3);
+    A(p2(v3[0]) == 1);
+    A(p2(v3[1]) == 2);
+    A(p2(v3[2]) == 3);
+
+  }
+  E;
+
+  B(c10, Counts operation, 0) {
+    c4_StringProp p1("p1");
+    c4_IntProp p2("p2"), p3("p3");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[""]);
+    v1.Add(p1["1"] + p2[1]);
+    v1.Add(p1["12"] + p2[1]);
+    v1.Add(p1["12"] + p2[2]);
+    v1.Add(p1["123"] + p2[1]);
+    v1.Add(p1["123"] + p2[2]);
+    v1.Add(p1["123"] + p2[3]);
+
+    v2 = v1.Counts(p1, p3);
+    A(v2.GetSize() == 4);
+    A(p1(v2[0]) == (c4_String)"");
+    A(p1(v2[1]) == (c4_String)"1");
+    A(p1(v2[2]) == (c4_String)"12");
+    A(p1(v2[3]) == (c4_String)"123");
+
+    A(p2(v2[0]) == 0);
+    A(p2(v2[1]) == 0);
+    A(p2(v2[2]) == 0);
+    A(p2(v2[3]) == 0);
+
+    A(p3(v2[0]) == 1);
+    A(p3(v2[1]) == 1);
+    A(p3(v2[2]) == 2);
+    A(p3(v2[3]) == 3);
+
+  }
+  E;
+}
diff --git a/8.x/mk/tests/tcusto2.cpp b/8.x/mk/tests/tcusto2.cpp
new file mode 100755 (executable)
index 0000000..300df60
--- /dev/null
@@ -0,0 +1,441 @@
+// tcusto2.cpp -- Regression test program, custom view tests
+// $Id: tcusto2.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestCustom2() {
+  B(c11, Unique operation, 0);
+   {
+    c4_IntProp p1("p1"), p2("p2");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[1] + p2[11]);
+    v1.Add(p1[1] + p2[22]);
+    v1.Add(p1[2] + p2[33]);
+    v1.Add(p1[2] + p2[33]);
+    v1.Add(p1[3] + p2[44]);
+    v1.Add(p1[4] + p2[55]);
+    v1.Add(p1[4] + p2[55]);
+    v1.Add(p1[4] + p2[55]);
+
+    v2 = v1.Unique();
+    A(v2.GetSize() == 5);
+    A(p1(v2[0]) == 1);
+    A(p1(v2[1]) == 1);
+    A(p1(v2[2]) == 2);
+    A(p1(v2[3]) == 3);
+    A(p1(v2[4]) == 4);
+
+    A(p2(v2[0]) == 11);
+    A(p2(v2[1]) == 22);
+    A(p2(v2[2]) == 33);
+    A(p2(v2[3]) == 44);
+    A(p2(v2[4]) == 55);
+
+  }
+  E;
+
+  B(c12, Union operation, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[1]);
+    v1.Add(p1[2]);
+    v1.Add(p1[3]);
+
+    v2.Add(p1[2]);
+    v2.Add(p1[3]);
+    v2.Add(p1[4]);
+    v2.Add(p1[5]);
+
+    v3 = v1.Union(v2);
+    A(v3.GetSize() == 5);
+    A(p1(v3[0]) == 1);
+    A(p1(v3[1]) == 2);
+    A(p1(v3[2]) == 3);
+    A(p1(v3[3]) == 4);
+    A(p1(v3[4]) == 5);
+  }
+  E;
+
+  B(c13, Intersect operation, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[1]);
+    v1.Add(p1[2]);
+    v1.Add(p1[3]);
+
+    v2.Add(p1[2]);
+    v2.Add(p1[3]);
+    v2.Add(p1[4]);
+    v2.Add(p1[5]);
+
+    v3 = v1.Intersect(v2);
+    A(v3.GetSize() == 2);
+    A(p1(v3[0]) == 2);
+    A(p1(v3[1]) == 3);
+  }
+  E;
+
+  B(c14, Different operation, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[1]);
+    v1.Add(p1[2]);
+    v1.Add(p1[3]);
+
+    v2.Add(p1[2]);
+    v2.Add(p1[3]);
+    v2.Add(p1[4]);
+    v2.Add(p1[5]);
+
+    v3 = v1.Different(v2);
+    A(v3.GetSize() == 3);
+    A(p1(v3[0]) == 1);
+    A(p1(v3[1]) == 4);
+    A(p1(v3[2]) == 5);
+  }
+  E;
+
+  B(c15, Minus operation, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[1]);
+    v1.Add(p1[2]);
+    v1.Add(p1[3]);
+
+    v2.Add(p1[2]);
+    v2.Add(p1[3]);
+    v2.Add(p1[4]);
+    v2.Add(p1[5]);
+
+    v3 = v1.Minus(v2);
+    A(v3.GetSize() == 1);
+    A(p1(v3[0]) == 1);
+  }
+  E;
+
+  B(c16, View comparisons, 0) {
+    c4_IntProp p1("p1");
+
+    c4_View v1;
+    v1.Add(p1[1]);
+    v1.Add(p1[2]);
+    v1.Add(p1[3]);
+    v1.Add(p1[4]);
+    v1.Add(p1[5]);
+
+    A(v1 == v1);
+    A(v1 == v1.Slice(0));
+    A(v1.Slice(0, 2) < v1.Slice(0, 3));
+    A(v1.Slice(0, 3) == v1.Slice(0, 3));
+    A(v1.Slice(0, 4) > v1.Slice(0, 3));
+    A(v1.Slice(0, 3) < v1.Slice(1, 3));
+    A(v1.Slice(0, 3) < v1.Slice(1, 4));
+    A(v1.Slice(1, 3) > v1.Slice(0, 3));
+    A(v1.Slice(1, 4) > v1.Slice(0, 3));
+  }
+  E;
+
+  B(c17, Join operation, 0) {
+    c4_StringProp p1("p1"), p2("p2");
+    c4_IntProp p3("p3");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[""]);
+    v1.Add(p1["1"] + p2["a"]);
+    v1.Add(p1["12"] + p2["ab"]);
+    v1.Add(p1["123"] + p2["abc"]);
+
+    v2.Add(p1["1"] + p3[1]);
+    v2.Add(p1["12"] + p3[1]);
+    v2.Add(p1["12"] + p3[2]);
+    v2.Add(p1["123"] + p3[1]);
+    v2.Add(p1["123"] + p3[2]);
+    v2.Add(p1["123"] + p3[3]);
+
+    v3 = v1.Join(p1, v2); // inner join
+    A(v3.GetSize() == 6);
+
+    A(p1(v3[0]) == (c4_String)"1");
+    A(p1(v3[1]) == (c4_String)"12");
+    A(p1(v3[2]) == (c4_String)"12");
+    A(p1(v3[3]) == (c4_String)"123");
+    A(p1(v3[4]) == (c4_String)"123");
+    A(p1(v3[5]) == (c4_String)"123");
+
+    A(p2(v3[0]) == (c4_String)"a");
+    A(p2(v3[1]) == (c4_String)"ab");
+    A(p2(v3[2]) == (c4_String)"ab");
+    A(p2(v3[3]) == (c4_String)"abc");
+    A(p2(v3[4]) == (c4_String)"abc");
+    A(p2(v3[5]) == (c4_String)"abc");
+
+    A(p3(v3[0]) == 1);
+    A(p3(v3[1]) == 1);
+    A(p3(v3[2]) == 2);
+    A(p3(v3[3]) == 1);
+    A(p3(v3[4]) == 2);
+    A(p3(v3[5]) == 3);
+
+    v3 = v1.Join(p1, v2, true); // outer join
+    A(v3.GetSize() == 7);
+
+    A(p1(v3[0]) == (c4_String)"");
+    A(p1(v3[1]) == (c4_String)"1");
+    A(p1(v3[2]) == (c4_String)"12");
+    A(p1(v3[3]) == (c4_String)"12");
+    A(p1(v3[4]) == (c4_String)"123");
+    A(p1(v3[5]) == (c4_String)"123");
+    A(p1(v3[6]) == (c4_String)"123");
+
+    A(p2(v3[0]) == (c4_String)"");
+    A(p2(v3[1]) == (c4_String)"a");
+    A(p2(v3[2]) == (c4_String)"ab");
+    A(p2(v3[3]) == (c4_String)"ab");
+    A(p2(v3[4]) == (c4_String)"abc");
+    A(p2(v3[5]) == (c4_String)"abc");
+    A(p2(v3[6]) == (c4_String)"abc");
+
+    A(p3(v3[0]) == 0);
+    A(p3(v3[1]) == 1);
+    A(p3(v3[2]) == 1);
+    A(p3(v3[3]) == 2);
+    A(p3(v3[4]) == 1);
+    A(p3(v3[5]) == 2);
+    A(p3(v3[6]) == 3);
+  }
+  E;
+
+  B(c18, Groupby sort fix, 0) { // fails in 1.8.4 (from P. Ritter, 14-10-1998)
+    c4_StringProp p1("Country");
+    c4_StringProp p2("City");
+    c4_ViewProp p3("SubList");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1["US"] + p2["Philadelphia"]);
+    v1.Add(p1["France"] + p2["Bordeaux"]);
+    v1.Add(p1["US"] + p2["Miami"]);
+    v1.Add(p1["France"] + p2["Paris"]);
+    v1.Add(p1["US"] + p2["Boston"]);
+    v1.Add(p1["France"] + p2["Nice"]);
+    v1.Add(p1["US"] + p2["NY"]);
+    v1.Add(p1["US"] + p2["Miami"]);
+
+    v2 = v1.GroupBy(p1, p3);
+    A(v2.GetSize() == 2);
+    A(p1(v2[0]) == (c4_String)"France");
+    A(p1(v2[1]) == (c4_String)"US");
+
+    v3 = p3(v2[0]);
+    A(v3.GetSize() == 3);
+    A(p2(v3[0]) == (c4_String)"Bordeaux");
+    A(p2(v3[1]) == (c4_String)"Nice");
+    A(p2(v3[2]) == (c4_String)"Paris");
+    v3 = p3(v2[1]);
+    A(v3.GetSize() == 5);
+    A(p2(v3[0]) == (c4_String)"Boston");
+    A(p2(v3[1]) == (c4_String)"Miami");
+    A(p2(v3[2]) == (c4_String)"Miami");
+    A(p2(v3[3]) == (c4_String)"NY");
+    A(p2(v3[4]) == (c4_String)"Philadelphia");
+  }
+  E;
+
+  B(c19, JoinProp operation, 0) { // moved, used to also be called c15
+    c4_StringProp p1("p1");
+    c4_ViewProp p2("p2");
+    c4_IntProp p3("p3");
+
+    c4_View v1, v2a, v2b, v2c, v3;
+
+    v2a.Add(p3[1]);
+    v2a.Add(p3[2]);
+    v2a.Add(p3[3]);
+    v1.Add(p1["123"] + p2[v2a]);
+
+    v2b.Add(p3[1]);
+    v2b.Add(p3[2]);
+    v1.Add(p1["12"] + p2[v2b]);
+
+    v2c.Add(p3[1]);
+    v1.Add(p1["1"] + p2[v2c]);
+
+    v1.Add(p1[""]);
+
+    v3 = v1.JoinProp(p2); // inner join
+    A(v3.GetSize() == 6);
+
+    A(p1(v3[0]) == (c4_String)"123");
+    A(p1(v3[1]) == (c4_String)"123");
+    A(p1(v3[2]) == (c4_String)"123");
+    A(p1(v3[3]) == (c4_String)"12");
+    A(p1(v3[4]) == (c4_String)"12");
+    A(p1(v3[5]) == (c4_String)"1");
+
+    A(p3(v3[0]) == 1);
+    A(p3(v3[1]) == 2);
+    A(p3(v3[2]) == 3);
+    A(p3(v3[3]) == 1);
+    A(p3(v3[4]) == 2);
+    A(p3(v3[5]) == 1);
+
+    v3 = v1.JoinProp(p2, true); // outer join
+    A(v3.GetSize() == 7);
+
+    A(p1(v3[0]) == (c4_String)"123");
+    A(p1(v3[1]) == (c4_String)"123");
+    A(p1(v3[2]) == (c4_String)"123");
+    A(p1(v3[3]) == (c4_String)"12");
+    A(p1(v3[4]) == (c4_String)"12");
+    A(p1(v3[5]) == (c4_String)"1");
+    A(p1(v3[6]) == (c4_String)"");
+
+    A(p3(v3[0]) == 1);
+    A(p3(v3[1]) == 2);
+    A(p3(v3[2]) == 3);
+    A(p3(v3[3]) == 1);
+    A(p3(v3[4]) == 2);
+    A(p3(v3[5]) == 1);
+    A(p3(v3[6]) == 0);
+  }
+  E;
+
+  B(c20, Wide cartesian product, 0) {
+    // added 2nd prop's to do a better test - 1999-12-23
+    c4_IntProp p1("p1");
+    c4_IntProp p2("p2");
+    c4_IntProp p3("p3");
+    c4_IntProp p4("p4");
+
+    c4_View v1;
+    v1.Add(p1[123] + p2[321]);
+    v1.Add(p1[234] + p2[432]);
+    v1.Add(p1[345] + p2[543]);
+
+    c4_View v2;
+    v2.Add(p3[111] + p4[11]);
+    v2.Add(p3[222] + p4[22]);
+
+    c4_View v3 = v1.Product(v2);
+    A(v3.GetSize() == 6);
+    A(p1(v3[0]) == 123);
+    A(p2(v3[0]) == 321);
+    A(p3(v3[0]) == 111);
+    A(p4(v3[0]) == 11);
+    A(p1(v3[1]) == 123);
+    A(p2(v3[1]) == 321);
+    A(p3(v3[1]) == 222);
+    A(p4(v3[1]) == 22);
+    A(p1(v3[2]) == 234);
+    A(p2(v3[2]) == 432);
+    A(p3(v3[2]) == 111);
+    A(p4(v3[2]) == 11);
+    A(p1(v3[3]) == 234);
+    A(p2(v3[3]) == 432);
+    A(p3(v3[3]) == 222);
+    A(p4(v3[3]) == 22);
+    A(p1(v3[4]) == 345);
+    A(p2(v3[4]) == 543);
+    A(p3(v3[4]) == 111);
+    A(p4(v3[4]) == 11);
+    A(p1(v3[5]) == 345);
+    A(p2(v3[5]) == 543);
+    A(p3(v3[5]) == 222);
+    A(p4(v3[5]) == 22);
+
+    v1.Add(p1[456]);
+    A(v3.GetSize() == 8);
+    v2.Add(p2[333]);
+    A(v3.GetSize() == 12);
+  }
+  E;
+
+  B(c21, Join on compound key, 0) {
+    c4_IntProp p1("p1"), p2("p2"), p3("p3"), p4("p4");
+
+    c4_View v1, v2, v3;
+
+    v1.Add(p1[1] + p2[11] + p3[111]);
+    v1.Add(p1[2] + p2[22] + p3[222]);
+    v1.Add(p1[3] + p2[22] + p3[111]);
+
+    v2.Add(p2[11] + p3[111] + p4[1111]);
+    v2.Add(p2[22] + p3[222] + p4[2222]);
+    v2.Add(p2[22] + p3[222] + p4[3333]);
+    v2.Add(p2[22] + p3[333] + p4[4444]);
+
+    // this works here, but it fails in Python, i.e. Mk4py 2.4.0
+    v3 = v1.Join((p2, p3), v2);
+
+    A(v3.GetSize() == 3);
+
+    A(p1(v3[0]) == 1);
+    A(p1(v3[1]) == 2);
+    A(p1(v3[2]) == 2);
+
+    A(p2(v3[0]) == 11);
+    A(p2(v3[1]) == 22);
+    A(p2(v3[2]) == 22);
+
+    A(p3(v3[0]) == 111);
+    A(p3(v3[1]) == 222);
+    A(p3(v3[2]) == 222);
+
+    A(p4(v3[0]) == 1111);
+    A(p4(v3[1]) == 2222);
+    A(p4(v3[2]) == 3333);
+  }
+  E;
+
+  B(c22, Groupby with selection, 0) {
+    c4_Storage s1;
+    c4_View v1 = s1.GetAs("v1[p1:I,p2:I,p3:I]");
+    c4_IntProp p1("p1"), p2("p2"), p3("p3");
+    c4_ViewProp p4("p4");
+
+    v1.Add(p1[0] + p2[1] + p3[10]);
+    v1.Add(p1[1] + p2[1] + p3[20]);
+    v1.Add(p1[2] + p2[2] + p3[30]);
+    v1.Add(p1[3] + p2[3] + p3[40]);
+    v1.Add(p1[4] + p2[3] + p3[50]);
+
+    s1.Commit();
+    A(v1.GetSize() == 5);
+
+    c4_View v2 = v1.GroupBy(p2, p4);
+    A(v2.GetSize() == 3);
+
+    c4_View v3 = p4(v2[0]);
+    A(v3.GetSize() == 2);
+    A(p3(v3[0]) == 10);
+    A(p3(v3[1]) == 20);
+
+    c4_View v4 = p4(v2[1]);
+    A(v4.GetSize() == 1);
+    A(p3(v4[0]) == 30);
+
+    c4_View v5 = p4(v2[2]);
+    A(v5.GetSize() == 2);
+    A(p3(v5[0]) == 40);
+    A(p3(v5[1]) == 50);
+
+    c4_View v6 = v4.Sort();
+    A(v6.GetSize() == 1);
+    A(p1(v6[0]) == 2);
+    A(p3(v6[0]) == 30);
+
+  }
+  E;
+}
diff --git a/8.x/mk/tests/tdiffer.cpp b/8.x/mk/tests/tdiffer.cpp
new file mode 100644 (file)
index 0000000..02dee66
--- /dev/null
@@ -0,0 +1,57 @@
+// tdiffer.cpp -- Regression test program, differential commit tests
+// $Id: tdiffer.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestDiffer() {
+  B(d01, Commit aside, 0)W(d01a);
+  W(d01b);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("d01a", 1);
+      A(s1.Strategy().FileSize() == 0);
+      c4_View v1 = s1.GetAs("a[p1:I]");
+      v1.Add(p1[123]);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("d01a", 0);
+      c4_Storage s2("d01b", 1);
+      s1.SetAside(s2);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+      v1.Add(p1[456]);
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 123);
+      A(p1(v1[1]) == 456);
+      s1.Commit();
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 123);
+      A(p1(v1[1]) == 456);
+      s2.Commit();
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 123);
+      A(p1(v1[1]) == 456);
+    }
+     {
+      c4_Storage s1("d01a", 0);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+      c4_Storage s2("d01b", 0);
+      s1.SetAside(s2);
+      c4_View v2 = s1.View("a");
+      A(v2.GetSize() == 2);
+      A(p1(v2[0]) == 123);
+      A(p1(v2[1]) == 456);
+    }
+  }
+  D(d01a);
+  D(d01b);
+  R(d01a);
+  R(d01b);
+  E;
+}
diff --git a/8.x/mk/tests/textend.cpp b/8.x/mk/tests/textend.cpp
new file mode 100644 (file)
index 0000000..3871d83
--- /dev/null
@@ -0,0 +1,209 @@
+// textend.cpp -- Regression test program, commit extend tests
+// $Id: textend.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+const int kSize1 = 41;
+const int kSize2 = 85;
+
+void TestExtend() {
+  B(e01, Extend new file, 0)W(e01a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("e01a", 2);
+    A(s1.Strategy().FileSize() == 0);
+    c4_View v1 = s1.GetAs("a[p1:I]");
+    v1.Add(p1[123]);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize1);
+    v1.Add(p1[456]);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize2);
+  }
+  D(e01a);
+  R(e01a);
+  E;
+
+  B(e02, Extend committing twice, 0)W(e02a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("e02a", 2);
+    A(s1.Strategy().FileSize() == 0);
+    c4_View v1 = s1.GetAs("a[p1:I]");
+    v1.Add(p1[123]);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize1);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize1);
+    v1.Add(p1[456]);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize2);
+  }
+  D(e02a);
+  R(e02a);
+  E;
+
+  B(e03, Read during extend, 0)W(e03a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("e03a", 2);
+    A(s1.Strategy().FileSize() == 0);
+    c4_View v1 = s1.GetAs("a[p1:I]");
+    v1.Add(p1[123]);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize1);
+
+     {
+      c4_Storage s2("e03a", 0);
+      c4_View v2 = s2.View("a");
+      A(v2.GetSize() == 1);
+      A(p1(v2[0]) == 123);
+    }
+
+    v1.Add(p1[456]);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize2);
+
+     {
+      c4_Storage s3("e03a", 0);
+      c4_View v3 = s3.View("a");
+      A(v3.GetSize() == 2);
+      A(p1(v3[0]) == 123);
+      A(p1(v3[1]) == 456);
+    }
+  }
+  D(e03a);
+  R(e03a);
+  E;
+
+  B(e04, Extend during read, 0)W(e04a);
+   {
+    c4_IntProp p1("p1");
+
+     {
+      c4_Storage s1("e04a", 2);
+      A(s1.Strategy().FileSize() == 0);
+      c4_View v1 = s1.GetAs("a[p1:I]");
+      v1.Add(p1[123]);
+      s1.Commit();
+      A(s1.Strategy().FileSize() == kSize1);
+    }
+
+    c4_Storage s2("e04a", 0);
+    c4_View v2 = s2.View("a");
+    A(v2.GetSize() == 1);
+    A(p1(v2[0]) == 123);
+
+    c4_Storage s3("e04a", 0); { // open, don't load
+
+    
+      c4_Storage s4("e04a", 2);
+      A(s4.Strategy().FileSize() == kSize1);
+      c4_View v4 = s4.View("a");
+      v4.Add(p1[123]);
+      s4.Commit();
+      A(s4.Strategy().FileSize() > kSize1); // == kSize2);
+    }
+
+    c4_View v2a = s2.View("a");
+    A(v2a.GetSize() == 1);
+    A(p1(v2a[0]) == 123);
+
+    c4_View v3 = s3.View("a");
+    A(v3.GetSize() == 1);
+    A(p1(v3[0]) == 123);
+
+  }
+  D(e04a);
+  R(e04a);
+  E;
+
+  B(e05, Test memory mapping, 0)W(e05a);
+   {
+    // this is not a test of MK, but of the underlying system code
+
+     {
+      c4_FileStrategy fs;
+      bool f1 = fs.DataOpen("e05a", 1);
+      A(!f1);
+      fs.DataWrite(0, "hi!", 3);
+      A(fs._failure == 0);
+      A(fs.FileSize() == 3);
+      fs.DataCommit(0);
+      A(fs.FileSize() == 3);
+      fs.ResetFileMapping();
+      if (fs._mapStart != 0) {
+        A(fs._dataSize == 3);
+        c4_String s((char*)fs._mapStart, 3);
+        A(s == "hi!");
+      }
+      fs.DataWrite(3, "hello", 5);
+      A(fs._failure == 0);
+      A(fs.FileSize() == 8);
+      fs.DataCommit(0);
+      A(fs.FileSize() == 8);
+      if (fs._mapStart != 0) {
+        A(fs._dataSize == 3);
+        c4_String s((char*)fs._mapStart, 8);
+        A(s == "hi!hello");
+      }
+      fs.DataWrite(100, "wow!", 4);
+      A(fs._failure == 0);
+      A(fs.FileSize() == 104);
+      fs.DataCommit(0);
+      A(fs.FileSize() == 104);
+      fs.ResetFileMapping();
+      if (fs._mapStart != 0) {
+        A(fs._dataSize == 104);
+        c4_String s((char*)fs._mapStart + 100, 4);
+        A(s == "wow!");
+      }
+    }
+
+    // clear the file, so dump doesn't choke on it
+    FILE *fp = fopen("e05a", "w");
+    A(fp != 0);
+    fclose(fp);
+
+  }
+  D(e05a);
+  R(e05a);
+  E;
+
+  B(e06, Rollback during extend, 0)W(e06a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("e06a", 2);
+    A(s1.Strategy().FileSize() == 0);
+    c4_View v1 = s1.GetAs("a[p1:I]");
+    v1.Add(p1[123]);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize1);
+
+    c4_Storage s2("e06a", 0);
+    c4_View v2 = s2.View("a");
+    A(v2.GetSize() == 1);
+    A(p1(v2[0]) == 123);
+
+    v1.Add(p1[456]);
+    s1.Commit();
+    A(s1.Strategy().FileSize() == kSize2);
+#if 0
+    /* fails on NT + Samba, though it works fine with mmap'ing disabled */
+    s2.Rollback();
+
+    c4_View v2a = s2.View("a");
+    A(v2a.GetSize() == 2);
+    A(p1(v2a[0]) == 123);
+    A(p1(v2a[1]) == 456);
+#else 
+    c4_View v2a = s2.View("a");
+    A(v2a.GetSize() == 1);
+    A(p1(v2a[0]) == 123);
+#endif 
+  }
+  D(e06a);
+  R(e06a);
+  E;
+}
diff --git a/8.x/mk/tests/tformat.cpp b/8.x/mk/tests/tformat.cpp
new file mode 100755 (executable)
index 0000000..750ab57
--- /dev/null
@@ -0,0 +1,335 @@
+// tformat.cpp -- Regression test program, (re-)format tests
+// $Id: tformat.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+#include "regress.h"
+
+void TestFormat() {
+  B(f01, Add view to format, 0)W(f01a);
+   {
+    c4_IntProp p1("p1");
+    c4_IntProp p2("p2");
+     {
+      c4_Storage s1("f01a", 1);
+      s1.SetStructure("a[p1:I]");
+
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+      s1.Commit();
+
+      c4_View v2 = s1.GetAs("b[p2:I]");
+
+      v2.Add(p2[345]);
+      v2.Add(p2[567]);
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("f01a", 0);
+
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+
+      c4_View v2 = s1.View("b");
+      A(v2.GetSize() == 2);
+      A(p2(v2[0]) == 345);
+      A(p2(v2[1]) == 567);
+    }
+  }
+  D(f01a);
+  R(f01a);
+  E;
+
+  B(f02, Remove view from format, 0)W(f02a);
+   {
+    c4_IntProp p1("p1");
+    c4_IntProp p2("p2");
+     {
+      c4_Storage s1("f02a", 1);
+      s1.SetStructure("a[p1:I],b[p2:I]");
+
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+
+      c4_View v2 = s1.View("b");
+      v2.Add(p2[345]);
+      v2.Add(p2[567]);
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("f02a", 1);
+      s1.SetStructure("b[p2:I]");
+
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1); // 19990916 new semantics, still as temp view
+      A(p1(v1[0]) == 123);
+
+      c4_View v2 = s1.View("b");
+      A(v2.GetSize() == 2);
+      A(p2(v2[0]) == 345);
+      A(p2(v2[1]) == 567);
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("f02a", 0);
+
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 0);
+
+      c4_View v2 = s1.View("b");
+      A(v2.GetSize() == 2);
+      A(p2(v2[0]) == 345);
+      A(p2(v2[1]) == 567);
+    }
+  }
+  D(f02a);
+  R(f02a);
+  E;
+
+  B(f03, Rollback format change, 0)W(f03a);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("f03a", 1);
+      s1.SetStructure("a[p1:I]");
+
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+
+      s1.Commit();
+
+      v1 = s1.GetAs("a");
+      A(v1.GetSize() == 0);
+
+      s1.Rollback();
+
+      v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+    }
+  }
+  D(f03a);
+  R(f03a);
+  E;
+
+  B(f04, Rearrange format, 0)W(f04a);
+   {
+    c4_IntProp p1("p1");
+    c4_IntProp p2("p2");
+     {
+      c4_Storage s1("f04a", 1);
+      s1.SetStructure("a[p1:I],b[p2:I]");
+
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+
+      c4_View v2 = s1.View("b");
+      v2.Add(p2[345]);
+      v2.Add(p2[567]);
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("f04a", 1);
+      s1.SetStructure("b[p2:I],a[p1:I]");
+
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+
+      c4_View v2 = s1.View("b");
+      A(v2.GetSize() == 2);
+      A(p2(v2[0]) == 345);
+      A(p2(v2[1]) == 567);
+
+      s1.Commit();
+    }
+  }
+  D(f04a);
+  R(f04a);
+  E;
+
+  B(f05, Nested reformat, 0)W(f05a);
+   {
+    c4_IntProp p1("p1");
+    c4_IntProp p2("p2");
+     {
+      c4_Storage s1("f05a", 1);
+      s1.SetStructure("a[p1:I],b[p2:I]");
+
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+
+      c4_View v2 = s1.View("b");
+      v2.Add(p2[345]);
+      v2.Add(p2[567]);
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("f05a", 1);
+      s1.SetStructure("a[p1:I],b[p1:I,p2:I]");
+
+      c4_View v2 = s1.View("b");
+      p1(v2[0]) = 543;
+      p1(v2[1]) = 765;
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("f05a", 0);
+
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+
+      c4_View v2 = s1.View("b");
+      A(v2.GetSize() == 2);
+      A(p1(v2[0]) == 543);
+      A(p1(v2[1]) == 765);
+      A(p2(v2[0]) == 345);
+      A(p2(v2[1]) == 567);
+    }
+  }
+  D(f05a);
+  R(f05a);
+  E;
+
+  B(f06, Flip foreign data, 0) {
+    D(reversed); // not created here, only dump existing file
+  }
+  E;
+
+  B(f07, Automatic structure info (obsolete), 0)W(f07a);
+   {
+    /* Structure() and Store() are no longer supported
+    c4_StringProp p1 ("p1"), p2 ("p2");
+    c4_Row r1 = p1 ["One"] + p2 ["Two"];
+    c4_Row r2;
+    c4_View v1;
+    v1.Add(r1);
+    v1.Add(r2);
+    v1.Add(r1);
+
+    c4_View v2 = v1.Structure();
+    A(v2.GetSize() == 1);
+
+    c4_ViewProp pView ("view");
+    c4_View v3 = pView (v2[0]);
+    A(v3.GetSize() == 2);
+     */
+#define FORMAT07 "dict[parent:I,index:I,view[name:S,type:S,child:I]]"
+    c4_Storage s1("f07a", 1);
+    s1.SetStructure(FORMAT07);
+
+    //s1.View("dict") = v1.Structure();
+
+    s1.Commit();
+
+  }
+  D(f07a);
+  R(f07a);
+  E;
+
+  B(f08, Automatic storage format, 0)W(f08a);
+   {
+    c4_StringProp p1("p1"), p2("p2");
+    c4_Row r1 = p1["One"] + p2["Two"];
+    c4_Row r2;
+    c4_View v1;
+    v1.Add(r1);
+    v1.Add(r2);
+    v1.Add(r1);
+
+    c4_Storage s1("f08a", 1);
+
+    // changed 2000-03-15: Store is gone
+    //s1.Store("dict", v1);
+    c4_View v2 = s1.GetAs("dict[p1:S,p2:S]");
+    v2.InsertAt(0, v1);
+
+    s1.Commit();
+
+  }
+  D(f08a);
+  R(f08a);
+  E;
+
+  B(f09, Partial restructuring, 0)W(f09a);
+   {
+    c4_IntProp p1("p1"), p2("p2"), p3("p3");
+    c4_Storage s1("f09a", 1);
+
+    c4_View v1 = s1.GetAs("a[p1:I]");
+    v1.SetSize(10);
+
+    for (int i = 0; i < v1.GetSize(); ++i)
+      p1(v1[i]) = 1000+i;
+
+    c4_View v2 = s1.GetAs("a[p1:I,p2:I]");
+
+    for (int j = 0; j < v2.GetSize(); j += 2)
+      p2(v2[j]) = 2000+j;
+
+    c4_View v3 = s1.GetAs("a[p1:I,p2:I,p3:I]");
+
+    for (int k = 0; k < v3.GetSize(); k += 3)
+      p3(v3[k]) = 3000+k;
+
+    s1.Commit();
+
+  }
+  D(f09a);
+  R(f09a);
+  E;
+
+  B(f10, Committed restructuring, 0)W(f10a);
+   {
+    c4_IntProp p1("p1"), p2("p2"), p3("p3");
+    c4_Storage s1("f10a", 1);
+
+    c4_View v1 = s1.GetAs("a[p1:I]");
+    v1.SetSize(10);
+
+    for (int i = 0; i < v1.GetSize(); ++i)
+      p1(v1[i]) = 1000+i;
+
+    s1.Commit();
+
+    c4_View v2 = s1.GetAs("a[p1:I,p2:I]");
+
+    for (int j = 0; j < v2.GetSize(); j += 2)
+      p2(v2[j]) = 2000+j;
+
+    s1.Commit();
+
+    c4_View v3 = s1.GetAs("a[p1:I,p2:I,p3:I]");
+
+    for (int k = 0; k < v3.GetSize(); k += 3)
+      p3(v3[k]) = 3000+k;
+
+    s1.Commit();
+
+  }
+  D(f10a);
+  R(f10a);
+  E;
+
+  // 19990824: don't crash on GetAs with an inexistent view
+  B(f11, Delete missing view, 0)W(f11a);
+   {
+    c4_Storage s1("f11a", 1);
+
+    c4_View v1 = s1.GetAs("a");
+    v1.SetSize(10);
+
+    s1.Commit();
+
+  }
+  D(f11a);
+  R(f11a);
+  E;
+}
diff --git a/8.x/mk/tests/tlimits.cpp b/8.x/mk/tests/tlimits.cpp
new file mode 100755 (executable)
index 0000000..cdb6c32
--- /dev/null
@@ -0,0 +1,292 @@
+// tlimits.cpp -- Regression test program, limit tests
+// $Id: tlimits.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestLimits() {
+  B(l00, Lots of properties, 0)W(l00a);
+   {
+    c4_String desc;
+
+    for (int i = 1; i < 150; ++i) {
+      char buf[20];
+      sprintf(buf, ",p%d:I", i);
+
+      desc += buf;
+    }
+
+    desc = "a[" + desc.Mid(1) + "]";
+
+    c4_Storage s1("l00a", 1);
+    s1.SetStructure(desc);
+    c4_View v1 = s1.View("a");
+    c4_IntProp p123("p123");
+    v1.Add(p123[123]);
+    s1.Commit();
+
+  }
+  D(l00a);
+  R(l00a);
+  E;
+
+  B(l01, Over 32 Kb of integers, 0)W(l01a);
+   {
+    c4_Storage s1("l01a", 1);
+    s1.SetStructure("a[p1:I]");
+    c4_View v1 = s1.View("a");
+    c4_IntProp p1("p1");
+    v1.SetSize(9000);
+
+    for (int i = 0; i < v1.GetSize(); ++i) {
+      p1(v1[i]) = 1000000L + i;
+
+      A(p1(v1[i]) - 1000000L == i);
+    }
+
+    for (int j = 0; j < v1.GetSize(); ++j) {
+      A(p1(v1[j]) - 1000000L == j);
+    }
+
+    s1.Commit();
+
+    for (int k = 0; k < v1.GetSize(); ++k) {
+      A(p1(v1[k]) - 1000000L == k);
+    }
+
+  }
+  D(l01a);
+  R(l01a);
+  E;
+
+  B(l02, Over 64 Kb of strings, 0)W(l02a);
+   {
+    static char *texts[3] =  {
+      "Alice in Wonderland", "The wizard of Oz", "I'm singin' in the rain"
+    };
+
+    c4_Storage s1("l02a", 1);
+    s1.SetStructure("a[p1:S]");
+    c4_View v1 = s1.View("a");
+    c4_StringProp p1("p1");
+    c4_Row r1;
+
+    for (int i = 0; i < 3500; ++i) {
+      p1(r1) = texts[i % 3];
+      v1.Add(r1);
+
+      A(p1(v1[i]) == (c4_String)texts[i % 3]);
+    }
+
+    for (int j = 0; j < v1.GetSize(); ++j) {
+      A(p1(v1[j]) == (c4_String)texts[j % 3]);
+    }
+
+    s1.Commit();
+
+    for (int k = 0; k < v1.GetSize(); ++k) {
+      A(p1(v1[k]) == (c4_String)texts[k % 3]);
+    }
+
+  }
+  D(l02a);
+  R(l02a);
+  E;
+
+  B(l03, Force sections in storage, 0)W(l03a);
+  W(l03b);
+   {
+    c4_ViewProp p1("p1");
+    c4_IntProp p2("p2");
+
+     {
+      c4_Storage s1("l03a", 1);
+      s1.SetStructure("a[p1[p2:I]]");
+      c4_View v1 = s1.View("a");
+
+      c4_View v2;
+      v2.SetSize(1);
+
+      for (int i = 0; i < 500; ++i) {
+        p2(v2[0]) = 9000+i;
+        v1.Add(p1[v2]);
+      }
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("l03a", 0);
+      c4_View v1 = s1.View("a");
+
+      for (int i = 0; i < 500; ++i) {
+        c4_View v2 = p1(v1[i]);
+        A(p2(v2[0]) == 9000+i);
+      }
+
+      c4_FileStream fs1(fopen("l03b", "wb"), true);
+      s1.SaveTo(fs1);
+    }
+     {
+      c4_Storage s1;
+
+      c4_FileStream fs1(fopen("l03b", "rb"), true);
+      s1.LoadFrom(fs1);
+
+      c4_View v1 = s1.View("a");
+
+      for (int i = 0; i < 500; ++i) {
+        c4_View v2 = p1(v1[i]);
+        A(p2(v2[0]) == 9000+i);
+      }
+    }
+  }
+  D(l03a);
+  D(l03b);
+  R(l03a);
+  R(l03b);
+  E;
+
+  B(l04, Modify sections in storage, 0)W(l04a);
+   {
+    c4_ViewProp p1("p1");
+    c4_IntProp p2("p2");
+
+     {
+      c4_Storage s1("l04a", 1);
+      s1.SetStructure("a[p1[p2:I]]");
+      c4_View v1 = s1.View("a");
+
+      c4_View v2;
+      v2.SetSize(1);
+
+      for (int i = 0; i < 500; ++i) {
+        p2(v2[0]) = 9000+i;
+        v1.Add(p1[v2]);
+      }
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("l04a", 1);
+      c4_View v1 = s1.View("a");
+      c4_View v2 = p1(v1[0]);
+
+      p2(v2[0]) = 1;
+      // this corrupted file in 1.5: free space was bad after load
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("l04a", 0);
+    }
+  }
+  D(l04a);
+  R(l04a);
+  E;
+
+  B(l05, Delete from 32 Kb of strings, 0)W(l05a);
+   {
+    static char *texts[3] =  {
+      "Alice in Wonderland", "The wizard of Oz", "I'm singin' in the rain"
+    };
+
+    c4_Storage s1("l05a", 1);
+    s1.SetStructure("a[p1:I,p2:S,p3:S]");
+    c4_View v1 = s1.View("a");
+    c4_IntProp p1("p1");
+    c4_StringProp p2("p2"), p3("p3");
+    c4_Row r1;
+
+    for (int i = 0; i < 1750; ++i) {
+      p1(r1) = i;
+      p2(r1) = texts[i % 3];
+      p3(r1) = texts[i % 3];
+      v1.Add(r1);
+
+      A(p2(v1[i]) == (c4_String)texts[i % 3]);
+    }
+
+    for (int j = 0; j < v1.GetSize(); ++j) {
+      A(p1(v1[j]) == j);
+      A(p2(v1[j]) == (c4_String)texts[j % 3]);
+      A(p3(v1[j]) == (c4_String)texts[j % 3]);
+    }
+
+    s1.Commit();
+
+    while (v1.GetSize() > 1)
+    // randomly remove entries
+      v1.RemoveAt((unsigned short)(211 *v1.GetSize()) % v1.GetSize());
+
+    s1.Commit();
+
+  }
+  D(l05a);
+  R(l05a);
+  E;
+
+  B(l06, Bit field manipulations, 0)W(l06a);
+   {
+    c4_IntProp p1("p1");
+    c4_View v2;
+
+     {
+      c4_Storage s1("l06a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      c4_Row r1;
+
+      for (int i = 2; i <= 256; i <<= 1) {
+        for (int j = 0; j < 18; ++j) {
+          p1(r1) = j &(i - 1);
+
+          v1.InsertAt(j, r1, j + 1);
+          v2.InsertAt(j, r1, j + 1);
+        }
+
+        s1.Commit();
+      }
+    }
+     {
+      c4_Storage s1("l06a", 0);
+      c4_View v1 = s1.View("a");
+
+      int n = v2.GetSize();
+      A(n == v1.GetSize());
+
+      for (int i = 0; i < n; ++i) {
+        long v = p1(v2[i]);
+        A(p1(v1[i]) == v);
+      }
+    }
+
+  }
+  D(l06a);
+  R(l06a);
+  E;
+
+  B(l07, Huge description, 0)W(l07a);
+   {
+    c4_String desc;
+
+    for (int i = 1; i < 150; ++i) {
+      char buf[50];
+      // 1999-07-25: longer size to force over 4 Kb of description
+      sprintf(buf, ",a123456789a123456789a123456789p%d:I", i);
+
+      desc += buf;
+    }
+
+    desc = "a[" + desc.Mid(1) + "]";
+
+    c4_Storage s1("l07a", 1);
+    s1.SetStructure(desc);
+    c4_View v1 = s1.View("a");
+    c4_IntProp p123("p123");
+    v1.Add(p123[123]);
+    s1.Commit();
+
+  }
+  D(l07a);
+  R(l07a);
+  E;
+}
diff --git a/8.x/mk/tests/tmapped.cpp b/8.x/mk/tests/tmapped.cpp
new file mode 100644 (file)
index 0000000..3003646
--- /dev/null
@@ -0,0 +1,262 @@
+// tmapped.cpp -- Regression test program, mapped view tests
+// $Id: tmapped.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestBlockDel(int pos_, int len_) {
+  printf("blockdel pos %d len %d\n", pos_, len_);
+
+  c4_ViewProp p1("_B");
+  c4_IntProp p2("p2");
+
+  c4_Storage s1;
+  c4_View v1 = s1.GetAs("v1[_B[p2:I]]");
+
+  int n = 0;
+  static int sizes[] =  {
+    999, 999, 999, 2, 0
+  };
+
+  for (int i = 0; sizes[i]; ++i) {
+    c4_View v;
+    v.SetSize(sizes[i]);
+    for (int j = 0; j < sizes[i]; ++j)
+      p2(v[j]) = ++n;
+    v1.Add(p1[v]);
+  }
+
+  c4_View v2 = v1.Blocked();
+  A(v2.GetSize() == 2999);
+
+  v2.RemoveAt(pos_, len_);
+  A(v2.GetSize() == 2999-len_);
+}
+
+void TestMapped() {
+  B(m01, Hash mapping, 0);
+   {
+    c4_StringProp p1("p1");
+
+    c4_Storage s1;
+    c4_View v1 = s1.GetAs("v1[p1:S]");
+    c4_View v2 = s1.GetAs("v2[_H:I,_R:I]");
+    c4_View v3 = v1.Hash(v2, 1);
+
+    v3.Add(p1["b93655249726e5ef4c68e45033c2e0850570e1e07"]);
+    v3.Add(p1["2ab03fba463d214f854a71ab5c951cea096887adf"]);
+    v3.Add(p1["2e196eecb91b02c16c23360d8e1b205f0b3e3fa3d"]);
+    A(v3.GetSize() == 3);
+
+    // infinite loop in 2.4.0, reported by Nathan Rogers, July 2001
+    // happens when looking for missing key after a hash collision
+    int f = v3.Find(p1["7c0734c9187133f34588517fb5b39294076f22ba3"]);
+    A(f ==  - 1);
+  }
+  E;
+
+  // example from Steve Baxter, Nov 2001, after block perf bugfix
+  // assertion failure on row 1001, due to commit data mismatch
+  B(m02, Blocked view bug, 0)W(m02a);
+   {
+    c4_BytesProp p1("p1");
+    c4_Bytes h;
+
+    c4_Storage s1("m02a", true);
+    c4_View v1 = s1.GetAs("v1[_B[p1:B]]");
+    c4_View v2 = v1.Blocked();
+
+    for (int i = 0; i < 1005; ++i) {
+      h.SetBuffer(2500+i);
+      v2.Add(p1[h]);
+
+      if (i >= 999)
+      // will crash a few rounds later, at row 1001
+        s1.Commit();
+    }
+
+    // reduce size to shorten the dump output
+    v2.RemoveAt(0, 990);
+    s1.Commit();
+
+  }
+  D(m02a);
+  R(m02a);
+  E;
+
+  B(m03, Hash adds, 0)W(m03a);
+   {
+    c4_StringProp p1("p1");
+
+    c4_Storage s1("m03a", true);
+
+    c4_View d1 = s1.GetAs("d1[p1:S]");
+    c4_View m1 = s1.GetAs("m1[_H:I,_R:I]");
+    c4_View h1 = d1.Hash(m1);
+
+    h1.Add(p1["one"]);
+    s1.Commit();
+
+    c4_View d2 = s1.GetAs("d2[p1:S]");
+    c4_View m2 = s1.GetAs("m2[_H:I,_R:I]");
+    c4_View h2 = d2.Hash(m2);
+
+    h1.Add(p1["two"]);
+    h2.Add(p1["two"]);
+    s1.Commit();
+
+    c4_View d3 = s1.GetAs("d3[p1:S]");
+    c4_View m3 = s1.GetAs("m3[_H:I,_R:I]");
+    c4_View h3 = d3.Hash(m3);
+
+    h1.Add(p1["three"]);
+    h2.Add(p1["three"]);
+    h3.Add(p1["three"]);
+    s1.Commit();
+
+    c4_View d4 = s1.GetAs("d4[p1:S]");
+    c4_View m4 = s1.GetAs("m4[_H:I,_R:I]");
+    c4_View h4 = d4.Hash(m4);
+
+    h1.Add(p1["four"]);
+    h2.Add(p1["four"]);
+    h3.Add(p1["four"]);
+    h4.Add(p1["four"]);
+    s1.Commit();
+
+  }
+  D(m03a);
+  R(m03a);
+  E;
+
+  B(m04, Locate bug, 0)W(m04a);
+   {
+    c4_IntProp p1("p1");
+    c4_StringProp p2("p2");
+
+    c4_Storage s1("m04a", true);
+    s1.AutoCommit();
+
+    c4_View v1 = s1.GetAs("v1[p1:I,p2:S]");
+
+    v1.Add(p1[1] + p2["one"]);
+    v1.Add(p1[2] + p2["two"]);
+    v1.Add(p1[3] + p2["three"]);
+    s1.Commit();
+
+    c4_View v2 = v1.Ordered();
+    A(v2.GetSize() == 3);
+    v2.Add(p1[6] + p2["six"]);
+    v2.Add(p1[5] + p2["five"]);
+    v2.Add(p1[4] + p2["four"]);
+    A(v2.GetSize() == 6);
+    A(v1.GetSize() == 6);
+
+    A(p1(v1[0]) == 1);
+    A(p1(v1[1]) == 2);
+    A(p1(v1[2]) == 3);
+    A(p1(v1[3]) == 4);
+    A(p1(v1[4]) == 5);
+    A(p1(v1[5]) == 6);
+
+    A(v2.Find(p1[4]) == 3);
+    A(v2.Search(p1[4]) == 3);
+
+    int i1 =  - 1;
+    A(v1.Locate(p1[4], &i1) == 1);
+    A(i1 == 3);
+
+    int i2 =  - 1;
+    A(v2.Locate(p1[4], &i2) == 1);
+    A(i2 == 3);
+
+  }
+  D(m04a);
+  R(m04a);
+  E;
+
+  // subviews are not relocated properly with blocked views in 2.4.7
+  B(m05, Blocked view with subviews, 0)W(m05a);
+   {
+    char buf[10];
+    c4_StringProp p1("p1");
+    c4_IntProp p2("p2");
+    c4_ViewProp pSv("sv");
+
+    c4_Storage s1("m05a", true);
+    c4_View v1 = s1.GetAs("v1[_B[p1:S,sv[p2:I]]]");
+    c4_View v2 = v1.Blocked();
+
+    for (int i = 0; i < 1000; ++i) {
+      sprintf(buf, "id-%d", i);
+      v2.Add(p1[buf]);
+
+      c4_View v3 = pSv(v2[i]);
+      v3.Add(p2[i]);
+    }
+
+    for (int j = 0; j < 1; ++j) {
+      sprintf(buf, "insert-%d", j);
+      v2.InsertAt(500, p1[buf]);
+    }
+
+    s1.Commit();
+
+  }
+  D(m05a);
+  R(m05a);
+  E;
+
+  // 2003/02/14 - assert fails for 2.4.8 in c4_Column::RemoveData
+  B(m06, Blocked view multi-row deletion, 0)W(m06a);
+   {
+    c4_IntProp p1("p1");
+
+    c4_Storage s1("m06a", true);
+    c4_View v1 = s1.GetAs("v1[p1:I]");
+    c4_View v2 = s1.GetAs("v2[_B[_H:I,_R:I]]");
+    c4_View v3 = v2.Blocked();
+    c4_View v4 = v1.Hash(v3, 1);
+
+    v4.Add(p1[1]);
+    v4.Add(p1[2]);
+    v4.RemoveAt(1);
+
+    for (int i = 100; i < 1000; ++i) {
+      v4.Add(p1[i]);
+    }
+
+    s1.Commit();
+
+  }
+  D(m06a);
+  R(m06a);
+  E;
+
+  // 2003/03/07 - still not correct on blocked veiw deletions
+  B(m07, All blocked view multi-deletion cases, 0);
+   {
+    int i, j;
+    for (i = 0; i < 2; ++i) {
+      for (j = 1; j < 4; ++j)
+        TestBlockDel(i, j);
+      for (j = 998; j < 1002; ++j)
+        TestBlockDel(i, j);
+      for (j = 1998; j < 2002; ++j)
+        TestBlockDel(i, j);
+    }
+    for (i = 998; i < 1002; ++i) {
+      for (j = 1; j < 4; ++j)
+        TestBlockDel(i, j);
+      for (j = 998; j < 1002; ++j)
+        TestBlockDel(i, j);
+    }
+    for (i = 1; i < 4; ++i)
+      TestBlockDel(2999-i, i);
+    for (i = 998; i < 1002; ++i)
+      TestBlockDel(2999-i, i);
+    for (i = 1998; i < 2002; ++i)
+      TestBlockDel(2999-i, i);
+  }
+  E;
+}
diff --git a/8.x/mk/tests/tnotify.cpp b/8.x/mk/tests/tnotify.cpp
new file mode 100755 (executable)
index 0000000..0e1efa2
--- /dev/null
@@ -0,0 +1,448 @@
+// tnotify.cpp -- Regression test program, notification tests
+// $Id: tnotify.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestNotify() {
+  B(n01, Add to selection, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 6);
+    c4_View v2 = v1.SelectRange(p1[200], p1[333]);
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+    v1.Add(p1[300]);
+    A(v1.GetSize() == 7);
+    A(v2.GetSize() == 4);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+    A(p1(v2[3]) == 300);
+    v1.Add(p1[199]);
+    A(v1.GetSize() == 8);
+    A(v2.GetSize() == 4);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+    A(p1(v2[3]) == 300);
+  }
+  E;
+
+  B(n02, Remove from selection, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 6);
+    c4_View v2 = v1.SelectRange(p1[200], p1[333]);
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+    v1.RemoveAt(2);
+    A(v1.GetSize() == 5);
+    A(v2.GetSize() == 2);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 234);
+    v1.RemoveAt(2);
+    A(v1.GetSize() == 4);
+    A(v2.GetSize() == 2);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 234);
+  }
+  E;
+
+  B(n03, Modify into selection, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 6);
+    c4_View v2 = v1.SelectRange(p1[200], p1[333]);
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+    p1(v1[5]) = 300;
+    A(v2.GetSize() == 4);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+    A(p1(v2[3]) == 300);
+  }
+  E;
+
+  B(n04, Modify out of selection, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 6);
+    c4_View v2 = v1.SelectRange(p1[200], p1[333]);
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+    p1(v1[2]) = 100;
+    A(v2.GetSize() == 2);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 234);
+  }
+  E;
+
+  B(n05, Add to sorted, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 6);
+    c4_View v2 = v1.Sort();
+    A(v2.GetSize() == 6);
+    A(p1(v2[0]) == 111);
+    A(p1(v2[1]) == 123);
+    A(p1(v2[2]) == 222);
+    A(p1(v2[3]) == 234);
+    A(p1(v2[4]) == 333);
+    A(p1(v2[5]) == 345);
+    v1.Add(p1[300]);
+    A(v2.GetSize() == 7);
+    A(p1(v2[0]) == 111);
+    A(p1(v2[1]) == 123);
+    A(p1(v2[2]) == 222);
+    A(p1(v2[3]) == 234);
+    A(p1(v2[4]) == 300);
+    A(p1(v2[5]) == 333);
+    A(p1(v2[6]) == 345);
+  }
+  E;
+
+  B(n06, Remove from sorted, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.Add(p1[111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 6);
+    c4_View v2 = v1.Sort();
+    A(v2.GetSize() == 6);
+    A(p1(v2[0]) == 111);
+    A(p1(v2[1]) == 123);
+    A(p1(v2[2]) == 222);
+    A(p1(v2[3]) == 234);
+    A(p1(v2[4]) == 333);
+    A(p1(v2[5]) == 345);
+    v1.RemoveAt(2);
+    A(v2.GetSize() == 5);
+    A(p1(v2[0]) == 111);
+    A(p1(v2[1]) == 123);
+    A(p1(v2[2]) == 222);
+    A(p1(v2[3]) == 234);
+    A(p1(v2[4]) == 345);
+  }
+  E;
+
+  B(n07, New property through sort, 0) {
+    c4_IntProp p1("p1"), p2("p2");
+    c4_View v1;
+    v1.Add(p1[11]);
+    v1.Add(p1[1]);
+    v1.Add(p1[111]);
+    A(v1.FindProperty(p2.GetId()) < 0);
+
+    c4_View v2 = v1.SortOn(p1);
+    A(v2.FindProperty(p2.GetId()) < 0);
+
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 1);
+    A(p1(v2[1]) == 11);
+    A(p1(v2[2]) == 111);
+
+    p2(v1[0]) = 22;
+    A(v1.FindProperty(p2.GetId()) == 1);
+    A(v2.FindProperty(p2.GetId()) == 1);
+
+    A(p2(v2[1]) == 22);
+  }
+  E;
+
+  B(n08, Nested project and select, 0) {
+    c4_IntProp p1("p1"), p2("p2");
+    c4_View v1;
+    v1.Add(p1[10] + p2[1]);
+    v1.Add(p1[11]);
+    v1.Add(p1[12] + p2[1]);
+    v1.Add(p1[13]);
+    v1.Add(p1[14] + p2[1]);
+    v1.Add(p1[15]);
+    v1.Add(p1[16] + p2[1]);
+    A(v1.GetSize() == 7);
+
+    c4_View v2 = v1.Select(p2[1]);
+    A(v2.GetSize() == 4);
+    A(p1(v2[0]) == 10);
+    A(p1(v2[1]) == 12);
+    A(p1(v2[2]) == 14);
+    A(p1(v2[3]) == 16);
+
+    c4_View v3 = v2.Project(p1);
+    A(v3.GetSize() == 4);
+    A(p1(v3[0]) == 10);
+    A(p1(v3[1]) == 12);
+    A(p1(v3[2]) == 14);
+    A(p1(v3[3]) == 16);
+
+    A(p2(v3[0]) == 0);
+    A(p2(v3[1]) == 0);
+    A(p2(v3[2]) == 0);
+    A(p2(v3[3]) == 0);
+
+    /* not yet implemented: setting result of selection 
+    p1 (v3[1]) = 123;
+    A(p1 (v3[1]) == 123);
+    A(p1 (v2[1]) == 123);
+    A(p1 (v1[2]) == 123);
+     */
+  }
+  E;
+
+  B(n09, Multiple dependencies, 0) {
+    c4_IntProp p1("p1"), p2("p2");
+    c4_View v1;
+    v1.Add(p1[111] + p2[1111]);
+    v1.Add(p1[222]);
+    v1.Add(p1[333]);
+    v1.Add(p1[345]);
+    v1.Add(p1[234]);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 6);
+
+    c4_View v2 = v1.SelectRange(p1[200], p1[333]);
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 333);
+    A(p1(v2[2]) == 234);
+
+    c4_View v3 = v1.SelectRange(p1[340], p1[350]);
+    A(v3.GetSize() == 1);
+    A(p1(v3[0]) == 345);
+
+    c4_View v4 = v2.SortOn(p1);
+    A(v4.GetSize() == 3);
+    A(p1(v4[0]) == 222);
+    A(p1(v4[1]) == 234);
+    A(p1(v4[2]) == 333);
+
+    c4_View v5 = v3.SortOn(p1);
+    A(v5.GetSize() == 1);
+    A(p1(v5[0]) == 345);
+
+    p1(v1[2]) = 346;
+
+    A(v2.GetSize() == 2);
+    A(p1(v2[0]) == 222);
+    A(p1(v2[1]) == 234);
+
+    A(v3.GetSize() == 2);
+    A(p1(v3[0]) == 346);
+    A(p1(v3[1]) == 345);
+
+    A(v4.GetSize() == 2);
+    A(p1(v4[0]) == 222);
+    A(p1(v4[1]) == 234);
+
+    A(v5.GetSize() == 2);
+    A(p1(v5[0]) == 345);
+    A(p1(v5[1]) == 346);
+  }
+  E;
+
+  B(n10, Modify sorted duplicates, 0) {
+    c4_IntProp p1("p1");
+    c4_View v1;
+    v1.SetSize(3);
+    p1(v1[0]) = 0;
+    c4_View v2 = v1.Sort();
+    p1(v1[0]) = 1;
+    p1(v1[1]) = 1; // crashed in 1.5, fix in: c4_SortSeq::PosInMap
+  }
+  E;
+
+  B(n11, Resize compound derived view, 0) {
+    c4_IntProp p1("p1"), p2("p2");
+    c4_View v1 = (p1, p2);
+    c4_View v2 = v1.SelectRange(p2[200], p2[333]);
+    c4_View v3 = v2.SortOn(p1);
+    A(v2.GetSize() == 0);
+    A(v3.GetSize() == 0);
+    v1.SetSize(1); // crashed in 1.5, fix in: c4_FilterSeq::Match
+    A(v1.GetSize() == 1);
+    A(v2.GetSize() == 0);
+    A(v3.GetSize() == 0);
+    v1[0] = p2[300];
+    A(v1.GetSize() == 1);
+    A(v2.GetSize() == 1);
+    A(v3.GetSize() == 1);
+    A(p2(v2[0]) == 300);
+    v1.Add(p1[199]);
+    A(v1.GetSize() == 2);
+    A(v2.GetSize() == 1);
+    A(p2(v2[0]) == 300);
+  }
+  E;
+
+  B(n12, Alter multiply derived view, 0) {
+    c4_IntProp p1("p1");
+    c4_StringProp p2("p2"), p3("p3");
+    c4_View v1 = (p1, p2);
+    c4_View v2 = v1.Select(p1[1]);
+    c4_View v3 = v2.SortOn(p2);
+    c4_View v4 = v1.Select(p1[2]);
+    c4_View v5 = v4.SortOn(p2);
+
+    v1.Add(p1[1] + p2["een"] + p3["1"]);
+    v1.Add(p1[1] + p2["elf"] + p3["11"]);
+    v1.Add(p1[2] + p2["twee"] + p3["2"]);
+    v1.Add(p1[2] + p2["twaalf"] + p3["12"]);
+    v1.Add(p1[2] + p2["twintig"] + p3["20"]);
+    v1.Add(p1[2] + p2["tachtig"] + p3["80"]);
+
+    A(v1.GetSize() == 6);
+    A(v2.GetSize() == 2);
+    A(v3.GetSize() == 2);
+    A(v4.GetSize() == 4);
+    A(v5.GetSize() == 4);
+
+    A(p3(v1[2]) == (c4_String)"2");
+    A(p3(v4[0]) == (c4_String)"2");
+
+    A(p3(v3[0]) == (c4_String)"1");
+    A(p3(v3[1]) == (c4_String)"11");
+
+    A(p3(v5[0]) == (c4_String)"80");
+    A(p3(v5[1]) == (c4_String)"12");
+    A(p3(v5[2]) == (c4_String)"2");
+    A(p3(v5[3]) == (c4_String)"20");
+
+    v1[3] = p1[2] + p2["twaalf"] + p3["12+"];
+
+    A(p3(v3[0]) == (c4_String)"1");
+    A(p3(v3[1]) == (c4_String)"11");
+
+    A(p3(v1[3]) == (c4_String)"12+");
+    A(p3(v4[1]) == (c4_String)"12+");
+
+    A(p3(v5[0]) == (c4_String)"80");
+    A(p3(v5[1]) == (c4_String)"12+");
+    A(p3(v5[2]) == (c4_String)"2");
+    A(p3(v5[3]) == (c4_String)"20");
+  }
+  E;
+
+  B(n13, Project without, 0) { // failed in 1.8.4
+    c4_IntProp p1("p1"), p2("p2");
+    c4_View v1;
+
+    v1.Add(p1[1] + p2[2]);
+    int n1 = v1.NumProperties();
+    A(n1 == 2);
+
+    c4_View v2 = v1.ProjectWithout(p2);
+    int n2 = v2.NumProperties();
+    A(n2 == 1);
+  }
+  E;
+
+  /*
+  B(n14, Add to reverse sorted, 0)
+  {
+  c4_IntProp p1 ("p1"), p2 ("p2");
+  c4_View v1;
+  v1.Add(p1 [333] + p2 [1]);
+  v1.Add(p1 [345] + p2 [1]);
+  v1.Add(p1 [234] + p2 [1]);
+  v1.Add(p1 [123] + p2 [0]);
+  A(v1.GetSize() == 4);
+  c4_View v1a = v1.Select(p2 [1]);
+  A(v1a.GetSize() == 3);
+  c4_View v1b = v1a.SelectRange(p1 [100], p1 [999]);
+  A(v1b.GetSize() == 3);
+  c4_View v2 = v1b.SortOnReverse(p1, p1);
+  A(v2.GetSize() == 3);
+  A(p1 (v2[0]) == 345);
+  A(p1 (v2[1]) == 333);
+  A(p1 (v2[2]) == 234);
+  v1.Add(p1 [300] + p2 [1]);
+  A(v2.GetSize() == 4);
+  A(p1 (v2[0]) == 345);
+  A(p1 (v2[1]) == 333);
+  A(p1 (v2[2]) == 300);
+  A(p1 (v2[3]) == 234);
+  v1.Add(p1 [299] + p2 [1]);
+  A(v2.GetSize() == 5);
+  A(p1 (v2[0]) == 345);
+  A(p1 (v2[1]) == 333);
+  A(p1 (v2[2]) == 300);
+  A(p1 (v2[3]) == 299);
+  A(p1 (v2[4]) == 234);
+  } E;
+   */
+  // this failed in 2.4.8, reported by S. Selznick, 2002-11-22
+  B(n14, Insert in non-mapped position, 0)W(n14a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("n14a", 1);
+    s1.SetStructure("a[p1:I]");
+    c4_View v1 = s1.View("a");
+
+    static int intlist[] =  {
+      0, 1, 2, 0, 1, 2, 0, 1, 2, 0,  - 1
+    };
+    for (int c = 0;  - 1 != intlist[c]; c++)
+      v1.Add(p1[intlist[c]]);
+
+    A(v1.GetSize() == 10);
+    c4_View v2 = v1.Select(p1[1]);
+    A(v2.GetSize() == 3);
+
+    v1.InsertAt(3, p1[6]);
+    A(v1.GetSize() == 11);
+    A(v2.GetSize() == 3);
+
+    v1.InsertAt(7, p1[1]);
+    A(v1.GetSize() == 12);
+    A(v2.GetSize() == 4);
+
+    s1.Commit();
+  }
+  D(n14a);
+  R(n14a);
+  E;
+}
diff --git a/8.x/mk/tests/tresize.cpp b/8.x/mk/tests/tresize.cpp
new file mode 100755 (executable)
index 0000000..52e34a8
--- /dev/null
@@ -0,0 +1,338 @@
+// trseize.cpp -- Regression test program, resizing tests
+// $Id: tresize.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+#include <stdlib.h>   // strtol
+#include <string.h>   // memory functions
+
+class CResizer: public c4_Storage {
+  public:
+    CResizer(const char *file);
+    ~CResizer();
+
+    void Verify();
+
+    int Ins(int, int);
+    int Del(int, int);
+
+  private:
+    enum {
+        kMaxData = 15000
+    };
+    char *_refData;
+    int _refSize;
+
+    c4_View _attached;
+    c4_View _unattached;
+    c4_IntProp _prop;
+
+    char _seed;
+
+    CResizer(const CResizer &); // not implemented
+    void operator = (const CResizer &); // not implemented
+};
+
+CResizer::CResizer(const char *file): c4_Storage(file, 1), _refSize(0), _prop(
+  "p1"), _seed(0) {
+  SetStructure("a[p1:I]");
+
+  _refData = new char[kMaxData];
+
+  _attached = View("a");
+
+  Verify();
+}
+
+CResizer::~CResizer() {
+  Verify();
+
+  Commit();
+
+  Verify();
+
+  delete [] _refData;
+}
+
+void CResizer::Verify() {
+  int i;
+
+  A(_refSize == _unattached.GetSize());
+  A(_refSize == _attached.GetSize());
+
+  for (i = 0; i < _refSize; ++i) {
+    A(_refData[i] == _prop(_unattached[i]));
+    A(_refData[i] == _prop(_attached[i]));
+  }
+}
+
+int CResizer::Ins(int pos_, int cnt_) {
+  A(pos_ <= _refSize);
+  A(_refSize + cnt_ < kMaxData);
+
+  memmove(_refData + pos_ + cnt_, _refData + pos_, _refSize - pos_);
+  _refSize += cnt_;
+
+  c4_Row row;
+  _unattached.InsertAt(pos_, row, cnt_);
+  _attached.InsertAt(pos_, row, cnt_);
+
+  for (int i = pos_; i < pos_ + cnt_; ++i) {
+    _refData[i] = ++_seed;
+    _prop(_unattached[i]) = _seed;
+    _prop(_attached[i]) = _seed;
+
+    if (_seed >= 123)
+      _seed = 0;
+  }
+
+  Verify();
+
+  return _refSize;
+}
+
+int CResizer::Del(int pos_, int cnt_) {
+  A(pos_ + cnt_ <= _refSize);
+
+  _refSize -= cnt_;
+  memmove(_refData + pos_, _refData + pos_ + cnt_, _refSize - pos_);
+
+  _unattached.RemoveAt(pos_, cnt_);
+  _attached.RemoveAt(pos_, cnt_);
+
+  Verify();
+
+  return _refSize;
+}
+
+void TestResize() {
+  B(r00, Simple insert, 0)W(r00a);
+   {
+    CResizer r1("r00a");
+
+    int n = r1.Ins(0, 250);
+    A(n == 250);
+
+  }
+  D(r00a);
+  R(r00a);
+  E;
+
+  B(r01, Simple removes, 0)W(r01a);
+   {
+    CResizer r1("r01a");
+    int n;
+
+    n = r1.Ins(0, 500);
+    A(n == 500);
+
+    n = r1.Del(0, 50);
+    A(n == 450);
+    n = r1.Del(350, 100);
+    A(n == 350);
+    n = r1.Del(25, 150);
+    A(n == 200);
+    n = r1.Del(0, 200);
+    A(n == 0);
+
+    n = r1.Ins(0, 15);
+    A(n == 15);
+
+  }
+  D(r01a);
+  R(r01a);
+  E;
+
+  B(r02, Large inserts and removes, 0)W(r02a);
+   {
+    int big = sizeof(int) == sizeof(short) ? 1000 : 4000;
+
+    CResizer r1("r02a");
+    int n;
+
+    n = r1.Ins(0, 2000);
+    A(n == 2000);
+    n = r1.Ins(0, 3000);
+    A(n == 5000);
+    n = r1.Ins(5000, 1000+big);
+    A(n == 6000+big);
+    n = r1.Ins(100, 10);
+    A(n == 6010+big);
+    n = r1.Ins(4000, 100);
+    A(n == 6110+big);
+    n = r1.Ins(0, 1001);
+    A(n == 7111+big);
+
+    n = r1.Del(7111, big);
+    A(n == 7111);
+    n = r1.Del(0, 4111);
+    A(n == 3000);
+    n = r1.Del(10, 10);
+    A(n == 2990);
+    n = r1.Del(10, 10);
+    A(n == 2980);
+    n = r1.Del(5, 10);
+    A(n == 2970);
+    n = r1.Del(0, 990);
+    A(n == 1980);
+    n = r1.Del(3, 1975);
+    A(n == 5);
+
+  }
+  D(r02a);
+  R(r02a);
+  E;
+
+  B(r03, Binary property insertions, 0)W(r03a);
+   {
+    c4_BytesProp p1("p1");
+    c4_Storage s1("r03a", 1);
+    s1.SetStructure("a[p1:B]");
+    c4_View v1 = s1.View("a");
+
+    char buf[1024];
+
+    memset(buf, 0x11, sizeof buf);
+    v1.Add(p1[c4_Bytes(buf, sizeof buf)]);
+
+    memset(buf, 0x22, sizeof buf);
+    v1.Add(p1[c4_Bytes(buf, sizeof buf / 2)]);
+
+    s1.Commit();
+
+    memset(buf, 0x33, sizeof buf);
+    p1(v1[1]) = c4_Bytes(buf, sizeof buf); // fix c4_Column::CopyData
+
+    memset(buf, 0x44, sizeof buf);
+    v1.Add(p1[c4_Bytes(buf, sizeof buf / 3)]);
+
+    s1.Commit();
+
+    memset(buf, 0x55, sizeof buf);
+    v1.InsertAt(1, p1[c4_Bytes(buf, sizeof buf)]);
+
+    memset(buf, 0x66, sizeof buf);
+    v1.InsertAt(1, p1[c4_Bytes(buf, sizeof buf / 4)]);
+
+    s1.Commit();
+
+  }
+  D(r03a);
+  R(r03a);
+  E;
+
+  B(r04, Scripted string property tests, 0)W(r04a);
+   {
+    c4_StringProp p1("p1");
+    c4_Storage s1("r04a", 1);
+    s1.SetStructure("a[p1:S]");
+
+    // This code implements a tiny language to specify tests in:
+    //
+    //  "<X>,<Y>A"  add X partial buffers of size Y
+    //  "<X>a"    add X full buffers at end
+    //  "<X>,<Y>C"  change entry X to a partial buffer of size Y
+    //  "<X>c"    change entry at position X to a full buffer
+    //  "<X>,<Y>I"  insert partial buffer of size Y at position X
+    //  "<X>i"    insert a full buffer at position X
+    //  "<X>,<Y>R"  remove Y entries at position X
+    //  "<X>r"    remove one entry at position X
+    //
+    //  ">"     commit changes
+    //  "<"     rollback changes
+    //
+    //  " "     ignore spaces
+    //  "<X>,"    for additional args
+    //  "<X>="    verify number of rows is X
+
+    const char *scripts[] =  {
+      //   A  B  C  D    E    F   G    H    I J
+      "5a 5a 5a 1r   5r   10r   6r     2r   > 10=", 
+        "5a 5a 5a 1,200C 5,200C 10,200C 6,200C 2,200C > 15=", 
+        "5a 5a 5a 1,300C 5,300C 10,300C 6,300C 2,300C > 15=", 
+
+      //   A   B   C   D     E     F      G     H     I J
+      "50a 50a 50a 10r   50r   100r   60r   20r   > 145=", 
+        "50a 50a 50a 10,200C 50,200C 100,200C 60,200C 20,200C > 150=", 
+        "50a 50a 50a 10,300C 50,300C 100,300C 60,300C 20,300C > 150=", 
+
+      //   A     B   C     D   E   F  G H I J
+      "50,0A 50,0A 50,0A 10c 50c 100c 60c 20c > 150=",  // asserts in 1.7b1
+
+      //   A    B   C  D E
+      "3,3A 1,10C 1,1C > 3=",  // asserts in 1.7 - June 6 build
+
+      "", 0
+    };
+
+    for (int i = 0; scripts[i]; ++i) {
+      c4_View v1 = s1.View("a");
+      v1.RemoveAll();
+      s1.Commit();
+      A(v1.GetSize() == 0); // start with a clean slate each time
+
+      const char *p = scripts[i];
+
+      char fill = '@';
+      int save = 0;
+      c4_Row row;
+
+      while (*p) {
+        // default is a string of 255 chars (with additional null byte)
+        p1(row) = c4_String(++fill, 255);
+
+        int arg = (int)strtol(p, (char **) &p, 10); // loses const
+
+        switch (*p++) {
+          case 'A':
+            p1(row) = c4_String(fill, arg);
+            arg = save;
+          case 'a':
+            while (--arg >= 0)
+              v1.Add(row);
+            break;
+          case 'C':
+            p1(row) = c4_String(fill, arg);
+            arg = save;
+          case 'c':
+            v1.SetAt(arg, row);
+            break;
+          case 'I':
+            p1(row) = c4_String(fill, arg);
+            arg = save;
+          case 'i':
+            v1.InsertAt(arg, row);
+            break;
+          case 'R':
+            v1.RemoveAt(save, arg);
+            break;
+          case 'r':
+            v1.RemoveAt(arg);
+            break;
+          case '>':
+            s1.Commit();
+            break;
+          case '<':
+            s1.Rollback();
+            v1 = s1.View("a");
+            break;
+          case ' ':
+            break;
+          case ',':
+            save = arg;
+            break;
+          case '=':
+            A(v1.GetSize() == arg);
+            break;
+        }
+      }
+    }
+
+    s1.Commit();
+
+  }
+  D(r04a);
+  R(r04a);
+  E;
+}
diff --git a/8.x/mk/tests/tstore1.cpp b/8.x/mk/tests/tstore1.cpp
new file mode 100755 (executable)
index 0000000..2a666ec
--- /dev/null
@@ -0,0 +1,212 @@
+// tstore1.cpp -- Regression test program, storage tests, part 1
+// $Id: tstore1.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestStores1() {
+  B(s00, Simple storage, 0)W(s00a);
+   {
+    c4_Storage s1("s00a", 1);
+    s1.SetStructure("a[p1:I]");
+    s1.Commit();
+  }
+  D(s00a);
+  R(s00a);
+  E;
+
+  B(s01, Integer storage, 0)W(s01a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("s01a", 1);
+    s1.SetStructure("a[p1:I]");
+    c4_View v1 = s1.View("a");
+    v1.Add(p1[123]);
+    v1.Add(p1[456]);
+    v1.InsertAt(1, p1[789]);
+    A(v1.GetSize() == 3);
+    s1.Commit();
+    A(v1.GetSize() == 3);
+  }
+  D(s01a);
+  R(s01a);
+  E;
+
+#if !q4_TINY
+  B(s02, Float storage, 0)W(s02a);
+   {
+    c4_FloatProp p1("p1");
+    c4_Storage s1("s02a", 1);
+    s1.SetStructure("a[p1:F]");
+    c4_View v1 = s1.View("a");
+    v1.Add(p1[12.3]);
+    v1.Add(p1[45.6]);
+    v1.InsertAt(1, p1[78.9]);
+    s1.Commit();
+  }
+  D(s02a);
+  R(s02a);
+  E;
+#endif 
+
+  B(s03, String storage, 0)W(s03a);
+   {
+    c4_StringProp p1("p1");
+    c4_Storage s1("s03a", 1);
+    s1.SetStructure("a[p1:S]");
+    c4_View v1 = s1.View("a");
+    v1.Add(p1["one"]);
+    v1.Add(p1["two"]);
+    v1.InsertAt(1, p1["three"]);
+    s1.Commit();
+  }
+  D(s03a);
+  R(s03a);
+  E;
+
+  B(s04, View storage, 0)W(s04a);
+   {
+    c4_StringProp p1("p1");
+    c4_ViewProp p2("p2");
+    c4_IntProp p3("p3");
+    c4_Storage s1("s04a", 1);
+    s1.SetStructure("a[p1:S,p2[p3:I]]");
+    c4_View v1 = s1.View("a");
+    v1.Add(p1["one"]);
+    v1.Add(p1["two"]);
+    c4_View v2 = p2(v1[0]);
+    v2.Add(p3[1]);
+    v2 = p2(v1[1]);
+    v2.Add(p3[11]);
+    v2.Add(p3[22]);
+    v1.InsertAt(1, p1["three"]);
+    v2 = p2(v1[1]);
+    v2.Add(p3[111]);
+    v2.Add(p3[222]);
+    v2.Add(p3[333]);
+    s1.Commit();
+  }
+  D(s04a);
+  R(s04a);
+  E;
+
+  B(s05, Store and reload, 0)W(s05a);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("s05a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s05a", 0);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+    }
+  }
+  D(s05a);
+  R(s05a);
+  E;
+
+  B(s06, Commit twice, 0)W(s06a);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("s06a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+      s1.Commit();
+      v1.Add(p1[234]);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s06a", 0);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 123);
+      A(p1(v1[1]) == 234);
+    }
+  }
+  D(s06a);
+  R(s06a);
+  E;
+
+  B(s07, Commit modified, 0)W(s07a);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("s07a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+      s1.Commit();
+      p1(v1[0]) = 234;
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s07a", 0);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 234);
+    }
+  }
+  D(s07a);
+  R(s07a);
+  E;
+
+  B(s08, View after storage, 0)W(s08a);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("s08a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+      s1.Commit();
+    }
+    c4_View v1;
+     {
+      c4_Storage s1("s08a", 0);
+      v1 = s1.View("a");
+    }
+    // 19990916 - semantics changed, view now 1 row, but 0 props
+    A(v1.GetSize() == 1);
+    A(v1.NumProperties() == 0);
+    v1.InsertAt(0, p1[234]);
+    A(v1.GetSize() == 2);
+    A(p1(v1[0]) == 234);
+    A(p1(v1[1]) == 0); // the original value is gone
+  }
+  D(s08a);
+  R(s08a);
+  E;
+
+  B(s09, Copy storage, 0)W(s09a);
+  W(s09b);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("s09a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s09a", 0);
+      c4_Storage s2("s09b", 1);
+      s2.SetStructure("a[p1:I]");
+      s2.View("a") = s1.View("a");
+      s2.Commit();
+    }
+  }
+  D(s09a);
+  D(s09b);
+  R(s09a);
+  R(s09b);
+  E;
+}
diff --git a/8.x/mk/tests/tstore2.cpp b/8.x/mk/tests/tstore2.cpp
new file mode 100755 (executable)
index 0000000..37e7fe2
--- /dev/null
@@ -0,0 +1,362 @@
+// tstore2.cpp -- Regression test program, storage tests, part 2
+// $Id: tstore2.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestStores2() {
+  B(s10, Stream storage, 0)W(s10a);
+  W(s10b);
+  W(s10c);
+   {
+    // s10a is original
+    // s10b is a copy, random access
+    // s10c is a serialized copy
+    c4_StringProp p1("p1");
+    c4_ViewProp p2("p2");
+    c4_IntProp p3("p3");
+     {
+      c4_Storage s1("s10a", 1);
+      s1.SetStructure("a[p1:S,p2[p3:I]]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1["one"]);
+      v1.Add(p1["two"]);
+      c4_View v2 = p2(v1[0]);
+      v2.Add(p3[1]);
+      v2 = p2(v1[1]);
+      v2.Add(p3[11]);
+      v2.Add(p3[22]);
+      v1.InsertAt(1, p1["three"]);
+      v2 = p2(v1[1]);
+      v2.Add(p3[111]);
+      v2.Add(p3[222]);
+      v2.Add(p3[333]);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s10a", 0);
+      c4_Storage s2("s10b", 1);
+      s2.SetStructure("a[p1:S,p2[p3:I]]");
+      s2.View("a") = s1.View("a");
+      s2.Commit();
+    }
+     {
+      c4_Storage s3("s10b", 0);
+
+      c4_FileStream fs1(fopen("s10c", "wb"), true);
+      s3.SaveTo(fs1);
+    }
+     {
+      c4_Storage s1("s10c", 0); 
+        // new after 2.01: serialized is no longer special
+
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 3);
+      c4_View v2 = p2(v1[0]);
+      A(v2.GetSize() == 1);
+      c4_View v3 = p2(v1[1]);
+      A(v3.GetSize() == 3);
+      c4_View v4 = p2(v1[2]);
+      A(v4.GetSize() == 2);
+    }
+     {
+      c4_Storage s1;
+
+      c4_FileStream fs1(fopen("s10c", "rb"), true);
+      s1.LoadFrom(fs1);
+
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 3);
+      c4_View v2 = p2(v1[0]);
+      A(v2.GetSize() == 1);
+      c4_View v3 = p2(v1[1]);
+      A(v3.GetSize() == 3);
+      c4_View v4 = p2(v1[2]);
+      A(v4.GetSize() == 2);
+    }
+     {
+      c4_Storage s1("s10c", 1);
+
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 3);
+      c4_View v2 = p2(v1[0]);
+      A(v2.GetSize() == 1);
+      c4_View v3 = p2(v1[1]);
+      A(v3.GetSize() == 3);
+      c4_View v4 = p2(v1[2]);
+      A(v4.GetSize() == 2);
+      v1.Add(p1["four"]);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s10c", 0);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 4);
+      c4_View v2 = p2(v1[0]);
+      A(v2.GetSize() == 1);
+      c4_View v3 = p2(v1[1]);
+      A(v3.GetSize() == 3);
+      c4_View v4 = p2(v1[2]);
+      A(v4.GetSize() == 2);
+      c4_View v5 = p2(v1[3]);
+      A(v5.GetSize() == 0);
+    }
+  }
+  D(s10a);
+  D(s10b);
+  D(s10c);
+  R(s10a);
+  R(s10b);
+  R(s10c);
+  E;
+
+  B(s11, Commit and rollback, 0)W(s11a);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("s11a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s11a", 0);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+      v1.InsertAt(0, p1[234]);
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 234);
+      A(p1(v1[1]) == 123);
+      s1.Rollback();
+      // 19990916 - semantics changed, still 2 rows, but 0 props
+      A(v1.GetSize() == 2);
+      A(v1.NumProperties() == 0);
+      v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+    }
+  }
+  D(s11a);
+  R(s11a);
+  E;
+
+  B(s12, Remove subview, 0)W(s12a);
+   {
+    c4_IntProp p1("p1"), p3("p3");
+    c4_ViewProp p2("p2");
+     {
+      c4_Storage s1("s12a", 1);
+      s1.SetStructure("a[p1:I,p2[p3:I]]");
+      c4_View v1 = s1.View("a");
+      c4_View v2;
+      v2.Add(p3[234]);
+      v1.Add(p1[123] + p2[v2]);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s12a", 1);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 123);
+      c4_View v2 = p2(v1[0]);
+      A(v2.GetSize() == 1);
+      A(p3(v2[0]) == 234);
+      v1.RemoveAt(0);
+      A(v1.GetSize() == 0);
+      s1.Commit();
+      A(v1.GetSize() == 0);
+    }
+  }
+  D(s12a);
+  R(s12a);
+  E;
+
+  B(s13, Remove middle subview, 0)W(s13a);
+   {
+    c4_IntProp p1("p1"), p3("p3");
+    c4_ViewProp p2("p2");
+     {
+      c4_Storage s1("s13a", 1);
+      s1.SetStructure("a[p1:I,p2[p3:I]]");
+      c4_View v1 = s1.View("a");
+
+      c4_View v2a;
+      v2a.Add(p3[234]);
+      v1.Add(p1[123] + p2[v2a]);
+
+      c4_View v2b;
+      v2b.Add(p3[345]);
+      v2b.Add(p3[346]);
+      v1.Add(p1[124] + p2[v2b]);
+
+      c4_View v2c;
+      v2c.Add(p3[456]);
+      v2c.Add(p3[457]);
+      v2c.Add(p3[458]);
+      v1.Add(p1[125] + p2[v2c]);
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s13a", 1);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 3);
+      A(p1(v1[0]) == 123);
+      A(p1(v1[1]) == 124);
+      A(p1(v1[2]) == 125);
+      c4_View v2a = p2(v1[0]);
+      A(v2a.GetSize() == 1);
+      A(p3(v2a[0]) == 234);
+      c4_View v2b = p2(v1[1]);
+      A(v2b.GetSize() == 2);
+      A(p3(v2b[0]) == 345);
+      c4_View v2c = p2(v1[2]);
+      A(v2c.GetSize() == 3);
+      A(p3(v2c[0]) == 456);
+      v1.RemoveAt(1);
+      A(v1.GetSize() == 2);
+      v2a = p2(v1[0]);
+      A(v2a.GetSize() == 1);
+      A(p3(v2a[0]) == 234);
+      v2b = p2(v1[1]);
+      A(v2b.GetSize() == 3);
+      A(p3(v2b[0]) == 456);
+      s1.Commit();
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 123);
+      A(p1(v1[1]) == 125);
+    }
+  }
+  D(s13a);
+  R(s13a);
+  E;
+
+  B(s14, Replace attached subview, 0)W(s14a);
+   {
+    c4_IntProp p1("p1");
+    c4_ViewProp p2("p2");
+     {
+      c4_Storage s1("s14a", 1);
+      s1.SetStructure("a[p1:I,p2[p3:I]]");
+      c4_View v1 = s1.View("a");
+
+      v1.Add(p1[123] + p2[c4_View()]);
+      A(v1.GetSize() == 1);
+
+      v1[0] = p2[c4_View()];
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 0);
+
+      s1.Commit();
+    }
+  }
+  D(s14a);
+  R(s14a);
+  E;
+
+  B(s15, Add after removed subviews, 0)W(s15a);
+   {
+    c4_IntProp p1("p1"), p3("p3");
+    c4_ViewProp p2("p2");
+     {
+      c4_Storage s1("s15a", 1);
+      s1.SetStructure("a[p1:I,p2[p3:I]]");
+      c4_View v1 = s1.View("a");
+
+      c4_View v2;
+      v2.Add(p3[234]);
+
+      v1.Add(p1[123] + p2[v2]);
+      v1.Add(p1[456] + p2[v2]);
+      v1.Add(p1[789] + p2[v2]);
+      A(v1.GetSize() == 3);
+
+      v1[0] = v1[2];
+      v1.RemoveAt(2);
+
+      v1[0] = v1[1];
+      v1.RemoveAt(1);
+
+      v1.RemoveAt(0);
+
+      v1.Add(p1[111] + p2[v2]);
+
+      s1.Commit();
+    }
+  }
+  D(s15a);
+  R(s15a);
+  E;
+
+  B(s16, Add after removed ints, 0)W(s16a);
+   {
+    c4_IntProp p1("p1");
+
+    c4_Storage s1("s16a", 1);
+    s1.SetStructure("a[p1:I,p2[p3:I]]");
+    c4_View v1 = s1.View("a");
+
+    v1.Add(p1[1]);
+    v1.Add(p1[2]);
+    v1.Add(p1[3]);
+
+    v1.RemoveAt(2);
+    v1.RemoveAt(1);
+    v1.RemoveAt(0);
+
+    v1.Add(p1[4]);
+
+    s1.Commit();
+
+  }
+  D(s16a);
+  R(s16a);
+  E;
+
+  B(s17, Add after removed strings, 0)W(s17a);
+   {
+    c4_StringProp p1("p1");
+
+    c4_Storage s1("s17a", 1);
+    s1.SetStructure("a[p1:S,p2[p3:I]]");
+    c4_View v1 = s1.View("a");
+
+    v1.Add(p1["one"]);
+    v1.Add(p1["two"]);
+    v1.Add(p1["three"]);
+
+    v1.RemoveAt(2);
+    v1.RemoveAt(1);
+    v1.RemoveAt(0);
+
+    v1.Add(p1["four"]);
+
+    s1.Commit();
+
+  }
+  D(s17a);
+  R(s17a);
+  E;
+
+  B(s18, Empty storage, 0)W(s18a);
+   {
+    c4_Storage s1("s18a", 1);
+
+  }
+  D(s18a);
+  R(s18a);
+  E;
+
+  B(s19, Empty view outlives storage, 0)W(s19a);
+   {
+    c4_View v1;
+    c4_Storage s1("s19a", 1);
+    v1 = s1.GetAs("a[p1:I,p2:S]");
+
+  }
+  D(s19a);
+  R(s19a);
+  E;
+}
diff --git a/8.x/mk/tests/tstore3.cpp b/8.x/mk/tests/tstore3.cpp
new file mode 100755 (executable)
index 0000000..98c90ea
--- /dev/null
@@ -0,0 +1,393 @@
+// tstore3.cpp -- Regression test program, storage tests, part 3
+// $Id: tstore3.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestStores3() {
+  B(s20, View outlives storage, 0)W(s20a);
+   {
+    c4_IntProp p1("p1");
+    c4_View v1;
+
+     {
+      c4_Storage s1("s20a", 1);
+      v1 = s1.GetAs("a[p1:I,p2:S]");
+      v1.Add(p1[123]);
+    }
+
+    // 19990916 - semantics changed, rows kept but no properties
+    //A(p1 (v1[0]) == 123);
+    A(v1.GetSize() == 1);
+    A(v1.NumProperties() == 0);
+
+  }
+  D(s20a);
+  R(s20a);
+  E;
+
+  B(s21, Test demo scenario, 0)W(s21a);
+   {
+    c4_StringProp p1("p1"), p2("p2");
+     {
+      c4_Storage storage("s21a", 1);
+      storage.SetStructure("a[p1:S,p2:S]");
+      c4_View v1;
+      c4_Row r1;
+
+      p1(r1) = "One";
+      p2(r1) = "Un";
+      v1.Add(r1);
+      A(v1.GetSize() == 1);
+
+      p1(r1) = "Two";
+      p2(r1) = "Deux";
+      v1.Add(r1);
+      A(v1.GetSize() == 2);
+
+      // changed 2000-03-15: Store is gone
+      //v1 = storage.Store("a", v1);
+      v1 = storage.View("a") = v1;
+
+      A(v1.GetSize() == 2);
+      A(p1(v1[1]) == (c4_String)"Two");
+      A(p2(v1[1]) == (c4_String)"Deux");
+      A(p1(v1[0]) == (c4_String)"One");
+      A(p2(v1[0]) == (c4_String)"Un");
+
+      storage.Commit();
+      A(v1.GetSize() == 2);
+      A(p1(v1[1]) == (c4_String)"Two");
+      A(p2(v1[1]) == (c4_String)"Deux");
+      A(p1(v1[0]) == (c4_String)"One");
+      A(p2(v1[0]) == (c4_String)"Un");
+
+      c4_String s1(p1(v1[1]));
+      c4_String s2(p2(v1[1]));
+      A(s1 == "Two");
+      A(s2 == "Deux");
+
+      storage.Commit();
+
+      v1.Add(p1["Three"] + p2["Trois"]);
+
+      storage.Commit();
+      A(v1.GetSize() == 3);
+      A(p2(v1[2]) == (c4_String)"Trois");
+
+      v1 = storage.GetAs("a[p1:S,p2:S,p3:I]");
+      A(v1.GetSize() == 3);
+      A(p2(v1[2]) == (c4_String)"Trois");
+
+      c4_IntProp p3("p3");
+      p3(v1[1]) = 123;
+
+      storage.Commit();
+      A(v1.GetSize() == 3);
+      A(p2(v1[2]) == (c4_String)"Trois");
+
+      c4_View v2 = storage.GetAs("b[p4:I]");
+
+      c4_IntProp p4("p4");
+      v2.Add(p4[234]);
+
+      storage.Commit();
+      A(v1.GetSize() == 3);
+      A(p2(v1[2]) == (c4_String)"Trois");
+
+      c4_IntProp p4a("p4");
+      v1.InsertAt(2, p1["Four"] + p4a[345]);
+
+      storage.Commit();
+      A(v1.GetSize() == 4);
+      A(p1(v1[0]) == (c4_String)"One");
+      A(p1(v1[1]) == (c4_String)"Two");
+      A(p1(v1[2]) == (c4_String)"Four");
+      A(p1(v1[3]) == (c4_String)"Three");
+      A(p2(v1[3]) == (c4_String)"Trois");
+      A(v2.GetSize() == 1);
+      A(p4(v2[0]) == 234);
+    }
+     {
+      c4_Storage storage("s21a", 0);
+      c4_View v1 = storage.View("a");
+      A(v1.GetSize() == 4);
+      A(p1(v1[0]) == (c4_String)"One");
+      A(p1(v1[1]) == (c4_String)"Two");
+      A(p1(v1[2]) == (c4_String)"Four");
+      A(p1(v1[3]) == (c4_String)"Three");
+      c4_View v2 = storage.View("b");
+      c4_IntProp p4("p4");
+      A(v2.GetSize() == 1);
+      A(p4(v2[0]) == 234);
+    }
+  }
+  D(s21a);
+  R(s21a);
+  E;
+
+#if !q4_TINY
+  B(s22, Double storage, 0)W(s22a);
+   {
+    c4_DoubleProp p1("p1");
+    c4_Storage s1("s22a", 1);
+    s1.SetStructure("a[p1:D]");
+    c4_View v1 = s1.View("a");
+    v1.Add(p1[1234.5678]);
+    v1.Add(p1[2345.6789]);
+    v1.InsertAt(1, p1[3456.7890]);
+    s1.Commit();
+  }
+  D(s22a);
+  R(s22a);
+  E;
+#endif 
+
+  B(s23, Find absent record, 0)W(s23a);
+   {
+    c4_Storage s1("s23a", 1);
+    s1.SetStructure("v[h:S,p:I,a:I,b:I,c:I,d:I,e:I,f:I,g:I,x:I]");
+    c4_View view = s1.View("v");
+
+    c4_StringProp H("h");
+    c4_IntProp P("p");
+
+    c4_Row row;
+    H(row) = "someString";
+    P(row) = 99;
+
+    int x = view.Find(row);
+    A(x ==  - 1);
+
+  }
+  D(s23a);
+  R(s23a);
+  E;
+
+  B(s24, Bitwise storage, 0)W(s24a);
+   {
+    c4_IntProp p1("p1");
+
+    int m = 9;
+
+    // insert values in front, but check fractional sizes at each step
+    for (int n = 0; n < m; ++n) {
+       {
+        c4_Storage s1("s24a", 1);
+        s1.SetStructure("a1[p1:I],a2[p1:I],a3[p1:I],a4[p1:I]");
+        s1.AutoCommit(); // new feature in 1.6
+
+        c4_View v1 = s1.View("a1");
+        c4_View v2 = s1.View("a2");
+        c4_View v3 = s1.View("a3");
+        c4_View v4 = s1.View("a4");
+
+        c4_Row row;
+        int k = ~n;
+
+        p1(row) = k &0x01;
+        v1.InsertAt(0, row);
+
+        p1(row) = k &0x03;
+        v2.InsertAt(0, row);
+
+        p1(row) = k &0x0F;
+        v3.InsertAt(0, row);
+
+        p1(row) = k &0x7F;
+        v4.InsertAt(0, row);
+      }
+      // the following checks that all tiny size combinations work
+       {
+        c4_Storage s1("s24a", 0);
+
+        c4_View v1 = s1.View("a1");
+        c4_View v2 = s1.View("a2");
+        c4_View v3 = s1.View("a3");
+        c4_View v4 = s1.View("a4");
+
+        A(v1.GetSize() == n + 1);
+        A(v2.GetSize() == n + 1);
+        A(v3.GetSize() == n + 1);
+        A(v4.GetSize() == n + 1);
+      }
+    }
+
+    c4_Storage s1("s24a", 0);
+
+    c4_View v1 = s1.View("a1");
+    c4_View v2 = s1.View("a2");
+    c4_View v3 = s1.View("a3");
+    c4_View v4 = s1.View("a4");
+
+    A(v1.GetSize() == m);
+    A(v2.GetSize() == m);
+    A(v3.GetSize() == m);
+    A(v4.GetSize() == m);
+
+    // now check that the inserted values are correct
+    for (int i = 0; i < m; ++i) {
+      int j = m - i - 1;
+      int k = ~i;
+
+      A(p1(v1[j]) == (k &0x01));
+      A(p1(v2[j]) == (k &0x03));
+      A(p1(v3[j]) == (k &0x0F));
+      A(p1(v4[j]) == (k &0x7F));
+    }
+
+  }
+  D(s24a);
+  R(s24a);
+  E;
+
+  B(s25, Bytes storage, 0)W(s25a);
+   {
+    c4_Bytes hi("hi", 2);
+    c4_Bytes gday("gday", 4);
+    c4_Bytes hello("hello", 5);
+
+    c4_BytesProp p1("p1");
+    c4_Storage s1("s25a", 1);
+    s1.SetStructure("a[p1:B]");
+    c4_View v1 = s1.View("a");
+
+    v1.Add(p1[hi]);
+    A(p1(v1[0]) == hi);
+    v1.Add(p1[hello]);
+    A(p1(v1[0]) == hi);
+    A(p1(v1[1]) == hello);
+    v1.InsertAt(1, p1[gday]);
+    A(p1(v1[0]) == hi);
+    A(p1(v1[1]) == gday);
+    A(p1(v1[2]) == hello);
+    s1.Commit();
+    A(p1(v1[0]) == hi);
+    A(p1(v1[1]) == gday);
+    A(p1(v1[2]) == hello);
+
+  }
+  D(s25a);
+  R(s25a);
+  E;
+
+  B(s26, Bitwise autosizing, 0)W(s26a);
+   {
+    c4_IntProp p1("p1"), p2("p2"), p3("p3"), p4("p4");
+    c4_Storage s1("s26a", 1);
+    s1.SetStructure("a[p1:I,p2:I,p3:I,p4:I]");
+    c4_View v1 = s1.View("a");
+
+    v1.Add(p1[1] + p2[3] + p3[15] + p4[127]);
+    A(p1(v1[0]) == 1);
+    A(p2(v1[0]) == 3);
+    A(p3(v1[0]) == 15);
+    A(p4(v1[0]) == 127);
+
+    p1(v1[0]) = 100000L;
+    p2(v1[0]) = 100000L;
+    p3(v1[0]) = 100000L;
+    p4(v1[0]) = 100000L;
+
+    // these failed in 1.61
+    A(p1(v1[0]) == 100000L);
+    A(p2(v1[0]) == 100000L);
+    A(p3(v1[0]) == 100000L);
+    A(p4(v1[0]) == 100000L);
+
+    s1.Commit();
+
+  }
+  D(s26a);
+  R(s26a);
+  E;
+
+  B(s27, Bytes restructuring, 0)W(s27a);
+   {
+    c4_Bytes test("test", 4);
+
+    c4_BytesProp p1("p1");
+    c4_Storage s1("s27a", 1);
+
+    c4_Row row;
+    p1(row) = test;
+
+    c4_View v1;
+    v1.Add(row);
+
+    // changed 2000-03-15: Store is gone
+    //s1.Store("a", v1); // asserts in 1.61
+    c4_View v2 = s1.GetAs("a[p1:B]");
+    v2.InsertAt(0, v1);
+
+    s1.Commit();
+
+  }
+  D(s27a);
+  R(s27a);
+  E;
+
+#if !q4_TINY
+  B(s28, Doubles added later, 0)W(s28a);
+   {
+    c4_FloatProp p1("p1");
+    c4_DoubleProp p2("p2");
+    c4_ViewProp p3("p3");
+
+    c4_Storage s1("s28a", 1);
+    s1.SetStructure("a[p1:F,p2:D,p3[p1:F,p2:D]]");
+    c4_View v1 = s1.View("a");
+
+    c4_Row r1;
+
+    p1(r1) = 123;
+    p2(r1) = 123;
+
+    c4_View v2;
+    v2.Add(p1[234] + p2[234]);
+    p3(r1) = v2;
+
+    v1.Add(r1);
+    double x1 = p1(v1[0]);
+    A(x1 == p2(v1[0]));
+
+    v2 = p3(v1[0]);
+    double x2 = p1(v2[0]);
+    A(x2 == p2(v2[0])); // fails in 1.6
+
+    s1.Commit();
+
+  }
+  D(s28a);
+  R(s28a);
+  E;
+#endif 
+
+  B(s29, Delete bytes property, 0)W(s29a);
+   {
+     {
+      c4_BytesProp p1("p1");
+
+      c4_Storage s1("s29a", 1);
+      s1.SetStructure("a[p1:B]");
+      c4_View v1 = s1.View("a");
+
+      int data = 99;
+      v1.Add(p1[c4_Bytes(&data, sizeof data)]);
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s29a", 1);
+      c4_View v1 = s1.View("a");
+
+      v1.RemoveAt(0); // asserts in 1.7
+
+      s1.Commit();
+    }
+
+  }
+  D(s29a);
+  R(s29a);
+  E;
+}
diff --git a/8.x/mk/tests/tstore4.cpp b/8.x/mk/tests/tstore4.cpp
new file mode 100755 (executable)
index 0000000..0e10712
--- /dev/null
@@ -0,0 +1,361 @@
+// tstore4.cpp -- Regression test program, storage tests, part 4
+// $Id: tstore4.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestStores4() {
+  B(s30, Memo storage, 0)W(s30a);
+   {
+    c4_Bytes hi("hi", 2);
+    c4_Bytes gday("gday", 4);
+    c4_Bytes hello("hello", 5);
+
+    c4_MemoProp p1("p1");
+    c4_Storage s1("s30a", 1);
+    s1.SetStructure("a[p1:B]");
+    c4_View v1 = s1.View("a");
+
+    v1.Add(p1[hi]);
+    A(p1(v1[0]) == hi);
+    v1.Add(p1[hello]);
+    A(p1(v1[0]) == hi);
+    A(p1(v1[1]) == hello);
+    v1.InsertAt(1, p1[gday]);
+    A(p1(v1[0]) == hi);
+    A(p1(v1[1]) == gday);
+    A(p1(v1[2]) == hello);
+    s1.Commit();
+    A(p1(v1[0]) == hi);
+    A(p1(v1[1]) == gday);
+    A(p1(v1[2]) == hello);
+
+  }
+  D(s30a);
+  R(s30a);
+  E;
+
+  // this failed in the unbuffered 1.8.5a interim release in Mk4tcl 1.0.5
+  B(s31, Check sort buffer use, 0)W(s31a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("s31a", 1);
+    s1.SetStructure("a[p1:I]");
+    c4_View v1 = s1.View("a");
+    v1.Add(p1[3]);
+    v1.Add(p1[1]);
+    v1.Add(p1[2]);
+    s1.Commit();
+
+    c4_View v2 = v1.SortOn(p1);
+    A(v2.GetSize() == 3);
+    A(p1(v2[0]) == 1);
+    A(p1(v2[1]) == 2);
+    A(p1(v2[2]) == 3);
+
+  }
+  D(s31a);
+  R(s31a);
+  E;
+
+  // this failed in 1.8.6, fixed 19990828
+  B(s32, Set memo empty or same size, 0)W(s32a);
+   {
+    c4_Bytes empty;
+    c4_Bytes full("full", 4);
+    c4_Bytes more("more", 4);
+
+    c4_MemoProp p1("p1");
+    c4_Storage s1("s32a", 1);
+    s1.SetStructure("a[p1:B]");
+    c4_View v1 = s1.View("a");
+
+    v1.Add(p1[full]);
+    A(p1(v1[0]) == full);
+    s1.Commit();
+    A(p1(v1[0]) == full);
+
+    p1(v1[0]) = empty;
+    A(p1(v1[0]) == empty);
+    s1.Commit();
+    A(p1(v1[0]) == empty);
+
+    p1(v1[0]) = more;
+    A(p1(v1[0]) == more);
+    s1.Commit();
+    A(p1(v1[0]) == more);
+
+    p1(v1[0]) = full;
+    A(p1(v1[0]) == full);
+    s1.Commit();
+    A(p1(v1[0]) == full);
+
+  }
+  D(s32a);
+  R(s32a);
+  E;
+
+  // this failed in 1.8.6, fixed 19990828
+  B(s33, Serialize memo fields, 0)W(s33a);
+  W(s33b);
+  W(s33c);
+   {
+    c4_Bytes hi("hi", 2);
+    c4_Bytes gday("gday", 4);
+    c4_Bytes hello("hello", 5);
+
+    c4_MemoProp p1("p1");
+
+    c4_Storage s1("s33a", 1);
+    s1.SetStructure("a[p1:B]");
+    c4_View v1 = s1.View("a");
+
+    v1.Add(p1[hi]);
+    v1.Add(p1[gday]);
+    v1.Add(p1[hello]);
+    A(p1(v1[0]) == hi);
+    A(p1(v1[1]) == gday);
+    A(p1(v1[2]) == hello);
+    s1.Commit();
+    A(p1(v1[0]) == hi);
+    A(p1(v1[1]) == gday);
+    A(p1(v1[2]) == hello);
+
+     {
+      c4_FileStream fs1(fopen("s33b", "wb"), true);
+      s1.SaveTo(fs1);
+    }
+
+    c4_Storage s2("s33c", 1);
+
+    c4_FileStream fs2(fopen("s33b", "rb"), true);
+    s2.LoadFrom(fs2);
+
+    c4_View v2 = s2.View("a");
+    A(p1(v2[0]) == hi);
+    A(p1(v2[1]) == gday);
+    A(p1(v2[2]) == hello);
+    s2.Commit();
+    A(p1(v2[0]) == hi);
+    A(p1(v2[1]) == gday);
+    A(p1(v2[2]) == hello);
+    s2.Commit();
+    A(p1(v2[0]) == hi);
+    A(p1(v2[1]) == gday);
+    A(p1(v2[2]) == hello);
+
+  }
+  D(s33a);
+  D(s33b);
+  D(s33c);
+  R(s33a);
+  R(s33b);
+  R(s33c);
+  E;
+
+  // check smarter commit and commit failure on r/o
+  B(s34, Smart and failed commits, 0)W(s34a);
+   {
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("s34a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[111]);
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 111);
+      bool f1 = s1.Commit();
+      A(f1);
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 111);
+      bool f2 = s1.Commit();
+      A(f2); // succeeds, but should not write anything
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 111);
+    }
+     {
+      c4_Storage s1("s34a", 0);
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[222]);
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 111);
+      A(p1(v1[1]) == 222);
+      bool f1 = s1.Commit();
+      A(!f1);
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 111);
+      A(p1(v1[1]) == 222);
+    }
+  }
+  D(s34a);
+  R(s34a);
+  E;
+
+  B(s35, Datafile with preamble, 0)W(s35a);
+   {
+     {
+      c4_FileStream fs1(fopen("s35a", "wb"), true);
+      fs1.Write("abc", 3);
+    }
+    c4_IntProp p1("p1");
+     {
+      c4_Storage s1("s35a", 1);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[111]);
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 111);
+      bool f1 = s1.Commit();
+      A(f1);
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 111);
+      bool f2 = s1.Commit();
+      A(f2); // succeeds, but should not write anything
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 111);
+    }
+     {
+      c4_FileStream fs1(fopen("s35a", "rb"), true);
+      char buffer[10];
+      int n1 = fs1.Read(buffer, 3);
+      A(n1 == 3);
+      A(c4_String(buffer, 3) == "abc");
+    }
+     {
+      c4_Storage s1("s35a", 0);
+      c4_View v1 = s1.View("a");
+      A(v1.GetSize() == 1);
+      A(p1(v1[0]) == 111);
+      v1.Add(p1[222]);
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 111);
+      A(p1(v1[1]) == 222);
+      bool f1 = s1.Commit();
+      A(!f1);
+      A(v1.GetSize() == 2);
+      A(p1(v1[0]) == 111);
+      A(p1(v1[1]) == 222);
+    }
+  }
+  D(s35a);
+  R(s35a);
+  E;
+
+  B(s36, Commit after load, 0)W(s36a);
+  W(s36b);
+   {
+    c4_IntProp p1("p1");
+
+    c4_Storage s1("s36a", 1);
+    s1.SetStructure("a[p1:I]");
+    c4_View v1 = s1.View("a");
+    v1.Add(p1[111]);
+    A(v1.GetSize() == 1);
+    A(p1(v1[0]) == 111);
+
+     {
+      c4_FileStream fs1(fopen("s36b", "wb"), true);
+      s1.SaveTo(fs1);
+    }
+
+    p1(v1[0]) = 222;
+    v1.Add(p1[333]);
+    bool f1 = s1.Commit();
+    A(f1);
+    A(v1.GetSize() == 2);
+    A(p1(v1[0]) == 222);
+    A(p1(v1[1]) == 333);
+
+    c4_FileStream fs2(fopen("s36b", "rb"), true);
+    s1.LoadFrom(fs2);
+    //A(v1.GetSize() == 0); // should be detached, but it's still 2
+
+    c4_View v2 = s1.View("a");
+    A(v2.GetSize() == 1);
+    A(p1(v2[0]) == 111);
+
+    // this fails in 2.4.0, reported by James Lupo, August 2001
+    bool f2 = s1.Commit();
+    A(f2);
+  }
+  D(s36a);
+  D(s36b);
+  R(s36a);
+  R(s36b);
+  E;
+
+  // fails in 2.4.1, reported Oct 31. 2001 by Steve Baxter
+  B(s37, Change short partial fields, 0)W(s37a);
+   {
+    c4_BytesProp p1("p1");
+    c4_Storage s1("s37a", true);
+    c4_View v1 = s1.GetAs("v1[key:I,p1:B]");
+
+    v1.Add(p1[c4_Bytes("12345", 6)]);
+    A(v1.GetSize() == 1);
+    s1.Commit();
+
+    c4_Bytes buf = p1(v1[0]);
+    A(buf.Size() == 6);
+    A(buf == c4_Bytes("12345", 6));
+    buf = p1(v1[0]).Access(1, 3);
+    A(buf == c4_Bytes("234", 3));
+    p1(v1[0]).Modify(c4_Bytes("ab", 2), 2, 0);
+    s1.Commit();
+
+    buf = p1(v1[0]);
+    A(buf == c4_Bytes("12ab5", 6));
+  }
+  D(s37a);
+  R(s37a);
+  E;
+
+  // Gross memory use (but no leaks), January 2002, Murat Berk
+  B(s38, Lots of empty subviews, 0)W(s38a);
+   {
+    c4_BytesProp p1("p1");
+     {
+      c4_Storage s1("s38a", true);
+      c4_View v = s1.GetAs("v[v1[p1:S]]");
+
+      v.SetSize(100000);
+      s1.Commit();
+    }
+     {
+      c4_Storage s2("s38a", true);
+      c4_View v2 = s2.View("v");
+      // this should not materialize all the empty subviews
+      v2.SetSize(v2.GetSize() + 1);
+      // nor should this
+      s2.Commit();
+    }
+     {
+      c4_Storage s3("s38a", true);
+      c4_View v3 = s3.View("v");
+      v3.RemoveAt(1, v3.GetSize() - 2);
+      A(v3.GetSize() == 2);
+      s3.Commit();
+    }
+  }
+  D(s38a);
+  R(s38a);
+  E;
+
+  // Fix bug introduced on 7-2-2002, as reported by M. Berk
+  B(s39, Do not detach empty top-level views, 0)W(s39a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("s39a", true);
+    c4_View v1 = s1.GetAs("v1[p1:I]");
+    s1.Commit();
+    A(v1.GetSize() == 0);
+    v1.Add(p1[123]);
+    A(v1.GetSize() == 1);
+    s1.Commit();
+    c4_View v2 = s1.View("v1");
+    A(v2.GetSize() == 1); // fails with 0 due to recent bug
+  }
+  D(s39a);
+  R(s39a);
+  E;
+}
diff --git a/8.x/mk/tests/tstore5.cpp b/8.x/mk/tests/tstore5.cpp
new file mode 100644 (file)
index 0000000..e0899b6
--- /dev/null
@@ -0,0 +1,359 @@
+// tstore5.cpp -- Regression test program, storage tests, part 5
+// $Id: tstore5.cpp 1230 2007-03-09 15:58:53Z jcw $
+// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
+
+#include "regress.h"
+
+void TestStores5() {
+  B(s40, LoadFrom after commit, 0)W(s40a);
+   {
+    c4_IntProp p1("p1");
+
+     {
+      // create datafile by streaming out
+      c4_Storage s1;
+      s1.SetStructure("a[p1:I]");
+
+      c4_View v1 = s1.View("a");
+      v1.Add(p1[123]);
+      A(p1(v1[0]) == 123);
+      A(v1.GetSize() == 1);
+
+      c4_FileStream fs1(fopen("s40a", "wb"), true);
+      s1.SaveTo(fs1);
+    }
+     {
+      // it should load just fine
+      c4_Storage s2;
+      c4_FileStream fs1(fopen("s40a", "rb"), true);
+      bool ok = s2.LoadFrom(fs1);
+      A(ok);
+
+      c4_View v1 = s2.View("a");
+      A(p1(v1[0]) == 123);
+      A(v1.GetSize() == 1);
+    }
+     {
+      // open the datafile and commit a change
+      c4_Storage s3("s40a", true);
+
+      c4_View v1 = s3.View("a");
+      A(p1(v1[0]) == 123);
+      A(v1.GetSize() == 1);
+      p1(v1[0]) = 456;
+      s3.Commit();
+      A(p1(v1[0]) == 456);
+      A(v1.GetSize() == 1);
+    }
+     {
+      // it should load fine and show the last changes
+      c4_Storage s4;
+      c4_FileStream fs1(fopen("s40a", "rb"), true);
+      bool ok = s4.LoadFrom(fs1);
+      A(ok);
+
+      c4_View v1 = s4.View("a");
+      A(p1(v1[0]) == 456);
+      A(v1.GetSize() == 1);
+    }
+     {
+      // it should open just fine in the normal way as well
+      c4_Storage s5("s40a", false);
+      c4_View v1 = s5.View("a");
+      A(p1(v1[0]) == 456);
+      A(v1.GetSize() == 1);
+    }
+  }
+  D(s40a);
+  R(s40a);
+  E;
+
+  // 2002-03-13: failure on Win32, Modify calls base class GetNthMemoCol
+  B(s41, Partial modify blocked, 0)W(s41a);
+   {
+    c4_BytesProp p1("p1");
+    c4_Storage s1("s41a", true);
+    c4_View v1 = s1.GetAs("a[_B[p1:B]]");
+
+    // custom viewers did not support partial access in 2.4.3
+    c4_View v2 = v1.Blocked();
+    s1.Commit();
+
+    v2.SetSize(1);
+
+    c4_BytesRef m = p1(v2[0]);
+    m.Modify(c4_Bytes("abcdefgh", 8), 0);
+
+    s1.Commit();
+
+  }
+  D(s41a);
+  R(s41a);
+  E;
+
+  B(s42, Get descriptions, 0) {
+    c4_Storage s1;
+    s1.SetStructure("a[p1:I],b[p2:S]");
+
+    c4_String x1 = s1.Description();
+    A(x1 == "a[p1:I],b[p2:S]");
+
+    c4_String x2 = s1.Description("b");
+    A(x2 == "p2:S");
+
+    const char *cp = s1.Description("c");
+    A(cp == 0);
+  }
+  E;
+
+  // 2002-04-24: VPI subview ints clobbered
+  B(s43, View reuse after sub-byte ints, 0)W(s43a);
+   {
+    c4_IntProp p1("p1");
+    c4_Storage s1("s43a", true);
+    c4_View v1 = s1.GetAs("a[p1:I]");
+
+    v1.Add(p1[0]);
+    v1.Add(p1[1]);
+    s1.Commit();
+
+    v1.SetSize(1); // 1 is an even trickier bug than 0
+    s1.Commit();
+
+    // adding the following two lines works around the 2.4.4 bug
+    //s1.Rollback();
+    //v1 = s1.GetAs("a[p1:I]");
+
+    v1.Add(p1[12345]);
+    s1.Commit();
+
+    //int n = p1 (v1[1]);
+    A(p1(v1[1]) == 12345);
+
+  }
+  D(s43a);
+  R(s43a);
+  E;
+
+  B(s44, Bad memo free space, 0)W(s44a);
+   {
+    c4_IntProp p1("p1");
+    c4_BytesProp p2("p2");
+    c4_Storage s1("s44a", true);
+    c4_View v1 = s1.GetAs("a[p1:I,p2:B]");
+
+    c4_Bytes data;
+    t4_byte *p = data.SetBuffer(12345);
+    for (int i = 0; i < data.Size(); ++i)
+      p[i] = (t4_byte)i;
+
+    v1.Add(p2[data]);
+    s1.Commit();
+
+    p1(v1[0]) = 1;
+    s1.Commit();
+
+    p1(v1[0]) = 0;
+    s1.Commit();
+
+    c4_Bytes temp = p2(v1[0]);
+    A(temp == data); // this failed in 2.4.5
+
+  }
+  D(s44a);
+  R(s44a);
+  E;
+
+  B(s45, Bad subview memo free space, 0)W(s45a);
+   {
+    c4_IntProp p1("p1");
+    c4_ViewProp p2("p2");
+    c4_BytesProp p3("p3");
+    c4_Storage s1("s45a", true);
+    c4_View v1 = s1.GetAs("a[p1:I,p2[p3:B]]");
+
+    c4_Bytes data;
+    t4_byte *p = data.SetBuffer(12345);
+    for (int i = 0; i < data.Size(); ++i)
+      p[i] = (t4_byte)i;
+
+    v1.SetSize(1);
+    c4_View v2 = p2(v1[0]);
+    v2.Add(p3[data]);
+    s1.Commit();
+
+    p1(v1[0]) = 1;
+    s1.Commit();
+
+    p1(v1[0]) = 0;
+    s1.Commit();
+
+    c4_View v3 = p2(v1[0]);
+    c4_Bytes temp = p3(v3[0]);
+    A(temp == data); // this failed in 2.4.5
+
+  }
+  D(s45a);
+  R(s45a);
+  E;
+
+  B(s46, LoadFrom after commit, 0)W(s46a);
+   {
+    c4_IntProp p1("p1");
+
+     {
+      c4_Storage s1("s46a", true);
+      s1.SetStructure("a[p1:I]");
+      c4_View v1 = s1.View("a");
+
+      v1.Add(p1[11]);
+      v1.Add(p1[22]);
+      v1.Add(p1[33]);
+      v1.Add(p1[44]);
+      v1.Add(p1[55]);
+      v1.Add(p1[66]);
+      v1.Add(p1[77]);
+      v1.Add(p1[88]);
+      v1.Add(p1[99]);
+
+      s1.Commit();
+    }
+     {
+      c4_Storage s2("s46a", true);
+      c4_View v2 = s2.View("a");
+
+      v2.Add(p1[1000]); // force 1->2 byte ints
+      v2.InsertAt(7, c4_Row());
+      v2.InsertAt(4, c4_Row());
+
+      //for (int i = 6; i <= 9; ++i) printf("%d\n", (int) p1 (v2[i]));
+
+      A(p1(v2[6]) == 66);
+      A(p1(v2[8]) == 0);
+      A(p1(v2[9]) == 88);
+      A(p1(v2[7]) == 77); // this failed in 2.4.6
+
+      s2.Commit();
+    }
+  }
+  D(s46a);
+  R(s46a);
+  E;
+
+  // 2004-01-16 bad property type crashes MK 2.4.9.2 and before
+  // this hits an assertion in debug mode, so then it has to be disabled
+  B(s47, Defining bad property type, 0) {
+    c4_IntProp p1("p2");
+
+    c4_Storage s1;
+#if defined(NDEBUG)
+    c4_View v1 = s1.GetAs("v1[p1:A]");
+#else 
+    // assertions are enabled, turn this into a dummy test instead
+    c4_View v1 = s1.GetAs("v1[p1:I]");
+#endif 
+    v1.Add(p1[123]);
+
+    A(v1.GetSize() == 1);
+    A(p1(v1[0]) == 123);
+  }
+  E;
+
+  // 2004-01-18 file damaging bug, when resizing a comitted subview
+  // to empty, committing, and then resizing back to containing data.
+  // Fortunately this usage pattern never happened in blocked views!
+  B(s48, Resize subview to zero and back, 0)W(s48a);
+  W(s48b);
+   {
+     {
+      c4_Storage s1("s48a", true);
+      c4_View v1 = s1.GetAs("v1[v2[p1:I]]");
+      v1.SetSize(1);
+      s1.Commit();
+    }
+     {
+      c4_Storage s1("s48a", true);
+      c4_View v1 = s1.View("v1");
+      v1.SetSize(0);
+      s1.Commit();
+      // the problem is that the in-memory copy has forgotten that it
+      // has nothing left on disk, and a comparison is done later on to
+      // avoid saving unmodified data - the bad decision is that data has
+      // not changed, but actually it has and must be reallocated!
+      // (fixes are in c4_FormatV::Insert and c4_FormatV::Remove)
+      v1.SetSize(1);
+      s1.Commit();
+      // at this point, the 2.4.9.2 file is corrupt!
+      c4_FileStream fs1(fopen("s48b", "wb"), true);
+      s1.SaveTo(fs1);
+    }
+     {
+      // using this damaged datafile will then crash
+      c4_Storage s1("s48a", false);
+      c4_View v1 = s1.View("v1");
+      v1.SetSize(2);
+    }
+  }
+  D(s48a);
+  D(s48b);
+  R(s48a);
+  R(s48b);
+  E;
+
+  // 2004-01-20 better handling of bad input: ignore repeated props
+  B(s49, Specify conflicting properties, 0)W(s49a);
+   {
+    c4_Storage s1("s49a", true);
+    c4_View v1 = s1.GetAs("v1[p1:I,p1:S]");
+    c4_View v2 = s1.GetAs("v2[p1:I,P1:S]");
+    c4_View v3 = s1.GetAs("v3[v3[^]]");
+    c4_String x1 = s1.Description();
+    A(x1 == "v1[p1:I],v2[p1:I],v3[v3[^]]");
+    s1.Commit();
+  }
+  D(s49a);
+  R(s49a);
+  E;
+
+  B(s50, Free space usage, 0)W(s50a);
+   {
+    t4_i32 c, b;
+    c4_IntProp p1("p1");
+
+    c4_Storage s1("s50a", true);
+    c4_View v1 = s1.GetAs("a[p1:I]");
+
+    v1.Add(p1[12345]);
+
+    s1.Commit();
+    c = s1.FreeSpace(&b);
+    A(c == 0);
+    A(b == 0);
+
+    v1.Add(p1[2345]);
+
+    s1.Commit();
+    c = s1.FreeSpace(&b);
+    A(c == 1);
+    A(b == 18);
+    s1.Commit();
+    c = s1.FreeSpace(&b);
+    A(c == 1);
+    A(b == 6);
+
+    v1.Add(p1[345]);
+
+    s1.Commit();
+    c = s1.FreeSpace(&b);
+    A(c == 2);
+    A(b == 56);
+    s1.Commit();
+    c = s1.FreeSpace(&b);
+    A(c == 1);
+    A(b == 44);
+    //fprintf(stderr, "c %d b %d\n", c, b);
+  }
+  D(s50a);
+  R(s50a);
+  E;
+}
diff --git a/8.x/mk/unix/Doxyfile b/8.x/mk/unix/Doxyfile
new file mode 100644 (file)
index 0000000..04bb29d
--- /dev/null
@@ -0,0 +1,1101 @@
+# Doxyfile 1.3.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = Metakit
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 2.4.9.7
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../builds
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, 
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en 
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, 
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is used 
+# as the annotated text. Otherwise, the brief description is used as-is. If left 
+# blank, the following values are used ("$name" is automatically replaced with the 
+# name of the entity): "The $name class" "The $name widget" "The $name file" 
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 
+# members of a class in the documentation of that class as if those members were 
+# ordinary class members. Constructors, destructors and assignment operators of 
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ../include \
+                         ../src
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS          = *.cpp \
+                         *.h \
+                         *.inl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = 
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = ../unix/Doxytail.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = 
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = 
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed.
+
+PREDEFINED             = d4_inline=inline
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = NO
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/8.x/mk/unix/Doxytail.html b/8.x/mk/unix/Doxytail.html
new file mode 100644 (file)
index 0000000..3bd3a8c
--- /dev/null
@@ -0,0 +1,8 @@
+<br><hr size=1>
+<center>
+    Metakit C++ API Reference -
+    <a href="http://www.equi4.com/metakit.html">http://www.equi4.com/metakit.html</a>
+    - extracted with
+    <a href="http://www.doxygen.org">Doxygen</a>
+</center>
+</body></html>
diff --git a/8.x/mk/unix/Makefile.in b/8.x/mk/unix/Makefile.in
new file mode 100755 (executable)
index 0000000..cf423f4
--- /dev/null
@@ -0,0 +1,274 @@
+# If this file has the name "Makefile.in" then it is a template for a
+# Makefile;  to generate the actual Makefile, run "./configure", which
+# is a configuration script generated by the "autoconf" program.
+
+SHELL =   /bin/sh
+
+LOBJS =   column.o custom.o derived.o fileio.o field.o format.o \
+          handler.o persist.o remap.o std.o store.o string.o table.o \
+         univ.o view.o viewx.o
+
+PYOBJS  = PyProperty.o PyRowRef.o PyStorage.o PyView.o PWOImp.o
+
+TSTOBJS = regress.o tbasic1.o tbasic2.o tcusto1.o tcusto2.o tdiffer.o \
+         textend.o tformat.o tlimits.o tmapped.o tnotify.o tresize.o \
+         tstore1.o tstore2.o tstore3.o tstore4.o tstore5.o
+
+DEMOS   = demo dump myio
+
+LINK_SPECIAL_FLAGS     =       @LINK_SPECIAL_FLAGS@ @LIBS@
+LINK_SPECIAL_FILES     =       @LINK_SPECIAL_FILES@
+
+#---------- Autoconf settings, can be overriden as "make" args
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+includedir = @includedir@
+libdir = @libdir@
+srcdir = @srcdir@
+top_builddir = .
+
+python = python
+pyincludedir = @PY_INCLUDE_DIR@
+pylibdir = @PY_LIB_DIR@
+
+tclsh = tclsh
+tclincludedir = @TCL_INCLUDE_DIR@
+tcllibdir = @TCL_LIB_DIR@
+
+CXX_FLAGS = @CPPFLAGS@ @CXXFLAGS@ @MK_THREADS@ @SHLIB_CFLAGS@ \
+               -I$(srcdir)/../include
+
+# Compiling without frame pointers can play tricks with exception handling
+# (e.g. in Mk4py).  This does not affect standard operation, *only* errors.
+# Happens in gcc 2.95.3, it has been disabled for now (even though slower).
+#CXXFLAGS = -fomit-frame-pointer $(CXX_FLAGS)
+CXXFLAGS = $(CXX_FLAGS)
+#CXXFLAGS = -Dq4_CHECK $(CXX_FLAGS)
+#CXXFLAGS = -Wall -pedantic -Wno-unused $(CXX_FLAGS)
+
+CXX = @CXX@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+LIB_SUFFIX = @LIB_SUFFIX@
+SHLIB_SUFFIX = @SHLIB_SUFFIX@
+SHLIB_LD = @SHLIB_LD@
+SHLIB_FLAGS = @SHLIB_FLAGS@
+STRIP_FLAGS = @STRIP_FLAGS@
+LIBEXT = @LIBEXT@
+EXEEXT = @EXEEXT@
+DESTDIR=
+
+#---------- Do not change, shorthand only
+
+CXX_SWITCHES      = $(CXXFLAGS) -I$(srcdir)/../src -I.
+CXX_SWITCHES_TCL  = $(CXXFLAGS) -I$(tclincludedir)/generic -I$(tclincludedir)
+CXX_SWITCHES_PY   = $(CXXFLAGS) -I$(srcdir)/../python/scxx -I$(pyincludedir)
+
+#---------- The targets normally specified when calling "make"
+
+all: @MK_TARGETS@
+
+core: Makefile libmk4$(LIBEXT) $(DEMOS)
+
+tcl: Makefile Mk4tcl$(LIBEXT)
+
+python: Makefile Mk4py$(LIBEXT)
+
+test: Makefile libmk4$(LIBEXT) regress
+       test -d tests || mkdir tests
+       -test -d ../tests/ok/CVS && (test -d tests/CVS || mkdir tests/CVS)
+       test -f reversed || cp $(srcdir)/reversed .
+       ./regress
+       diff --exclude=.svn $(srcdir)/../tests/ok tests
+
+test-tcl: tcl
+       cd $(srcdir)/../tcl/test && $(tclsh) all.tcl
+
+test-python: python
+       $(python) $(srcdir)/../python/test/all.py
+
+install: @MK_INSTALL@
+
+install-mk: libmk4$(LIBEXT)
+       mkdir -p $(DESTDIR)$(includedir) $(DESTDIR)$(libdir)
+       $(INSTALL_DATA) $(srcdir)/../include/mk4.h \
+                       $(srcdir)/../include/mk4.inl \
+                       $(srcdir)/../include/mk4str.h \
+                       $(srcdir)/../include/mk4str.inl $(DESTDIR)$(includedir)
+       $(INSTALL_PROGRAM) libmk4$(LIBEXT) $(DESTDIR)$(libdir)
+       if [ '${LIBEXT}' = '.a' ]; then ranlib $(DESTDIR)$(libdir)/libmk4.a; fi
+
+install-tcl: Mk4tcl$(LIBEXT)
+       mkdir -p $(DESTDIR)$(tcllibdir)/Mk4tcl
+       $(INSTALL_PROGRAM) Mk4tcl$(LIBEXT) $(DESTDIR)$(tcllibdir)/Mk4tcl
+       if [ '${LIBEXT}' = '.a' ]; then ranlib $(DESTDIR)$(tcllibdir)/Mk4tcl/Mk4tcl.a; fi
+       echo 'package ifneeded Mk4tcl 2.4.9.7 [list load [file join $$dir Mk4tcl$(LIBEXT)] Mk4tcl]' >$(DESTDIR)$(tcllibdir)/Mk4tcl/pkgIndex.tcl
+
+install-python: Mk4py$(LIBEXT)
+       mkdir -p $(DESTDIR)$(pylibdir)
+       $(INSTALL_PROGRAM) Mk4py$(LIBEXT) $(DESTDIR)$(pylibdir)
+       $(INSTALL_PROGRAM) $(srcdir)/../python/metakit.py $(DESTDIR)$(pylibdir)
+
+clean:
+       rm -f *$(LIBEXT) *.o
+       rm -f $(DEMOS) struct regress myfile.dat secret.dat
+       rm -rf tests/[a-z]*
+
+distclean: clean
+       rm -f Makefile config.h config.status config.log config.cache
+
+#---------- This defines what each of the targets does
+
+Makefile: $(srcdir)/Makefile.in config.status
+       $(SHELL) ./config.status
+
+config.status: $(srcdir)/configure
+       $(SHELL) ./config.status --recheck
+
+$(srcdir)/configure: $(srcdir)/configure.in
+       cd $(srcdir) && autoconf
+
+libmk4$(LIB_SUFFIX): $(LOBJS)
+       ar rcu $@ $(LOBJS)
+       ranlib $@
+
+libmk4$(SHLIB_SUFFIX): $(LOBJS) $(LINK_SPECIAL_FILES)
+       $(SHLIB_LD) -o $@ $(LOBJS) $(LINK_SPECIAL_FLAGS) $(LDFLAGS)
+
+Mk4tcl$(LIB_SUFFIX): mk4tcl.o mk4too.o $(LOBJS)
+       ar rcu $@ mk4tcl.o mk4too.o $(LOBJS)
+       ranlib $@
+
+Mk4tcl$(SHLIB_SUFFIX): mk4tcl.o mk4too.o $(LOBJS) $(LINK_SPECIAL_FILES)
+       $(SHLIB_LD) -o $@ mk4tcl.o mk4too.o \
+                       $(LOBJS) $(LINK_SPECIAL_FLAGS) $(LDFLAGS)
+
+Mk4py$(LIB_SUFFIX): $(PYOBJS) $(LOBJS)
+       ar cru $@ $(PYOBJS) $(LOBJS)
+       ranlib $@
+
+Mk4py$(SHLIB_SUFFIX): $(PYOBJS) $(LOBJS) $(LINK_SPECIAL_FILES)
+       $(SHLIB_LD) -o $@ $(PYOBJS) $(LOBJS) $(LINK_SPECIAL_FLAGS) $(LDFLAGS)
+
+demo: $(srcdir)/../demos/demo.cpp libmk4$(LIBEXT)
+       $(CXX) $(CXX_SWITCHES) -o $@$(EXEEXT) \
+               $(srcdir)/../demos/demo.cpp libmk4$(LIBEXT) @LIBS@
+
+dump: $(srcdir)/../demos/dump.cpp libmk4$(LIBEXT)
+       $(CXX) $(CXX_SWITCHES) -o $@$(EXEEXT) \
+               $(srcdir)/../demos/dump.cpp libmk4$(LIBEXT) @LIBS@
+
+myio: $(srcdir)/../demos/myio.cpp libmk4$(LIBEXT)
+       $(CXX) $(CXX_SWITCHES) -o $@$(EXEEXT) \
+               $(srcdir)/../demos/myio.cpp libmk4$(LIBEXT) @LIBS@
+
+struct: $(srcdir)/../demos/struct.cpp
+       $(CXX) $(CXX_SWITCHES) -o $@$(EXEEXT) \
+               $(srcdir)/../demos/struct.cpp -lmk4 @LIBS@
+
+regress: $(TSTOBJS) libmk4$(LIBEXT)
+       $(CXX) $(CXX_SWITCHES) -o $@$(EXEEXT) $(TSTOBJS) libmk4$(LIBEXT) @LIBS@
+
+#---------- Dependencies
+
+# Hack.
+# Configuration: HPUX, CXX=aCC, CC=cc, cpu PA-RISC
+# => Have to link this object file to satisfy symbols.
+#
+cpprt0_stubs.o: $(srcdir)/cpprt0_stubs.s
+       as -o $@ $?
+
+mk4tcl.o: $(srcdir)/../tcl/mk4tcl.cpp
+       $(CXX) -c $(CXX_SWITCHES_TCL) $?
+mk4too.o: $(srcdir)/../tcl/mk4too.cpp
+       $(CXX) -c $(CXX_SWITCHES_TCL) $?
+
+PyProperty.o: $(srcdir)/../python/PyProperty.cpp
+       $(CXX) -c $(CXX_SWITCHES_PY) $?
+PyRowRef.o: $(srcdir)/../python/PyRowRef.cpp
+       $(CXX) -c $(CXX_SWITCHES_PY) $?
+PyStorage.o: $(srcdir)/../python/PyStorage.cpp
+       $(CXX) -c $(CXX_SWITCHES_PY) $?
+PyView.o: $(srcdir)/../python/PyView.cpp
+       $(CXX) -c $(CXX_SWITCHES_PY) $?
+
+PWOImp.o: $(srcdir)/../python/scxx/PWOImp.cpp \
+         $(srcdir)/../python/scxx/PWOBase.h \
+         $(srcdir)/../python/scxx/PWOCallable.h \
+         $(srcdir)/../python/scxx/PWOMSequence.h \
+         $(srcdir)/../python/scxx/PWOMapping.h \
+         $(srcdir)/../python/scxx/PWONumber.h \
+         $(srcdir)/../python/scxx/PWOSequence.h
+       $(CXX) -c $(CXX_SWITCHES_PY) $(srcdir)/../python/scxx/PWOImp.cpp
+
+column.o:  $(srcdir)/../src/column.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+custom.o:  $(srcdir)/../src/custom.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+derived.o: $(srcdir)/../src/derived.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+field.o:   $(srcdir)/../src/field.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+fileio.o:  $(srcdir)/../src/fileio.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+format.o:  $(srcdir)/../src/format.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+handler.o: $(srcdir)/../src/handler.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+persist.o: $(srcdir)/../src/persist.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+remap.o:   $(srcdir)/../src/remap.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+std.o:     $(srcdir)/../src/std.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+store.o:   $(srcdir)/../src/store.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+string.o:  $(srcdir)/../src/string.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+table.o:   $(srcdir)/../src/table.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+univ.o:    $(srcdir)/../src/univ.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+view.o:    $(srcdir)/../src/view.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+viewx.o:   $(srcdir)/../src/viewx.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+
+regress.o: $(srcdir)/../tests/regress.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tbasic1.o: $(srcdir)/../tests/tbasic1.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tbasic2.o: $(srcdir)/../tests/tbasic2.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tcusto1.o: $(srcdir)/../tests/tcusto1.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tcusto2.o: $(srcdir)/../tests/tcusto2.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tdiffer.o: $(srcdir)/../tests/tdiffer.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+textend.o: $(srcdir)/../tests/textend.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tformat.o: $(srcdir)/../tests/tformat.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tlimits.o: $(srcdir)/../tests/tlimits.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tmapped.o: $(srcdir)/../tests/tmapped.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tnotify.o: $(srcdir)/../tests/tnotify.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tresize.o: $(srcdir)/../tests/tresize.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tstore1.o: $(srcdir)/../tests/tstore1.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tstore2.o: $(srcdir)/../tests/tstore2.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tstore3.o: $(srcdir)/../tests/tstore3.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tstore4.o: $(srcdir)/../tests/tstore4.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+tstore5.o: $(srcdir)/../tests/tstore5.cpp
+       $(CXX) -c $(CXX_SWITCHES) $?
+
+#---------- End
diff --git a/8.x/mk/unix/README b/8.x/mk/unix/README
new file mode 100644 (file)
index 0000000..859498b
--- /dev/null
@@ -0,0 +1,9 @@
+To keep the unix/ directory as is, please build Metakit using:
+
+       cd ../builds
+       ../unix/configure
+       make
+       make test
+       make install
+
+Further documentation and install notes are in "../README".
diff --git a/8.x/mk/unix/config.h.in b/8.x/mk/unix/config.h.in
new file mode 100755 (executable)
index 0000000..ba73917
--- /dev/null
@@ -0,0 +1,56 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if the system has the type `long long'. */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+   if it is not supported. */
+#undef inline
diff --git a/8.x/mk/unix/configure b/8.x/mk/unix/configure
new file mode 100755 (executable)
index 0000000..54a8743
--- /dev/null
@@ -0,0 +1,4733 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="../include/mk4.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CXXCPP EGREP LINK_SPECIAL_FLAGS LINK_SPECIAL_FILES MK_TARGETS MK_INSTALL MK_THREADS PY_INCLUDE_DIR PY_LIB_DIR TCL_INCLUDE_DIR TCL_LIB_DIR LIBEXT LIB_SUFFIX SHLIB_SUFFIX SHLIB_CFLAGS SHLIB_LD SHLIB_FLAGS STRIP_FLAGS LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CXXCPP_set=${CXXCPP+set}
+ac_env_CXXCPP_value=$CXXCPP
+ac_cv_env_CXXCPP_set=${CXXCPP+set}
+ac_cv_env_CXXCPP_value=$CXXCPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-threads        build with threads
+  --enable-shared         build as shared lib (default=yes)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-python=PATH      build the Mk4py extension for Python with headers in
+                          `PATH/include/python2.5'; install the Mk4py modules in
+                          `PATH/lib/python2.5/site-packages'.  If PATH is of the
+                          form `HEADER,LIB', search for header files in HEADER,
+                          and install Mk4py in LIB.  If you omit the `=PATH'
+                          part, use the standard includedir and libdir.
+  --with-tcl=PATH         build the Mk4tcl extension for Tcl with tcl.h in
+                          `PATH/tcl.h'; install the Mk4tcl package in
+                         `PATH/../lib'.  If PATH is of the form `HEADER,LIB',
+                          search for tcl.h in HEADER, and install Mk4tcl in
+                          LIB.  If you omit the `=PATH' part, use the standard
+                         includedir and libdir.
+
+Some influential environment variables:
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CXXCPP      C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in scripts $srcdir/scripts; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in scripts $srcdir/scripts" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in scripts $srcdir/scripts" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+          ac_config_headers="$ac_config_headers config.h"
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+MK_TARGETS="core"
+MK_INSTALL="install-mk"
+
+
+# Check whether --with-python or --without-python was given.
+if test "${with_python+set}" = set; then
+  withval="$with_python"
+  with_python=${withval}
+else
+  with_python=no
+fi;
+
+echo "$as_me:$LINENO: checking for Python configuration" >&5
+echo $ECHO_N "checking for Python configuration... $ECHO_C" >&6
+case "$with_python" in
+  "yes" )
+       PY_INCLUDE_DIR="${prefix}/include/python2.5"
+       PY_LIB_DIR="${prefix}/lib/python2.5/site-packages"
+  ;;
+  "no" )
+       PY_INCLUDE_DIR="# no Python headers"
+  ;;
+  *","* )
+       PY_INCLUDE_DIR="`echo $with_python | sed -e 's/,.*$//'`"
+       PY_LIB_DIR="`echo $with_python | sed -e 's/^.*,//'`"
+  ;;
+  * )
+    PY_INCLUDE_DIR="$with_python/include/python2.5"
+    PY_LIB_DIR="$with_python/lib/python2.5/site-packages"
+  ;;
+esac
+
+if test x"$with_python" = xno; then
+  echo "$as_me:$LINENO: result: not enabled" >&5
+echo "${ECHO_T}not enabled" >&6
+else
+  MK_TARGETS="$MK_TARGETS python"
+  MK_INSTALL="$MK_INSTALL install-python"
+  if test -f "${PY_INCLUDE_DIR}/Python.h" ; then
+    MK_TARGETS="$MK_TARGETS python"
+    MK_INSTALL="$MK_INSTALL install-python"
+    echo "$as_me:$LINENO: result: $PY_INCLUDE_DIR and $PY_LIB_DIR" >&5
+echo "${ECHO_T}$PY_INCLUDE_DIR and $PY_LIB_DIR" >&6
+  else
+    echo "$as_me:$LINENO: result: can't find ${PY_INCLUDE_DIR}/Python.h" >&5
+echo "${ECHO_T}can't find ${PY_INCLUDE_DIR}/Python.h" >&6
+  fi
+fi
+
+
+# Check whether --with-tcl or --without-tcl was given.
+if test "${with_tcl+set}" = set; then
+  withval="$with_tcl"
+  with_tcl=${withval}
+else
+  with_tcl=no
+fi;
+
+echo "$as_me:$LINENO: checking for Tcl headers" >&5
+echo $ECHO_N "checking for Tcl headers... $ECHO_C" >&6
+case "$with_tcl" in
+  "yes" )
+       TCL_INCLUDE_DIR="${prefix}/include"
+       TCL_LIB_DIR="${prefix}/lib/tcl8.4"
+  ;;
+  "no" )
+       TCL_INCLUDE_DIR="# no Tcl headers"
+  ;;
+  *","* )
+       TCL_INCLUDE_DIR="`echo $with_tcl | sed -e 's/,.*$//'`"
+       TCL_LIB_DIR="`echo $with_tcl | sed -e 's/^.*,//'`"
+  ;;
+  * )
+    TCL_INCLUDE_DIR="$with_tcl"
+    TCL_LIB_DIR="$with_tcl/../lib"
+  ;;
+esac
+
+if test x"$with_tcl" = xno ; then
+  echo "$as_me:$LINENO: result: not enabled" >&5
+echo "${ECHO_T}not enabled" >&6
+else
+  MK_TARGETS="$MK_TARGETS tcl"
+  MK_INSTALL="$MK_INSTALL install-tcl"
+  if test -f "${TCL_INCLUDE_DIR}/tcl.h" ; then
+    echo "$as_me:$LINENO: result: found ${TCL_INCLUDE_DIR}/tcl.h" >&5
+echo "${ECHO_T}found ${TCL_INCLUDE_DIR}/tcl.h" >&6
+    MK_TARGETS="$MK_TARGETS tcl"
+    MK_INSTALL="$MK_INSTALL install-tcl"
+    echo "$as_me:$LINENO: checking for Tcl package installation location" >&5
+echo $ECHO_N "checking for Tcl package installation location... $ECHO_C" >&6
+    echo "$as_me:$LINENO: result: ${TCL_LIB_DIR}" >&5
+echo "${ECHO_T}${TCL_LIB_DIR}" >&6
+  else
+    { { echo "$as_me:$LINENO: error: ${TCL_INCLUDE_DIR} directory doesn't contain tcl.h" >&5
+echo "$as_me: error: ${TCL_INCLUDE_DIR} directory doesn't contain tcl.h" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+echo "$as_me:$LINENO: checking for building with threads" >&5
+echo $ECHO_N "checking for building with threads... $ECHO_C" >&6
+# Check whether --enable-threads or --disable-threads was given.
+if test "${enable_threads+set}" = set; then
+  enableval="$enable_threads"
+  ok=$enableval
+else
+  ok=no
+fi;
+if test "$ok" = yes; then
+  MK_THREADS="-Dq4_MULTI -DTCL_THREADS"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  MK_THREADS=""
+  echo "$as_me:$LINENO: result: no (default)" >&5
+echo "${ECHO_T}no (default)" >&6
+fi
+
+echo "$as_me:$LINENO: checking for building as shared lib" >&5
+echo $ECHO_N "checking for building as shared lib... $ECHO_C" >&6
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  ok=$enableval
+else
+  ok=yes
+fi;
+if test "$ok" = yes; then
+  SHARED_BUILD=1
+  echo "$as_me:$LINENO: result: yes (default)" >&5
+echo "${ECHO_T}yes (default)" >&6
+else
+  SHARED_BUILD=0
+  echo "$as_me:$LINENO: result: no, static" >&5
+echo "${ECHO_T}no, static" >&6
+fi
+
+if test $SHARED_BUILD = 1; then
+  SHLIB_FLAGS="-shared"
+  SHLIB_CFLAGS="-fPIC -DUSE_TCL_STUBS"
+  SHLIB_LD="g++ -shared"
+else
+  SHLIB_FLAGS=""
+  SHLIB_CFLAGS=""
+  SHLIB_LD=""
+fi
+
+# Checks for programs.
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5
+echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5
+echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Checks for libraries.
+
+# Checks for header files.
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6
+if test "${ac_cv_c_inline+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_inline=$ac_kw; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6
+
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+  return 0;
+if (sizeof (long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
+
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for long long" >&5
+echo $ECHO_N "checking for long long... $ECHO_C" >&6
+if test "${ac_cv_type_long_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long long *) 0)
+  return 0;
+if (sizeof (long long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_long_long" >&6
+if test $ac_cv_type_long_long = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG_LONG 1
+_ACEOF
+
+
+fi
+
+
+# Checks for library functions.
+
+
+
+for ac_func in mmap memmove bcopy
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Deal with static & shared lib differences
+LIB_SUFFIX=".a"
+SHLIB_SUFFIX=".so"
+STRIP_FLAGS=
+
+build_os=`uname -s`
+build_cpu=`uname -p`
+
+case $build_os in
+  Darwin*)
+    SHLIB_SUFFIX=".dylib"
+    SHLIB_LD="g++ -dynamiclib -flat_namespace -undefined suppress"
+    STRIP_FLAGS=-S
+    ;;
+  HP-UX*)
+    case "`uname -r`" in
+      B.11.00|B.10*)
+       CXXFLAGS="$CXXFLAGS -DNO_MMAP"
+       ;;
+    esac
+    SHLIB_SUFFIX=".sl"
+    ;;
+  cyg*)
+    LIB_SUFFIX=".lib"
+    SHLIB_SUFFIX=".dll"
+    ;;
+esac
+
+if test $SHARED_BUILD = 1; then
+  LIBEXT=$SHLIB_SUFFIX
+else
+  LIBEXT=$LIB_SUFFIX
+fi
+
+echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6
+if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then
+  LIBS="$LIBS -lpthread"
+fi
+
+
+# ---------------------------------------------------------
+# Special hackery for hpux machines to allow usage of the
+# metakit C++ library from within Tcl (C application).
+#
+# The special configurations are:
+#
+# (1)  CXX=aCC, CC=cc, build_os=hpux*, build_cpu=hppa
+# (1a) CXX=aCC, CC=cc, build_os=hpux*, build_cpu=hppa2.0w (true 64 bit)
+# (2)  CXX=aCC, CC=cc, build_os=hpux*, build_cpu=ia64
+#
+# [Ad 1]  Link against -lCsup and insert cpprt0_stub.o
+# [Ad 1a] Link against -lCsup
+# [Ad 2]  Link against -lCsup
+#
+# Variables to substitute
+# = LINK_SPECIAL_FLAGS
+# = LINK_SPECIAL_FILES
+
+LINK_SPECIAL_FLAGS=""
+LINK_SPECIAL_FILES=""
+
+case $build_os in
+  HP-UX*)
+    if test "X$build_cpu" != "Xia64" -a "$threads_ok" = yes; then
+       # Handle special link requirements of hpux-parisc in threaded case.
+       LINK_SPECIAL_FLAGS="$LINK_SPECIAL_FLAGS -lpthread"
+    fi
+
+    if test \
+       "`basename $CXX`x" = "aCCx" -a  \
+       "Z`basename $CC`" = "Zcc"
+    then
+       # Native HP compilers
+
+       if test "X$build_cpu" = "Xia64" ; then
+           # Itanium: No -lstdc++
+           LINK_SPECIAL_FLAGS="$LINK_SPECIAL_FLAGS -lCsup"
+           LINK_SPECIAL_FILES=""
+       else
+           # pa-risc: The exact architecture of the cpu is now important.
+           # Actually: The exact nature of the code we generate is important.
+
+           case $CXXFLAGS in
+             *DA2.0W*)
+               # True 64 bit, no stdc++, no stubs
+               LINK_SPECIAL_FLAGS="$LINK_SPECIAL_FLAGS -lCsup"
+             ;;
+             *)
+               # Everything else
+               LINK_SPECIAL_FLAGS="$LINK_SPECIAL_FLAGS -lCsup -Wl,cpprt0_stubs.o"
+               LINK_SPECIAL_FILES="cpprt0_stubs.o"
+               LDFLAGS="${LDFLAGS} -lstdc++"
+             ;;
+           esac
+       fi
+    fi
+    ;;
+  SunOS-*)
+    # Tested for solaris-2.8.
+
+    if test "x`basename $CXX`" = "xCC"
+    then
+       # Native SUN C++ compiler
+       # Depending on 32/64 mode choose between runtime libraries
+
+       # Stupid which can insert warnings into the output
+       # instad of using stderr. Bah.
+
+       base=`which $CXX 2>/dev/null`    ; # Full path of compiler.
+       basea=`echo "$base" | sed -e 's/^Warning: ridiculously long PATH truncated//'`
+       baseb=`dirname $basea` ; # Strip name of compiler
+       basec=`dirname $baseb` ; # Strip bin directory
+       CCRUNDIR="$basec/lib"
+
+       case $CXXFLAGS in
+           *xarch=v9*) CCRUNDIR="$CCRUNDIR/v9" ;;
+           *)          :                       ;;
+       esac
+
+       LDFLAGS="${LDFLAGS} -L${CCRUNDIR} -lCrun"
+    else
+       # Setup not using CC, use -lstdc++, like for case '*' below.
+
+       LDFLAGS="${LDFLAGS} -lstdc++"
+    fi
+    ;;
+  *)
+    LDFLAGS="${LDFLAGS} -lstdc++"
+    ;;
+esac
+
+
+
+
+# ---------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                  instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CXXCPP@,$CXXCPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@LINK_SPECIAL_FLAGS@,$LINK_SPECIAL_FLAGS,;t t
+s,@LINK_SPECIAL_FILES@,$LINK_SPECIAL_FILES,;t t
+s,@MK_TARGETS@,$MK_TARGETS,;t t
+s,@MK_INSTALL@,$MK_INSTALL,;t t
+s,@MK_THREADS@,$MK_THREADS,;t t
+s,@PY_INCLUDE_DIR@,$PY_INCLUDE_DIR,;t t
+s,@PY_LIB_DIR@,$PY_LIB_DIR,;t t
+s,@TCL_INCLUDE_DIR@,$TCL_INCLUDE_DIR,;t t
+s,@TCL_LIB_DIR@,$TCL_LIB_DIR,;t t
+s,@LIBEXT@,$LIBEXT,;t t
+s,@LIB_SUFFIX@,$LIB_SUFFIX,;t t
+s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t
+s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t
+s,@SHLIB_LD@,$SHLIB_LD,;t t
+s,@SHLIB_FLAGS@,$SHLIB_FLAGS,;t t
+s,@STRIP_FLAGS@,$STRIP_FLAGS,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([   ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[        ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([   ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        # Do quote $f, to prevent DOS paths from being IFS'd.
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[      ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[    ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[     ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[     ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[     ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/8.x/mk/unix/configure.in b/8.x/mk/unix/configure.in
new file mode 100755 (executable)
index 0000000..1a97866
--- /dev/null
@@ -0,0 +1,296 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(../include/mk4.h)
+AC_PREREQ(2.5)
+AC_CONFIG_AUX_DIR(scripts)
+AC_CONFIG_HEADER(config.h)
+AC_LANG_CPLUSPLUS
+
+MK_TARGETS="core"
+MK_INSTALL="install-mk"
+
+AC_ARG_WITH(python,
+[  --with-python=PATH      build the Mk4py extension for Python with headers in
+                          `PATH/include/python2.5'; install the Mk4py modules in
+                          `PATH/lib/python2.5/site-packages'.  If PATH is of the
+                          form `HEADER,LIB', search for header files in HEADER,
+                          and install Mk4py in LIB.  If you omit the `=PATH'
+                          part, use the standard includedir and libdir.],
+                          [with_python=${withval}], [with_python=no])
+
+AC_MSG_CHECKING([for Python configuration])
+case "$with_python" in
+  "yes" )
+       PY_INCLUDE_DIR="${prefix}/include/python2.5"
+       PY_LIB_DIR="${prefix}/lib/python2.5/site-packages"
+  ;;
+  "no" )
+       PY_INCLUDE_DIR="# no Python headers"
+  ;;
+  *","* )
+       PY_INCLUDE_DIR="`echo $with_python | sed -e 's/,.*$//'`"
+       PY_LIB_DIR="`echo $with_python | sed -e 's/^.*,//'`"
+  ;;
+  * )
+    PY_INCLUDE_DIR="$with_python/include/python2.5"
+    PY_LIB_DIR="$with_python/lib/python2.5/site-packages"
+  ;;
+esac
+
+if test x"$with_python" = xno; then
+  AC_MSG_RESULT(not enabled)
+else
+  MK_TARGETS="$MK_TARGETS python"
+  MK_INSTALL="$MK_INSTALL install-python"
+  if test -f "${PY_INCLUDE_DIR}/Python.h" ; then
+    MK_TARGETS="$MK_TARGETS python"
+    MK_INSTALL="$MK_INSTALL install-python"
+    AC_MSG_RESULT($PY_INCLUDE_DIR and $PY_LIB_DIR)
+  else
+    AC_MSG_RESULT(can't find ${PY_INCLUDE_DIR}/Python.h)
+  fi
+fi
+
+AC_ARG_WITH(tcl, 
+[  --with-tcl=PATH         build the Mk4tcl extension for Tcl with tcl.h in
+                          `PATH/tcl.h'; install the Mk4tcl package in
+                         `PATH/../lib'.  If PATH is of the form `HEADER,LIB',
+                          search for tcl.h in HEADER, and install Mk4tcl in
+                          LIB.  If you omit the `=PATH' part, use the standard
+                         includedir and libdir.],
+                         [with_tcl=${withval}], [with_tcl=no])
+
+AC_MSG_CHECKING([for Tcl headers])
+case "$with_tcl" in
+  "yes" )
+       TCL_INCLUDE_DIR="${prefix}/include"
+       TCL_LIB_DIR="${prefix}/lib/tcl8.4"
+  ;;
+  "no" )
+       TCL_INCLUDE_DIR="# no Tcl headers"
+  ;;
+  *","* )
+       TCL_INCLUDE_DIR="`echo $with_tcl | sed -e 's/,.*$//'`"
+       TCL_LIB_DIR="`echo $with_tcl | sed -e 's/^.*,//'`"
+  ;;
+  * )
+    TCL_INCLUDE_DIR="$with_tcl"
+    TCL_LIB_DIR="$with_tcl/../lib"
+  ;;
+esac
+
+if test x"$with_tcl" = xno ; then
+  AC_MSG_RESULT(not enabled)
+else
+  MK_TARGETS="$MK_TARGETS tcl"
+  MK_INSTALL="$MK_INSTALL install-tcl"
+  if test -f "${TCL_INCLUDE_DIR}/tcl.h" ; then
+    AC_MSG_RESULT(found ${TCL_INCLUDE_DIR}/tcl.h)
+    MK_TARGETS="$MK_TARGETS tcl"
+    MK_INSTALL="$MK_INSTALL install-tcl"
+    AC_MSG_CHECKING(for Tcl package installation location)
+    AC_MSG_RESULT(${TCL_LIB_DIR})
+  else
+    AC_MSG_ERROR([${TCL_INCLUDE_DIR} directory doesn't contain tcl.h])
+  fi
+fi
+
+AC_MSG_CHECKING([for building with threads])
+AC_ARG_ENABLE(threads, [  --enable-threads        build with threads], [ok=$enableval], [ok=no])
+if test "$ok" = yes; then
+  MK_THREADS="-Dq4_MULTI -DTCL_THREADS"
+  AC_MSG_RESULT(yes)
+else
+  MK_THREADS=""
+  AC_MSG_RESULT([no (default)])
+fi
+
+AC_MSG_CHECKING([for building as shared lib])
+AC_ARG_ENABLE(shared, [  --enable-shared         build as shared lib (default=yes)], [ok=$enableval], [ok=yes])
+if test "$ok" = yes; then
+  SHARED_BUILD=1
+  AC_MSG_RESULT([yes (default)])
+else
+  SHARED_BUILD=0
+  AC_MSG_RESULT([no, static])
+fi
+
+if test $SHARED_BUILD = 1; then
+  SHLIB_FLAGS="-shared"
+  SHLIB_CFLAGS="-fPIC -DUSE_TCL_STUBS"
+  SHLIB_LD="g++ -shared"
+else
+  SHLIB_FLAGS=""
+  SHLIB_CFLAGS=""
+  SHLIB_LD=""
+fi
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_INSTALL
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_CHECK_SIZEOF(long,4)
+AC_CHECK_TYPES(long long)
+
+# Checks for library functions.
+AC_CHECK_FUNCS(mmap memmove bcopy)
+
+# Deal with static & shared lib differences
+LIB_SUFFIX=".a"
+SHLIB_SUFFIX=".so"
+STRIP_FLAGS=
+
+build_os=`uname -s`
+build_cpu=`uname -p`
+
+case $build_os in
+  Darwin*)
+    SHLIB_SUFFIX=".dylib"
+    SHLIB_LD="g++ -dynamiclib -flat_namespace -undefined suppress"
+    STRIP_FLAGS=-S
+    ;;
+  HP-UX*)
+    case "`uname -r`" in
+      B.11.00|B.10*)
+       CXXFLAGS="$CXXFLAGS -DNO_MMAP"
+       ;;
+    esac
+    SHLIB_SUFFIX=".sl"
+    ;;
+  cyg*)
+    LIB_SUFFIX=".lib"
+    SHLIB_SUFFIX=".dll"
+    ;;
+esac
+
+if test $SHARED_BUILD = 1; then
+  LIBEXT=$SHLIB_SUFFIX
+else
+  LIBEXT=$LIB_SUFFIX
+fi
+
+AC_CHECK_LIB(pthread, pthread_mutex_init, [LIBS="$LIBS -lpthread"])
+
+# ---------------------------------------------------------
+# Special hackery for hpux machines to allow usage of the
+# metakit C++ library from within Tcl (C application).
+#
+# The special configurations are:
+#
+# (1)  CXX=aCC, CC=cc, build_os=hpux*, build_cpu=hppa
+# (1a) CXX=aCC, CC=cc, build_os=hpux*, build_cpu=hppa2.0w (true 64 bit)
+# (2)  CXX=aCC, CC=cc, build_os=hpux*, build_cpu=ia64
+#
+# [Ad 1]  Link against -lCsup and insert cpprt0_stub.o
+# [Ad 1a] Link against -lCsup
+# [Ad 2]  Link against -lCsup
+#
+# Variables to substitute
+# = LINK_SPECIAL_FLAGS
+# = LINK_SPECIAL_FILES
+
+LINK_SPECIAL_FLAGS=""
+LINK_SPECIAL_FILES=""
+
+case $build_os in
+  HP-UX*)
+    if test "X$build_cpu" != "Xia64" -a "$threads_ok" = yes; then
+       # Handle special link requirements of hpux-parisc in threaded case.
+       LINK_SPECIAL_FLAGS="$LINK_SPECIAL_FLAGS -lpthread"
+    fi
+
+    if test \
+       "`basename $CXX`x" = "aCCx" -a  \
+       "Z`basename $CC`" = "Zcc"
+    then
+       # Native HP compilers
+
+       if test "X$build_cpu" = "Xia64" ; then
+           # Itanium: No -lstdc++
+           LINK_SPECIAL_FLAGS="$LINK_SPECIAL_FLAGS -lCsup"
+           LINK_SPECIAL_FILES=""
+       else
+           # pa-risc: The exact architecture of the cpu is now important.
+           # Actually: The exact nature of the code we generate is important.
+
+           case $CXXFLAGS in
+             *DA2.0W*)
+               # True 64 bit, no stdc++, no stubs
+               LINK_SPECIAL_FLAGS="$LINK_SPECIAL_FLAGS -lCsup"
+             ;;
+             *)
+               # Everything else
+               LINK_SPECIAL_FLAGS="$LINK_SPECIAL_FLAGS -lCsup -Wl,cpprt0_stubs.o"
+               LINK_SPECIAL_FILES="cpprt0_stubs.o"
+               LDFLAGS="${LDFLAGS} -lstdc++"
+             ;;
+           esac
+       fi
+    fi
+    ;;
+  SunOS-*)
+    # Tested for solaris-2.8.
+
+    if test "x`basename $CXX`" = "xCC"
+    then
+       # Native SUN C++ compiler
+       # Depending on 32/64 mode choose between runtime libraries
+
+       # Stupid which can insert warnings into the output
+       # instad of using stderr. Bah.
+
+       base=`which $CXX 2>/dev/null`    ; # Full path of compiler.
+       basea=`echo "$base" | sed -e 's/^Warning: ridiculously long PATH truncated//'`
+       baseb=`dirname $basea` ; # Strip name of compiler
+       basec=`dirname $baseb` ; # Strip bin directory
+       CCRUNDIR="$basec/lib"
+
+       case $CXXFLAGS in
+           *xarch=v9*) CCRUNDIR="$CCRUNDIR/v9" ;;
+           *)          :                       ;;
+       esac
+
+       LDFLAGS="${LDFLAGS} -L${CCRUNDIR} -lCrun"
+    else
+       # Setup not using CC, use -lstdc++, like for case '*' below.
+
+       LDFLAGS="${LDFLAGS} -lstdc++"
+    fi
+    ;;
+  *)
+    LDFLAGS="${LDFLAGS} -lstdc++"
+    ;;
+esac
+
+AC_SUBST(LINK_SPECIAL_FLAGS)
+AC_SUBST(LINK_SPECIAL_FILES)
+
+# ---------------------------------------------------------
+
+
+AC_SUBST(MK_TARGETS)
+AC_SUBST(MK_INSTALL)
+AC_SUBST(MK_THREADS)
+AC_SUBST(PY_INCLUDE_DIR)
+AC_SUBST(PY_LIB_DIR)
+AC_SUBST(TCL_INCLUDE_DIR)
+AC_SUBST(TCL_LIB_DIR)
+AC_SUBST(EXEEXT)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(LIBEXT)
+AC_SUBST(LIB_SUFFIX)
+AC_SUBST(SHLIB_SUFFIX)
+AC_SUBST(SHLIB_CFLAGS)
+AC_SUBST(SHLIB_LD)
+AC_SUBST(SHLIB_FLAGS)
+AC_SUBST(STRIP_FLAGS)
+
+AC_OUTPUT(Makefile)
diff --git a/8.x/mk/unix/cpprt0_stubs.s b/8.x/mk/unix/cpprt0_stubs.s
new file mode 100644 (file)
index 0000000..5ef37f6
--- /dev/null
@@ -0,0 +1,14 @@
+
+        .code
+; stubs for static constructors in a.out
+       .export __StaticCtorTable_Start,data
+        .export __StaticCtorTable_End,data
+__StaticCtorTable_Start
+__StaticCtorTable_End
+
+       .data
+; stubs for static constructors in a.out, compiled with +z/+Z
+       .export __ZStaticCtorTable_Start,data
+        .export __ZStaticCtorTable_End,data
+__ZStaticCtorTable_Start
+__ZStaticCtorTable_End
diff --git a/8.x/mk/unix/metakit.spec b/8.x/mk/unix/metakit.spec
new file mode 100644 (file)
index 0000000..a1291a6
--- /dev/null
@@ -0,0 +1,103 @@
+%define name metakit
+%define ver 2.0
+%define extension tar.gz
+
+Summary: The Metakit Library 2.0
+Name: %{name}
+Version: %{ver}
+Release: 1
+Copyright: GPL
+Group: Applications/Databases
+Source: %{name}-%{ver}.%{extension}
+Patch: metakit-install.patch
+URL: http://www.equi4.com/metakit/
+Buildroot: /tmp/%{name}-%{ver}-root
+Packager: Sean Summers <rpm-metakit@GeneralProtectionfault.com>
+
+%description
+Metakit is an embeddable database which runs on Unix, Windows,
+Macintosh, and other platforms.  It lets you build applications which
+store their data efficiently, in a portable way, and which will not need a
+complex runtime installation.  In terms of the data model, Metakit takes
+the middle ground between RDBMS, OODBMS, and flat-file databases - yet it
+is quite different from each of them.
+
+WHAT IT ISN'T - Metakit is not: 1) an SQL database, 2) multi-user/-threading,
+3) scalable to gigabytes, 4) proprietary software, 5) a toy.
+
+%package devel
+Summary: Development Libraries for The Metakit Library 2.0
+Group: Development/Libraries
+%description devel
+The %{name}-devel package contains the libraries and header files necessary
+for writing programs that make use of the Metakit library.
+
+%package python
+Group: Development/Libraries
+Summary: Python module for The Metakit Library 2.0
+%description python
+The %{name}-python package contains the libraries necessary
+for using the Metakit as a python module.
+
+#%package tcl
+#Group: Development/Libraries
+#Summary: TCL module for The Metakit Library 2.0
+#%description tcl
+#The %{name}-tcl package contains the libraries necessary
+#for using the Metakit as a tcl module.
+
+%prep
+%setup
+%patch -p1
+
+%build
+cd builds
+../unix/configure --prefix=/usr --with-python
+#--with-tcl ## maybe TCL_DECLARE_MUTEX is too new for RH6.1.92?
+make ${RPM_BUILD_OPTS}
+
+# Testing takes a while
+rm tests/\!keepme.txt
+make ${RPM_BUILD_OPTS} test
+
+%install
+cd builds
+make install DESTDIR=${RPM_BUILD_ROOT}
+libtool --finish ${RPM_BUILD_ROOT}/usr/lib/
+
+#python setup
+make Mk4py.so
+install -Ds Mk4py.so ${RPM_BUILD_ROOT}/usr/lib/python1.5/site-packages/Mk4pymodule.so
+
+#%install tcl
+#make Mk4tcl.so
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%doc CHANGES README Metakit.html
+%doc doc/e4s.gif doc/format.html
+/usr/lib/libmk4.so
+/usr/lib/libmk4.so.0
+/usr/lib/libmk4.so.0.0.0
+/usr/lib/libmk4.la
+
+%files devel
+%doc doc/api/ demos/
+/usr/lib/libmk4.a
+/usr/include/mk4.h
+/usr/include/mk4.inl
+/usr/include/mk4str.h
+/usr/include/mk4str.inl
+
+%files python
+%doc python/*.py
+%doc doc/python.*
+/usr/lib/python1.5/site-packages/Mk4pymodule.so
+
+#%files tcl
+#%doc tcl/*.tcl
+#%doc doc/tcl.*
+#/usr/lib/tcl
+
diff --git a/8.x/mk/unix/reversed b/8.x/mk/unix/reversed
new file mode 100644 (file)
index 0000000..7e3fa33
Binary files /dev/null and b/8.x/mk/unix/reversed differ
diff --git a/8.x/mk/unix/scripts/config.guess b/8.x/mk/unix/scripts/config.guess
new file mode 100755 (executable)
index 0000000..5145e35
--- /dev/null
@@ -0,0 +1,1363 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-10-21'
+
+# This file 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.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# This shell variable is my proudest work .. or something. --bje
+
+set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ;
+(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old)
+   || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ;
+dummy=$tmpdir/dummy ;
+files="$dummy.c $dummy.o $dummy.rel $dummy" ;
+trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+       for c in cc gcc c89 c99 ; do
+         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       rm -f $files ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;
+unset files'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # NetBSD (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       #
+       # Note: NetBSD doesn't particularly care about the vendor
+       # portion of the name.  We always set it to "unknown".
+       sysctl="sysctl -n hw.machine_arch"
+       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+       case "${UNAME_MACHINE_ARCH}" in
+           armeb) machine=armeb-unknown ;;
+           arm*) machine=arm-unknown ;;
+           sh3el) machine=shl-unknown ;;
+           sh3eb) machine=sh-unknown ;;
+           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    macppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mipseb-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       eval $set_cc_for_build
+       cat <<EOF >$dummy.s
+       .data
+\$Lformat:
+       .byte 37,100,45,37,120,10,0     # "%d-%x\n"
+
+       .text
+       .globl main
+       .align 4
+       .ent main
+main:
+       .frame \$30,16,\$26,0
+       ldgp \$29,0(\$27)
+       .prologue 1
+       .long 0x47e03d80 # implver \$0
+       lda \$2,-1
+       .long 0x47e20c21 # amask \$2,\$1
+       lda \$16,\$Lformat
+       mov \$0,\$17
+       not \$1,\$18
+       jsr \$26,printf
+       ldgp \$29,0(\$26)
+       mov 0,\$16
+       jsr \$26,exit
+       .end main
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null
+       if test "$?" = 0 ; then
+               case `$dummy` in
+                       0-0)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       1-0)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       1-1)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       1-101)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       2-303)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       2-307)
+                               UNAME_MACHINE="alphaev67"
+                               ;;
+                       2-1307)
+                               UNAME_MACHINE="alphaev68"
+                               ;;
+                       3-1307)
+                               UNAME_MACHINE="alphaev7"
+                               ;;
+               esac
+       fi
+       rm -f $dummy.s $dummy && rmdir $tmpdir
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+       case `/usr/bin/uname -p` in
+           sparc) echo sparc-icl-nx7 && exit 0 ;;
+       esac ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c \
+         && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+       rm -f $dummy.c $dummy && rmdir $tmpdir
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+       echo powerpc-harris-powermax
+       exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS)
+       echo powerpc-harris-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               eval $set_cc_for_build
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+               rm -f $dummy.c $dummy && rmdir $tmpdir
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+               if [ -x /usr/bin/getconf ]; then
+                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+               fi
+               if [ "${HP_ARCH}" = "" ]; then
+                   eval $set_cc_for_build
+                   sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+                   if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+                   rm -f $dummy.c $dummy && rmdir $tmpdir
+               fi ;;
+       esac
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+       rm -f $dummy.c $dummy && rmdir $tmpdir
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3D:*:*:*)
+       echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       # Determine whether the default compiler uses glibc.
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #if __GLIBC__ >= 2
+       LIBC=gnu
+       #else
+       LIBC=
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       rm -f $dummy.c && rmdir $tmpdir
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    x86:Interix*:3*)
+       echo i386-pc-interix3
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i386-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    mips:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips
+       #undef mipsel
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mipsel
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       rm -f $dummy.c && rmdir $tmpdir
+       test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit 0 ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       # Set LC_ALL=C to ensure ld outputs messages in English.
+       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #ifdef __ELF__
+       # ifdef __GLIBC__
+       #  if __GLIBC__ >= 2
+       LIBC=gnu
+       #  else
+       LIBC=gnulibc1
+       #  endif
+       # else
+       LIBC=gnulibc1
+       # endif
+       #else
+       #ifdef __INTEL_COMPILER
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       rm -f $dummy.c && rmdir $tmpdir
+       test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+       echo m68k-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+       echo sx6-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       echo `uname -p`-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       UNAME_PROCESSOR=`uname -p`
+       if test "$UNAME_PROCESSOR" = "x86"; then
+               UNAME_PROCESSOR=i386
+               UNAME_MACHINE=pc
+       fi
+       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit 0 ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit 0 ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+rm -f $dummy.c $dummy && rmdir $tmpdir
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/8.x/mk/unix/scripts/config.sub b/8.x/mk/unix/scripts/config.sub
new file mode 100755 (executable)
index 0000000..1dea9b7
--- /dev/null
@@ -0,0 +1,1470 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-09-05'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       1750a | 580 \
+       | a29k \
+       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+       | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k \
+       | m32r | m68000 | m68k | m88k | mcore \
+       | mips | mipsbe | mipseb | mipsel | mipsle \
+       | mips16 \
+       | mips64 | mips64el \
+       | mips64vr | mips64vrel \
+       | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el \
+       | mips64vr4300 | mips64vr4300el \
+       | mips64vr5000 | mips64vr5000el \
+       | mipsisa32 | mipsisa32el \
+       | mipsisa64 | mipsisa64el \
+       | mipsisa64sb1 | mipsisa64sb1el \
+       | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipstx39 | mipstx39el \
+       | mn10200 | mn10300 \
+       | ns16k | ns32k \
+       | openrisc | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xscale | xstormy16 | xtensa \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       580-* \
+       | a29k-* \
+       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+       | avr-* \
+       | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \
+       | clipper-* | cydra-* \
+       | d10v-* | d30v-* | dlx-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | ip2k-* \
+       | m32r-* \
+       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | mcore-* \
+       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+       | mips16-* \
+       | mips64-* | mips64el-* \
+       | mips64vr-* | mips64vrel-* \
+       | mips64orion-* | mips64orionel-* \
+       | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* \
+       | mips64vr5000-* | mips64vr5000el-* \
+       | mipsisa32-* | mipsisa32el-* \
+       | mipsisa64-* | mipsisa64el-* \
+       | mipsisa64sb1-* | mipsisa64sb1el-* \
+       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipstx39 | mipstx39el \
+       | none-* | np1-* | ns16k-* | ns32k-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | pyramid-* \
+       | romp-* | rs6000-* \
+       | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+       | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+       | xtensa-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       c90)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | j90)
+               basic_machine=j90-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       decsystem10* | dec10*)
+               basic_machine=pdp10-dec
+               os=-tops10
+               ;;
+       decsystem20* | dec20*)
+               basic_machine=pdp10-dec
+               os=-tops20
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       or32 | or32-*)
+               basic_machine=or32-unknown
+               os=-coff
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+       pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexgen | viac3)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon | athlon_*)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i686-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64)  basic_machine=powerpc64-unknown
+               ;;
+       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+               basic_machine=powerpc64le-unknown
+               ;;
+       ppc64le-* | powerpc64little-*)
+               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       s390 | s390-*)
+               basic_machine=s390-ibm
+               ;;
+       s390x | s390x-*)
+               basic_machine=s390x-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sb1)
+               basic_machine=mipsisa64sb1-unknown
+               ;;
+       sb1el)
+               basic_machine=mipsisa64sb1el-unknown
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sparclite-wrs | simso-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3d)
+               basic_machine=alpha-cray
+               os=-unicos
+               ;;
+       t3e)
+               basic_machine=alphaev5-cray
+               os=-unicos
+               ;;
+       t90)
+               basic_machine=t90-cray
+               os=-unicos
+               ;;
+        tic4x | c4x*)
+               basic_machine=tic4x-unknown
+               os=-coff
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       toad1)
+               basic_machine=pdp10-xkl
+               os=-tops20
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       windows32)
+               basic_machine=i386-pc
+               os=-windows32-msvcrt
+               ;;
+       xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
+               basic_machine=sh-unknown
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparc | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+       cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto*)
+               os=-nto-qnx
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -atheos*)
+               os=-atheos
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -nova*)
+               os=-rtmk-nova
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+       # This must come before the *-dec entry.
+       pdp10-*)
+               os=-tops20
+               ;;
+       pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       or32-*)
+               os=-coff
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+       *-gould)
+               os=-sysv
+               ;;
+       *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+       *-sgi)
+               os=-irix
+               ;;
+       *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks* | -windiss*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+                       -vos*)
+                               vendor=stratus
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/8.x/mk/unix/scripts/install-sh b/8.x/mk/unix/scripts/install-sh
new file mode 100755 (executable)
index 0000000..e843669
--- /dev/null
@@ -0,0 +1,250 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/8.x/mk/win/config.h b/8.x/mk/win/config.h
new file mode 100755 (executable)
index 0000000..0c4a154
--- /dev/null
@@ -0,0 +1,12 @@
+#if _MSC_VER >= 1000
+       #define HAVE_MMAP 1
+       #define HAVE_MEMMOVE 1
+       #define HAVE_BCOPY 0
+       #define SIZEOF_LONG 4
+       #define LONG_LONG __int64
+#else
+       #define HAVE_MMAP 0
+       #define HAVE_MEMMOVE 1
+       #define HAVE_BCOPY 0
+       #define SIZEOF_LONG 4
+#endif
diff --git a/8.x/mk/win/msvc60/mkbug.dsp b/8.x/mk/win/msvc60/mkbug.dsp
new file mode 100755 (executable)
index 0000000..d152dfd
--- /dev/null
@@ -0,0 +1,150 @@
+# Microsoft Developer Studio Project File - Name="mkbug" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=mkbug - Win32 Debug STD\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkbug.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkbug.mak" CFG="mkbug - Win32 Debug STD"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mkbug - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mkbug - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mkbug - Win32 Debug MFC" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mkbug - Win32 Debug STD" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mkbug - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds\msvc60\mkbug\Release"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkbug\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\builds\mkbug.exe"\r
+\r
+!ELSEIF  "$(CFG)" == "mkbug - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mkbug\Debug"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkbug\Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkbug_d.exe" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "mkbug - Win32 Debug MFC"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mkbug___Win32_Debug_MFC"\r
+# PROP BASE Intermediate_Dir "mkbug___Win32_Debug_MFC"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 1\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mkbug\Debug_MFC"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkbug\Debug_MFC"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_MFC" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkbug_d.exe" /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /debugtype:both /machine:I386 /out:"..\..\builds\mkbug_mfc_d.exe" /pdbtype:sept\r
+# SUBTRACT LINK32 /incremental:no /map /nodefaultlib\r
+\r
+!ELSEIF  "$(CFG)" == "mkbug - Win32 Debug STD"\r
+\r
+# PROP BASE Use_MFC 1\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mkbug___Win32_Debug_STD"\r
+# PROP BASE Intermediate_Dir "mkbug___Win32_Debug_STD"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mkbug\Debug_STD"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkbug\Debug_STD"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_MFC" /FR /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_STD" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkbug_mfc_d.exe" /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkbug_std_d.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mkbug - Win32 Release"\r
+# Name "mkbug - Win32 Debug"\r
+# Name "mkbug - Win32 Debug MFC"\r
+# Name "mkbug - Win32 Debug STD"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\examples\mkbug.cpp\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mkdemo.dsp b/8.x/mk/win/msvc60/mkdemo.dsp
new file mode 100755 (executable)
index 0000000..65e2f52
--- /dev/null
@@ -0,0 +1,92 @@
+# Microsoft Developer Studio Project File - Name="mkdemo" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=mkdemo - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkdemo.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkdemo.mak" CFG="mkdemo - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mkdemo - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mkdemo - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mkdemo - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds\msvc60\mkdemo\Release"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkdemo\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\builds\mkdemo.exe"\r
+\r
+!ELSEIF  "$(CFG)" == "mkdemo - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mkdemo\Debug"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkdemo\Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkdemo_d.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mkdemo - Win32 Release"\r
+# Name "mkdemo - Win32 Debug"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\demos\demo.cpp\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mkdist.dsp b/8.x/mk/win/msvc60/mkdist.dsp
new file mode 100755 (executable)
index 0000000..2cc824f
--- /dev/null
@@ -0,0 +1,59 @@
+# Microsoft Developer Studio Project File - Name="mkdist" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=mkdist - Win32 Release\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkdist.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkdist.mak" CFG="mkdist - Win32 Release"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mkdist - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds\msvc60\mkdist\Release"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkdist\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\builds\mkdist.exe"\r
+# Begin Target\r
+\r
+# Name "mkdist - Win32 Release"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\demos\demo.cpp\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mkdll.dsp b/8.x/mk/win/msvc60/mkdll.dsp
new file mode 100755 (executable)
index 0000000..06545d6
--- /dev/null
@@ -0,0 +1,265 @@
+# Microsoft Developer Studio Project File - Name="mkdll" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=mkdll - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkdll.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkdll.mak" CFG="mkdll - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mkdll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "mkdll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mkdll - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkdll\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MKDLL_EXPORTS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W4 /GX /O1 /Ob2 /I "..\..\include" /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MKDLL_EXPORTS" /FD /c\r
+# SUBTRACT CPP /Fr /YX\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 /nologo /dll /machine:I386 /out:"..\..\builds\mk4vc60.dll"\r
+\r
+!ELSEIF  "$(CFG)" == "mkdll - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkdll\Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MKDLL_EXPORTS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W4 /Gm /GX /Zi /Od /I "..\..\include" /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MKDLL_EXPORTS" /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /dll /incremental:no /debug /machine:I386 /out:"..\..\builds\mk4vc60_d.dll" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mkdll - Win32 Release"\r
+# Name "mkdll - Win32 Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\column.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\custom.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\derived.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\field.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\fileio.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\format.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\handler.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\persist.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\remap.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\std.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\store.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\string.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\table.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\univ.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\view.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\viewx.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\column.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\column.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\custom.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\derived.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\field.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\field.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\format.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\handler.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\handler.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\header.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\mfc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4dll.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4io.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4str.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4str.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\msvc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\persist.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\std.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\store.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\store.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\univ.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\univ.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\win.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mkdump.dsp b/8.x/mk/win/msvc60/mkdump.dsp
new file mode 100755 (executable)
index 0000000..b768b45
--- /dev/null
@@ -0,0 +1,92 @@
+# Microsoft Developer Studio Project File - Name="mkdump" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=mkdump - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkdump.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkdump.mak" CFG="mkdump - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mkdump - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mkdump - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mkdump - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds\msvc60\mkdump\Release"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkdump\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /map /machine:I386 /out:"..\..\builds\mkdump.exe"\r
+\r
+!ELSEIF  "$(CFG)" == "mkdump - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mkdump\Debug"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkdump\Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkdump_d.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mkdump - Win32 Release"\r
+# Name "mkdump - Win32 Debug"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\demos\dump.cpp\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mkhash.dsp b/8.x/mk/win/msvc60/mkhash.dsp
new file mode 100755 (executable)
index 0000000..7f97c3c
--- /dev/null
@@ -0,0 +1,149 @@
+# Microsoft Developer Studio Project File - Name="mkhash" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=mkhash - Win32 Debug STD\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkhash.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkhash.mak" CFG="mkhash - Win32 Debug STD"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mkhash - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mkhash - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mkhash - Win32 Debug MFC" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mkhash - Win32 Debug STD" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mkhash - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds\msvc60\mkhash\Release"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkhash\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "q4_INLINE" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\builds\mkhash.exe"\r
+\r
+!ELSEIF  "$(CFG)" == "mkhash - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mkhash\Debug"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkhash\Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkhash_d.exe" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "mkhash - Win32 Debug MFC"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mkhash___Win32_Debug_MFC"\r
+# PROP BASE Intermediate_Dir "mkhash___Win32_Debug_MFC"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 1\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mkhash\Debug_MFC"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkhash\Debug_MFC"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_MFC" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkhash_d.exe" /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkhash_mfc_d.exe" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "mkhash - Win32 Debug STD"\r
+\r
+# PROP BASE Use_MFC 1\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mkhash___Win32_Debug_STD"\r
+# PROP BASE Intermediate_Dir "mkhash___Win32_Debug_STD"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mkhash\Debug_STD"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkhash\Debug_STD"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_MFC" /FR /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_STD" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkhash_mfc_d.exe" /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mkhash_std_d.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mkhash - Win32 Release"\r
+# Name "mkhash - Win32 Debug"\r
+# Name "mkhash - Win32 Debug MFC"\r
+# Name "mkhash - Win32 Debug STD"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\examples\mkhash.cpp\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mklib.dsp b/8.x/mk/win/msvc60/mklib.dsp
new file mode 100755 (executable)
index 0000000..d4aad49
--- /dev/null
@@ -0,0 +1,311 @@
+# Microsoft Developer Studio Project File - Name="mklib" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Static Library" 0x0104\r
+\r
+CFG=mklib - Win32 Debug STD\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mklib.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mklib.mak" CFG="mklib - Win32 Debug STD"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mklib - Win32 Release" (based on "Win32 (x86) Static Library")\r
+!MESSAGE "mklib - Win32 Debug" (based on "Win32 (x86) Static Library")\r
+!MESSAGE "mklib - Win32 Debug MFC" (based on "Win32 (x86) Static Library")\r
+!MESSAGE "mklib - Win32 Debug STD" (based on "Win32 (x86) Static Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mklib - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds\msvc60\mklib\Release"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mklib\Release"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c\r
+# ADD CPP /nologo /MD /W4 /GX /O2 /Ob2 /I "..\..\include" /I ".." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "q4_INLINE" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo\r
+# ADD LIB32 /nologo /out:"..\..\builds\mk4vc60s.lib"\r
+\r
+!ELSEIF  "$(CFG)" == "mklib - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mklib___Win32_Debug"\r
+# PROP BASE Intermediate_Dir "mklib___Win32_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mklib\Debug"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mklib\Debug"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W4 /Gm /GX /Zi /Od /I "..\..\include" /I ".." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo\r
+# ADD LIB32 /nologo /out:"..\..\builds\mk4vc60s_d.lib"\r
+\r
+!ELSEIF  "$(CFG)" == "mklib - Win32 Debug MFC"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mklib___Win32_Debug_MFC"\r
+# PROP BASE Intermediate_Dir "mklib___Win32_Debug_MFC"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 1\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mklib\Debug_MFC"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mklib\Debug_MFC"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /I ".." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W4 /Gm /GX /Zi /Od /I "..\..\include" /I ".." /D "_LIB" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_MFC" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo /out:"..\..\builds\mk4vc60s_d.lib"\r
+# ADD LIB32 /nologo /out:"..\..\builds\mk4vc60s_mfc_d.lib"\r
+\r
+!ELSEIF  "$(CFG)" == "mklib - Win32 Debug STD"\r
+\r
+# PROP BASE Use_MFC 1\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mklib___Win32_Debug_STD"\r
+# PROP BASE Intermediate_Dir "mklib___Win32_Debug_STD"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mklib\Debug_STD"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mklib\Debug_STD"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /I ".." /D "_LIB" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_MFC" /FR /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /I ".." /D "_LIB" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_STD" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo /out:"..\..\builds\mk4vc60s_mfc_d.lib"\r
+# ADD LIB32 /nologo /out:"..\..\builds\mk4vc60s_std_d.lib"\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mklib - Win32 Release"\r
+# Name "mklib - Win32 Debug"\r
+# Name "mklib - Win32 Debug MFC"\r
+# Name "mklib - Win32 Debug STD"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\column.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\custom.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\derived.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\field.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\fileio.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\format.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\handler.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\persist.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\remap.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\std.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\store.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\string.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\table.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\univ.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\view.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\viewx.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\column.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\column.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\custom.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\derived.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\field.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\field.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\format.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\handler.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\handler.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\header.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\mfc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4io.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4str.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\include\mk4str.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\msvc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\persist.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\remap.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\std.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\store.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\store.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\univ.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\univ.inl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\win.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mkpython.dsp b/8.x/mk/win/msvc60/mkpython.dsp
new file mode 100755 (executable)
index 0000000..28022e2
--- /dev/null
@@ -0,0 +1,163 @@
+# Microsoft Developer Studio Project File - Name="mkpython" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=mkpython - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkpython.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mkpython.mak" CFG="mkpython - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mkpython - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "mkpython - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mkpython - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkpython\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "mkpython_EXPORTS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\include" /I "..\..\python\scxx" /I "c:\python24\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MKPYTHON_EXPORTS" /FD /c\r
+# SUBTRACT CPP /Fr /YX\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 c:\Python24\libs\python24.lib /nologo /dll /machine:I386 /out:"..\..\builds\Mk4py.dll" /libpath:"c:\python23\libs"\r
+# SUBTRACT LINK32 /debug\r
+\r
+!ELSEIF  "$(CFG)" == "mkpython - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mkpython\Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "mkpython_EXPORTS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /I "..\..\python\scxx" /I "c:\python24\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MKPYTHON_EXPORTS" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 c:\Python24\libs\python24.lib /nologo /dll /incremental:no /machine:I386 /nodefaultlib:"python20_d.lib" /out:"..\..\builds\Mk4py_d.dll" /pdbtype:sept /libpath:"c:\python23\libs"\r
+# SUBTRACT LINK32 /debug\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mkpython - Win32 Release"\r
+# Name "mkpython - Win32 Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\scxx\PWOImp.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyProperty.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyRowRef.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyStorage.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyView.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\scxx\PWOBase.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\scxx\PWOMapping.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\scxx\PWOMSequence.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\scxx\PWONumber.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\scxx\PWOSequence.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyHead.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyProperty.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyRowRef.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyStorage.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\python\PyView.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mksrc.dsw b/8.x/mk/win/msvc60/mksrc.dsw
new file mode 100755 (executable)
index 0000000..1f4371e
--- /dev/null
@@ -0,0 +1,173 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "mkbug"=.\mkbug.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name mklib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mkdemo"=.\mkdemo.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name mkdll\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mkdist"=.\mkdist.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name mkdll\r
+    End Project Dependency\r
+    Begin Project Dependency\r
+    Project_Dep_Name mklib\r
+    End Project Dependency\r
+    Begin Project Dependency\r
+    Project_Dep_Name mkpython\r
+    End Project Dependency\r
+    Begin Project Dependency\r
+    Project_Dep_Name mktcl\r
+    End Project Dependency\r
+    Begin Project Dependency\r
+    Project_Dep_Name mkhash\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mkdll"=.\mkdll.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mkdump"=.\mkdump.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name mklib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mkhash"=.\mkhash.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name mklib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mklib"=.\mklib.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mkpython"=.\mkpython.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name mklib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mktcl"=.\mktcl.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name mklib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "mktest"=.\mktest.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name mklib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/8.x/mk/win/msvc60/mktcl.dsp b/8.x/mk/win/msvc60/mktcl.dsp
new file mode 100755 (executable)
index 0000000..e20e430
--- /dev/null
@@ -0,0 +1,107 @@
+# Microsoft Developer Studio Project File - Name="mktcl" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=mktcl - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mktcl.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mktcl.mak" CFG="mktcl - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mktcl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "mktcl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mktcl - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mktcl\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "mktcl_EXPORTS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\include" /I "c:\tcl\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MKTCL_EXPORTS" /D "USE_TCL_STUBS" /D "TCL_THREADS" /FD /c\r
+# SUBTRACT CPP /Fr /YX\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 c:\tcl\lib\tclstub84.lib /nologo /dll /machine:I386 /out:"..\..\builds\Mk4tcl.dll" /libpath:"c:\tcl\bin"\r
+# SUBTRACT LINK32 /nodefaultlib\r
+\r
+!ELSEIF  "$(CFG)" == "mktcl - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mktcl\Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "mktcl_EXPORTS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /I "c:\tcl\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MKTCL_EXPORTS" /D "USE_TCL_STUBS" /D "TCL_THREADS" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 c:\tcl\lib\tclstub84.lib /nologo /dll /incremental:no /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\..\builds\Mk4tcl_d.dll" /pdbtype:sept /libpath:"c:\tcl\bin"\r
+# SUBTRACT LINK32 /nodefaultlib\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mktcl - Win32 Release"\r
+# Name "mktcl - Win32 Debug"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tcl\mk4tcl.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tcl\mk4tcl.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tcl\mk4too.cpp\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/mktest.dsp b/8.x/mk/win/msvc60/mktest.dsp
new file mode 100755 (executable)
index 0000000..74c2b21
--- /dev/null
@@ -0,0 +1,225 @@
+# Microsoft Developer Studio Project File - Name="mktest" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=mktest - Win32 Debug STD\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mktest.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "mktest.mak" CFG="mktest - Win32 Debug STD"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "mktest - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mktest - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mktest - Win32 Debug MFC" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "mktest - Win32 Debug STD" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "mktest - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "..\..\builds\msvc60\mktest\Release"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mktest\Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\builds\mktest.exe"\r
+\r
+!ELSEIF  "$(CFG)" == "mktest - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mktest\Debug"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mktest\Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mktest_d.exe" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "mktest - Win32 Debug MFC"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mktest___Win32_Debug_MFC"\r
+# PROP BASE Intermediate_Dir "mktest___Win32_Debug_MFC"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 1\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mktest\Debug_MFC"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mktest\Debug_MFC"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_MFC" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mktest_d.exe" /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /incremental:no /debug /debugtype:both /machine:I386 /out:"..\..\builds\mktest_mfc_d.exe" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "mktest - Win32 Debug STD"\r
+\r
+# PROP BASE Use_MFC 1\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mktest___Win32_Debug_STD"\r
+# PROP BASE Intermediate_Dir "mktest___Win32_Debug_STD"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "..\..\builds\msvc60\mktest\Debug_STD"\r
+# PROP Intermediate_Dir "..\..\builds\msvc60\mktest\Debug_STD"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_MFC" /FR /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "q4_STD" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mktest_mfc_d.exe" /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"..\..\builds\mktest_std_d.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "mktest - Win32 Release"\r
+# Name "mktest - Win32 Debug"\r
+# Name "mktest - Win32 Debug MFC"\r
+# Name "mktest - Win32 Debug STD"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\regress.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tbasic1.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tbasic2.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tcusto1.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tcusto2.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tdiffer.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\textend.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tformat.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tlimits.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tmapped.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tnotify.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tresize.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tstore1.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tstore2.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tstore3.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tstore4.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\tstore5.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\tests\regress.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/8.x/mk/win/msvc60/reversed b/8.x/mk/win/msvc60/reversed
new file mode 100644 (file)
index 0000000..7e3fa33
Binary files /dev/null and b/8.x/mk/win/msvc60/reversed differ
diff --git a/8.x/mk/win/msvc70/mkbug.vcproj b/8.x/mk/win/msvc70/mkbug.vcproj
new file mode 100755 (executable)
index 0000000..7acd85d
--- /dev/null
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mkbug"\r
+       SccProjectName=""\r
+       SccLocalPath=""\r
+       Keyword="MFCProj">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug STD|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkbug\Debug_STD"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkbug\Debug_STD"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="_CONSOLE,WIN32,_DEBUG,q4_STD"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="5"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkbug\Debug_STD/mkbug.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkbug\Debug_STD/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkbug\Debug_STD/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkbug\Debug_STD/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkbug_std_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkbug\Debug_STD/mkbug_std_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkbug\Debug_STD/mkbug.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug MFC|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkbug\Debug_MFC"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkbug\Debug_MFC"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="1"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="_CONSOLE,WIN32,_DEBUG,q4_MFC"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkbug\Debug_MFC/mkbug.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkbug\Debug_MFC/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkbug\Debug_MFC/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkbug\Debug_MFC/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               OutputFile="..\..\builds\mkbug_mfc_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkbug\Debug_MFC/mkbug_mfc_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkbug\Debug_MFC/mkbug.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkbug\Release"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkbug\Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkbug\Release/mkbug.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkbug\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkbug\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkbug\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkbug.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkbug\Release/mkbug.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkbug\Release/mkbug.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkbug\Debug"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkbug\Debug"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkbug\Debug/mkbug.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkbug\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkbug\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkbug\Debug/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkbug_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkbug\Debug/mkbug_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkbug\Debug/mkbug.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <File\r
+                       RelativePath="..\..\examples\mkbug.cpp">\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mkdemo.vcproj b/8.x/mk/win/msvc70/mkdemo.vcproj
new file mode 100755 (executable)
index 0000000..6b99d24
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mkdemo"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkdemo\Release"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkdemo\Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkdemo\Release/mkdemo.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkdemo\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkdemo\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkdemo\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkdemo.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkdemo\Release/mkdemo.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkdemo\Release/mkdemo.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkdemo\Debug"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkdemo\Debug"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkdemo\Debug/mkdemo.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkdemo\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkdemo\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkdemo\Debug/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkdemo_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkdemo\Debug/mkdemo_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkdemo\Debug/mkdemo.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <File\r
+                       RelativePath="..\..\demos\demo.cpp">\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mkdist.vcproj b/8.x/mk/win/msvc70/mkdist.vcproj
new file mode 100755 (executable)
index 0000000..0f4d4ff
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mkdist"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkdist\Release"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkdist\Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkdist\Release/mkdist.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkdist\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkdist\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkdist\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkdist.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkdist\Release/mkdist.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkdist\Release/mkdist.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <File\r
+                       RelativePath="..\..\demos\demo.cpp">\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mkdll.vcproj b/8.x/mk/win/msvc70/mkdll.vcproj
new file mode 100755 (executable)
index 0000000..2d28089
--- /dev/null
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mkdll"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkdll\Release"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="1"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include,.."\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MKDLL_EXPORTS"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkdll\Release/mkdll.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkdll\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkdll\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkdll\Release/"\r
+                               WarningLevel="4"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mk4vc70.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds/mk4vc70.pdb"\r
+                               ImportLibrary=".\..\..\builds/mk4vc70.lib"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName=".\..\..\builds/mkdll.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkdll\Debug"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include,.."\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MKDLL_EXPORTS"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkdll\Debug/mkdll.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkdll\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkdll\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkdll\Debug/"\r
+                               WarningLevel="4"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mk4vc70_d.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds/mk4vc70_d.pdb"\r
+                               ImportLibrary=".\..\..\builds/mk4vc70_d.lib"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName=".\..\..\builds/mkdll.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="..\..\src\column.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\custom.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\derived.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\field.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\fileio.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\format.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\handler.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\persist.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\remap.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\std.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\store.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\string.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\table.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\univ.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\view.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\viewx.cpp">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath="..\..\src\column.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\column.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\custom.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\derived.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\field.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\field.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\format.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\handler.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\handler.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\header.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\mfc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4dll.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4io.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4str.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4str.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\msvc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\persist.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\std.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\store.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\store.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\univ.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\univ.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\win.h">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mkdump.vcproj b/8.x/mk/win/msvc70/mkdump.vcproj
new file mode 100755 (executable)
index 0000000..1f5974d
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mkdump"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkdump\Release"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkdump\Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkdump\Release/mkdump.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkdump\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkdump\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkdump\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkdump.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkdump\Release/mkdump.pdb"\r
+                               GenerateMapFile="TRUE"\r
+                               MapFileName=".\..\..\builds\msvc70\mkdump\Release/mkdump.map"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkdump\Release/mkdump.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkdump\Debug"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkdump\Debug"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkdump\Debug/mkdump.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkdump\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkdump\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkdump\Debug/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkdump_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkdump\Debug/mkdump_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkdump\Debug/mkdump.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <File\r
+                       RelativePath="..\..\demos\dump.cpp">\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mkhash.vcproj b/8.x/mk/win/msvc70/mkhash.vcproj
new file mode 100755 (executable)
index 0000000..7cfa284
--- /dev/null
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mkhash"\r
+       SccProjectName=""\r
+       SccLocalPath=""\r
+       Keyword="MFCProj">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug MFC|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkhash\Debug_MFC"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkhash\Debug_MFC"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="1"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="_CONSOLE,WIN32,_DEBUG,q4_MFC"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkhash\Debug_MFC/mkhash.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkhash\Debug_MFC/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkhash\Debug_MFC/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkhash\Debug_MFC/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               OutputFile="..\..\builds\mkhash_mfc_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkhash\Debug_MFC/mkhash_mfc_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkhash\Debug_MFC/mkhash.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkhash\Debug"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkhash\Debug"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkhash\Debug/mkhash.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkhash\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkhash\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkhash\Debug/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkhash_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkhash\Debug/mkhash_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkhash\Debug/mkhash.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkhash\Release"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkhash\Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE,q4_INLINE"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkhash\Release/mkhash.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkhash\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkhash\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkhash\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkhash.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkhash\Release/mkhash.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkhash\Release/mkhash.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug STD|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mkhash\Debug_STD"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkhash\Debug_STD"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="_CONSOLE,WIN32,_DEBUG,q4_STD"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="5"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkhash\Debug_STD/mkhash.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkhash\Debug_STD/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkhash\Debug_STD/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkhash\Debug_STD/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mkhash_std_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mkhash\Debug_STD/mkhash_std_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mkhash\Debug_STD/mkhash.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <File\r
+                       RelativePath="..\..\examples\mkhash.cpp">\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mklib.vcproj b/8.x/mk/win/msvc70/mklib.vcproj
new file mode 100755 (executable)
index 0000000..588f7f1
--- /dev/null
@@ -0,0 +1,329 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mklib"\r
+       SccProjectName=""\r
+       SccLocalPath=""\r
+       Keyword="MFCProj">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mklib\Debug"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mklib\Debug"\r
+                       ConfigurationType="4"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include,.."\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_LIB"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mklib\Debug/mklib.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mklib\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mklib\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mklib\Debug/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="4"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               OutputFile="..\..\builds\mk4vc70s_d.lib"\r
+                               SuppressStartupBanner="TRUE"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug MFC|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mklib\Debug_MFC"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mklib\Debug_MFC"\r
+                       ConfigurationType="4"\r
+                       UseOfMFC="1"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include,.."\r
+                               PreprocessorDefinitions="_LIB,WIN32,_DEBUG,q4_MFC"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mklib\Debug_MFC/mklib.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mklib\Debug_MFC/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mklib\Debug_MFC/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mklib\Debug_MFC/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="4"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               OutputFile="..\..\builds\mk4vc70s_mfc_d.lib"\r
+                               SuppressStartupBanner="TRUE"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mklib\Release"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mklib\Release"\r
+                       ConfigurationType="4"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include,.."\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_LIB,q4_INLINE"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mklib\Release/mklib.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mklib\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mklib\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mklib\Release/"\r
+                               WarningLevel="4"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               OutputFile="..\..\builds\mk4vc70s.lib"\r
+                               SuppressStartupBanner="TRUE"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug STD|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mklib\Debug_STD"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mklib\Debug_STD"\r
+                       ConfigurationType="4"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include,.."\r
+                               PreprocessorDefinitions="_LIB,WIN32,_DEBUG,q4_STD"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="5"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mklib\Debug_STD/mklib.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mklib\Debug_STD/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mklib\Debug_STD/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mklib\Debug_STD/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               OutputFile="..\..\builds\mk4vc70s_std_d.lib"\r
+                               SuppressStartupBanner="TRUE"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="..\..\src\column.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\custom.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\derived.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\field.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\fileio.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\format.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\handler.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\persist.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\remap.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\std.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\store.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\string.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\table.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\univ.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\view.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\viewx.cpp">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath="..\..\src\column.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\column.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\custom.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\derived.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\field.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\field.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\format.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\handler.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\handler.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\header.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\mfc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4io.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4str.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\include\mk4str.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\msvc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\persist.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\remap.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\std.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\store.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\store.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\univ.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\univ.inl">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\win.h">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mkpython.vcproj b/8.x/mk/win/msvc70/mkpython.vcproj
new file mode 100755 (executable)
index 0000000..89d6a6b
--- /dev/null
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mkpython"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkpython\Release"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include,..\..\python\scxx,c:\python22\include"\r
+                               PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;MKPYTHON_EXPORTS"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkpython\Release/mkpython.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkpython\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkpython\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkpython\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="python22.lib"\r
+                               OutputFile="..\..\builds\Mk4py.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               AdditionalLibraryDirectories="c:\python22\libs"\r
+                               ProgramDatabaseFile=".\..\..\builds/Mk4py.pdb"\r
+                               ImportLibrary=".\..\..\builds/Mk4py.lib"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName=".\..\..\builds/mkpython.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mkpython\Debug"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include,..\..\python\scxx,c:\python22\include"\r
+                               PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_USRDLL;MKPYTHON_EXPORTS"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mkpython\Debug/mkpython.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mkpython\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mkpython\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mkpython\Debug/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="python22.lib"\r
+                               OutputFile="..\..\builds\Mk4py_d.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               AdditionalLibraryDirectories="c:\python22\libs"\r
+                               IgnoreDefaultLibraryNames="python20_d.lib"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds/Mk4py_d.pdb"\r
+                               ImportLibrary=".\..\..\builds/Mk4py_d.lib"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName=".\..\..\builds/mkpython.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="..\..\python\scxx\PWOImp.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyProperty.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyRowRef.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyStorage.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyView.cpp">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath="..\..\python\scxx\PWOBase.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\scxx\PWOMSequence.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\scxx\PWOMapping.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\scxx\PWONumber.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\scxx\PWOSequence.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyHead.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyProperty.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyRowRef.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyStorage.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\python\PyView.h">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mksrc.sln b/8.x/mk/win/msvc70/mksrc.sln
new file mode 100755 (executable)
index 0000000..aba8cd5
--- /dev/null
@@ -0,0 +1,129 @@
+Microsoft Visual Studio Solution File, Format Version 7.00\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mkbug", "mkbug.vcproj", "{C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mkdemo", "mkdemo.vcproj", "{54D78258-9298-4EC0-A1A9-A33FBD244C53}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mkdist", "mkdist.vcproj", "{9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mkdll", "mkdll.vcproj", "{F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mkdump", "mkdump.vcproj", "{2E5D9D66-F7A0-488B-AD81-723573A015FA}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mkhash", "mkhash.vcproj", "{B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mklib", "mklib.vcproj", "{1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mkpython", "mkpython.vcproj", "{339D7839-433D-4DE5-A8B6-54823FD884A1}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mktcl", "mktcl.vcproj", "{EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mktest", "mktest.vcproj", "{94BAF742-2F31-4598-83EB-3414BDD4D039}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfiguration) = preSolution\r
+               ConfigName.0 = Debug\r
+               ConfigName.1 = Debug MFC\r
+               ConfigName.2 = Debug STD\r
+               ConfigName.3 = Release\r
+       EndGlobalSection\r
+       GlobalSection(ProjectDependencies) = postSolution\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.0 = {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.0 = {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.0 = {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.1 = {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.2 = {339D7839-433D-4DE5-A8B6-54823FD884A1}\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.3 = {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.4 = {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.0 = {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.0 = {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.0 = {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.0 = {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.0 = {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfiguration) = postSolution\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.Debug.ActiveCfg = Debug|Win32\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.Debug.Build.0 = Debug|Win32\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.Debug MFC.ActiveCfg = Debug MFC|Win32\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.Debug MFC.Build.0 = Debug MFC|Win32\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.Debug STD.ActiveCfg = Debug STD|Win32\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.Debug STD.Build.0 = Debug STD|Win32\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.Release.ActiveCfg = Release|Win32\r
+               {C85AD3FA-CC71-4E52-B28F-A9F5F9C100E8}.Release.Build.0 = Release|Win32\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.Debug.ActiveCfg = Debug|Win32\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.Debug.Build.0 = Debug|Win32\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.Debug MFC.ActiveCfg = Debug|Win32\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.Debug MFC.Build.0 = Debug|Win32\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.Debug STD.ActiveCfg = Debug|Win32\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.Debug STD.Build.0 = Debug|Win32\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.Release.ActiveCfg = Release|Win32\r
+               {54D78258-9298-4EC0-A1A9-A33FBD244C53}.Release.Build.0 = Release|Win32\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.Debug.ActiveCfg = Release|Win32\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.Debug.Build.0 = Release|Win32\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.Debug MFC.ActiveCfg = Release|Win32\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.Debug MFC.Build.0 = Release|Win32\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.Debug STD.ActiveCfg = Release|Win32\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.Debug STD.Build.0 = Release|Win32\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.Release.ActiveCfg = Release|Win32\r
+               {9D8A27B3-25DC-4F17-BB6F-EB7C81052C5D}.Release.Build.0 = Release|Win32\r
+               {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}.Debug.ActiveCfg = Debug|Win32\r
+               {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}.Debug.Build.0 = Debug|Win32\r
+               {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}.Debug MFC.ActiveCfg = Debug|Win32\r
+               {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}.Debug MFC.Build.0 = Debug|Win32\r
+               {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}.Debug STD.ActiveCfg = Debug|Win32\r
+               {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}.Debug STD.Build.0 = Debug|Win32\r
+               {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}.Release.ActiveCfg = Release|Win32\r
+               {F957B6DD-DD9F-47D7-8DE9-E5971C8C5F12}.Release.Build.0 = Release|Win32\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.Debug.ActiveCfg = Debug|Win32\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.Debug.Build.0 = Debug|Win32\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.Debug MFC.ActiveCfg = Debug|Win32\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.Debug MFC.Build.0 = Debug|Win32\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.Debug STD.ActiveCfg = Debug|Win32\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.Debug STD.Build.0 = Debug|Win32\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.Release.ActiveCfg = Release|Win32\r
+               {2E5D9D66-F7A0-488B-AD81-723573A015FA}.Release.Build.0 = Release|Win32\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.Debug.ActiveCfg = Debug|Win32\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.Debug.Build.0 = Debug|Win32\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.Debug MFC.ActiveCfg = Debug MFC|Win32\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.Debug MFC.Build.0 = Debug MFC|Win32\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.Debug STD.ActiveCfg = Debug STD|Win32\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.Debug STD.Build.0 = Debug STD|Win32\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.Release.ActiveCfg = Release|Win32\r
+               {B2CC5CC1-9D9C-432B-9B0D-9FC4C2323224}.Release.Build.0 = Release|Win32\r
+               {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}.Debug.ActiveCfg = Debug|Win32\r
+               {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}.Debug.Build.0 = Debug|Win32\r
+               {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}.Debug MFC.ActiveCfg = Debug MFC|Win32\r
+               {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}.Debug MFC.Build.0 = Debug MFC|Win32\r
+               {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}.Debug STD.ActiveCfg = Debug STD|Win32\r
+               {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}.Debug STD.Build.0 = Debug STD|Win32\r
+               {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}.Release.ActiveCfg = Release|Win32\r
+               {1A078EAB-0236-4FE7-8D01-6733C7EDBBD4}.Release.Build.0 = Release|Win32\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.Debug.ActiveCfg = Debug|Win32\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.Debug.Build.0 = Debug|Win32\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.Debug MFC.ActiveCfg = Debug|Win32\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.Debug MFC.Build.0 = Debug|Win32\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.Debug STD.ActiveCfg = Debug|Win32\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.Debug STD.Build.0 = Debug|Win32\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.Release.ActiveCfg = Release|Win32\r
+               {339D7839-433D-4DE5-A8B6-54823FD884A1}.Release.Build.0 = Release|Win32\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.Debug.ActiveCfg = Debug|Win32\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.Debug.Build.0 = Debug|Win32\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.Debug MFC.ActiveCfg = Debug|Win32\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.Debug MFC.Build.0 = Debug|Win32\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.Debug STD.ActiveCfg = Debug|Win32\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.Debug STD.Build.0 = Debug|Win32\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.Release.ActiveCfg = Release|Win32\r
+               {EA281CEE-3409-4143-8C4E-AFFAAA6A7B16}.Release.Build.0 = Release|Win32\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.Debug.ActiveCfg = Debug|Win32\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.Debug.Build.0 = Debug|Win32\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.Debug MFC.ActiveCfg = Debug MFC|Win32\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.Debug MFC.Build.0 = Debug MFC|Win32\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.Debug STD.ActiveCfg = Debug STD|Win32\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.Debug STD.Build.0 = Debug STD|Win32\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.Release.ActiveCfg = Release|Win32\r
+               {94BAF742-2F31-4598-83EB-3414BDD4D039}.Release.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityGlobals) = postSolution\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityAddIns) = postSolution\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/8.x/mk/win/msvc70/mktcl.vcproj b/8.x/mk/win/msvc70/mktcl.vcproj
new file mode 100755 (executable)
index 0000000..03e7587
--- /dev/null
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mktcl"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mktcl\Release"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include,c:\tcl\include"\r
+                               PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;MKTCL_EXPORTS;USE_TCL_STUBS;TCL_THREADS"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mktcl\Release/mktcl.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mktcl\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mktcl\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mktcl\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="tclstub84.lib"\r
+                               OutputFile="..\..\builds\Mk4tcl.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               AdditionalLibraryDirectories="c:\tcl\lib"\r
+                               ProgramDatabaseFile=".\..\..\builds/Mk4tcl.pdb"\r
+                               ImportLibrary=".\..\..\builds/Mk4tcl.lib"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName=".\..\..\builds/mktcl.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mktcl\Debug"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include,c:\tcl\include"\r
+                               PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_USRDLL;MKTCL_EXPORTS;USE_TCL_STUBS;TCL_THREADS"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mktcl\Debug/mktcl.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mktcl\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mktcl\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mktcl\Debug/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="tclstub84.lib"\r
+                               OutputFile="..\..\builds\Mk4tcl_d.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               AdditionalLibraryDirectories="c:\tcl\lib"\r
+                               IgnoreDefaultLibraryNames="msvcrt.lib"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds/Mk4tcl_d.pdb"\r
+                               ImportLibrary=".\..\..\builds/Mk4tcl_d.lib"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName=".\..\..\builds/mktcl.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <File\r
+                       RelativePath="..\..\tcl\mk4tcl.cpp">\r
+               </File>\r
+               <File\r
+                       RelativePath="..\..\tcl\mk4tcl.h">\r
+               </File>\r
+               <File\r
+                       RelativePath="..\..\tcl\mk4too.cpp">\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/mktest.vcproj b/8.x/mk/win/msvc70/mktest.vcproj
new file mode 100755 (executable)
index 0000000..5dd6350
--- /dev/null
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="mktest"\r
+       SccProjectName=""\r
+       SccLocalPath=""\r
+       Keyword="MFCProj">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mktest\Debug"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mktest\Debug"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mktest\Debug/mktest.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mktest\Debug/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mktest\Debug/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mktest\Debug/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mktest_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mktest\Debug/mktest_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mktest\Debug/mktest.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mktest\Release"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mktest\Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="2"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mktest\Release/mktest.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mktest\Release/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mktest\Release/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mktest\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mktest.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mktest\Release/mktest.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mktest\Release/mktest.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug STD|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mktest\Debug_STD"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mktest\Debug_STD"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="_CONSOLE,WIN32,_DEBUG,q4_STD"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="5"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mktest\Debug_STD/mktest.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mktest\Debug_STD/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mktest\Debug_STD/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mktest\Debug_STD/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="..\..\builds\mktest_std_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mktest\Debug_STD/mktest_std_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mktest\Debug_STD/mktest.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug MFC|Win32"\r
+                       OutputDirectory=".\..\..\builds\msvc70\mktest\Debug_MFC"\r
+                       IntermediateDirectory=".\..\..\builds\msvc70\mktest\Debug_MFC"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="1"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\include"\r
+                               PreprocessorDefinitions="_CONSOLE,WIN32,_DEBUG,q4_MFC"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               PrecompiledHeaderFile=".\..\..\builds\msvc70\mktest\Debug_MFC/mktest.pch"\r
+                               AssemblerListingLocation=".\..\..\builds\msvc70\mktest\Debug_MFC/"\r
+                               ObjectFile=".\..\..\builds\msvc70\mktest\Debug_MFC/"\r
+                               ProgramDataBaseFileName=".\..\..\builds\msvc70\mktest\Debug_MFC/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               OutputFile="..\..\builds\mktest_mfc_d.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile=".\..\..\builds\msvc70\mktest\Debug_MFC/mktest_mfc_d.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\..\..\builds\msvc70\mktest\Debug_MFC/mktest.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="..\..\tests\regress.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tbasic1.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tbasic2.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tcusto1.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tcusto2.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tdiffer.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\textend.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tformat.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tlimits.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tmapped.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tnotify.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tresize.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tstore1.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tstore2.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tstore3.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tstore4.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\tests\tstore5.cpp">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath="..\..\tests\regress.h">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/mk/win/msvc70/reversed b/8.x/mk/win/msvc70/reversed
new file mode 100644 (file)
index 0000000..7e3fa33
Binary files /dev/null and b/8.x/mk/win/msvc70/reversed differ
diff --git a/8.x/mk/win/msvc70/tests/!keepme.txt b/8.x/mk/win/msvc70/tests/!keepme.txt
new file mode 100644 (file)
index 0000000..48cdce8
--- /dev/null
@@ -0,0 +1 @@
+placeholder
diff --git a/8.x/tclvfs/ChangeLog b/8.x/tclvfs/ChangeLog
new file mode 100644 (file)
index 0000000..b261d85
--- /dev/null
@@ -0,0 +1,1237 @@
+2010-05-16  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       * library/vfslib.tcl: Changed memchan condition from Tcl version 8.6 or
+       greater to presence of chan command (since chan now in later 8.5 builds)
+
+2010-02-01  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       * Makefile.in (PKG_TCL_SOURCES): Added 'template/tclIndex' to the list 
+       of installed files. Required for vfs's based on template vfs to load.
+
+2010-01-30  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       * templatevfs.tcl: workaround for bug in how virtual volumes
+       are mounted. Version bumped to 1.5.4.  See:
+http://sf.net/tracker/?func=detail&aid=2886914&group_id=10894&atid=110894
+
+2009-10-20  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       * tclIndex: Corrected version number.
+       * pkgIndex.tcl.in: Edited to replace function of deleted 
+       pkgIndex.tcl in template subdir.
+
+2009-10-15  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       vfs::template package update ver. 1.5.3:
+
+       * templatevfs.tcl: Incorporated AK's fix below.
+       * collatevfs.tcl: ensured binary file contents got written
+       correctly, and ensured that not only file contents but 
+       also file attributes were updated to all write targets.
+
+2009-07-06  Andreas Kupries  <andreask@activestate.com>
+
+       * library/template/templatevfs.tcl (memchan): Fix result for
+       * pkgIndex.tcl: unix. The bug was reported on the wiki. The fix
+         there was wrong, did improper handling of the $args argument.
+         Fixed here. Version bumped to 1.5.3.
+
+2009-05-14  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * library/zipvfs.tcl: Handle directory names that include
+       * tests/vfsZip.test:  glob chars. Added some tests.
+       * win/makefile.vc: fix running the tests.
+
+2009-02-06  Andreas Kupries  <andreask@activestate.com>
+
+       * library/vfs.tcl.in: New file encapsulating the package load
+       process. Cleaner than the loadvfs proc, and much more suitable for
+       conversion to a teabag.
+
+       * pkgIndex.tcl.in: Cleaned up the declarations for package 'vfs'.
+       Removed the 'vfslib' package, it never was such.
+       
+       * Makefile.in: Added installation of library/vfs.tcl.
+       * configure.in: Added library/vfs.tcl.in.
+       * configure: Regenerated.
+
+       * win/makefile.vc: Updated the windows build file to configure
+       vfs.tcl.in, and install vfs.tcl.
+
+2009-01-22  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * tests/vfslib.test: Make use of the core zlib and refchan features
+       * pkgIndex.tcl.in:   by default for Tcl 8.6.
+
+       * win/makefile.vc:  Updated windows build files
+       * win/rules.vc:
+       * win/nmakehlp.c:
+
+       * tests/*.test: Tidied up the tests. Added lots of zipfs tests.
+       
+       * library/zipvfs.tcl: Applied patch from [Bug 1011492] to ensure
+       we handle zipfiles with a prefix block robustly.
+
+2009-01-21  Andreas Kupries  <andreask@activestate.com>
+
+       * pkgIndex.tcl.in: Incremented version of vfs::zip
+       * library/zipvfs.tcl (zip::EndOfArchive): Fixed Schelte Bron's
+       [Bug 2256740]. Trigger on outermost magic sequence, not an inner
+       sequence from a n uncompressed zip archive stored in the zip.
+
+2008-12-22  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * library/mk4vfs.tcl: Fix vfs::zstream to support 8.6 core zlib
+       * library/vfslib.tcl:
+
+2008-12-12  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * library/zipvfs.tcl: Cleaned up the zip stream read function to
+       conform to the published specification more closely and avoid
+       excess calls to the stat function.
+       * pkgIndex.tcl.in: Incremented version of vfs::zip
+
+2008-12-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in: change VPATH to ensure that configure munging of
+       VPATH when configuring in the main directory does not break it.
+       [Bug 2389466]
+
+2008-12-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tests/vfsFtp.test: correct unmount ordering
+
+       * library/tclprocvfs.tcl (vfs::ns::matchindirectory): Handle the
+       single item dir/file, and don't add a slash for single proc.
+
+2008-12-02  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tests/vfs.test (vfs-2.3,2.4,4.1): add tests for mount command
+       not existing and for an issue with .. resolution.
+
+       * pkgIndex.tcl.in, library/tclprocvfs.tcl: vfs::ns bump to 0.5.1
+       Correct glob of namespaces. [Bug 1280914]
+
+       * generic/vfs.c (TCLVFS_POSIXERROR): note use of -1 return code to
+       indicate a posix error passing through.
+
+       * tclconfig/tcl.m4, generic/vfs.c, doc/vfs.n:
+       * configure, configure.in: update to TEA 3.7, bump vfs to v1.4
+
+       * pkgIndex.tcl.in: this is now the sole pkgIndex.tcl script.
+       vfs::loadvfs updated to source vfsUtils.tcl right after loading
+       the dll.  Package versions updated, removed mk4vfs and zipvfs
+       compat packages.
+
+       * Makefile.in, win/makefile.vc: update for removed files
+
+       * library/template/*: add package provide 1.5.2 for each template
+
+       * library/mk4vfscompat.tcl (removed): remove old compat pkg
+       * library/zipvfscompat.tcl (removed): remove old compat pkg
+
+       * library/tclIndex (removed): users should package require the
+       appropriate driver, not rely on autoload
+       * library/pkgIndex.tcl (removed): impotent index files
+       * library/template/pkgIndex.tcl (removed):
+
+       * tests/all.tcl (vfsCreateInterp): simplify the test to require
+       vfs as the main interps do.
+
+       * library/vfslib.tcl: remove vfs::normalize compat proc
+       bump vfslib to 1.4
+
+       * library/mk4vfs.tcl: remove unused lassign defn
+
+       * library/starkit.tcl (header): require namespace-based vfs driver
+       (eg. vfs::mk4 instead of mk4vfs).  bump starkit to v1.3.3
+
+       * mac/* (removed): removed outdated Mac classic pieces
+
+       * Makefile.in (install-lib-binaries): use lib_BINARIES for the
+       binary install list. [Bug 1699827]
+       Install pkgIndex.tcl for static or shared build. [Bug 699176]
+       (pkgIndex.tcl): add rebuild target
+
+2008-11-20  Andreas Kupries  <andreask@activestate.com>
+
+       * library/starkit.tcl (_startup, autoextend): Replaced the buggy
+         'vfs::filesystem fullynormalize' with the ok 'fullnormalize'
+         defined in the same file. Now 'starkit::startup' handles
+         sym-links to a starpack ok when detecting the wrap mode.
+
+2008-10-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * pkgIndex.tcl.in, library/pkgIndex.tcl: update vfs::tar to 0.91
+       * library/tarvfs.tcl: update vfs::tar to use only its own
+       namespace and not conflict with tcllib tar. [Bug 80465]
+
+2008-10-10  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * generic/vfs.c: Make use of CONST86 for 8.6a3 support.
+
+2008-08-11  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * http2.6/http.tcl: Merged zlib crc fix from Tcl.
+
+2008-04-30  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * win/makefile.vc:  Updated the NMAKE build files.
+       * win/rules.vc:
+       * win/nmakehlp.c:
+
+2008-04-15  Andreas Kupries  <andreask@activestate.com>
+
+       * pkgIndex.tcl.in: Updated to handle the new files, and
+       * Makefile.in: sync'd generated index with manual one.
+
+       * library/pkgIndex.tcl: Moved the backward compatibility package
+       * library/mkvfs.tcl: names (mk4vfs, zipvfs) into separate files,
+       * library/zipvfs.tcl: as true packages. They properly load the new
+       * library/mk4vfscompat.tcl: packages. The mess with one file
+       * library/zipvfscompat.tcl: annoncing itself as two packages has
+       been removed. Patchlevels bumped (1.10.1, 1.0.1 respectively),
+       considering it as bug fix.
+
+2008-04-11  Andreas Kupries  <andreask@activestate.com>
+
+       * library/pkgIndex.tcl: Bumped version of starkit to 1.3.2. We
+       * library/starkit.tcl: should have done that when we synchronized
+       * pkgIndex.tcl.in: the mismatched version on 2005-11-09 anyway,
+       because it was a bugfix, with attendant change to the version
+       number. Without this bump we now have 1.3.1 floating around in two
+       variants, i.e. it may or may not be mismatched with its package
+       index, and the two variants cannot be distinguished. By bumping
+       the patchlevel the correct version would have been easy to
+       distinguish. Now it will.
+
+2008-04-08  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * configure:    If building static then do not define USE_TCL_STUBS
+       * configure.in: (needed to link tclkit with 8.6)
+
+2008-03-21  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * http2.6/http.tcl, http2.6/pkgIndex.tcl: merge with tcl cvs 2.7
+       http changes, change this version to 2.6.8.
+
+2008-03-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * http2.6/http.n, http2.6/http.tcl, http2.6/pkgIndex.tcl: merge
+       with tcl cvs 2.5.5 http changes, correct whitespace differences,
+       require Tcl 8.4.
+
+2008-03-04  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       vfs::template package update ver. 1.5.2:
+
+       * templatevfs.tcl, deltavfs.tcl, versionvfs.tcl, quotavfs.tcl, fishvfs.tcl:
+         added workaround to memchan bug that shows up when tclkit used.
+       * pkgIndex.tcl, tclIndex: moved auto_index edits from former to latter
+         to conform to Tcl package management standard practice.
+
+2008-02-26  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       vfs::template package update ver. 1.5.1:
+
+       * deltavfs.tcl, versionvfs.tcl, quotavfs.tcl: minor bug
+         fixes and reformatting.
+
+2008-02-15  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       vfs::template package update ver. 1.5:
+
+       * Better formatting as Tcl package (added template/pkgIndex.tcl)
+       * Added chrootvfs.tcl
+       * Code refactored for simplicity and better performance
+       * Added improved globfind package
+       * Bug fixes.
+
+2007-06-19  Andreas Kupries  <andreask@activestate.com>
+
+       * library/starkit.tcl (header): See last entry. Simplified the
+         helper command 'fullnormalize', replaced complex file
+         split/lrange/join/eval operation with 'file dirname'.
+
+2007-05-28  Andreas Kupries  <andreask@activestate.com>
+
+       * library/starkit.tcl (header): Added helper command
+         'fullnormalize' and use it to resolve symlinks in the path to
+         the file calling starkit::header. This makes it possible to run
+         starkits and starpacks via symlinks.
+
+2007-04-17  Andreas Kupries  <andreask@activestate.com>
+
+       * library/zipvfs.tcl: "zip::DosTime" extended to handle bad
+         timestamps without crashing. Force-fixed to nearest legal
+         date/time. "zip::EndOfArchive" extended to find chunk even
+         if a (long) zip archive comment is present.
+
+2007-04-13  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * Makefile.in:     Applied patch #1589278 to include the template
+       * pkgIndex.tcl.in: vfs files in the install.
+
+2007-04-05  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * Makefile.in: Was failing install the pkgIndex.tcl file
+
+2007-03-12  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * http2.6/http.tcl: Fixed some bugs (0 length body with chunked
+       transfer) and added support for gzip encoding if zlib is
+       available. Tested continued operation with Tcl 8.2.
+       * library/webdavvfs.tcl: Encoding is now in the http package.
+       * http2.6/pkgIndex.tcl: version to 2.6.6
+
+2007-03-07  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * library/webdavvfs.tcl: silence debug output
+       * http2.6/http.tcl: merge in from tclsoap and jcw's webdav
+       versions and merged in tcl8.5 changes.
+       * http2.6/pkgIndex.tcl: version to 2.6.5
+
+2006-12-28  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * configure: autoconf 2.59
+       * tclconfig/tcl.m4: based on tcl.m4,v 1.97 2006/12/19 01:20:55 das
+
+2006-12-10  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       * library/template/versionvfs.tcl: when time attribute is set,
+       files created after set time are made invisible.
+
+2006-11-14  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/mkclvfs.tcl: removed, now part of the vlerq extension again
+       * library/pkgIndex.tcl, pkgIndex.tcl.in, Makefile.in: removed mkcl
+
+2006-11-10  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       * library/template/templatevfs.tcl: file delete on vfs mount 
+       point now causes vfs to unmount ; can now pass empty string
+       as arbitrary attribute value
+
+       * library/template/versionvfs.tcl: more efficient directory
+       deletion code
+
+2006-10-31  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       * library/template/versionvfs.tcl: added code to ensure all
+       subfiles of a directory are deleted before dir deletion.
+
+2006-10-29  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       Added comments and license info:
+       * library/template/globfind.tcl
+       * library/template/tdelta.tcl
+
+2006-10-23  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       Initial upload of template virtual filesystems in new subfolder:
+       * library/template/collatevfs.tcl
+       * library/template/deltavfs.tcl
+       * library/template/fishvfs.tcl
+       * library/template/quotavfs.tcl
+       * library/template/templatevfs.tcl
+       * library/template/versionvfs.tcl
+
+       Plus helper utlities:
+       * library/template/tdelta.tcl - required by deltavfs.tcl
+       * library/template/globfind.tcl - required by quotavfs.tcl
+
+       * library/pkgIndex.tcl - added "package ifneeded" statements for
+       template virtual filesystems.
+
+2006-09-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * library/httpvfs.tcl (vfs::http::geturl): wrapper around
+       http::geturl that does 404 check.
+
+2006-09-19  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * library/httpvfs.tcl (vfs::http::urlparse): add method to
+       deconstruct the url using RFC 3986 semantics.
+       (vfs::http::Mount): add support for HTTP basic auth if a user was
+       passed in the url
+
+2006-09-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * library/pkgIndex.tcl: bump vfs::http to 0.6
+       * library/httpvfs.tcl:  Add urlname encoding to handle the
+       translation of "/foo/my file (2).txt" as
+       foo/my%20file%20%282%29.txt, per RFC 3986, for the user.  This is
+       controlled via a new ?-urlencode bool? mount option, default 1.
+               **** POTENTIAL INCOMPATIBILITY ****
+               **** if user was "working around" at [open] level ****
+
+2006-09-14  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * library/httpvfs.tcl: rewritten to clean up http tokens and
+       actually interpret data from them.
+       (Mount): If a url doesn't return "ok" status, return failure.
+       (stat, access): If HEAD returns 404 or status != ok, return ENOENT.
+
+       * library/vfslib.tcl: code cleanup
+
+2006-08-30  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * generic/vfs.c: move static globals to being thread-specific.  If
+       you wish to access a mount point or volume in a thread, you need
+       to remount the file in the thread.  This is a change from the
+       previous behavior that would allow access across threads, which
+       was unsafe and would potentially crash.
+               **** POTENTIAL INCOMPATIBILITY ****
+
+2006-06-22  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/mkclvfs.tcl: Updated to latest 1.4 revision
+
+2006-05-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * generic/vfs.c (VfsOpenFileChannel): handle closing channels that
+       were inherited as std channels. [Bug 1468291]
+
+2006-03-12  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/ftpvfs.tcl: provide caching of listings to improve
+       performance for many standard use cases.
+
+2006-02-27  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/mkclvfs.tcl: Small optimization so a writable starkit
+       does not cause a real commit if no changes at all were made.
+
+2006-01-25  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure, configure.in: update to TEA 3.5
+       * tclconfig/tcl.m4:        TEA rcs 1.89 2006/01/25 21:25:02
+
+2006-01-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tclconfig/tcl.m4, configure: update to TEA 3.4 interim
+
+2005-12-02  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tclconfig/tcl.m4, configure.in, configure: update to TEA 3.4
+
+2005-11-10  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * Makefile.in: added missing mkclvfs.tcl dependency
+
+2005-11-09  Andreas Kupries <andreask@activestate.com>
+
+       * library/vfslib.tcl:  Brought the version numbers of provide
+       * library/starkit.tcl: and ifneeded commands back into sync.
+
+2005-11-04  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/mkclvfs.tcl: some more thrill api mods
+       * pkgIndex.tcl.in, library/pkgIndex.tcl: bumped to 1.2
+
+2005-11-01  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/mkclvfs.tcl: renamed vlerq package to thrill
+       * pkgIndex.tcl.in, library/pkgIndex.tcl: bumped to 1.1
+
+2005-10-19  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/mk4vfs.tcl: added fallback to new vfs::mkcl
+       * library/mkclvfs.tcl: new MK Compatible Lite driver
+       * pkgIndex.tcl.in, library/pkgIndex.tcl: adjusted
+
+2005-08-31  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: despite lack of documentation on this point,
+       VfsMatchInDirectory should really allow a NULL interp, even in
+       error situations.  Tcl 8.5 now documents that this is allowed.
+
+2005-03-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in (AR): use @AR@
+       * configure, tclconfig/tcl.m4: TEA 3.2 patch update
+
+2005-02-14  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * configure, configure.in, tclconfig/tcl.m4: update from sample
+
+2005-02-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure, configure.in, tclconfig/tcl.m4: update to TEA 3.2
+
+2005-01-25  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure, configure.in (BUILD_vfs): correct from sample default
+
+2005-01-20  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/mk4vfs.tcl: added return in periodicCommit
+
+2004-11-22  Andreas Kupries <andreask@activestate.com>
+
+       * Makefile.in (PKG_TCL_SOURCES): Added 'tkvfs.tcl' to the list of
+         installed files. It is listed in the package index, but was not
+         installed.
+
+2004-09-28  Vince Darley <vincentdarley@sourceforge.net>
+
+       * win/makefile.vc: some cleanup of makefile to allow compilation
+         with more than just VC++ 5.x.
+
+2004-09-13  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: fix to crash if TclVfsAttr(Set|Get) are called
+         with a NULL interp for error reporting. [Bug 1022202]
+
+2004-08-05  Andreas Kupries  <andreask@activestate.com>
+
+       * library/zipvfs.tcl (Data): Fixed [SF Tclvfs Bug 1003591]. This
+         reverts an incomplete and unrecorded fix for handling dashes at
+         the beginning of data, giving precedence to '2004-07-04 @
+         library/vfsUtils.tcl' instead, see below. The unrecorded fix was
+         entered two days before and clashes with the other one. As it
+         was incomplete the other fix was chosen, despite coming later.
+
+2004-08-04  Andreas Kupries  <andreask@activestate.com>
+
+       * library/zipvfs.tcl (EndOfArchive): Fixed [SF Tclvfs Bug
+         1003574]. Added code preventing us from seeking before the
+         beginning of the zip file.
+
+2004-07-15  Andreas Kupries  <andreask@activestate.com>
+
+       * doc/vfs-fsapi.man: Clarified description of the close callback
+       the handler method 'open' may set up. Especially noted that
+       'close' must not be called from within this callback, that it is
+       done by the caller itself.
+
+2004-07-15  Vince Darley <vincentdarley@sourceforge.net>
+
+       * doc/*: fix to removedirectory docs which should say to return
+       a posix EEXIST error if the directory is non-empty.
+
+2004-07-04  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+       
+       * library/vfsUtils.tcl (crc, zip): Modified the Trf adapter
+         commands. They are now adding in a "--" before the last argument
+         they get, to ensure its interpretation as data instead of being
+         misinterpreted as option should it begin with a dash. Without
+         this adding a file beginning with a dash to a filesystem will
+         fail.
+
+2004-06-29  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/zipvfs.tcl: fix to bug finding zip header (reported on
+       Tcl'ers wiki).
+
+2004-06-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in: corrected targets that use 'for' over what may be
+       an empty list.  Cleaned up echo output.
+
+       * generic/vfs.c (Vfs_Init): added #ifndef PACKAGE_VERSION for
+       non-TEA based build system.
+
+2004-06-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * examples/simpleExamples.tcl:
+       * tests/vfsUrl.test: s/scriptics.com/tcl.tk
+
+       * library/zipvfs.tcl (zip::Data): add zip::stat call that
+       correctly determines size for some zip files (Ferril).
+
+       * generic/vfs.c: use PACKAGE_VERSION instead of hard-coded version
+       info.
+
+       * configure, configure.in, Makefile.in, tclconfig/tcl.m4: updated
+       to the latest TEA3 spec
+       * pkgIndex.tcl.in (added): move from library/ subdir
+       * library/pkgIndex.tcl.in (removed): 
+
+2004-06-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure (regened):
+       * tclconfig/tcl.m4 (TEA_TCL_64BIT_FLAGS): update to define
+       TCL_WIDE_INT_IS_LONG when 'using long'.
+
+2004-05-21  Vince Darley <vincentdarley@sourceforge.net>
+
+       * win/makefile.vc: fix to compilation problem with new #includes
+       in Tcl 8.5.
+
+2004-05-21  Daniel Steffen <das@users.sourceforge.net>
+
+       * library/starkit.tcl: improved previous symbolic link patch by
+       using [vfs::filesystem fullynormalize], as suggessted by Vince.
+       
+       * library/pkgIndex.tcl.in: brought back into sync with pkgIndex.tcl
+       * library/pkgIndex.tcl: fixed spacing to be like pkgIndex.tcl.in
+
+2004-05-19  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/starkit.tcl: added a patch from Bryan Schofield to properly
+       resolve all symbolic links so starkit::startup detection works.
+       * library/pkgIndex.tcl: bumped starkit version from 1.3 to 1.3.1
+
+       * ChangeLog: cleaned up a few tab-vs-space indentations
+
+2004-04-18  Daniel Steffen <das@users.sourceforge.net>
+
+       * generic/vfs.c: continue to #include tclPort.h, otherwise
+       compilation breaks against tcl 8.4.x.
+
+2004-04-01  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: added #include tclInt.h given recent Tcl
+        changes which broke compilation.
+
+        Fix to privately reported vfs bug with 'glob -type d -dir .  *'
+        across a vfs boundary.  No tests for this are currently possible
+        without effectively moving tclvfs into Tcl's test suite.
+
+2003-11-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure: regen
+       * tclconfig/tcl.m4: update to latest TEA that corrects calling
+       order of compiler and header checks.
+
+2003-10-30  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/tarvfs.tcl: fix to problem with relative paths
+       (Thanks Stefan).
+
+2003-10-21  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * starkit.tcl: add starkit::mode variable, which remembers the
+       return value of starkit::startup (suggestion by Andreas Kupries)
+       * pkgIndex.tcl: bumped starkit version from 1.2 to 1.3
+
+       * ChangeLog: cleaned up a few tab-vs-space indentations
+
+2003-10-17  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: removed some compiler warnings on OS X.
+
+2003-10-13  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: added support for TCL_GLOB_TYPE_MOUNT flag to
+       the MatchInDirectory proc, which provides for more seamless
+       boundaries between filesystems which allows for fixing Tcl's [Bug
+       800106].  This means (with a suitable version of Tcl) that 'glob
+       */*' across a filesystem boundary will now work correctly.
+       
+       The code should work fine with Tcl 8.4 and 8.5, although with
+       8.4.4 the mount list will never be queried.
+       
+       * library/pkgIndex.tcl(.in): 
+       * DESCRIPTION.txt:
+       * win/makefile.vc:
+       * configure.in: updated version to 1.3.0 reflecting the above
+       significant improvement.
+       
+2003-10-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure:        updated to autoconf 2.5
+       * tclconfig/tcl.m4: updated to latest TEA spec with WinCE support
+       and corrected defn of TCL_WIDE_INT_TYPE for compiling.
+
+       * Makefile.in: add CFLAGS_WARNING and pedantic quoting
+
+2003-09-28  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * starkit.tcl: added "package" and "pload" procs, to simplify
+       loading compiled extensions from a platform-specific subdir.
+       The naming conventions and code were adopted from Critcl.
+
+2003-09-26  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * starkit.tcl: add file normalize around info nameofexe, fixes
+       startup detection when exec'd in some cases (thx E Boudaillier).
+
+2003-09-01  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/mk4vfs.tcl: fix to Bug #796782.
+       * library/zipvfs.tcl:
+       * library/tarvfs.tcl: fix to similar bug in these filesystems.
+       
+2003-07-15  Vince Darley <vincentdarley@sourceforge.net>
+
+       * tests/vfsZip.test:
+       * tests/vfsTar.test: added some new tests for recently fixed
+        bugs.
+       * library/tarvfs.tcl: fix to bug when closing an empty archive.
+
+        Also updated package to version 1.2.1 since a variety of bugs
+        have been fixed since the 1.2 release
+       
+2003-07-06  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/ftpvfs.tcl: fix to 'file stat' on a directory, which
+        fixes a variety of problems (e.g. recurisve 'file copy' in a 
+        directory).  Thanks to msofer for the detailed bug report and
+        test script.
+       * library/zipvfs.tcl:
+       * library/tarvfs.tcl: ensure archive channel is closed if an
+       error is encountered while trying to open it.
+       
+2003-07-03  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/ftpvfs.tcl: added support for ports other than 21,
+       patch from msofer -- thanks.
+       
+2003-06-16  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/ftpvfs.tcl: added '-output ::vfs::log' to ftp
+        initialisation code to avoid messages being dumped to stderr
+        when errors occur.
+       
+2003-05-16  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/tkvfs.tcl: added 'tk' widget hierarchy vfs.  Use:
+            package require vfs::tk
+            vfs::tk::Mount .frame.a.b foo
+            cd foo
+            ...
+         to examine.
+       * library/pkgIndex.tcl(.in): added new package.
+       
+2003-05-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * library/pkgIndex.tcl.in: use vfs::dll var directly
+
+2003-05-14  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/vfsUtils.tcl: fix to package names
+       * library/mk4vfs.tcl: fix to 'file attributes' implementation
+       
+2003-04-29  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/zipvfs.tcl: patterns in 'glob' should be case-insensitive
+       since everything else is.
+       
+2003-04-04  Andreas Kupries  <andreask@activestate.com>
+
+       * configure.in:
+       * tclconfig/tcl.m4: Updated to newest tcl.m4, regenerated
+         configure's.
+
+2003-03-17  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * pkgIndex.tcl, pkgIndex.tcl.in: mk4vfs rev bumped to 1.9
+       * mk4vfs.tcl: reverted to old translucent/readwrite open modes
+
+2003-03-11  Andreas Kupries  <andreask@activestate.com>
+
+       * doc/vfs.man:             Added doctools documentation derived
+       * doc/vfs-fsapi.man:       from the original nroff-based
+       * doc/vfs-filesystems.man: manpages. Approved by Vincent.
+
+2003-03-11  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/pkgIndex.tcl:
+       * win/makefile.vc: updated for Tcl's incompatible change 
+       from 'd' to 'g' for debug builds.
+
+2003-02-24  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * pkgIndex.tcl, pkgIndex.tcl.in: starkit rev bumped to 1.2
+       * starkit.tcl: more contexts, panic ok if "." already gone
+
+2003-02-23  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure: regen
+       * configure.in:
+       * tclconfig/tcl.m4: regen from latest TEA setup
+       * Makefile.in: only use pkgIndex.tcl with shared builds
+       Handle RUNTIME_SOURCES properly when srcdir == top_builddir
+
+2003-02-21  Vince Darley <vincentdarley@sourceforge.net>
+
+       * doc/vfs.n:
+       * library/*.tcl: added missing 'recursive' flag to most
+        .tcl 'removedirectory' implementations.
+       
+       * library/mk4vfs.tcl: added catch around 'after cancel'
+       
+2003-02-21  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: some small cleanup
+       * doc/vfs.n: better documentation for 'createdirectory'
+       * library/mk4vfs.tcl: better posix adherence.
+       * library/vfsUtils.tcl: typo fix.
+       
+2003-02-20  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: completed use of internalerror and posix handling
+       for all functions.
+       * doc/vfs.n:
+       * doc/vfslib.n: more documentation regarding handling of errors
+       and use of the 'internalerror' feature.
+       
+        Around the time Tcl 8.4.2 is released we should increment tclvfs's
+       version to 1.3 and make a proper release.  In the meantime,
+       improvements to all .tcl implementations (esp. proper error
+       handling) would be greatly appreciated.
+       
+2003-02-20  Andreas Kupries  <andreask@activestate.com>
+
+       * library/mk4vfs.tcl: Switching to canceling the stored after id
+         of the periodic commit in _unmount instead of canceling by
+         script. The scripts in '_umount' and 'periodicCommit' were
+         different, causing the cancel to fail, and thus an eternal
+         commit, failing after the close; hanging the system.
+
+2003-02-20  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: added new debugging feature 'vfs::filesystem
+       internalerror ?script?'  which can be used to specify a script to
+       evaluate when any tclvfs implementation throws a standard Tcl
+       error.  Once implementation of all .tcl's is complete, they
+       should only return TCL_OK or a posix error code (which has a Tcl
+       return value of -1).  Any other code will signal an unintended
+       error which can be logged or reported using this new hook.  If
+       the script is not set, the behaviour of this extension is
+       unchanged.  For example:
+       
+        vfs::filesystem internalerror vfsreport
+       proc vfsreport {} {
+           puts "vfs bug found: $::errorInfo"
+       }
+       
+       Note that this has only been applied to those VFS api's which
+       are not currently able to pass an error message at the Tcl level.
+       Some (open, matchindirectory, fileattributes with get/set) are
+       already able to pass their errors up, so these cases are *not*
+       passed to this handler.
+
+       * library/mk4vfs.tcl: made one change to support the above
+       feature.
+       
+2003-02-19  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/mk4vfs.tcl: added 'commit' attribute
+       * library/vfsUtils.tcl:
+       * library/tarvfs.tcl:
+       * library/zipvfs.tcl:
+       * library/ftpvfs.tcl: added support for 'state' attribute
+       of these filesystems.
+       
+2003-02-18  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c:
+       * library/*.tcl: clean up of posix error handling.
+
+       * doc/vfs.n: added some more documentation.
+       
+2003-02-18  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: added 'vfs::filesystem posixerror' command
+       to allow direct reporting of posix error codes to Tcl.
+       * library/vfsUtils.tcl: added support for state switching
+       between "readonly", "translucent" and "readwrite".
+       * library/mk4vfs.tcl: 
+       * library/tarvfs.tcl:
+       * library/zipvfs.tcl:
+       * library/httpvfs.tcl: added support for proper reporting
+       of read-only status of filesystem
+       * library/tclIndex:  regen.
+       
+        You can now switch an mk4 filesystem between translucent and
+       readonly with 'vfs::attributes $mount -state readonly'. All
+       errors etc are correctly reported as if the filesystem is
+       read-only.
+       
+2003-02-17  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/vfsUtils.tcl: added beginnings of interface for
+       filesystem configuration.
+       * library/mk4vfs.tcl: 
+       * library/tclIndex:  regen.
+       
+2003-02-01  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/vfslib.tcl: fixed bug in new vfs::zstream code,
+       preventing forward seeking from working properly
+       * library/starkit.tcl: recognize if launched as NT service
+
+2003-02-08  Vince Darley <vincentdarley@sourceforge.net>
+
+       * library/*.tcl: made all 'matchindirectory' implementations
+       robust to whether they are passed a directory with a trailing
+       file-separator or not.  (Tcl doesn't document whether there
+       will be one, and optimisations to Tcl's filesystem require
+       this flexibility.  Also the use of 'file join' will actually
+       make the entire filesystem *more* efficient soon).
+       
+2003-02-06  Andreas Kupries  <andreask@activestate.com>
+
+       * tclconfig/tcl.m4: Added SC_TCL_EARLY_FLAGS and
+       * configure.in:     SC_TCL64BIT_FLAGS, copied from the Tcl
+       * configure:        configuration. Usage prevents mismatch
+                           between tcl core and tclvfs with regard
+                           to the selected types for wide integer
+                           and Tcl_StatBuf. Regenerated configure.
+
+2003-02-04  Vince Darley <vincentdarley@sourceforge.net>
+
+       * doc/vfs.n: 
+       * doc/vfslib.n: update docs to reflect last six months
+       of changes.
+       
+2003-02-04  Andreas Kupries  <andreask@activestate.com>
+
+       * library/mk4vfs.tcl: Fixed bad vfs::mk4::Mount change.
+
+2003-02-04  Vince Darley <vincentdarley@sourceforge.net>
+
+       * generic/vfs.c: fixed version of VfsFullyNormalizePath,
+       should resolve some problems with symlinks. Tcl really needs
+       a 'file normalized -full' and equivalent C api.
+       
+2003-02-04  Vince Darley <vincentdarley@sourceforge.net>
+
+       * tests/*.test: cleanup
+       
+       Also updated version of the package to 1.2 (not 1.1 since there's
+       a Windows binary floating around with that number, and we want to
+       avoid confusion).  It's been fixed at 1.0 for far too long.
+       
+2003-02-01  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/mk4vfs.tcl:  fixed bad mk4vfs::_umount change
+
+2003-02-01  Jean-Claude Wippler  <jcw@equi4.com>
+
+       * library/pkgIndex.tcl.in: mk4vfs 1.8, starkit 1.1, vfslib 1.3.1
+       * library/pkgIndex.tcl: (shouldn't this be dropped from CVS now?)
+       * library/mk4vfs.tcl:  updated from tclkit project
+       * library/starkit.tcl: updated from tclkit project
+       * library/vfslib.tcl:  updated from tclkit project
+
+2003-01-30  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in: only install pkgIndex.tcl for shared builds
+
+2003-01-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * library/pkgIndex.tcl.in (new):
+       * library/pkgIndex.tcl: Replace pkgIndex.tcl with one that is
+       * configure:            generated by configure to include the right
+       * configure.in:         vfs dll name.  Left the old one for
+       * Makefile.in:          non-configure users, but it can be wrong.
+       Also added tarvfs.tcl to list of files to install.
+
+       * library/vfsUtils.tcl: code cleanup
+
+2003-01-28  Vince Darley <vincentdarley@sourceforge.net>
+       * library/*.tcl: add 'package provide vfs::<name>' to the
+       virtual filesystems.  These are the current versions:
+       
+       package ifneeded vfs::ftp 1.0 
+       package ifneeded vfs::http 0.5
+       package ifneeded vfs::mk4 1.6 
+       package ifneeded vfs::ns 0.5 
+       package ifneeded vfs::tar 0.9
+       package ifneeded vfs::test 1.0
+       package ifneeded vfs::urltype 1.0
+       package ifneeded vfs::webdav 0.1
+       package ifneeded vfs::zip 1.0 
+       
+        I've used '0.1' to indicate a very preliminary version, 0.5 for
+       something which has had some work, 0.9 for nearly complete and
+       1.0 or newer for something which is well used.
+       
+        There is no need to do 'package require vfs', simply do a package
+       require of the particular vfs implementation you want from the
+       above list.
+       
+       * DESCRIPTION.txt:
+       * make55.tcl: new files for TIP55 compliance. (Steve Cassidy)
+
+       * tests/*:
+       * doc/tcllib.n: updated tests and docs for the above 'package'
+       information.
+
+2003-01-16  Vince Darley <vincentdarley@sourceforge.net>
+       * library/tarvfs.tcl: 
+       * library/zipvfs.tcl: ::close .zip or .tar file when unmounting
+       the filesystem.
+       
+2003-01-14  Vince Darley <vincentdarley@sourceforge.net>
+       * library/tarvfs.tcl: new 'tar' filesystem courtesy of Stefan
+       Vogel -- many thanks!  The tar vfs is currently read-only and
+       doesn't support .tgz.
+       * library/tclIndex:
+       * library/pkgIndex.tcl:
+       * library/vfsUtils.tcl: updated for new tar vfs.
+       
+2003-01-06  Vince Darley <vincentdarley@sourceforge.net>
+       * library/ftpvfs.tcl: allow 'file mtime' to set the modified
+       time of a file, if the ftp package supports it.
+       
+2002-12-24  Vince Darley <vincentdarley@sourceforge.net>
+       * library/ftpvfs.tcl: set the 'size' element in stat calls.
+       (Bug reported on comp.lang.tcl).
+       * library/vfsUtils.tcl: added '.kit' to the set of extensions
+       which vfs::auto will recognise for auto-mounting.
+       
+2002-10-30  Andreas Kupries  <andreask@activestate.com>
+
+       * library/pkgIndex.tcl: Changed 'tcl_platform' to
+         '::tcl_platform'. Package index must not assume execution at
+         global level.
+
+2002-10-19  Jean-Claude Wippler <jcw@equi4.com>
+
+       * library/pkgIndex.tcl:
+       * library/mk4vfs.tcl: merged 1.6 changes, periodic commit/flush
+
+2002-10-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in: add tclIndex to install
+
+       * library/mk4vfs.tcl:
+       * library/starkit.tcl:
+       * library/vfsUtils.tcl:
+       * library/vfslib.tcl:
+       * library/webdavvfs.tcl: whitespace cleanup
+
+       * library/pkgIndex.tcl: remove 8.4 alpha checks, use vfs::dll var
+       to store library name.
+
+2002-10-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tclconfig/tcl.m4:
+       * configure:
+       * configure.in: move the CFLAGS definition into TEA_ENABLE_SHARED
+       and make it pick up the env CFLAGS at configure time.
+
+2002-09-25  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in:               replace the ancient build system
+       * README.cygwin:             with TEA 2002 build spec.
+       * aclocal.m4:
+       * config.guess (removed):
+       * config.sub (removed):
+       * configure:
+       * configure.in:
+       * install-sh (removed):
+       * mkIndex.tcl.in (removed):
+       * mkinstalldirs (removed):
+       * tcl.m4 (removed):
+       * tclconfig/README.txt (new):
+       * tclconfig/install-sh (new):
+       * tclconfig/tcl.m4 (new):
+       * generic/vfs.c: changed BUILD_Vfs to BUILD_vfs
+
+2002-09-10  Jean-Claude Wippler <jcw@equi4.com>
+       * library/pkgIndex.tcl: adjusted for two new packages,
+       also fixed to use proper file name on unix (as shared lib)
+       * library/starkit.tcl: added, new impl of scripdoc.tcl
+       * library/vfslib.tcl: added back in, need by above
+
+2002-07-18  Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: ensure all mount activity is with fully
+       normalized paths in which the last path element is not a link.
+       Solves (together with latest cvs head changes) a problem in
+       starting up a tclkit(sh) from a link.
+       
+2002-07-08  Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: update for latest cvs head.
+       * win/makefile.vc: compilation into Release and Debug
+       directories as appropriate.
+       
+2002-06-22  Jean-Claude Wippler <jcw@equi4.com>
+       * mac/pkgIndex_mac.tcl:
+       * library/pkgIndex.tcl:
+       * library/mk4vfs.in: fix recursive file deletion, bump to 1.5
+
+2002-05-29  Jean-Claude Wippler <jcw@equi4.com>
+       * Makefile.in: moved the definition of $(OBJEXT) up so the
+       definition of vfs_OBJECTS works with more make's
+
+2002-05-13  Vince Darley <vincentdarley@sourceforge.net>
+       * library/webdavvfs.tcl: v. early implementation of a webdav
+       vfs.  (Note: this and the 'http' vfs need lots of work --
+       please help out!).  This requires the '2.6' version of the http
+       package which is distributed with tclvfs.
+       
+2002-05-13  Vince Darley <vincentdarley@sourceforge.net>
+       * library/mk4vfs.tcl: newer version from tclkit.
+
+2002-05-03  Vince Darley <vincentdarley@sourceforge.net>
+       * tests/*: more test improvements, and new file vfsArchive.test
+       which will test the running of the tests inside an archive. 
+       This requires recursive invocation of the 'tcltest' package,
+       which may well cause some problems if it isn't designed to
+       handle that (i.e. executing one test actually causes the
+       execution of a lot of other tests).
+       * library/pkgIndex.tcl: update to try to avoid the 'no such
+       command vfs::*::Mount' error messages which you can get, if
+       the relevant .tcl files are not on your auto_path.
+
+2002-05-02  Vince Darley <vincentdarley@sourceforge.net>
+       * tests/vfs.test: tests work independent of directory in which
+       they run.  Tests added to check that at least 'vfs::memchan'
+       basically works, and vfs::zip, vfs::crc helpers do what they
+       are supposed to.
+       * tests/vfsZip.test: test to run all tests inside a zip.
+       * mac/*: updated for removal of scripdoc.tcl and vfs.tcl
+       
+2002-04-25  Jean-Claude Wippler <jcw@equi4.com>
+       * library/*vfs.tcl: switching to vfs::{crc,memchan,zip}
+       * library/vfsUtils.tcl: fixed env to be global, added unset
+       so unmounting cleans up its list of mounted file systems,
+       define Trf/memchan-based versions of vfs::{crc,memchan,zip}
+       * library/{scripdoc.tcl,vfs.tcl}: removed, tclkit specific
+       * library/pkgIndex.tcl: drop packages "scripdoc" and "vfslib"
+
+2002-04-25  Vince Darley <vincentdarley@sourceforge.net>
+       * tests/*: revamp of tests to be more robust, and to be
+       able to run from inside a mounted virtual filesystem.
+       
+2002-04-09  Jean-Claude Wippler <jcw@equi4.com>
+       * configure: generated and added to project
+
+2002-04-08  Daniel Steffen  <das@users.sourceforge.net>
+       * mac/pkgIndex_mac.tcl: synced to generic/pkgIndex.tcl
+
+2002-04-01  Vince Darley <vincentdarley@sourceforge.net>
+       * Makefile.in: compilation fix from jcw.
+       
+2002-03-16  Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: updated for latest cvs head of Tcl 8.4a5.
+       * library/vfs.tcl: New version from jcw, with better handling
+       of env(PATH).
+
+2002-03-09  Vince Darley <vincentdarley@sourceforge.net>
+       * library/mk4vfs.tcl: updated version from Jean-Claude Wippler.
+
+2002-03-01  Vince Darley <vincentdarley@sourceforge.net>
+       * library/*.tcl: completed and tested most changes from 02-19.
+
+2002-02-19  Vince Darley <vincentdarley@sourceforge.net>
+       * library/*.tcl: updated the vfs implementations to deal
+       with the 2002-02-01 change below.  More work needed.
+
+2002-02-17  Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: updated for TIP#72 application to cvs head.
+       The 'file stat' implementation now deals with files of size
+       greater than a 32 bit representation.  This requires the
+       very latest cvs head of Tcl 8.4a4, and is not compatible
+       with previous releases (but that is fine, since we're still
+       tracking alpha releases anyway).
+
+2002-02-01 Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: allow 'pattern' to be NULL in calls to 
+       Tcl_FSMatchInDirectory in preparation for fix of Tcl bug
+       511666.  This will require additions to each individual
+       filesystem to handle that special case (and thereby fix the
+       bug that fully specified files were not matched against
+       'types').
+
+2002-01-28 Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: const, MacOS fixes (also thanks Daniel Steffen).
+
+2001-12-07 Vince Darley <vincentdarley@sourceforge.net>
+       * various test, install fixes (unix) thanks to Larry Virden.
+       
+2001-12-02 Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: minor code cleanup and simplification. Fix
+       to problem with absolute paths on unix systems introduced in
+       recent changes.
+       
+2001-11-21 Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: added more comments to the code, and 
+       made mount point checking faster and simpler (we no longer
+       need to modify strings temporarily).
+       
+2001-11-09 Vince Darley <vincentdarley@sourceforge.net>
+       * tests/vfs*.test: better tests; more platform independent.
+
+2001-11-08  Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: made code thread-safe.  Disallow
+       safe interpreters from using vfs code since they can then
+       mess with the filesystem across all interpreters.
+
+2001-11-07  Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: all mount information is now stored in a
+       purpose built data structure ('vfs::mount' variable is gone),
+       and the code handles multiple interpreters in a very robust
+       fashion.  Fixes crashing problem in pkg_mkIndex and
+       general inconsistencies with multiple interps.  Also, the 
+       '-volume' flag is no longer required for unmounting.  Lastly
+       added a lot more documentation in the code.
+       * library/vfsUrl.tcl: remove '-volume' flag.
+       * tests/vfs*.test: various new tests added
+       * doc/vfs.n: documentation much improved, especially with
+       respect to multiple interpreters.
+
+2001-11-01  Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: 'vfs::mount' no longer a string-literal
+       * tests/vfs*.test: various new tests added
+       
+2001-10-31  Vince Darley <vincentdarley@sourceforge.net>
+       * examples/simpleExamples.tcl: a demo
+       * doc/vfslib.n: some documentation on the 'library' code.
+       
+2001-10-29  Vince Darley <vincentdarley@sourceforge.net>
+       * win/makefile.vc: installation is better.
+       * library/vfsUrl.tcl: improved urltype mounting.  The following
+       will now work in all cases:
+       % vfs::urltype::Mount ftp
+       % set listing [glob -dir ftp://ftp.scriptics.com/pub *]
+       ...
+       % vfs::urltype::Mount http
+       % set fd [open http://sourceforge.net/projects/tcl]
+       % set contents [read $fd] ; close $fd
+       ...
+       
+2001-09-27  Vince Darley <vincentdarley@sourceforge.net>
+       * library/mk4vfs.tcl: Update from Jean-Claude Wippler
+       * library/vfsUtils.tcl:
+       * generic/vfs.c: Moved 'list volumes' functionality
+       entirely into C from Tcl (faster and easier for tclkit
+       to make proper use of).  This required the addition
+       of a '-volume' flag to the mount/unmount commands, and
+       meant we can remove the 'mountschanged' subcommand.
+
+2001-09-07  Vince Darley <vincentdarley@sourceforge.net>
+       * generic/vfs.c: Fixed '==' error
+       * doc/vfs.n: Improved docs.
+       * library/mk4vfs.tcl: Better mk support
+
+2001-09-06  Vince Darley <vincentdarley@sourceforge.net>
+       * Further minor improvements, unfortunately requires
+       new release of Tcl from cvs (today).  Also added
+       'install' target to vc++ makefile.
+
+2001-08-29  Vince Darley <vincentdarley@sourceforge.net>
+       * can now mount root volumes which end in separator
+       characters (such as 'ftp://').  The code handles path
+       separation in such cases.  This means the 'urltype'
+       vfs now works (the 8-22 changes below didn't quite
+       complete the job).
+       This requires the latest 8.4a4 release from cvs.
+       
+2001-08-22  Vince Darley <vincentdarley@sourceforge.net>
+       * added ability to treat entire urls as file paths, so
+       we can mount 'ftp://' as a root volume and examine its
+       contents.  This requires the latest 8.4a4 release from cvs.
+       
+2001-08-13  Vince Darley <vincentdarley@sourceforge.net>
+       * ftp vfs works reasonably well now; try:
+       % package require vfs
+       % vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ local
+       % cd local ; cd tcl ; source vfsTest.tcl
+       
+2001-08-10  Vince Darley <vincentdarley@sourceforge.net>
+       * added a man page vfs.n
+       * added 'utime' to various vfs
+       * included mk4tcl vfs implementation which works
+       * added some support files so this library can be
+         used more easily with TclKit.
+       * memory leak in file attributes get fixed.
+
+2001-05-09  Vince Darley <vincentdarley@sourceforge.net>
+       * initial distribution, zip vfs works
diff --git a/8.x/tclvfs/DESCRIPTION.txt b/8.x/tclvfs/DESCRIPTION.txt
new file mode 100644 (file)
index 0000000..8c48444
--- /dev/null
@@ -0,0 +1,20 @@
+Identifier: vfs
+Version: 1.3.0
+Title: Interface to Virtual File Systems for Tcl 8.4
+Creator: Vince Darley
+Description: The goal of this extension is to expose Tcl 8.4's new
+            filesystem C API to the Tcl level.
+Rights: BSD
+URL: http://sourceforge.net/projects/tclvfs
+Date: 2003-10-08
+Architecture: tcl
+Architecture: Linux-x86
+Require: tcl 8.4
+Recommend: tcl 8.5
+Recommend: Trf
+Recommend: http 2.6
+Recommend: base64
+Recommend: Memchan
+Recommend: Mk4tcl
+Recommend: ftp
+Subject: filesystem
diff --git a/8.x/tclvfs/Makefile.in b/8.x/tclvfs/Makefile.in
new file mode 100644 (file)
index 0000000..680c404
--- /dev/null
@@ -0,0 +1,388 @@
+# Makefile.in --
+#
+#      This file is a Makefile for Sample TEA Extension.  If it has the name
+#      "Makefile.in" then it is a template for a Makefile;  to generate the
+#      actual Makefile, run "./configure", which is a configuration script
+#      generated by the "autoconf" program (constructs like "@foo@" will get
+#      replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: Makefile.in,v 1.31 2010/02/01 07:32:58 blacksqr Exp $
+
+#========================================================================
+# Edit the following few lines when writing a new extension
+#========================================================================
+
+#========================================================================
+# The names of the source files is defined in the configure script.
+# The object files are used for linking into the final library.
+# This will be used when a dist target is added to the Makefile.
+# It is not important to specify the directory, as long as it is the
+# $(srcdir) or in the generic, win or unix subdirectory.
+#========================================================================
+
+PKG_SOURCES    = @PKG_SOURCES@
+PKG_OBJECTS    = @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+#========================================================================
+# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
+# this package that need to be installed, if any.
+#========================================================================
+
+# vfs.tcl is found in the build, as it was generated by configure from
+# library/vfs.tcl.in. This necessitated extensions to the target
+# install-lib-binaries.
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ \
+                 ftpvfs.tcl httpvfs.tcl mk4vfs.tcl starkit.tcl \
+                 tarvfs.tcl tclprocvfs.tcl testvfs.tcl \
+                 vfsUrl.tcl vfsUtils.tcl vfslib.tcl \
+                 webdavvfs.tcl zipvfs.tcl tkvfs.tcl \
+                 template/collatevfs.tcl template/deltavfs.tcl \
+                 template/fishvfs.tcl template/globfind.tcl \
+                 template/quotavfs.tcl template/tdelta.tcl \
+                 template/templatevfs.tcl template/versionvfs.tcl \
+                 template/chrootvfs.tcl template/tclIndex vfs.tcl
+
+
+#========================================================================
+# This is a list of public header files to be installed, if any.
+#========================================================================
+
+PKG_HEADERS    = @PKG_HEADERS@
+
+#========================================================================
+# "PKG_LIB_FILE" refers to the library (dynamic or static as per
+# configuration options) composed of the named objects.
+#========================================================================
+
+PKG_LIB_FILE   = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES   = $(PKG_LIB_FILE)
+BINARIES       = $(lib_BINARIES) pkgIndex.tcl
+
+SHELL          = @SHELL@
+
+srcdir         = @srcdir@
+prefix         = @prefix@
+exec_prefix    = @exec_prefix@
+
+bindir         = @bindir@
+libdir         = @libdir@
+datadir                = @datadir@
+mandir         = @mandir@
+includedir     = @includedir@
+
+DESTDIR                =
+
+PKG_DIR                = $(PACKAGE_NAME)$(PACKAGE_VERSION)
+pkgdatadir     = $(datadir)/$(PKG_DIR)
+pkglibdir      = $(libdir)/$(PKG_DIR)
+pkgincludedir  = $(includedir)/$(PKG_DIR)
+
+top_builddir   = .
+
+INSTALL                = @INSTALL@
+INSTALL_PROGRAM        = @INSTALL_PROGRAM@
+INSTALL_DATA   = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+PACKAGE_NAME   = @PACKAGE_NAME@
+PACKAGE_VERSION        = @PACKAGE_VERSION@
+CC             = @CC@
+CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+CLEANFILES     = @CLEANFILES@
+EXEEXT         = @EXEEXT@
+LDFLAGS_DEFAULT        = @LDFLAGS_DEFAULT@
+MAKE_LIB       = @MAKE_LIB@
+MAKE_SHARED_LIB        = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB        = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB  = @MAKE_STUB_LIB@
+OBJEXT         = @OBJEXT@
+RANLIB         = @RANLIB@
+RANLIB_STUB    = @RANLIB_STUB@
+SHLIB_CFLAGS   = @SHLIB_CFLAGS@
+SHLIB_LD       = @SHLIB_LD@
+SHLIB_LD_FLAGS = @SHLIB_LD_FLAGS@
+SHLIB_LD_LIBS  = @SHLIB_LD_LIBS@
+STLIB_LD       = @STLIB_LD@
+TCL_DEFS       = @TCL_DEFS@
+TCL_BIN_DIR    = @TCL_BIN_DIR@
+TCL_SRC_DIR    = @TCL_SRC_DIR@
+# This is necessary for packages that use private Tcl headers
+TCL_TOP_DIR_NATIVE     = @TCL_TOP_DIR_NATIVE@
+# Not used, but retained for reference of what libs Tcl required
+TCL_LIBS       = @TCL_LIBS@
+
+#========================================================================
+# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
+# package without installing.  The other environment variables allow us
+# to test against an uninstalled Tcl.  Add special env vars that you
+# require for testing here (like TCLX_LIBRARY).
+#========================================================================
+
+EXTRA_PATH     = $(top_builddir):$(TCL_BIN_DIR)
+TCLSH_ENV      = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
+                 @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+                 VFS_LIBRARY="`@CYGPATH@ $(srcdir)/library`" \
+                 PATH="$(EXTRA_PATH):$(PATH)" \
+                 TCLLIBPATH="$(top_builddir)"
+TCLSH_PROG     = @TCLSH_PROG@
+TCLSH          = $(TCLSH_ENV) $(TCLSH_PROG)
+SHARED_BUILD   = @SHARED_BUILD@
+
+INCLUDES       = @PKG_INCLUDES@ @TCL_INCLUDES@
+
+PKG_CFLAGS     = @PKG_CFLAGS@
+
+DEFS           = @DEFS@ $(PKG_CFLAGS)
+
+CONFIG_CLEAN_FILES = Makefile
+
+CPPFLAGS       = @CPPFLAGS@
+LIBS           = @PKG_LIBS@ @LIBS@
+AR             = @AR@
+## need to include the tcl source dir here for tclPort.h
+CFLAGS         = @CFLAGS@
+COMPILE                = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+#========================================================================
+# Start of user-definable TARGETS section
+#========================================================================
+
+#========================================================================
+# TEA TARGETS.  Please note that the "libraries:" target refers to platform
+# independent files, and the "binaries:" target inclues executable programs and
+# platform-dependent libraries.  Modify these targets so that they install
+# the various pieces of your package.  The make and install rules
+# for the BINARIES that you specified above have already been done.
+#========================================================================
+
+all: binaries libraries doc
+
+#========================================================================
+# The binaries target builds executable programs, Windows .dll's, unix
+# shared/static libraries, and any other platform-dependent files.
+# The list of targets to build for "binaries:" is specified at the top
+# of the Makefile, in the "BINARIES" variable.
+#========================================================================
+
+binaries: $(BINARIES)
+
+libraries:
+
+doc:
+
+install: all install-binaries install-libraries install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+
+#========================================================================
+# This rule installs platform-independent files, such as header files.
+#========================================================================
+
+install-libraries: libraries
+       @mkdir -p $(DESTDIR)$(includedir)
+       @echo "Installing header files in $(DESTDIR)$(includedir)"
+       @list='$(PKG_HEADERS)'; for i in $$list; do \
+           echo "    $$i" ; \
+           $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+       done;
+
+#========================================================================
+# Install documentation.  Unix manpages should go in the $(mandir)
+# directory.
+#========================================================================
+
+install-doc: doc
+       @mkdir -p $(DESTDIR)$(mandir)/mann
+       @echo "Installing documentation in $(DESTDIR)$(mandir)/mann"
+       @list='$(srcdir)/doc/*.n'; for i in $$list; do \
+           echo "    `basename $$i`"; \
+           rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
+           $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
+       done
+
+test: binaries libraries
+       $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+shell: binaries libraries
+       @$(TCLSH) $(SCRIPT)
+
+gdb:
+       $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+#========================================================================
+# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
+# mentioned above.  That will ensure that this target is built when you
+# run "make binaries".
+#
+# The $(PKG_OBJECTS) objects are created and linked into the final
+# library.  In most cases these object files will correspond to the
+# source files above.
+#========================================================================
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+       -rm -f $(PKG_LIB_FILE)
+       ${MAKE_LIB}
+       $(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+       -rm -f $(PKG_STUB_LIB_FILE)
+       ${MAKE_STUB_LIB}
+       $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#========================================================================
+# We need to enumerate the list of .c to .o lines here.
+#
+# In the following lines, $(srcdir) refers to the toplevel directory
+# containing your extension.  If your sources are in a subdirectory,
+# you will have to modify the paths to reflect this:
+#
+# sample.$(OBJEXT): $(srcdir)/generic/sample.c
+#      $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
+#
+# Setting the VPATH variable to a list of paths will cause the makefile
+# to look into these paths when resolving .c to .obj dependencies.
+# As necessary, add $(srcdir):$(srcdir)/compat:....
+#
+# The first $(srcdir) isn't necessary, but configure will strip it the
+# first $(srcdir) it sees in VPATH when configuring in the toplevel dir.
+#========================================================================
+
+VPATH = $(srcdir):$(srcdir)/generic
+
+.c.@OBJEXT@:
+       $(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#========================================================================
+# Create the pkgIndex.tcl file.
+# It is usually easiest to let Tcl do this for you with pkg_mkIndex, but
+# you may find that you need to customize the package.  If so, either
+# modify the -hand version, or create a pkgIndex.tcl.in file and have
+# the configure script output the pkgIndex.tcl by editing configure.in.
+#========================================================================
+
+#pkgIndex.tcl:
+#      ( echo pkg_mkIndex . $(PKG_LIB_FILE) \; exit; ) | $(TCLSH)
+pkgIndex.tcl: $(srcdir)/pkgIndex.tcl.in
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+#========================================================================
+# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
+# variable in configure.in
+#========================================================================
+
+clean:  
+       -test -z "$(BINARIES)" || rm -f $(BINARIES)
+       -rm -f *.$(OBJEXT) core *.core
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+       -rm -f *.tab.c
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log config.status
+
+#========================================================================
+# Install binary object libraries.  On Windows this includes both .dll and
+# .lib files.  Because the .lib files are not explicitly listed anywhere,
+# we need to deduce their existence from the .dll file of the same name.
+# Additionally, the .dll files go into the bin directory, but the .lib
+# files go into the lib directory.  On Unix platforms, all library files
+# go into the lib directory.  In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh8.2 shell)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-lib-binaries:
+       @mkdir -p $(DESTDIR)$(pkglibdir)
+       @list='$(lib_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo "Installing $$p in $(DESTDIR)$(pkglibdir)"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+           stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
+           if test "x$$stub" = "xstub"; then \
+               echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
+           else \
+               echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
+           fi; \
+           ext=`echo $$p|sed -e "s/.*\.//"`; \
+           if test "x$$ext" = "xdll"; then \
+               lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+               if test -f $$lib; then \
+                   echo "Install $$lib in $(DESTDIR)$(pkglibdir)"; \
+                   $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+               fi; \
+           fi; \
+         fi; \
+       done
+       @echo "Installing library files in $(DESTDIR)$(pkglibdir)";
+       @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         if test -f $(srcdir)/library/$$p; then \
+           destd=`dirname $$p`; \
+           echo "    $$p"; \
+           mkdir -p $(DESTDIR)$(pkglibdir)/$$destd; \
+           $(INSTALL_DATA) $(srcdir)/library/$$p $(DESTDIR)$(pkglibdir)/$$p; \
+         elif test -f $(top_builddir)/library/$$p; then \
+           destd=`dirname $$p`; \
+           echo "    $$p (generated)"; \
+           mkdir -p $(DESTDIR)$(pkglibdir)/$$destd; \
+           $(INSTALL_DATA) $(top_builddir)/library/$$p $(DESTDIR)$(pkglibdir)/$$p; \
+         fi; \
+       done
+       @echo "Installing pkgIndex.tcl in $(DESTDIR)$(pkglibdir)";
+       @$(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir);
+
+#========================================================================
+# Install binary executables (e.g. .exe files)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-bin-binaries:
+       @mkdir -p $(DESTDIR)$(bindir)
+       @list='$(bin_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo "Installing $$p in $(DESTDIR)$(bindir)"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+         fi; \
+       done
+
+.SUFFIXES: .c .$(OBJEXT)
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+       list='$(BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         p=`basename $$p`; \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(bin_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/$$p; \
+       done
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/8.x/tclvfs/README.cygwin b/8.x/tclvfs/README.cygwin
new file mode 100644 (file)
index 0000000..bff4be4
--- /dev/null
@@ -0,0 +1,3 @@
+The contents of this file were out of date and misleading. 
+They have been removed until someone contributes something
+which works and is up to date.
diff --git a/8.x/tclvfs/Readme.txt b/8.x/tclvfs/Readme.txt
new file mode 100644 (file)
index 0000000..ed66b0c
--- /dev/null
@@ -0,0 +1,171 @@
+Hello!  The code here has evolved from ideas and excellent work by Matt
+Newman, Jean-Claude Wippler, TclKit etc.  To make this really successful,
+we need a group of volunteers to enhance what we have and build a new way
+of writing and distributing Tcl code.
+
+Introduction
+------------
+
+This is an implementation of a 'vfs' extension (and a 'vfs' package,
+including a small library of Tcl code).  The goal of this extension
+is to expose Tcl 8.4's new filesystem C API to the Tcl level.
+
+Using this extension, the editor Alphatk can actually auto-mount,
+view and edit (but not save, since they're read-only) the contents of
+.zip files directly (see <http://www.purl.org/net/alphatk/>), and you
+can do things like:
+
+    file copy ftp://ftp.foo.com/pub/readme.txt .
+
+With 'Tkhtml' and this extension, writing a web-browser in Tcl should be 
+pretty trivial.
+
+None of the vfs's included are 100% complete or optimal yet, so if only for
+that reason, code contributions are very welcome.  Many of them still
+contain various debugging code, etc.  This will be gradually removed and
+the code completely cleaned up and documented as the package evolves.
+
+-- Vince Darley, April 2002-February 2003
+
+Compile/build
+-------------
+
+The standard 'configure ; make ; make install' should work, but if it
+doesn't, I'm afraid I can't help --- I am not an expert on these issues
+and find it amazing that to compile a single C file (generic/vfs.c) a
+dozen or so TEA 'helper' files are required.  I believe 'gmake' may
+be required on some platforms.
+
+For windows, there is a VC++ makefile in the win directory ('nmake -f
+makefile.vc') should do the trick.
+
+Tests and installation
+----------------------
+
+The tests/vfs*.test files should all pass (provided you have an active
+internet connection).
+
+To install, you probably want to rename the directory 'library' to 'vfs1.0'
+and place it in your Tcl hierarchy, with the necessary shared library inside
+(improvements to makefiles to streamline this much appreciated).  On Windows
+'nmake -f makefile.vc install' should do everything for you.
+
+Current implementation
+----------------------
+
+Some of the provided vfs's require the Memchan extension for any operation 
+which involves opening files.  The zip vfs also require 'Trf' (for its
+'zip' command).
+
+The vfs's currently available are:
+
+package vfs::ftp 1.0 
+package vfs::http 0.5
+package vfs::mk4 1.6 
+package vfs::ns 0.5 
+package vfs::tar 0.9
+package vfs::test 1.0
+package vfs::urltype 1.0
+package vfs::webdav 0.1
+package vfs::zip 1.0 
+
+--------+-----------------------------------------------------------------
+vfs     |  example mount command                       
+--------+-----------------------------------------------------------------
+zip     |  vfs::zip::Mount my.zip local
+ftp     |  vfs::ftp::Mount ftp://user:pass@ftp.foo.com/dir/name/ local
+mk4     |  vfs::mk4::Mount myMk4database local
+urltype |  vfs::urltype::Mount ftp
+test    |  vfs::test::Mount ...
+--------+-----------------------------------------------------------------
+
+These are also available, but not so heavily debugged:
+
+--------+-----------------------------------------------------------------
+ns      |  vfs::ns::Mount ::tcl local
+webdav  |  vfs::webdav::Mount http://user:pass@foo.com/blah local
+http    |  vfs::http::Mount http://foo.com/blah local
+--------+-----------------------------------------------------------------
+
+For file-systems which make use of a local file (e.g. mounting zip or mk4
+archives), it is often most simple to have 'local' be the same name as 
+the archive itself.  The result of this is that Tcl will then see the
+archive as a directory, rather than a file.  Otherwise you might wish
+to create a dummy file/directory called 'local' before mounting.
+
+C versus Tcl
+------------
+
+It may be worth writing a vfs for commonly used formats like 'zip' in C. 
+This would make it easier to create single-file executables because with
+this extension we have a bootstrap problem: to mount the executable
+(assuming it has a .zip archive appended to it) we need to have
+'vfs::zip::Mount' and related procedures loaded, but this means that those 
+procedures would have to be stored in the executable outside the zip
+archive, wasting space.
+
+Note: Richard Hipp has written 'zvfs' which uses the older, less-complete
+vfs support in Tcl 8.3.  It is GNU-licensed, which makes distributing binary
+versions a little more complex.  Also Prowrap contains a similar zip-vfs
+implementation using the same old APIs (it is BSD-licensed).  Either of 
+these can probably be modified to work with the new APIs quite easily.
+
+Helping!
+--------
+
+Any help is much appreciated!  The current code has very much _evolved_
+which means it isn't necessarily even particular well thought out, so if
+you wish to contribute a single line of code or a complete re-write, I'd be
+very happy!
+
+Future thoughts
+---------------
+
+See:
+
+http://developer.gnome.org/doc/API/gnome-vfs/
+http://www.appwatch.com/lists/gnome-announce/2001-May/000267.html
+http://www.lh.com/~oleg/ftp/HTTP-VFS.html
+http://www.atnf.csiro.au/~rgooch/linux/vfs.txt
+
+for some ideas.  It would be good to accumulate ideas on the limitations of
+the current VFS support so we can plan out what vfs 2.0 will look like (and
+what changes will be needed in Tcl's core to support it).  
+
+"Asynchronicity" -- Obvious things which come to mind are asynchronicity:
+'file copy' from a mounted remote site (ftp or http) is going to be very
+slow and simply block the application.  Commands like that should have new
+asynchronous versions which can be used when desired (for example, 'file
+copy from to -callback foo' would be one approach to handling this).
+
+"exec" -- this Tcl command effectively boils down to forking off a variety
+of processes and hooking their input/output/errors up appropriately.  Most
+of this code is quite generic, and ends up in 'TclpCreateProcess' for the
+actual forking and execution of another process (whose name is given by
+'argv[0]' in TclpCreateProcess).  Would it be possible to make a
+Tcl_FSCreateProcess which can pass the command on either to the native
+filesystem or to virtual filesystems?  The simpler answer is "yes", given
+that we can simply examine 'argv[0]' and see if it is it is a path in a
+virtual filesystem and then hand it off appropriately, but could a vfs
+actually implement anything sensible?  The kind of thing I'm thinking of is
+this: we mount an ftp site and would then like to execute various ftp
+commands directly.  Now, we could use 'ftp::Quote' (from the ftp package) to
+send commands directly, but why not 'exec' them?  If my ftp site is mounted
+at /tcl/ftppub, why couldn't "exec /tcl/ftppub FOO arg1 arg2" attempt a
+verbatim "FOO arg1 arg2" command on the ftp connection?  (Or would perhaps
+"exec /tcl/ftppub/FOO arg1 arg2" be the command?).  Similarly a Tcl
+'namespace' filesystem could use 'exec' to evaluate code in the relevant
+namespace (of course you could just use 'namespace eval' directly, but then
+you couldn't hook the code up to input/output pipes).
+
+Debugging virtual filesystems
+-----------------------------
+
+Bugs in Tcl vfs's are hard to track down, since error _messages_ can't
+necessarily propagate to the toplevel (errors of course do propagate and
+result in a filesystem action failing, but informative error messages cannot
+usually be provided, since Tcl is only expecting one of the standard POSIX
+error codes).  We could add a debugging command to this extension so
+unexpected errors are logged somewhere.  Alternatively the 'reporting'
+filesystem in Tcl's test suite can be used to aid debugging.
+
diff --git a/8.x/tclvfs/aclocal.m4 b/8.x/tclvfs/aclocal.m4
new file mode 100644 (file)
index 0000000..0f09fb8
--- /dev/null
@@ -0,0 +1 @@
+builtin(include,tclconfig/tcl.m4)
diff --git a/8.x/tclvfs/configure b/8.x/tclvfs/configure
new file mode 100755 (executable)
index 0000000..48285f3
--- /dev/null
@@ -0,0 +1,11286 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for vfs 1.4.1.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='vfs'
+PACKAGE_TARNAME='vfs'
+PACKAGE_VERSION='1.4.1'
+PACKAGE_STRING='vfs 1.4.1'
+PACKAGE_BUGREPORT=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS PKG_SOURCES PKG_OBJECTS TCL_INCLUDES TCL_TOP_DIR_NATIVE CLEANFILES TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS LD_LIBRARY_PATH_VAR CFLAGS_DEFAULT LDFLAGS_DEFAULT TCL_DBGX MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures vfs 1.4.1 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of vfs 1.4.1:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-threads        build with threads
+  --enable-shared         build and link with shared libraries (default: on)
+  --enable-64bit          enable 64bit support (default: off)
+  --enable-64bit-vis      enable 64bit Sparc VIS support (default: off)
+  --disable-rpath         disable rpath support (default: on)
+  --enable-wince          enable Win/CE support (where applicable)
+  --enable-load           allow dynamic loading and "load" command (default:
+                          on)
+  --enable-symbols        build with debugging symbols (default: off)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-tcl              directory containing tcl configuration
+                          (tclConfig.sh)
+  --with-tclinclude       directory containing the public Tcl header files
+  --with-celib=DIR        use Windows/CE support library from DIR
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+vfs configure 1.4.1
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by vfs $as_me 1.4.1, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.7"
+
+    echo "$as_me:$LINENO: checking for correct TEA configuration" >&5
+echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6
+    if test x"${PACKAGE_NAME}" = x ; then
+       { { echo "$as_me:$LINENO: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5
+echo "$as_me: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test x"3.7" = x ; then
+       { { echo "$as_me:$LINENO: error:
+TEA version not specified." >&5
+echo "$as_me: error:
+TEA version not specified." >&2;}
+   { (exit 1); exit 1; }; }
+    elif test "3.7" != "${TEA_VERSION}" ; then
+       echo "$as_me:$LINENO: result: warning: requested TEA version \"3.7\", have \"${TEA_VERSION}\"" >&5
+echo "${ECHO_T}warning: requested TEA version \"3.7\", have \"${TEA_VERSION}\"" >&6
+    else
+       echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5
+echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+           # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CYGPATH+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CYGPATH"; then
+  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CYGPATH="cygpath -w"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+  echo "$as_me:$LINENO: result: $CYGPATH" >&5
+echo "${ECHO_T}$CYGPATH" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+
+
+
+    # This package name must be replaced statically for AC_SUBST to work
+
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in tclconfig $srcdir/tclconfig; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+
+
+
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+
+# Check whether --with-tcl or --without-tcl was given.
+if test "${with_tcl+set}" = set; then
+  withval="$with_tcl"
+  with_tclconfig=${withval}
+fi;
+       echo "$as_me:$LINENO: checking for Tcl configuration" >&5
+echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6
+       if test "${ac_cv_c_tclconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
+echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5
+echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # TEA specific: on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+
+fi
+
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           { { echo "$as_me:$LINENO: error: Can't find Tcl configuration definitions" >&5
+echo "$as_me: error: Can't find Tcl configuration definitions" >&2;}
+   { (exit 1); exit 1; }; }
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6
+       fi
+    fi
+
+
+    echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        echo "$as_me:$LINENO: result: loading" >&5
+echo "${ECHO_T}loading" >&6
+       . "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # TEA specific:
+
+
+
+
+
+
+
+
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
+echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
+           prefix=${TCL_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5
+echo "$as_me: --prefix defaulting to /usr/local" >&6;}
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
+echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5
+echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;}
+           exec_prefix=$prefix
+       fi
+    fi
+
+
+
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+    # Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5
+echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6
+if test "${tcl_cv_cc_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_pipe=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_pipe=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5
+echo "${ECHO_T}$tcl_cv_cc_pipe" >&6
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+    if test "${TEA_PLATFORM}" = "unix" ; then
+
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking for sin" >&5
+echo $ECHO_N "checking for sin... $ECHO_C" >&6
+if test "${ac_cv_func_sin+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define sin to an innocuous variant, in case <limits.h> declares sin.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define sin innocuous_sin
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char sin (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef sin
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char sin ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_sin) || defined (__stub___sin)
+choke me
+#else
+char (*f) () = sin;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != sin;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_sin=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_sin=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5
+echo "${ECHO_T}$ac_cv_func_sin" >&6
+if test $ac_cv_func_sin = yes; then
+  MATH_LIBS=""
+else
+  MATH_LIBS="-lm"
+fi
+
+    echo "$as_me:$LINENO: checking for main in -lieee" >&5
+echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6
+if test "${ac_cv_lib_ieee_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lieee  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ieee_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ieee_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5
+echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6
+if test $ac_cv_lib_ieee_main = yes; then
+  MATH_LIBS="-lieee $MATH_LIBS"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking for main in -linet" >&5
+echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6
+if test "${ac_cv_lib_inet_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5
+echo "${ECHO_T}$ac_cv_lib_inet_main" >&6
+if test $ac_cv_lib_inet_main = yes; then
+  LIBS="$LIBS -linet"
+fi
+
+    if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking net/errno.h usability" >&5
+echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <net/errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking net/errno.h presence" >&5
+echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <net/errno.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: net/errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_net_errno_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
+
+fi
+if test $ac_cv_header_net_errno_h = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NET_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+if test $ac_cv_func_connect = yes; then
+  tcl_checkSocket=0
+else
+  tcl_checkSocket=1
+fi
+
+    if test "$tcl_checkSocket" = 1; then
+       echo "$as_me:$LINENO: checking for setsockopt" >&5
+echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6
+if test "${ac_cv_func_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define setsockopt to an innocuous variant, in case <limits.h> declares setsockopt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define setsockopt innocuous_setsockopt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char setsockopt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef setsockopt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char setsockopt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_setsockopt) || defined (__stub___setsockopt)
+choke me
+#else
+char (*f) () = setsockopt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != setsockopt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_setsockopt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_func_setsockopt" >&6
+if test $ac_cv_func_setsockopt = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5
+echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char setsockopt ();
+int
+main ()
+{
+setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_setsockopt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6
+if test $ac_cv_lib_socket_setsockopt = yes; then
+  LIBS="$LIBS -lsocket"
+else
+  tcl_checkBoth=1
+fi
+
+fi
+
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       echo "$as_me:$LINENO: checking for accept" >&5
+echo $ECHO_N "checking for accept... $ECHO_C" >&6
+if test "${ac_cv_func_accept+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define accept to an innocuous variant, in case <limits.h> declares accept.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define accept innocuous_accept
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char accept (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef accept
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char accept ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_accept) || defined (__stub___accept)
+choke me
+#else
+char (*f) () = accept;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != accept;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_accept=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_accept=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5
+echo "${ECHO_T}$ac_cv_func_accept" >&6
+if test $ac_cv_func_accept = yes; then
+  tcl_checkNsl=0
+else
+  LIBS=$tk_oldLibs
+fi
+
+    fi
+    echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+char (*f) () = gethostbyname;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != gethostbyname;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
+if test $ac_cv_func_gethostbyname = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  LIBS="$LIBS -lnsl"
+fi
+
+fi
+
+
+    # TEA specific: Don't perform the eval of the libraries here because
+    # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+
+
+
+
+    echo "$as_me:$LINENO: checking dirent.h" >&5
+echo $ECHO_N "checking dirent.h... $ECHO_C" >&6
+if test "${tcl_cv_dirent_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_dirent_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_dirent_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5
+echo "${ECHO_T}$tcl_cv_dirent_h" >&6
+
+    if test $tcl_cv_dirent_h = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DIRENT_H 1
+_ACEOF
+
+    fi
+
+    # TEA specific:
+    if test "${ac_cv_header_errno_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking errno.h usability" >&5
+echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking errno.h presence" >&5
+echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <errno.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_errno_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+
+fi
+if test $ac_cv_header_errno_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_float_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking float.h usability" >&5
+echo $ECHO_N "checking float.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <float.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking float.h presence" >&5
+echo $ECHO_N "checking float.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <float.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: float.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_float_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6
+
+fi
+if test $ac_cv_header_float_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_FLOAT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_values_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking values.h usability" >&5
+echo $ECHO_N "checking values.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <values.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking values.h presence" >&5
+echo $ECHO_N "checking values.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <values.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: values.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_values_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6
+
+fi
+if test $ac_cv_header_values_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_VALUES_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_limits_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking limits.h usability" >&5
+echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <limits.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking limits.h presence" >&5
+echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <limits.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: limits.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_limits_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6
+
+fi
+if test $ac_cv_header_limits_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIMITS_H 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_LIMITS_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking stdlib.h usability" >&5
+echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <stdlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking stdlib.h presence" >&5
+echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: stdlib.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_stdlib_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
+
+fi
+if test $ac_cv_header_stdlib_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtol" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtoul" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtod" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STDLIB_H 1
+_ACEOF
+
+    fi
+    if test "${ac_cv_header_string_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking string.h usability" >&5
+echo $ECHO_N "checking string.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <string.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking string.h presence" >&5
+echo $ECHO_N "checking string.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: string.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_string_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6
+
+fi
+if test $ac_cv_header_string_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strstr" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strerror" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STRING_H 1
+_ACEOF
+
+    fi
+
+    if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/wait.h usability" >&5
+echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <sys/wait.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/wait.h presence" >&5
+echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/wait.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_wait_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+
+fi
+if test $ac_cv_header_sys_wait_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking dlfcn.h usability" >&5
+echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <dlfcn.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking dlfcn.h presence" >&5
+echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <dlfcn.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_dlfcn_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+
+fi
+if test $ac_cv_header_dlfcn_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DLFCN_H 1
+_ACEOF
+
+fi
+
+
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+
+for ac_header in sys/param.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the vfs lists.  ##
+## ------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+
+
+
+    vars="vfs.c"
+    for i in $vars; do
+       case $i in
+           \$*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               # To add more dirs here (like 'src'), you have to update VPATH
+               # in Makefile.in as well
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5
+echo "$as_me: error: could not find source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+
+
+
+    vars="-I\"$(${CYGPATH} ${TCL_SRC_DIR}/generic)\""
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+
+
+
+    vars=""
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+
+    PKG_CFLAGS="$PKG_CFLAGS "
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5
+echo "$as_me: error: could not find stub source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+
+
+
+#TEA_PUBLIC_TCL_HEADERS
+
+    echo "$as_me:$LINENO: checking for Tcl public headers" >&5
+echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6
+
+
+# Check whether --with-tclinclude or --without-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then
+  withval="$with_tclinclude"
+  with_tclinclude=${withval}
+fi;
+
+    if test "${ac_cv_c_tclh+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5
+echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;}
+   { (exit 1); exit 1; }; }
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+
+fi
+
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       { { echo "$as_me:$LINENO: error: tcl.h not found.  Please specify its location with --with-tclinclude" >&5
+echo "$as_me: error: tcl.h not found.  Please specify its location with --with-tclinclude" >&2;}
+   { (exit 1); exit 1; }; }
+    else
+       echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5
+echo "${ECHO_T}${ac_cv_c_tclh}" >&6
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+
+
+
+    # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+
+    echo "$as_me:$LINENO: checking for Tcl private include files" >&5
+echo $ECHO_N "checking for Tcl private include files... $ECHO_C" >&6
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+    # Check to see if tcl<Plat>Port.h isn't already with the public headers
+    # Don't look for tclInt.h because that resides with tcl.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+       -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+       result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+       -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+       result="private headers found with public headers"
+    else
+       TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+       if test "${TEA_PLATFORM}" = "windows"; then
+           TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+       else
+           TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+       fi
+       # Overwrite the previous TCL_INCLUDES as this should capture both
+       # public and private headers in the same set.
+       # We want to ensure these are substituted so as not to require
+       # any *_NATIVE vars be defined in the Makefile
+       TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+       if test "`uname -s`" = "Darwin"; then
+            # If Tcl was built as a framework, attempt to use
+            # the framework's Headers and PrivateHeaders directories
+            case ${TCL_DEFS} in
+               *TCL_FRAMEWORK*)
+                   if test -d "${TCL_BIN_DIR}/Headers" -a \
+                           -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+                       TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+                   else
+                       TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+                   fi
+                   ;;
+           esac
+           result="Using ${TCL_INCLUDES}"
+       else
+           if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+               { { echo "$as_me:$LINENO: error: Cannot find private header tclInt.h in ${TCL_SRC_DIR}" >&5
+echo "$as_me: error: Cannot find private header tclInt.h in ${TCL_SRC_DIR}" >&2;}
+   { (exit 1); exit 1; }; }
+           fi
+           result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+       fi
+    fi
+
+
+
+
+    echo "$as_me:$LINENO: result: ${result}" >&5
+echo "${ECHO_T}${result}" >&6
+
+
+#--------------------------------------------------------------------
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_VFS in this case) so
+# that we create the export library with the dll.  See sha1.h on how
+# to use this.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
+# These will be appended to the current set of compiler flags for
+# your system.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    cat >>confdefs.h <<\_ACEOF
+#define BUILD_vfs 1
+_ACEOF
+
+    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+else
+    CLEANFILES="pkgIndex.tcl"
+fi
+
+
+
+    # Check whether --enable-threads or --disable-threads was given.
+if test "${enable_threads+set}" = set; then
+  enableval="$enable_threads"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_THREAD_ALLOC 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+           if test "`uname -s`" = "SunOS" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+           fi
+
+cat >>confdefs.h <<\_ACEOF
+#define _THREAD_SAFE 1
+_ACEOF
+
+           echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6
+if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char __pthread_mutex_init ();
+int
+main ()
+{
+__pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread___pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread___pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6
+if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6
+if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthreads_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthreads_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6
+if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6
+if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_c_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_c_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6
+if test $ac_cv_lib_c_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                   if test "$tcl_ok" = "no"; then
+                       echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6
+if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc_r  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_c_r_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_c_r_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6
+if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           { echo "$as_me:$LINENO: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5
+echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;}
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    echo "$as_me:$LINENO: checking for building with threads" >&5
+echo $ECHO_N "checking for building with threads... $ECHO_C" >&6
+    if test "${TCL_THREADS}" = 1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_THREADS 1
+_ACEOF
+
+       echo "$as_me:$LINENO: result: yes (default)" >&5
+echo "${ECHO_T}yes (default)" >&6
+    else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               { echo "$as_me:$LINENO: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&5
+echo "$as_me: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&2;}
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               { echo "$as_me:$LINENO: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&5
+echo "$as_me: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&2;}
+           fi
+           ;;
+    esac
+
+
+
+    echo "$as_me:$LINENO: checking how to build libraries" >&5
+echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6
+    # Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       echo "$as_me:$LINENO: result: shared" >&5
+echo "${ECHO_T}shared" >&6
+       SHARED_BUILD=1
+    else
+       echo "$as_me:$LINENO: result: static" >&5
+echo "${ECHO_T}static" >&6
+       SHARED_BUILD=0
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_BUILD 1
+_ACEOF
+
+    fi
+
+
+
+
+
+    # Step 0.a: Enable 64 bit support?
+
+    echo "$as_me:$LINENO: checking if 64bit support is requested" >&5
+echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6
+    # Check whether --enable-64bit or --disable-64bit was given.
+if test "${enable_64bit+set}" = set; then
+  enableval="$enable_64bit"
+  do64bit=$enableval
+else
+  do64bit=no
+fi;
+    echo "$as_me:$LINENO: result: $do64bit" >&5
+echo "${ECHO_T}$do64bit" >&6
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5
+echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6
+    # Check whether --enable-64bit-vis or --disable-64bit-vis was given.
+if test "${enable_64bit_vis+set}" = set; then
+  enableval="$enable_64bit_vis"
+  do64bitVIS=$enableval
+else
+  do64bitVIS=no
+fi;
+    echo "$as_me:$LINENO: result: $do64bitVIS" >&5
+echo "${ECHO_T}$do64bitVIS" >&6
+    # Force 64bit on with VIS
+    if test "$do64bitVIS" = "yes"; then
+  do64bit=yes
+fi
+
+
+    # Step 0.c: Check if visibility support is available. Do this here so
+    # that platform specific alternatives can be used below if this fails.
+
+    echo "$as_me:$LINENO: checking if compiler supports visibility \"hidden\"" >&5
+echo $ECHO_N "checking if compiler supports visibility \"hidden\"... $ECHO_C" >&6
+if test "${tcl_cv_cc_visibility_hidden+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+           extern __attribute__((__visibility__("hidden"))) void f(void);
+           void f(void) {}
+int
+main ()
+{
+f();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_visibility_hidden=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_visibility_hidden=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+       CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5
+echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6
+    if test $tcl_cv_cc_visibility_hidden = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define MODULE_SCOPE extern __attribute__((__visibility__("hidden")))
+_ACEOF
+
+
+fi
+
+
+    # Step 0.d: Disable -rpath support?
+
+    echo "$as_me:$LINENO: checking if rpath support is requested" >&5
+echo $ECHO_N "checking if rpath support is requested... $ECHO_C" >&6
+    # Check whether --enable-rpath or --disable-rpath was given.
+if test "${enable_rpath+set}" = set; then
+  enableval="$enable_rpath"
+  doRpath=$enableval
+else
+  doRpath=yes
+fi;
+    echo "$as_me:$LINENO: result: $doRpath" >&5
+echo "${ECHO_T}$doRpath" >&6
+
+    # TEA specific: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = windows; then
+
+       echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5
+echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6
+       # Check whether --enable-wince or --disable-wince was given.
+if test "${enable_wince+set}" = set; then
+  enableval="$enable_wince"
+  doWince=$enableval
+else
+  doWince=no
+fi;
+       echo "$as_me:$LINENO: result: $doWince" >&5
+echo "${ECHO_T}$doWince" >&6
+
+fi
+
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+
+    echo "$as_me:$LINENO: checking system version" >&5
+echo $ECHO_N "checking system version... $ECHO_C" >&6
+if test "${tcl_cv_sys_version+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       # TEA specific:
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5
+echo "$as_me: WARNING: can't find uname command" >&2;}
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $3}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5
+echo "${ECHO_T}$tcl_cv_sys_version" >&6
+    system=$tcl_cv_sys_version
+
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  have_dl=yes
+else
+  have_dl=no
+fi
+
+
+    # Require ranlib early so we can override it in special cases below.
+
+
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    if test "$GCC" = yes; then
+
+       # TEA specific:
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall -Wno-implicit-int"
+
+else
+  CFLAGS_WARNING=""
+fi
+
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+    # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    case $system in
+       # TEA specific:
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+                   { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5
+echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+                   do64bit="no"
+               else
+                   echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
+echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5
+echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               if test "$GCC" = "yes" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5
+echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+
+# Check whether --with-celib or --without-celib was given.
+if test "${with_celib+set}" = set; then
+  withval="$with_celib"
+  with_celibconfig=${withval}
+fi;
+       echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
+echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6
+       if test "${ac_cv_c_celibconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5
+echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+fi
+
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5
+echo "$as_me: error: Cannot find celib support library directory" >&2;}
+   { (exit 1); exit 1; }; }
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5
+echo "${ECHO_T}found $CELIB_DIR" >&6
+       fi
+    fi
+
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
+           if ($1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
+           if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
+           if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5
+echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;}
+   { (exit 1); exit 1; }; }
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+
+    vars="bufferoverflowU.lib"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower($0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+
+cat >>confdefs.h <<_ACEOF
+#define $i 1
+_ACEOF
+
+                   done
+
+cat >>confdefs.h <<_ACEOF
+#define _WIN32_WCE $CEVERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNDER_CE $CEVERSION
+_ACEOF
+
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # and also
+               # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug -debugtype:cv"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then
+
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r)
+                       # ok ...
+                       ;;
+                   *)
+                       CC=${CC}_r
+                       ;;
+               esac
+               echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5
+echo "${ECHO_T}Using $CC for compiling with threads" >&6
+
+fi
+
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           if test "$do64bit" = yes -a "`uname -v`" -gt 3; then
+
+               if test "$GCC" = yes; then
+
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+
+else
+
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+
+fi
+
+
+fi
+
+
+           if test "`uname -m`" = ia64; then
+
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               if test "$GCC" = yes; then
+
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+
+else
+
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+
+fi
+
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+
+else
+
+               if test "$GCC" = yes; then
+  SHLIB_LD='${CC} -shared'
+else
+
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+
+fi
+
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               # TEA specific: use PACKAGE_VERSION instead of VERSION
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+
+fi
+
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           if test "$system" = "AIX-4.1" -o "`uname -v`" -lt 4; then
+
+               case $LIBOBJS in
+    "tclLoadAix.$ac_objext"   | \
+  *" tclLoadAix.$ac_objext"   | \
+    "tclLoadAix.$ac_objext "* | \
+  *" tclLoadAix.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;;
+esac
+
+               DL_LIBS="-lld"
+
+fi
+
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5
+echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6
+if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gettimeofday ();
+int
+main ()
+{
+gettimeofday ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bsd_gettimeofday=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bsd_gettimeofday=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5
+echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6
+if test $ac_cv_lib_bsd_gettimeofday = yes; then
+  libbsd=yes
+else
+  libbsd=no
+fi
+
+           if test $libbsd = yes; then
+
+               MATH_LIBS="$MATH_LIBS -lbsd"
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_DELTA_FOR_TZ 1
+_ACEOF
+
+
+fi
+
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -nostart'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5
+echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6
+if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbind  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_ntoa ();
+int
+main ()
+{
+inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bind_inet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bind_inet_ntoa=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6
+if test $ac_cv_lib_bind_inet_ntoa = yes; then
+  LIBS="$LIBS -lbind -lsocket"
+fi
+
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD='${CC} -shared'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+
+cat >>confdefs.h <<\_ACEOF
+#define _XOPEN_SOURCE_EXTENDED 1
+_ACEOF
+
+           # TEA specific: Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           if test "`uname -m`" = ia64; then
+
+               SHLIB_SUFFIX=".so"
+               # Use newer C++ library for C++ extensions
+               #if test "$GCC" != "yes" ; then
+               #   CPPFLAGS="-AA"
+               #fi
+
+else
+
+               SHLIB_SUFFIX=".sl"
+
+fi
+
+           echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+
+fi
+
+           if test "$GCC" = yes; then
+
+               SHLIB_LD='${CC} -shared'
+               SHLIB_LD_LIBS='${LIBS}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+fi
+
+
+           # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+           #CFLAGS="$CFLAGS +DAportable"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes"; then
+
+               if test "$GCC" = yes; then
+
+                   case `${CC} -dumpmachine` in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD='${CC} -shared'
+                           SHLIB_LD_LIBS='${LIBS}'
+                           if test $doRpath = yes; then
+
+                               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+                           ;;
+                   esac
+
+else
+
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+
+fi
+
+
+fi
+ ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+
+fi
+ ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           if test "$GCC" = yes; then
+
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+
+else
+
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+
+fi
+
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           if test "$do64bit" = yes; then
+
+               if test "$GCC" = yes; then
+
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5
+echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
+
+else
+
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+
+fi
+
+
+fi
+
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           # TEA specific:
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "`uname -m`" = "alpha"; then
+  CFLAGS="$CFLAGS -mieee"
+fi
+
+           if test $do64bit = yes; then
+
+               echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_m64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_m64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_m64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                   CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5
+echo "${ECHO_T}$tcl_cv_cc_m64" >&6
+               if test $tcl_cv_cc_m64 = yes; then
+
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+
+fi
+
+
+fi
+
+
+           # The combo of gcc + glibc has a bug related to inlining of
+           # functions like strtod(). The -fno-builtin flag should address
+           # this problem but it does not work. The -fno-inline flag is kind
+           # of overkill but it works. Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+
+           if test x"${USE_COMPAT}" != x; then
+  CFLAGS="$CFLAGS -fno-inline"
+fi
+
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD='${CC} -shared'
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           if test "`uname -m`" = "alpha"; then
+  CFLAGS="$CFLAGS -mieee"
+fi
+
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD='${CC} -shared'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-1.*|FreeBSD-[1-2].*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6
+           if test $tcl_cv_ld_elf = yes; then
+
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+
+else
+
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+
+fi
+
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6
+           if test $tcl_cv_ld_elf = yes; then
+
+               LDFLAGS=-Wl,-export-dynamic
+
+else
+  LDFLAGS=""
+fi
+
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       NetBSD-*|FreeBSD-*)
+           # FreeBSD 3.* and greater have ELF.
+           # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "${TCL_THREADS}" = "1"; then
+
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+
+fi
+
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           # To avoid discrepancies between what headers configure sees during
+           # preprocessing tests and compiling tests, move any -isysroot and
+           # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+           CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
+           CFLAGS="`echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
+           if test $do64bit = yes; then
+
+               case `arch` in
+                   ppc)
+                       echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_arch_ppc64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_arch_ppc64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_arch_ppc64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6
+                       if test $tcl_cv_cc_arch_ppc64 = yes; then
+
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+
+fi
+;;
+                   i386)
+                       echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_arch_x86_64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_arch_x86_64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_arch_x86_64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6
+                       if test $tcl_cv_cc_arch_x86_64 = yes; then
+
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+
+fi
+;;
+                   *)
+                       { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
+               esac
+
+else
+
+               # Check for combined 32-bit and 64-bit fat build
+               if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+                   && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then
+
+                   fat_32_64=yes
+fi
+
+
+fi
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5
+echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_single_module+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_single_module=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_single_module=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5
+echo "${ECHO_T}$tcl_cv_ld_single_module" >&6
+           if test $tcl_cv_ld_single_module = yes; then
+
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+
+fi
+
+           # TEA specific: link shlib with current and compatiblity version flags
+           vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([0-9]\{1,5\}\)\(\(\.[0-9]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+           SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
+               "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then
+
+               LDFLAGS="$LDFLAGS -prebind"
+fi
+
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5
+echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_search_paths_first+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_search_paths_first=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_search_paths_first=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5
+echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6
+           if test $tcl_cv_ld_search_paths_first = yes; then
+
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+
+fi
+
+           if test "$tcl_cv_cc_visibility_hidden" != yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define MODULE_SCOPE __private_extern__
+_ACEOF
+
+
+fi
+
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+           # TEA specific: for combined 32 & 64 bit fat builds of Tk
+           # extensions, verify that 64-bit build is possible.
+           if test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"; then
+
+               if test "${TEA_WINDOWINGSYSTEM}" = x11; then
+
+                   echo "$as_me:$LINENO: checking for 64-bit X11" >&5
+echo $ECHO_N "checking for 64-bit X11... $ECHO_C" >&6
+if test "${tcl_cv_lib_x11_64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+                       done
+                       CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+                       LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+                       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_lib_x11_64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_lib_x11_64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval $v'="$hold_'$v'"'
+                       done
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_lib_x11_64" >&5
+echo "${ECHO_T}$tcl_cv_lib_x11_64" >&6
+
+fi
+
+               # remove 64-bit arch flags from CFLAGS et al. if configuration
+               # does not support 64-bit.
+               if test "${TEA_WINDOWINGSYSTEM}" = aqua -o "$tcl_cv_lib_x11_64" = no; then
+
+                   { echo "$as_me:$LINENO: Removing 64-bit architectures from compiler & linker flags" >&5
+echo "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;}
+                   for v in CFLAGS CPPFLAGS LDFLAGS; do
+                       eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+                   done
+fi
+
+
+fi
+
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD='${CC} -nostdlib -r'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+
+cat >>confdefs.h <<\_ACEOF
+#define _OE_SOCKETS 1
+_ACEOF
+
+           ;;
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export :'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           if test "$SHARED_BUILD" = 1; then
+  SHLIB_LD="ld -shared"
+else
+
+               SHLIB_LD="ld -non_shared"
+
+fi
+
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           if test "$SHARED_BUILD" = 1; then
+
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+
+else
+
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+
+fi
+
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           if test "$GCC" = yes; then
+  CFLAGS="$CFLAGS -mieee"
+else
+
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+fi
+
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           if test "${TCL_THREADS}" = 1; then
+
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               if test "$GCC" = yes; then
+
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+
+else
+
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+
+fi
+
+
+fi
+
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           if test "$GCC" = yes; then
+
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+
+else
+
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+
+fi
+
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[0-6])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = yes; then
+
+               SHLIB_LD='${CC} -shared'
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+else
+
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+fi
+
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = yes; then
+
+               arch=`isainfo`
+               if test "$arch" = "sparcv9 sparc"; then
+
+                   if test "$GCC" = yes; then
+
+                       if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then
+
+                           { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
+
+else
+
+                           do64bit_ok=yes
+                           CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                           LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                           SHLIB_CFLAGS="-fPIC"
+
+fi
+
+
+else
+
+                       do64bit_ok=yes
+                       if test "$do64bitVIS" = yes; then
+
+                           CFLAGS="$CFLAGS -xarch=v9a"
+                           LDFLAGS_ARCH="-xarch=v9a"
+
+else
+
+                           CFLAGS="$CFLAGS -xarch=v9"
+                           LDFLAGS_ARCH="-xarch=v9"
+
+fi
+
+                       # Solaris 64 uses this as well
+                       #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+
+fi
+
+
+else
+  if test "$arch" = "amd64 i386"; then
+
+                   if test "$GCC" = yes; then
+
+                       case $system in
+                           SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64"
+                               LDFLAGS="$LDFLAGS -m64";;
+                           *)
+                               { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
+                       esac
+
+else
+
+                       do64bit_ok=yes
+                       case $system in
+                           SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
+                               CFLAGS="$CFLAGS -m64"
+                               LDFLAGS="$LDFLAGS -m64";;
+                           *)
+                               CFLAGS="$CFLAGS -xarch=amd64"
+                               LDFLAGS="$LDFLAGS -xarch=amd64";;
+                       esac
+
+fi
+
+
+else
+  { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5
+echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+fi
+
+fi
+
+
+fi
+
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = yes; then
+
+               SHLIB_LD='${CC} -shared'
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               if test "$do64bit_ok" = yes; then
+
+                   if test "$arch" = "sparcv9 sparc"; then
+
+                       # We need to specify -static-libgcc or we need to
+                       # add the path to the sparv9 libgcc.
+                       # JH: static-libgcc is necessary for core Tcl, but may
+                       # not be necessary for extensions.
+                       SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                       # for finding sparcv9 libgcc, get the regular libgcc
+                       # path, remove so name and append 'sparcv9'
+                       #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                       #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+
+else
+  if test "$arch" = "amd64 i386"; then
+
+                       # JH: static-libgcc is necessary for core Tcl, but may
+                       # not be necessary for extensions.
+                       SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+
+fi
+
+fi
+
+
+fi
+
+
+else
+
+               case $system in
+                   SunOS-5.[1-9][0-9]*)
+                       SHLIB_LD='${CC} -G -z text ${LDFLAGS}';;
+                   *)
+                       SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+               esac
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+
+fi
+
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5
+echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_Bexport+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_Bexport=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_Bexport=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5
+echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6
+           if test $tcl_cv_ld_Bexport = yes; then
+
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+
+fi
+
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    if test "$do64bit" = yes -a "$do64bit_ok" = no; then
+
+       { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+
+fi
+
+
+
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    # Check whether --enable-load or --disable-load was given.
+if test "${enable_load+set}" = set; then
+  enableval="$enable_load"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+    if test "$tcl_ok" = no; then
+  DL_OBJS=""
+fi
+
+
+    if test "x$DL_OBJS" != x; then
+  BUILD_DLTEST="\$(DLTEST_TARGETS)"
+else
+
+       { echo "$as_me:$LINENO: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5
+echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;}
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+
+fi
+
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then
+
+       case $system in
+           AIX-*) ;;
+           BSD/OS*) ;;
+           IRIX*) ;;
+           NetBSD-*|FreeBSD-*) ;;
+           Darwin-*) ;;
+           SCO_SV-3.2*) ;;
+           *) SHLIB_CFLAGS="-fPIC" ;;
+       esac
+fi
+
+
+    if test "$SHARED_LIB_SUFFIX" = ""; then
+
+       # TEA specific: use PACKAGE_VERSION instead of VERSION
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+fi
+
+    if test "$UNSHARED_LIB_SUFFIX" = ""; then
+
+       # TEA specific: use PACKAGE_VERSION instead of VERSION
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+
+    echo "$as_me:$LINENO: checking for required early compiler flags" >&5
+echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6
+    tcl_flags=""
+
+    if test "${tcl_cv_flag__isoc99_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__isoc99_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__isoc99_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__isoc99_source=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _ISOC99_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _ISOC99_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile64_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile64_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE64_SOURCE 1
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile64_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__largefile64_source=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE64_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile_source64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile_source64=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE_SOURCE64 1
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile_source64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__largefile_source64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE_SOURCE64 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
+    fi
+
+    if test "x${tcl_flags}" = "x" ; then
+       echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+    else
+       echo "$as_me:$LINENO: result: ${tcl_flags}" >&5
+echo "${ECHO_T}${tcl_flags}" >&6
+    fi
+
+
+    echo "$as_me:$LINENO: checking for 64-bit integer type" >&5
+echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6
+    if test "${tcl_cv_type_64bit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__int64 value = (__int64) 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_type_64bit=__int64
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_type_64bit="long long"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+switch (0) {
+            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+        }
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_type_64bit=${tcl_type_64bit}
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "${tcl_cv_type_64bit}" = none ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_WIDE_INT_IS_LONG 1
+_ACEOF
+
+       echo "$as_me:$LINENO: result: using long" >&5
+echo "${ECHO_T}using long" >&6
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # TEA specific: We actually want to use the default tcl.h checks in
+       # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       echo "$as_me:$LINENO: result: using Tcl header defaults" >&5
+echo "${ECHO_T}using Tcl header defaults" >&6
+    else
+
+cat >>confdefs.h <<_ACEOF
+#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
+_ACEOF
+
+       echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5
+echo "${ECHO_T}${tcl_cv_type_64bit}" >&6
+
+       # Now check for auxiliary declarations
+       echo "$as_me:$LINENO: checking for struct dirent64" >&5
+echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6
+if test "${tcl_cv_struct_dirent64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/dirent.h>
+int
+main ()
+{
+struct dirent64 p;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_struct_dirent64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_struct_dirent64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5
+echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_DIRENT64 1
+_ACEOF
+
+       fi
+
+       echo "$as_me:$LINENO: checking for struct stat64" >&5
+echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6
+if test "${tcl_cv_struct_stat64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 p;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_struct_stat64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_struct_stat64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5
+echo "${ECHO_T}$tcl_cv_struct_stat64" >&6
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_STAT64 1
+_ACEOF
+
+       fi
+
+
+
+for ac_func in open64 lseek64
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+       echo "$as_me:$LINENO: checking for off64_t" >&5
+echo $ECHO_N "checking for off64_t... $ECHO_C" >&6
+       if test "${tcl_cv_type_off64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+off64_t offset;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_type_off64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_type_off64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+                       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TYPE_OFF64_T 1
+_ACEOF
+
+           echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+           echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+       fi
+    fi
+
+
+
+
+    echo "$as_me:$LINENO: checking for build with symbols" >&5
+echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6
+    # Check whether --enable-symbols or --disable-symbols was given.
+if test "${enable_symbols+set}" = set; then
+  enableval="$enable_symbols"
+  tcl_ok=$enableval
+else
+  tcl_ok=no
+fi;
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
+echo "${ECHO_T}yes (standard debugging)" >&6
+       fi
+    fi
+    # TEA specific:
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+
+
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_MEM_DEBUG 1
+_ACEOF
+
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5
+echo "${ECHO_T}enabled symbols mem debugging" >&6
+       else
+           echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
+echo "${ECHO_T}enabled $tcl_ok debugging" >&6
+       fi
+    fi
+
+
+if test "${SHARED_BUILD}" = "1"; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_TCL_STUBS 1
+_ACEOF
+
+fi
+
+
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+
+
+
+
+
+
+
+
+    echo "$as_me:$LINENO: checking for tclsh" >&5
+echo $ECHO_N "checking for tclsh... $ECHO_C" >&6
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+    fi
+    echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5
+echo "${ECHO_T}${TCLSH_PROG}" >&6
+
+
+
+                              ac_config_files="$ac_config_files Makefile pkgIndex.tcl library/vfs.tcl"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by vfs $as_me 1.4.1, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+vfs config.status 1.4.1
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "pkgIndex.tcl" ) CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;;
+  "library/vfs.tcl" ) CONFIG_FILES="$CONFIG_FILES library/vfs.tcl" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CYGPATH@,$CYGPATH,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t
+s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t
+s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t
+s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t
+s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t
+s,@PKG_HEADERS@,$PKG_HEADERS,;t t
+s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t
+s,@PKG_LIBS@,$PKG_LIBS,;t t
+s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t
+s,@TCL_VERSION@,$TCL_VERSION,;t t
+s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
+s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t
+s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t
+s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t
+s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t
+s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t
+s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t
+s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t
+s,@TCL_LIBS@,$TCL_LIBS,;t t
+s,@TCL_DEFS@,$TCL_DEFS,;t t
+s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t
+s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t
+s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@EGREP@,$EGREP,;t t
+s,@MATH_LIBS@,$MATH_LIBS,;t t
+s,@PKG_SOURCES@,$PKG_SOURCES,;t t
+s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t
+s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t
+s,@TCL_TOP_DIR_NATIVE@,$TCL_TOP_DIR_NATIVE,;t t
+s,@CLEANFILES@,$CLEANFILES,;t t
+s,@TCL_THREADS@,$TCL_THREADS,;t t
+s,@SHARED_BUILD@,$SHARED_BUILD,;t t
+s,@AR@,$AR,;t t
+s,@CELIB_DIR@,$CELIB_DIR,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@DL_LIBS@,$DL_LIBS,;t t
+s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t
+s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t
+s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
+s,@STLIB_LD@,$STLIB_LD,;t t
+s,@SHLIB_LD@,$SHLIB_LD,;t t
+s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t
+s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t
+s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t
+s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t
+s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t
+s,@TCL_DBGX@,$TCL_DBGX,;t t
+s,@MAKE_LIB@,$MAKE_LIB,;t t
+s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t
+s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t
+s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t
+s,@RANLIB_STUB@,$RANLIB_STUB,;t t
+s,@TCLSH_PROG@,$TCLSH_PROG,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/8.x/tclvfs/configure.in b/8.x/tclvfs/configure.in
new file mode 100644 (file)
index 0000000..690c839
--- /dev/null
@@ -0,0 +1,83 @@
+#!/bin/bash -norc
+dnl    This file is an input file used by the GNU "autoconf" program to
+dnl    generate the file "configure", which is run during Tcl installation
+dnl    to configure the system for the local environment.
+#
+# RCS: @(#) $Id: configure.in,v 1.19 2009/02/06 19:13:27 andreas_kupries Exp $
+
+#--------------------------------------------------------------------
+# This configure.in is based on the Tcl Extension Architecture (TEA)
+# v3 spec.  See the sampleextension module for a fully commented
+# version of the configure.in and makefiles to build your own extension.
+#    http://tcl.sourceforge.net/  'sampleextension' cvs module
+#    http://www.tcl.tk/           Tcl Developer Exchange
+#--------------------------------------------------------------------
+
+AC_INIT([vfs], [1.4.1])
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+TEA_INIT([3.7])
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+TEA_PREFIX
+
+TEA_SETUP_COMPILER
+
+TEA_ADD_SOURCES([vfs.c])
+TEA_ADD_HEADERS([])
+TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${TCL_SRC_DIR}/generic)\"])
+TEA_ADD_LIBS([])
+TEA_ADD_CFLAGS([])
+TEA_ADD_STUB_SOURCES([])
+TEA_ADD_TCL_SOURCES([])
+
+#TEA_PUBLIC_TCL_HEADERS
+TEA_PRIVATE_TCL_HEADERS
+
+#--------------------------------------------------------------------
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_VFS in this case) so
+# that we create the export library with the dll.  See sha1.h on how
+# to use this.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
+# These will be appended to the current set of compiler flags for
+# your system.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    AC_DEFINE(BUILD_vfs)
+    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+else
+    CLEANFILES="pkgIndex.tcl"
+fi
+AC_SUBST(CLEANFILES)
+
+TEA_ENABLE_THREADS
+TEA_ENABLE_SHARED
+TEA_CONFIG_CFLAGS
+TEA_ENABLE_SYMBOLS
+
+if test "${SHARED_BUILD}" = "1"; then
+AC_DEFINE(USE_TCL_STUBS)
+fi
+
+TEA_MAKE_LIB
+
+TEA_PROG_TCLSH
+
+AC_OUTPUT([Makefile pkgIndex.tcl library/vfs.tcl])
diff --git a/8.x/tclvfs/doc/vfs-filesystems.man b/8.x/tclvfs/doc/vfs-filesystems.man
new file mode 100644 (file)
index 0000000..f25b02a
--- /dev/null
@@ -0,0 +1,95 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin vfs-filesystems n 1.0]
+[copyright {2001-2003 Vince Darley <vincentdarley@users.sourceforge.net>}]
+[copyright {2003 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc   {Tcl-level Virtual Filesystems}]
+[titledesc {Filesystems provided by tclvfs}]
+[require Tcl 8.4]
+[require vfs [opt 1.2.1]]
+[require vfs::zip     [opt 1.0]]
+[require vfs::mk4     [opt 1.6]]
+[require vfs::tar     [opt 0.9]]
+[require vfs::ftp     [opt 1.0]]
+[require vfs::ns      [opt 1.0]]
+[require vfs::webdav  [opt 0.1]]
+[require vfs::http    [opt 0.5]]
+[require vfs::urltype [opt 1.0]]
+[description]
+
+The package [package vfs] provides not only the means to implement a
+virtual filesystem at the tcl level, but also a number of ready to be
+used filesystems as well.
+
+[para]
+
+Each of these filesystem exists as its own package, and can be
+accessed through [cmd {package require vfs::NAME}].
+
+The whole set of these virtual filesystems is known informally as
+'[term vfslib]'.
+
+[section {SUPPORTED VFS TYPES}]
+
+Currently supported are ftp, tar, http, zip, mk4, ns, and webdav.
+
+In addition there is the ability to mount any 'urltype' as a new
+directory, provided an appropriate vfs is supported.  This means that
+you can treat urls based on the schemes [emph ftp://], [emph http://]
+and [emph file://] as files.  To do this, simply evaluate the command
+
+[cmd {vfs::urltype::Mount ftp}]
+
+for example.  Any access inside the new volume will result in an
+attempt to require a package through
+
+[cmd {package require vfs::${type}}], which must therefore exist, or
+errors will be thrown.
+
+If a filesystem is loaded, use the associated command listed below to
+mount a source for that filesystem as a tcl directory.
+
+[list_begin definitions]
+[call [cmd vfs::zip::Mount] [arg path] [arg to]]
+
+Mount the zip file [arg path] as directory [arg to].
+
+[call [cmd vfs::mk4::Mount] [arg path] [arg to]]
+
+Mount the metakit database file file [arg path] as directory [arg to].
+
+[call [cmd vfs::tar::Mount] [arg path] [arg to]]
+
+Mount the tar file [arg path] as directory [arg to].
+
+[call [cmd vfs::ftp::Mount] [arg path] [arg to]]
+
+Mount the ftp url [arg path] as directory [arg to].
+
+[call [cmd vfs::ns::Mount] [arg path] [arg to]]
+
+Mount the tcl namespace [arg path] as directory [arg to].
+
+[call [cmd vfs::webdav::Mount] [arg path] [arg to]]
+
+Mount the webdav url [arg path] as directory [arg to].
+
+[call [cmd vfs::http::Mount] [arg path] [arg to]]
+
+Mount the http url [arg path] as directory [arg to].
+
+[call [cmd vfs::urltype::Mount] [arg path] [arg to]]
+
+Mount the url [arg path], of type [arg urltype] as directory [arg to].
+
+[list_end]
+
+
+[section LIMITATIONS]
+
+Most of the vfs types listed above have not been very well debugged as
+yet.  Please test them!
+
+
+[see_also vfs vfs-fsapi]
+[keywords vfs filesystem file vfslib zip tar webdav ftp http namespace metakit]
+[manpage_end]
diff --git a/8.x/tclvfs/doc/vfs-fsapi.man b/8.x/tclvfs/doc/vfs-fsapi.man
new file mode 100644 (file)
index 0000000..ba5c32e
--- /dev/null
@@ -0,0 +1,413 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin vfs-fsapi n 1.0]
+[copyright {2001-2003 Vince Darley <vincentdarley@users.sourceforge.net>}]
+[copyright {2003 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc   {Tcl-level Virtual Filesystems}]
+[titledesc {API for the implementation of a filesystem in Tcl}]
+[require Tcl 8.4]
+[require vfs [opt 1.2.1]]
+[description]
+
+This document explains the API used by the package [package vfs]
+to communicate with filesystem implementations written in tcl.
+
+[section {HANDLER OVERVIEW}]
+
+The package [package vfs] intercepts every filesystem operation which
+falls within a given mount point, and passes the operation on to the
+mount point's [cmd vfshandler] command in the interpreter which
+registered it.
+
+[para]
+
+If the handler takes appropriate action for each of the cases it is
+called for, a complete, perfect virtual filesystem will be achieved,
+indistinguishable to Tcl from the native filesystem.
+
+(CAVEATS: Right now [package vfs] does not expose to Tcl all the
+permission-related flags of [cmd glob]).
+
+[para]
+[list_begin definitions]
+
+[call [cmd vfshandler] [arg subcmd] [arg root] [arg relative] [arg actualpath] [arg args]...]
+
+The first argument specifies the operation to perform on behalf of the
+filesystem code in the tcl core, the remainder specify the file path
+on which to operate, in different forms, and parts, and any additional
+arguments which may be required to carry out the action.
+
+[nl]
+
+To demonstrate the treatment of a path by the generic layer we use
+[file C:/foo/bar/mount.zip/xxx/yyy] as an example and additionally
+assume that the following conditions are true:
+
+[list_begin enum]
+[enum]
+[file mount.zip] is a zip archive which has been mounted on top of
+itself,
+[enum]
+said zip archive contains a file with path [file xxx/yyy],
+[enum]
+the current working directory of the application is inside of
+directory [file xxx],
+[enum]
+and the command executed is [cmd {file exists yyy}].
+[list_end]
+[nl]
+
+The file separator between [arg root] and [arg relative] is omitted.
+Most filesystem operations need only the [arg relative] argument for
+their correct operation, but some actually require the other parts of
+the path.
+
+
+[list_begin definitions]
+
+[lst_item [arg subcmd]]
+
+This argument of the handler can be one of the following
+[method access], [method createdirectory], [method deletefile],
+[method fileattributes], [method matchindirectory], [method open],
+[method removedirectory], [method stat], or [method utime].
+
+[nl]
+
+The generic layer expects that the subcommands of a handler signal
+error conditions by calling [cmd {vfs::filesystem posixerror}] with
+the appropriate posix error code instead of throwing a tcl error. If
+the latter is done nevertheless it will be treated as an unknown posix
+error.
+
+[nl]
+
+There are three exceptions to the rule above: If any of [method open]
+(when an interpreter is given), [method matchindirectory], and
+
+[method fileattributes] (for a set or get operation only) throw a tcl
+error, this error will be passed up to the caller of the filesystem
+command which invoked the handler. Note that this does not preclude
+the ability of these subcommands to use the command
+
+[cmd {vfs::filesystem posixerror}] to report more regular filesystem
+errors.
+
+
+[lst_item [arg root]]
+
+Part of the specification of the path to operate upon. It contains the
+part of the path which lies outside this filesystem's mount point. For
+example outlined above its value will be [file C:/foo/bar/mount.zip].
+
+[lst_item [arg relative]]
+
+Part of the specification of the path to operate upon. It contains the
+part of the path which lies inside this filesystem. For example
+outlined above its value will be [file xxx/yyy].
+
+[lst_item [arg actualpath]]
+
+Part of the specification of the path to operate upon. It contains the
+original (unnormalized) name of the path which was used in the current
+command wherever it originated (in Tcl or C). For example outlined
+above its value will be [file yyy].
+
+[list_end]
+[list_end]
+
+[section {HANDLER METHODS}]
+[list_begin definitions]
+
+
+[call [cmd vfshandler] [method access] [arg root] [arg relative] [arg actualpath] [arg mode]]
+
+Signal a posix error if the specified access [arg mode] (an integer
+number) is not compatible with the file or directory described by the
+path. The generic layer will ignore any non-empty return value.
+
+[nl]
+
+The command [cmd vfs::accessMode] (see section
+
+[sectref {HANDLER ENVIRONMENT}]) can be used to convert the integer
+[arg mode] into an easier to check string value.
+
+
+[call [cmd vfshandler] [method createdirectory] [arg root] [arg relative] [arg actualpath]]
+
+Create a directory with the given name.  The command can assume that
+all sub-directories in the path exist and are valid, and that the
+actual desired path does not yet exist (Tcl takes care of all of that
+for us).
+
+
+[call [cmd vfshandler] [method deletefile] [arg root] [arg relative] [arg actualpath]]
+
+Delete the given file.
+
+
+[call [cmd vfshandler] [method fileattributes] [arg root] [arg relative] [arg actualpath] [opt [arg index]] [opt [arg value]]]
+
+The command has to return a list containing the names of all
+acceptable attributes, if neither [arg index] nor [arg value] were
+specified.
+
+[nl]
+
+The command has to return the value of the [arg index]'th attribute if
+the [arg index] is specified, but not the [arg value]. The attributes
+are counted in the same order as their names appear in the list
+returned by a call where neither [arg index] nor [arg value] were
+specified. The first attribute is has the index [const 0].
+
+[nl]
+
+The command has to set the value of the [arg index]'th attribute to
+[arg value] if both [arg index] and [arg value] were specified for the
+call.
+
+
+[call [cmd vfshandler] [method matchindirectory] [arg root] [arg relative] [arg actualpath] [arg pattern] [arg types]]
+
+Return the list of files or directories in the given path which match
+the glob [arg pattern] and are compatible with the specified list of
+[arg types]. The specified path is always the name of an existing
+directory.
+
+[nl]
+
+[emph Note:] As Tcl generates requests for directory-only matches from
+the filesystems involved when performing any type of recursive
+globbing this subcommand absolutely has to handle such (and file-only)
+requests correctly or bad things (TM) will happen.
+
+[nl]
+
+The commands [cmd vfs::matchDirectories] and [cmd vfs::matchFiles]
+(see section [sectref {HANDLER ENVIRONMENT}]) can aid the
+implementation greatly in this task.
+
+
+[call [cmd vfshandler] [method open] [arg root] [arg relative] [arg actualpath] [arg mode] [arg permissions]]
+
+Either returns a list describing the successfully opened file, or
+throws an error describing how the operation failed.
+
+[nl]
+
+The list returned upon success contains at least one and at most two
+elements. The first, obligatory, element is always the handle of the
+channel which was created to allow access to the contents of the
+file.
+
+[nl]
+
+If specified the second element will be interpreted as a callback,
+i.e. a command prefix. This prefix will always be executed as is,
+i.e. without additional arguments. Any required arguments have to be
+returned as part of the result of the call to [method open].
+
+[nl]
+
+If present the specified callback will be evaluated just before the
+channel is closed [emph {by the generic filesystem layer}]. The
+callback itself [emph {must not}] call [cmd close].
+
+[nl]
+
+The channel however is live enough to allow [cmd seek] and [cmd read]
+operations. In addition all available data will have been flushed into
+it already. This means, for example, that the callback can seek to the
+beginning of the said channel, read its contents and then store the
+gathered data elsewhere. In other words, this callback is not only
+crucial to the cleanup of any resources associated with an opened
+file, but also for the ability to implement a filesystem which can be
+written to.
+
+[nl]
+
+Under normal circumstances return code and any errors thrown by the
+callback itself are ignored. In that case errors have to be signaled
+asychronously, for example by calling [cmd bgerror].
+
+However if, through a call of the subcommand [method internalerror],
+an error handling script has been specified for the file system, all
+errors thrown here will be passed to that script for further action.
+
+
+[list_begin definitions]
+
+[lst_item [arg mode]]
+can be any of [const r], [const w], [const a], [const w+], or [const a+].
+
+[lst_item [arg permissions]]
+determines the native mode the openend file is created with. Relevant
+only of the open [arg mode] actually requests the creation of a
+non-existing file, i.e. is not [const r].
+
+[list_end]
+[nl]
+
+[call [cmd vfshandler] [method removedirectory] [arg root] [arg relative] [arg actualpath] [arg recursive]]
+
+Delete the given directory. Argument [arg recursive] is a boolean. If
+the specified value is [const true] then even if the directory is
+non-empty, an attempt has to be made to recursively delete it and its
+contents.  If the spcified value is [const false] and the directory is
+non-empty, a posix error ([const EEXIST]) has to be thrown.
+
+
+[call [cmd vfshandler] [method stat] [arg root] [arg relative] [arg actualpath]]
+
+The result has to be a list of keys and values, in a format acceptable
+to the builtin command [cmd {array set}]. It describes the contents of
+a stat structure. The order of the keys in the list is not important.
+
+[nl]
+
+Given this the subcommand should use something like 
+
+[example {return [list dev 0 type file mtime 1234 ...].}]
+
+as the last command of its implementation.
+
+[nl]
+
+The following keys and their values have to be supplied by the
+filesystem:
+
+[list_begin definitions]
+[lst_item [const dev]]
+
+A long integer number, the device number of the path stat was called for.
+
+[lst_item [const ino]]
+
+A long integer number, the inode number of the path stat was called for.
+
+Each path handled by the filesystem should be uniquely identified by
+the combination of device and inode number. Violating this principle
+will cause higher-level algorithms which(have to) keep track of device
+and inode information to fail in all manners possible.
+
+[nl]
+
+An example of such an algorithm would be a directory walker using
+device/inode information to keep itself out of infinite loops
+generated through symbolic links. Returning non-unique device/inode
+information will most likely cause such a walker to skip over paths
+under the wrong assumption of having them seen already.
+
+[lst_item [const mode]]
+
+An integer number, the access mode of the path. It is this mode which
+is checked by the subcommand [method access].
+
+[lst_item [const nlink]]
+
+A long integer number, the number of hard links to the specified path.
+
+[lst_item [const uid]]
+
+A long integer number, the id of the user owning the virtual path.
+
+[lst_item [const gid]]
+
+A long integer number, the id of the user group the virtual path
+belongs to.
+
+[lst_item [const size]]
+
+A long integer number, the true size of the virtual path, in bytes.
+
+[lst_item [const atime]]
+
+A long integer number, the time of the latest access to the path, in
+seconds since the epoch. Convertible into a readable date/time by the
+command [cmd {clock format}].
+
+[lst_item [const mtime]]
+
+A long integer number, the time of the latest modification of the
+path, in seconds since the epoch. Convertible into a readable
+date/time by the command [cmd {clock format}].
+
+[lst_item [const ctime]]
+
+A long integer number, the time of the path was created, in seconds
+since the epoch. Convertible into a readable date/time by the command
+[cmd {clock format}].
+
+[lst_item [const type]]
+
+A string, either [const directory], or [const file], describing the
+type of the given path.
+
+[list_end]
+[nl]
+
+[call [cmd vfshandler] [method utime] [arg root] [arg relative] [arg actualpath] [arg actime] [arg mtime]]
+
+Set the access and modification times of the given file (these are
+read with [method stat]).
+
+[list_end]
+
+
+[section {HANDLER ENVIRONMENT}]
+
+The implementation of a filesystem handler can rely on the
+existence of the following utility commands:
+
+[list_begin definitions]
+[call [cmd vfs::accessMode] [arg mode]]
+
+This commands converts an access [arg mode] given as integer into a
+string, one of [const F], [const X], [const W], [const XW], [const R],
+[const RX], and [const RW].
+
+
+[call [cmd vfs::matchDirectories] [arg types]]
+
+Checks if the glob types specification ask for the inclusion of
+directories. Returns a boolean result. [const true] is returned if
+types does ask for directories, else [const false].
+
+
+[call [cmd vfs::matchFiles] [arg types]]
+
+Checks if the glob types specification ask for the inclusion of
+files. Returns a boolean result. [const true] is returned if types
+does ask for directories, else [const false].
+
+
+[call [cmd vfs::matchCorrectTypes] [arg types] [arg filelist] [opt [arg inDir]]]
+
+Returns that subset of the [arg filelist] which are compatible with
+the [arg types] given. The elements of [arg filelist] are either
+absolute paths, or names of files in the directory [arg indir].  The
+latter interpretation is taken if and only if the argument [arg indir]
+is specified.
+
+
+[list_end]
+
+[section {FILESYSTEM DEBUGGING}]
+
+To debug a problem in the implementation of a filesystem use code as
+shown below. This registers the command [cmd report] as the error
+handler for the filesystem, which in turn prints out the error stack
+provided by tcl.
+
+[para]
+[example {vfs::filesystem internalerror report
+
+proc report {} {
+    puts stderr $::errorInfo
+}}]
+
+[see_also vfs vfs-filesystems]
+[keywords vfs filesystem file]
+[manpage_end]
+
diff --git a/8.x/tclvfs/doc/vfs.man b/8.x/tclvfs/doc/vfs.man
new file mode 100644 (file)
index 0000000..6d723a7
--- /dev/null
@@ -0,0 +1,203 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin vfs n 1.0]
+[copyright {2001-2003 Vince Darley <vincentdarley@users.sourceforge.net>}]
+[copyright {2003 Andreas Kupries <andreas_kupries@users.sourceforge.net>}]
+[moddesc   {Tcl-level Virtual Filesystems}]
+[titledesc {Filesystem management in Tcl}]
+[require Tcl 8.4]
+[require vfs [opt 1.2.1]]
+[description]
+
+The package [package vfs] provides commands to query, mount and
+unmount virtual filesystems implemented in Tcl. This is further
+facilitated through the provison of helper commands in a tcl script
+library. See section "HANDLER ENVIRONMENT" of [cmd vfs-fsapi] for
+more information.
+
+[para]
+
+Once a virtual filesystem is in place, the standard Tcl commands, like
+[cmd file], [cmd glob], [cmd cd], [cmd pwd], [cmd open], including all
+their C APIs in the Tcl library (e.g.
+
+[fun Tcl_FSOpenFileChannel], [fun Tcl_FSMatchInDirectory],
+...), can be used within the filesystem (and indeed, properly written
+extensions such as [package Tk] which may open or read files will also
+transparently access the virtual filesystem).
+
+[para]
+
+Because all of Tcl's filesystem activity passes through a single
+layer, every operation can be intercepted. This package does just
+that.
+
+This is also quite different from simply overloading the [cmd file]
+command in Tcl.  We are actually providing replacements for C commands
+like [syscmd access], [syscmd stat], etc.
+
+By implementing a small number of low-level commands we ensure that
+all commands at higher levels will function irrespective of what is
+going on inside the filesystem layer.
+
+[para]
+
+Tcl's filesystem hooks operate on a per-process basis.  This means
+every Tcl interpreter in the same process/application will see the
+same filesystem, including any virtual filesystems.
+
+[para]
+
+To access this package use the command [cmd {package require vfs}].
+
+This automatically registers the vfs hooks into Tcl's filesystem and
+provides the command [cmd vfs::filesystem]. The latter allows the
+registration of actual virtual filesystems. More in the upcoming
+section [sectref API].
+
+The hooks will not be removed until Tcl exits. If desired, control
+over this could be exposed to Tcl in the future.
+
+By and in itself the command above will have no further effect. Only
+after filesystem implementations have been registered and filesystems
+using them been mounted filesystem commands will actually be
+intercepted, and handled by the Tcl code of the mounted virtual
+filesystem.
+
+
+[section API]
+
+[list_begin definitions]
+
+[call [cmd vfs::filesystem] [method mount] [opt [option -volume]] [arg path] [arg command]]
+
+[term Mount]s a virtual filesystem at [arg path], making it
+useable. After completion of the call any access to a subdirectory of
+[arg path] will be handled by that filesystem. The filesystem is
+represented here by the [arg command] prefix which will be executed
+whenever an operation on a file or directory within [arg path] has to
+be performed.
+
+[nl]
+
+Whether the [arg command] is implemented in C or Tcl is of no
+relevance as long as it adheres to the API specified in
+
+[cmd vfs-fsapi] and is present in the interpreter where the mount
+operation is executed.
+
+[nl]
+
+If the option [option -volume] is specified the new mount point is
+also registered with Tcl as a new volume and will therefore from then
+on appear in the output of the command [cmd {file volumes}]. This is
+useful (and required for reasonable operation) for mounts like
+
+[const ftp://]. It should not be used for paths mounted inside the
+native filesystem.
+
+[nl]
+
+The new filesystem mounts will be observed immediately in all
+interpreters in the current process.  If the interpreter is later
+deleted, all mounts which are intercepted by it will be automatically
+removed (and will therefore affect the view of the filesystem seen by
+all interpreters).
+
+
+[call [cmd vfs::filesystem] [method unmount] [arg path]]
+
+This unmounts the virtual filesystem which was mounted at
+[arg path]. An error is thrown if no filesystem was mounted there.
+
+After the completion of the operation the filesystem is not visible
+anymore, and any previous filesystem accessible through this path
+becomes accessible again.
+
+
+[call [cmd vfs::filesystem] [method info] [opt [arg path]]]
+
+A list of all filesystems mounted in all interpreters is returned, if
+no [arg path] argument was specified.
+
+Else the filesystem responsible for that [arg path] is examined and
+the command prefix used to handle all filesystem operations returned.
+
+An error is thrown if no filesystem is mounted for that [arg path].
+
+[nl]
+
+There is currently no facility for examining in which interpreter each
+command will be evaluated.
+
+
+[call [cmd vfs::filesystem] [method fullynormalize] [arg path]]
+
+Performs a full expansion of [arg path], (as per [cmd {file
+normalize}]). This includes the following of any links in the last
+element of [arg path].
+
+
+[call [cmd vfs::filesystem] [method posixerror] [arg int]]
+
+This command can be called by filesystem implementations during the
+execution of a filesystem operation to signal the posix error code of
+a failure. See also [syscmd vfs-fsapi].
+
+
+[call [cmd vfs::filesystem] [method internalerror] [arg command]]
+
+When used the specified [arg command] is registerd as the command to
+trap and report any internal errors thrown by filesystem
+implementations.
+
+[list_end]
+
+[section LIMITATIONS]
+
+The code of the package [package vfs] has only a few limitations.
+
+[para]
+
+[list_begin enum]
+
+[enum]
+
+One subtlety one has to be aware of is that mixing case-(in)sensitive
+filesystems and application code may yield unexpected results.
+
+[nl]
+
+For example mounting a case-sensitive virtual filesystem into a
+case-insensitive system (like the standard Windows or MacOS
+filesystems) and then using this with code relying on
+case-insensitivity problems will appear when accessing the virtual
+filesystem.
+
+[nl]
+
+Note that application code relying on case-insensitivity will not
+under Unix either, i.e. is inherently non-portable, and should be
+fixed.
+
+
+[enum]
+
+The C-API's for [method link] and [method lstat] are currently not
+exposed to the Tcl level. This may be done in the future to allow
+virtual filesystems implemented in Tcl to support the reading and
+writing of links.
+
+[enum]
+
+The public C-API filesystem function [fun Tcl_FSMatchInDirectory] is
+given a variety of type information in a [term Tcl_GlobTypeData]
+structure.  Currently only the [term type] field of said strcuture is
+exposed to the tcl-level. Fields like [term permissions] and MacOS
+[term type/creator] are ignored.
+
+[list_end]
+
+
+[see_also vfs-filesystems vfs-fsapi]
+[keywords vfs filesystem file]
+[manpage_end]
diff --git a/8.x/tclvfs/doc/vfs.n b/8.x/tclvfs/doc/vfs.n
new file mode 100644 (file)
index 0000000..df91e01
--- /dev/null
@@ -0,0 +1,287 @@
+'\"
+'\" Copyright (c) 2001-2003, Vince Darley
+'\" 
+'\" 
+.so man.macros
+.TH vfs n 1.4 Vfs "Tcl-only Virtual File Systems"
+.BS
+'\" Note:  do not modify the .sh NAME line immediately below!
+.SH NAME
+::vfs \- Commands and Procedures to create virtual filesystems
+.SH SYNOPSIS
+.BS
+.sp
+\fBpackage require Tcl 8.4\fR
+.sp
+\fBpackage require vfs ?1.4?\fR
+.sp
+\fBvfs::filesystem\fR \fIinfo\fR
+.sp
+\fBvfs::filesystem\fR \fImount\fR
+.sp
+\fBvfs::filesystem\fR \fIunmount\fR
+.sp
+\fBvfs::accessMode\fR \fImode\fR
+.sp
+\fBvfs::matchDirectories\fR \fItypes\fR
+.sp
+\fBvfs::matchFiles\fR \fItypes\fR
+.sp
+\fBvfs::matchCorrectTypes\fR \fItypes\fR \fIfilelist\fR \fI?inDir?\fR
+.sp
+.BE
+.SH DESCRIPTION
+.PP
+The \fB::vfs\fR package provides commands to query, mount and unmount
+virtual filesystems, and provides as Tcl libraries some facilities for
+helping the writing of new virtual filesystems in Tcl.  Once a virtual
+filesystem is in place, the standard Tcl \fBfile\fP, \fBglob\fP,
+\fBcd\fP, \fBpwd\fP, \fBopen\fP commands, including all their C APIs in
+the Tcl library (e.g. \fBTcl_FSOpenFileChannel\fR,
+\fBTcl_FSMatchInDirectory\fR,...), can be used within the filesystem
+(and indeed, properly written extensions such as Tk which may open or
+read files will also transparently access the virtual filesystem). 
+Because all of Tcl's FS activity passes through a single layer, it can
+all be intercepted.  This package does just that.  Notice that this
+is quite different to overloading the \fBfile\fP command in Tcl.  We
+are actually providing vfs replacements for C commands like
+\fBaccess\fP, \fBstat\fP.  By implementing just a handful of commands
+at this low level, we ensure that all commands at higher levels
+function irrespective of what is going on inside the FS layer.
+.PP
+Tcl's filesystem hooks operate on a per-process basis.  This means every
+Tcl interpreter in the same process/application sees the same
+filesystem, including any virtual filesystems.
+.PP
+The \fBpackage require vfs\fP command should be used to access this
+library.  It automatically registers the vfs hooks into Tcl's
+filesystem, and these will not be removed until Tcl exits (if desired,
+control over this could be exposed to Tcl in the future).  However, the
+vfs package will at that stage not have any new filesystems mounted, so
+it will have little effect.  Note that \fBpackage require vfs\fP
+has two effects.  First of all, when it is issued in \fBany\fR Tcl 
+interpreter it will ensure the vfs hooks have been
+registered with Tcl's core just once (and if any of those interpreters
+are later deleted, the vfs hooks will still remain registered - they 
+remain until Tcl exits).  The second 
+effect is to provide the command \fBvfs::filesystem\fR which allows
+the interpreter to intercept filesystem commands and handle them with
+Tcl code in that interpreter.
+.PP
+There are three somewhat unsupported subcommands of
+\fBvfs::filesystem\fR, \fBfullynormalize path\fR, \fBposixerror int\fR,
+\fBinternalerror ?script?\fR, which are used to normalize a path
+(including any final symlink), to register a posix error code with a Tcl
+error, and to trap/report internal errors in tclvfs implementations
+respectively.
+.TP
+\fBvfs::filesystem\fR \fImount\fR \fI?-volume?\fR \fIpath\fR \fIcommand\fR
+To use a virtual filesystem, it must be 'mounted'.  Mounting involves
+declaring to the vfs package that any subdirectories of a given
+\fIpath\fR in the filesystem should be handled by the given \fIcommand\fR
+which should be a Tcl command or procedure in the interpreter in which
+the \fBvfs::filesystem\fR is executed.  If the \fI?-volume?\fR
+flag is given, the given mount point is also registered with Tcl as
+a new volume (like a new drive which will appear in \fIfile volumes\fR).  
+This is useful (and required for reasonable operation) for mounts like 
+\fIftp://\fR.  For paths mounted
+inside the native filesystem, it should of course not be given.  The
+new filesystem mounts will be observed immediately in all interpreters
+in the current process.  If
+the interpreter is later deleted, all mounts which are intercepted by 
+it will be automatically removed (and will therefore affect the view
+of the filesystem seen by all interpreters).
+.TP
+\fBvfs::filesystem\fR \fIunmount\fR \fIpath\fR 
+This unmounts the virtual filesystem which was mounted at \fIpath\fR
+(hence removing it from Tcl's filesystem), or throws an error if no
+filesystem was mounted there.
+.TP
+\fBvfs::filesystem\fR \fIinfo\fR \fI?path?\fR
+If no arguments are given, this returns a list of all filesystems
+mounted (in all interpreters).  If a path argument is given, then 
+the \fIcommand\fR to be
+used for that path is returned, or an error is thrown if no vfs is
+mounted for that path.  There is currently no facility for examining
+in which interpreter each command will be evaluated.
+.TP
+\fBvfs::filesystem\fR \fIfullynormalize\fR \fIpath\fR
+Performs a full expansion of \fIpath\fR, (as per 'file normalize'), but
+including following any links in the last element of path.
+.PP
+.SH IMPLEMENTING A TCL ONLY VFS
+.PP
+The vfs package will intercept every filesystem operation which falls
+within a given mount point, and pass the operation on to the mount
+point's \fIcommand\fR in the interpreter which registered it. In 
+general this occurs by the C equivalent of an
+evaluation like this: \fIeval $command [list $subcmd $root $relative
+$actualpath] $args\fR.
+.PP
+Here \fIsubcmd\fR may be any of the following: \fIaccess\fR,
+\fIcreatedirectory\fR, \fIdeletefile\fR, \fIfileattributes\fR,
+\fImatchindirectory\fR, \fIopen\fR, \fIremovedirectory\fR, \fIstat\fR,
+\fIutime\fR. If \fIcommand\fR takes appropriate action for each of
+these cases, a complete, perfect virtual filesystem will be achieved,
+indistinguishable to Tcl from the native filesystem.  (CAVEATS: right 
+now I don't expose to Tcl all the permission-related flags of 'glob').
+.PP
+The remaining arguments specify a file path on which to operate (all
+commands operate on one of these), and any additional arguments which
+may be required to carry out the action.  The file path is specified by
+three arguments: \fIroot\fR is the part of the path which lies outside
+this filesystem's mount point, \fIrelative\fR is the part of the path
+which lies inside this filesytem, and \fIactualpath\fR is the original
+(unnormalized) name of the path which was used in the current command
+wherever it originated (in Tcl or C).  For example, if
+\fIC:/foo/bar/mount.zip/xxx/yyy\fR is a path in your filesystem, where
+\fImount.zip\fR is a zip archive which has been mounted (on top of
+itself) and contains \fIxxx/yyy\fR, and the current working directory
+is inside \fIxxx\fR, and we evaluate a command like \fIfile exists
+yyy\fR, then \fIroot\R will be \fIC:/foo/bar/mount.zip\fR,
+\fIrelative\fR will be \fIxxx/yyy\fR, and \fIactualpath\fR will be
+\fIyyy\fR. The file separator between the \fIroot\fR and \fIrelative\fR
+is omitted.
+.PP
+Note that most filesystem operations will only require the
+\fIrelative\fR argument to work correctly, but the other arguments are
+actually required for correct operation of some subcommands.
+.PP
+Almost all of these commands should either return correctly (i.e. with a
+TCL_OK result at the C level) or they should use vfs::filesystem
+posixerror to signal the appropriate posix error code.  If a Tcl error is
+thrown, that should be considered a bug, but it will be interpreted as an
+unknown posix error in the filesystem call.  The exceptions to these
+rules are those filesystem commands which are able to specify a Tcl error
+message directly: open (when an interpreter is given), matchindirectory
+and fileattributes (for a set or get operation only).  These three
+commands are allowed to throw any Tcl error message which will be passed
+along to the caller, or they may throw a posix error which will be
+handled appropriately.
+.PP
+The actual commands are as follows (where \fIr-r-a\fR represents the
+standard argument triplet of \fIroot\fR, \fIrelative\fR and
+\fIactualpath\fR):
+.TP
+\fIcommand\fR \fIaccess\fR \fIr-r-a\fR \fImode\fR
+Return TCL_OK or throw a posix error depending on whether the given
+access mode (which is an integer) is compatible with the file.
+.TP
+\fIcommand\fR \fIcreatedirectory\fR \fIr-r-a\fR
+Create a directory with the given name.  The command can assume
+that all sub-directories in the path exist and are valid, and
+that the actual desired path does not yet exist (Tcl takes care
+of all of that for us).
+.TP
+\fIcommand\fR \fIdeletefile\fR \fIr-r-a\fR
+Delete the given file.
+.TP
+\fIcommand\fR \fIfileattributes\fR \fIr-r-a\fR \fI?index?\fR \fI?value?\fR
+If neither index nor value is given, then return a list of all
+acceptable attribute names.  If \fIindex\fR is given, but no value,
+then retrieve the value of the \fIindex\fR'th attribute (counting in
+order over the list returned when no argument is given) for the given 
+file.  If a value is also given then set the \fIindex\fR'th attribute of
+the given file to that value.
+.TP
+\fIcommand\fR \fImatchindirectory\fR \fIr-r-a\fR \fIpattern\fR \fItypes\fR
+Return the list of files or directories in the given path (which is
+always the name of an existing directory), which match the
+\fIpattern\fR and are compatible with the \fItypes\fR given.  It is
+very important that the command correctly handle \fItypes\fR requests
+for directories only (and files only), because to handle any kind of
+recursive globbing, Tcl will actually generate requests for
+directory-only matches from the filesystem.  See \fBvfs::matchDirectories\fR
+below for help.
+.TP
+\fIcommand\fR \fIopen\fR \fIr-r-a\fR \fImode\fR \fIpermissions\fR
+For this command, \fImode\fR is any of "r", "w", "a", "w+", "a+".
+If the open involves creating a file, then
+\fIpermissions\fR dictates what modes to create it with.  If the open
+operation was not successful, an error should be thrown.  If the open
+operation is successful, the command should return a list of either one
+or two items.  The first item (which is obligatory) is the name of the
+channel which has been created.  The second item, if given, is a
+Tcl-callback to be used when the channel is closed, so that the vfs can
+clean up as appropriate.  This callback will be evaluated by Tcl just
+before the channel is closed.  The channel will still exist, and all
+available data will have been flushed into it.  The callback can, for
+example, seek to the beginning of the channel, read its contents and
+store that contents elsewhere (e.g. compressed or on a remote ftp
+site, etc).  The return code or any errors returned by the callback
+are ignored (if the callback wishes to signal an error, it must do so 
+asycnhronously, with bgerror, for example), unless the 'internalerror' 
+script has been specified, when they are passed to that script for
+further action.
+.TP
+\fIcommand\fR \fIremovedirectory\fR \fIr-r-a\fR \fIrecursive\fR
+Delete the given directory.  \fIrecursive\fR is either 0 or 1. If
+it is 1 then even if the directory is non-empty, an attempt should
+be made to recursively delete it and its contents.  If it is 0 and
+the directory is non-empty, a posix error (EEXIST) should be
+thrown.
+.TP
+\fIcommand\fR \fIstat\fR \fIr-r-a\fR
+Return a list of even length containing field-name and value pairs for
+the contents of a stat structure.  The order is not important.  
+The option names are dev (long), ino (long), mode (int), nlink (long),
+uid (long), gid (long), size (long), atime (long), mtime (long), ctime
+(long), type (string which is either "directory" or "file"), where the
+type of each argument is given in brackets.  The procedure should
+therefore return with something like \fIreturn [list dev 0 type file 
+mtime 1234 ...]\fR.
+.TP
+\fIcommand\fR \fIutime\fR \fIr-r-a\fR \fIactime\fR \fImtime\fR
+Set the access and modification times of the given file (these are
+read with 'stat').
+
+.SH VFS HELPERS
+.PP
+The vfslib provides a number of Tcl procedures which can help with
+writing command procedures to handle the above possibilities.  These
+are:
+.TP
+\fBvfs::accessMode\fR \fImode\fR
+converts an integer \fIaccess\fR mode to a somewhat more preferable
+string, any of F X W XW R RX RW.
+.TP
+\fBvfs::matchDirectories\fR \fItypes\fR
+Does \fItypes\fR want directories included?
+.TP
+\fBvfs::matchFiles\fR \fItypes\fR
+Does \fItypes\fR want files included?
+.TP
+\fBvfs::matchCorrectTypes\fR \fItypes\fR \fIfilelist\fR \fI?inDir?\fR
+Returns that subset of the \fIfilelist\fR (which are either absolute
+paths or names of files in \fIinDir\fR) which are compatible with the
+\fItypes\fR given.
+
+.SH VFS DEBUGGING
+.PP
+Use something like this to debug problems in your implementation:
+vfs::filesystem internalerror report ; proc report {} { puts
+stderr $::errorInfo }
+
+.SH LIMITATIONS
+.PP
+There are very few limitations to the vfs code.  One subtlety that you
+may encounter is if you mount a case-sensitive virtual filesystem into
+a case-insensitive system (e.g. the standard Windows or MacOS fs) and
+your code relies on case-insensitivity, then it will not run properly
+in the virtual filesystem.  Of course if your code relies on
+case-insensitivity, it wouldn't run under Tcl on Unix either, so the
+best solution is to fix your code!
+.PP
+We may add \fIlink\fR and \fIlstat\fR commands in the future to allow
+virtual filesystems to support reading and writing links - this is
+supported by the C API, but has simply not been exposed to Tcl in this
+extension, yet.
+.PP
+The Tcl 'Tcl_FSMatchInDirectory' function takes a variety of type
+information in a Tcl_GlobTypeData structure.  We currently only expose 
+the 'type' field from that structure (so the 'permissions' and MacOS
+type/creator fields are ignored).
+.SH KEYWORDS
+vfs, filesystem, file
+
+
diff --git a/8.x/tclvfs/doc/vfslib.n b/8.x/tclvfs/doc/vfslib.n
new file mode 100644 (file)
index 0000000..8d68219
--- /dev/null
@@ -0,0 +1,78 @@
+'\"
+'\" Copyright (c) 2001, Vince Darley
+'\" 
+'\" 
+.so man.macros
+.TH vfslib n 1.0 Vfslib "Tcl-only Virtual File Systems"
+.BS
+'\" Note:  do not modify the .sh NAME line immediately below!
+.SH NAME
+::vfslib \- Procedures to interact with virtual filesystems
+.SH SYNOPSIS
+.BS
+.sp
+\fBpackage require Tcl 8.4\fR
+.sp
+\fBpackage require vfs ?1.2.1?\fR
+.sp
+\fBpackage require vfs::zip ?1.0?\fR
+.sp
+\fBpackage require vfs::mk4 ?1.6?\fR
+.sp
+\fBpackage require vfs::tar ?0.9?\fR
+.sp
+\fBpackage require vfs::ftp ?1.0?\fR
+.sp
+\fBpackage require vfs::ns ?1.0?\fR
+.sp
+\fBpackage require vfs::webdav ?0.1?\fR
+.sp
+\fBpackage require vfs::http ?0.5?\fR
+.sp
+\fBpackage require vfs::urltype ?1.0?\fR
+.sp
+\fBvfs::zip::Mount\fR \fIpath\fR \fIto\fR
+.sp
+\fBvfs::ftp::Mount\fR \fIpath\fR \fIto\fR
+.sp
+\fBvfs::tar::Mount\fR \fIpath\fR \fIto\fR
+.sp
+\fBvfs::http::Mount\fR \fIpath\fR \fIto\fR
+.sp
+\fBvfs::mk4::Mount\fR \fIpath\fR \fIto\fR
+.sp
+\fBvfs::ns::Mount\fR \fIpath\fR \fIto\fR
+.sp
+\fBvfs::urltype::Mount\fR \fItype\fR
+.sp
+.BE
+.SH DESCRIPTION
+.PP
+The \fB::vfs\fR package includes a library of Tcl code, implementing
+a number of different virtual filesystems.  Each of these exists
+as its own package, and can be accessed through \fBpackage require
+vfs::NAME\fP.  The whole set of virtual filesystems is known informally
+as 'vfslib'
+.PP
+.SH SUPPORTED VFS TYPES
+.PP
+The current supported types are ftp, tar, http, zip, mk4, ns, webdav.  In
+addition there is the ability to mount any 'urltype' as a new volume,
+provided an appropriate vfs is supported.  This means that you can treat
+'ftp://', 'http://' and 'file://' urls as files.  To do this, simply
+evaluate the command
+.PP
+\fIvfs::urltype::Mount ftp\fR
+.PP
+for instance.  Any access inside the new volume will result in an attempt
+to require a package through 'package require vfs::${type}', which must
+therefore exist, or errors will be thrown.
+.PP
+.SH LIMITATIONS
+.PP
+Most of the vfs types listed above have not been very well debugged
+as yet.  Please test them!
+.SH KEYWORDS
+vfs, vfslib, filesystem, zip, tar, webdav, namespace, ftp, http, file
+
+
diff --git a/8.x/tclvfs/examples/simpleExamples.tcl b/8.x/tclvfs/examples/simpleExamples.tcl
new file mode 100644 (file)
index 0000000..19fada3
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/sh
+#-*-tcl-*-
+# the next line restarts using wish \
+exec tclsh "$0" ${1+"$@"}
+
+catch {console show}
+
+puts "(pwd is '[pwd]', file volumes is '[file volumes]')"
+
+package require vfs
+
+package require vfs::zip
+package require vfs::urltype
+package require vfs::ftp
+package require vfs::http
+puts "Adding ftp:// volume..."
+vfs::urltype::Mount ftp
+set listing [glob -dir ftp://ftp.tcl.tk/pub *]
+puts "ftp.tcl.tk/pub listing"
+puts "$listing"
+puts "----"
+puts "(file volumes is '[file volumes]')"
+
+puts "Adding http:// volume..."
+vfs::urltype::Mount http
+set fd [open http://sourceforge.net/projects/tcl]
+set contents [read $fd] ; close $fd
+puts "Contents of <http://sourceforge.net/projects/tcl> web page"
+puts [string range $contents 0 100]
+puts "(first 100 out of [string length $contents] characters)"
+puts "----"
+puts "(file volumes is '[file volumes]')"
+
+puts "Mounting ftp://ftp.ucsd.edu/pub/alpha/ ..."
+vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ localmount
+cd localmount ; cd tcl
+puts "(pwd is now '[pwd]' which is effectively a transparent link\
+  to a remote ftp site)"
+puts "Contents of remote directory is:" 
+foreach file [glob -nocomplain *] {
+    puts "\t$file"
+}
+puts "sourcing remote file 'vfsTest.tcl', using 'source vfsTest.tcl'"
+# This will actually source the contents of a file on the
+# remote ftp site (which is now the 'pwd').
+source vfsTest.tcl
+
+puts "Done"
diff --git a/8.x/tclvfs/generic/vfs.c b/8.x/tclvfs/generic/vfs.c
new file mode 100644 (file)
index 0000000..effcfdc
--- /dev/null
@@ -0,0 +1,2064 @@
+/* 
+ * vfs.c --
+ *
+ *     This file contains the implementation of the Vfs extension
+ *     to Tcl.  It provides a script level interface to Tcl's 
+ *     virtual file system support, and therefore allows 
+ *     vfs's to be implemented in Tcl.
+ *     
+ *     Some of this file could be used as a basis for a hard-coded
+ *     vfs implemented in C (e.g. a zipvfs).
+ *     
+ *     The code is thread-safe.  Although under normal use only
+ *     one interpreter will be used to add/remove mounts and volumes,
+ *     it does cope with multiple interpreters in multiple threads.
+ *     
+ * Copyright (c) 2001-2004 Vince Darley.
+ * Copyright (c) 2006 ActiveState Software Inc.
+ * 
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include <tcl.h>
+/* Required to access the 'stat' structure fields, and TclInExit() */
+#include "tclInt.h"
+#include "tclPort.h"
+
+/*
+ * Windows needs to know which symbols to export.  Unix does not.
+ * BUILD_vfs should be undefined for Unix.
+ */
+
+#ifdef BUILD_vfs
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+#endif /* BUILD_vfs */
+
+#ifndef TCL_GLOB_TYPE_MOUNT
+#define TCL_GLOB_TYPE_MOUNT            (1<<7)
+#endif
+
+/*
+ * tclvfs will return this code instead of TCL_OK/ERROR/etc. to propagate
+ * through the Tcl_Eval* calls to indicate a posix error has been raised by
+ * some vfs implementation.  -1 is what Tcl expects, adopts from posix's
+ * standard error value.
+ */
+#define TCLVFS_POSIXERROR (-1)
+
+#ifndef CONST86
+#define CONST86
+#endif
+
+/*
+ * Only the _Init function is exported.
+ */
+
+EXTERN int Vfs_Init _ANSI_ARGS_((Tcl_Interp*));
+
+/* 
+ * Functions to add and remove a volume from the list of volumes.
+ * These aren't currently exported, but could be in the future.
+ */
+static void Vfs_AddVolume    _ANSI_ARGS_((Tcl_Obj*));
+static int  Vfs_RemoveVolume _ANSI_ARGS_((Tcl_Obj*));
+
+/*
+ * struct Vfs_InterpCmd --
+ * 
+ * Any vfs action which is exposed to Tcl requires both an interpreter
+ * and a command prefix for evaluation.  To carry out any filesystem
+ * action inside a vfs, this extension will lappend various additional
+ * parameters to the command string, evaluate it in the interpreter and
+ * then extract the result (the way the result is handled is documented
+ * in each individual vfs callback below).
+ * 
+ * We retain a refCount on the 'mountCmd' object, but there is no need
+ * for us to register our interpreter reference, since we will be
+ * made invalid when the interpreter disappears.  Also, Tcl_Objs of
+ * "path" type which use one of these structures as part of their
+ * internal representation also do not need to add to any refCounts,
+ * because if this object disappears, all internal representations will
+ * be made invalid.
+ */
+
+typedef struct Vfs_InterpCmd {
+    Tcl_Obj *mountCmd;    /* The Tcl command prefix which will be used
+                           * to perform all filesystem actions on this
+                           * file. */
+    Tcl_Interp *interp;   /* The Tcl interpreter in which the above
+                           * command will be evaluated. */
+} Vfs_InterpCmd;
+
+/*
+ * struct VfsNativeRep --
+ * 
+ * Structure used for the native representation of a path in a Tcl vfs.
+ * To fully specify a file, the string representation is also required.
+ * 
+ * When a Tcl interpreter is deleted, all mounts whose callbacks
+ * are in it are removed and freed.  This also means that the
+ * global filesystem epoch that Tcl retains is modified, and all
+ * path internal representations are therefore discarded.  Therefore we
+ * don't have to worry about vfs files containing stale VfsNativeRep
+ * structures (but it also means we mustn't touch the fsCmd field
+ * of one of these structures if the interpreter has gone).  This
+ * means when we free one of these structures, we just free the
+ * memory allocated, and ignore the fsCmd pointer (which may or may
+ * not point to valid memory).
+ */
+
+typedef struct VfsNativeRep {
+    int splitPosition;    /* The index into the string representation
+                           * of the file which indicates where the 
+                           * vfs filesystem is mounted. */
+    Vfs_InterpCmd* fsCmd; /* The Tcl interpreter and command pair
+                           * which will be used to perform all filesystem 
+                           * actions on this file. */
+} VfsNativeRep;
+
+/*
+ * struct VfsChannelCleanupInfo --
+ * 
+ * Structure we use to retain sufficient information about
+ * a channel that we can properly clean up all resources
+ * when the channel is closed.  This is required when using
+ * 'open' on things inside the vfs.
+ * 
+ * When the channel in question is begin closed, we will
+ * temporarily register the channel with the given interpreter,
+ * evaluate the closeCallBack, and then detach the channel
+ * from the interpreter and return (allowing Tcl to continue
+ * closing the channel as normal).
+ * 
+ * Nothing in the callback can prevent the channel from
+ * being closed.
+ */
+
+typedef struct VfsChannelCleanupInfo {
+    Tcl_Channel channel;    /* The channel which needs cleaning up */
+    Tcl_Obj* closeCallback; /* The Tcl command string to evaluate
+                             * when the channel is closing, which will
+                             * carry out any cleanup that is necessary. */
+    Tcl_Interp* interp;     /* The interpreter in which to evaluate the
+                             * cleanup operation. */
+} VfsChannelCleanupInfo;
+
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static int              VfsFilesystemObjCmd _ANSI_ARGS_((ClientData dummy,
+                           Tcl_Interp *interp, int objc, 
+                           Tcl_Obj *CONST objv[]));
+
+/* 
+ * Now we define the virtual filesystem callbacks.  Note that some
+ * of these callbacks are passed a Tcl_Interp for error messages.
+ * We will copy over the error messages from the vfs interp to the
+ * calling interp.  Currently this is done directly, but we
+ * could investigate using 'TclTransferResult' which would allow
+ * error traces to be copied over as well.
+ */
+
+static Tcl_FSStatProc VfsStat;
+static Tcl_FSAccessProc VfsAccess;
+static Tcl_FSOpenFileChannelProc VfsOpenFileChannel;
+static Tcl_FSMatchInDirectoryProc VfsMatchInDirectory;
+static Tcl_FSDeleteFileProc VfsDeleteFile;
+static Tcl_FSCreateDirectoryProc VfsCreateDirectory;
+static Tcl_FSRemoveDirectoryProc VfsRemoveDirectory; 
+static Tcl_FSFileAttrStringsProc VfsFileAttrStrings;
+static Tcl_FSFileAttrsGetProc VfsFileAttrsGet;
+static Tcl_FSFileAttrsSetProc VfsFileAttrsSet;
+static Tcl_FSUtimeProc VfsUtime;
+static Tcl_FSPathInFilesystemProc VfsPathInFilesystem;
+static Tcl_FSFilesystemPathTypeProc VfsFilesystemPathType;
+static Tcl_FSFilesystemSeparatorProc VfsFilesystemSeparator;
+static Tcl_FSFreeInternalRepProc VfsFreeInternalRep;
+static Tcl_FSDupInternalRepProc VfsDupInternalRep;
+static Tcl_FSListVolumesProc VfsListVolumes;
+
+static Tcl_Filesystem vfsFilesystem = {
+    "tclvfs",
+    sizeof(Tcl_Filesystem),
+    TCL_FILESYSTEM_VERSION_1,
+    &VfsPathInFilesystem,
+    &VfsDupInternalRep,
+    &VfsFreeInternalRep,
+    /* No internal to normalized, since we don't create any
+     * pure 'internal' Tcl_Obj path representations */
+    NULL,
+    /* No create native rep function, since we don't use it
+     * or 'Tcl_FSNewNativePath' */
+    NULL,
+    /* Normalize path isn't needed - we assume paths only have
+     * one representation */
+    NULL,
+    &VfsFilesystemPathType,
+    &VfsFilesystemSeparator,
+    &VfsStat,
+    &VfsAccess,
+    &VfsOpenFileChannel,
+    &VfsMatchInDirectory,
+    &VfsUtime,
+    /* We choose not to support symbolic links inside our vfs's */
+    NULL,
+    &VfsListVolumes,
+    &VfsFileAttrStrings,
+    &VfsFileAttrsGet,
+    &VfsFileAttrsSet,
+    &VfsCreateDirectory,
+    &VfsRemoveDirectory, 
+    &VfsDeleteFile,
+    /* No copy file - fallback will occur at Tcl level */
+    NULL,
+    /* No rename file - fallback will occur at Tcl level */
+    NULL,
+    /* No copy directory - fallback will occur at Tcl level */
+    NULL, 
+    /* Use stat for lstat */
+    NULL,
+    /* No load - fallback on core implementation */
+    NULL,
+    /* We don't need a getcwd or chdir - fallback on Tcl's versions */
+    NULL,
+    NULL
+};
+
+/*
+ * struct VfsMount --
+ * 
+ * Each filesystem mount point which is registered will result in
+ * the allocation of one of these structures.  They are stored
+ * in a linked list whose head is 'listOfMounts'.
+ */
+
+typedef struct VfsMount {
+    CONST char* mountPoint;
+    int mountLen;
+    int isVolume;
+    Vfs_InterpCmd interpCmd;
+    struct VfsMount* nextMount;
+} VfsMount;
+
+#define TCL_TSD_INIT(keyPtr)   (ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData))
+
+/*
+ * Declare a thread-specific list of vfs mounts and volumes.
+ *
+ * Stores the list of volumes registered with the vfs (and therefore
+ * also registered with Tcl).  It is maintained as a valid Tcl list at
+ * all times, or NULL if there are none (we don't keep it as an empty
+ * list just as a slight optimisation to improve Tcl's efficiency in
+ * determining whether paths are absolute or relative).
+ *
+ * We keep a refCount on this object whenever it is non-NULL.
+ *
+ * internalErrorScript is evaluated when an internal error is detected in
+ * a tclvfs implementation.  This is most useful for debugging.
+ *
+ * When it is not NULL we keep a refCount on it.
+ */
+
+typedef struct ThreadSpecificData {
+    VfsMount *listOfMounts;
+    Tcl_Obj *vfsVolumes;
+    Tcl_Obj *internalErrorScript;
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
+
+/* We might wish to consider exporting these in the future */
+
+static int             Vfs_AddMount(Tcl_Obj* mountPoint, int isVolume, 
+                                   Tcl_Interp *interp, Tcl_Obj* mountCmd);
+static int             Vfs_RemoveMount(Tcl_Obj* mountPoint, Tcl_Interp* interp);
+static Vfs_InterpCmd*  Vfs_FindMount(Tcl_Obj *pathMount, int mountLen);
+static Tcl_Obj*        Vfs_ListMounts(void);
+static void            Vfs_UnregisterWithInterp _ANSI_ARGS_((ClientData, 
+                                                            Tcl_Interp*));
+static void            Vfs_RegisterWithInterp _ANSI_ARGS_((Tcl_Interp*));
+
+/* Some private helper procedures */
+
+static VfsNativeRep*   VfsGetNativePath(Tcl_Obj* pathPtr);
+static Tcl_CloseProc   VfsCloseProc;
+static void            VfsExitProc(ClientData clientData);
+static void            VfsThreadExitProc(ClientData clientData);
+static Tcl_Obj*               VfsFullyNormalizePath(Tcl_Interp *interp, 
+                                            Tcl_Obj *pathPtr);
+static Tcl_Obj*        VfsBuildCommandForPath(Tcl_Interp **iRef, 
+                                 CONST char* cmd, Tcl_Obj * pathPtr);
+static void            VfsInternalError(Tcl_Interp* interp);
+
+/* 
+ * Hard-code platform dependencies.  We do not need to worry 
+ * about backslash-separators on windows, because a normalized
+ * path will never contain them.
+ */
+#ifdef MAC_TCL
+    #define VFS_SEPARATOR ':'
+#else
+    #define VFS_SEPARATOR '/'
+#endif
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Vfs_Init --
+ *
+ *     This procedure is the main initialisation point of the Vfs
+ *     extension.
+ *
+ * Results:
+ *     Returns a standard Tcl completion code, and leaves an error
+ *     message in the interp's result if an error occurs.
+ *
+ * Side effects:
+ *     Adds a command to the Tcl interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Vfs_Init(interp)
+    Tcl_Interp *interp;                /* Interpreter for application. */
+{
+    if (Tcl_InitStubs(interp, "8.4", 0) == NULL) {
+       return TCL_ERROR;
+    }
+    if (Tcl_PkgRequire(interp, "Tcl", "8.4", 0) == NULL) {
+       return TCL_ERROR;
+    }
+    
+    /* 
+     * Safe interpreters are not allowed to modify the filesystem!
+     * (Since those modifications will affect other interpreters).
+     */
+    if (Tcl_IsSafe(interp)) {
+        return TCL_ERROR;
+    }
+
+#ifndef PACKAGE_VERSION
+    /* keep in sync with actual version */
+#define PACKAGE_VERSION "1.4"
+#endif
+    if (Tcl_PkgProvide(interp, "vfs", PACKAGE_VERSION) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+
+    /*
+     * Create 'vfs::filesystem' command, and interpreter-specific
+     * initialisation.
+     */
+
+    Tcl_CreateObjCommand(interp, "vfs::filesystem", VfsFilesystemObjCmd, 
+           (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+    Vfs_RegisterWithInterp(interp);
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Vfs_RegisterWithInterp --
+ *
+ *     Allow the given interpreter to be used to handle vfs callbacks.
+ *
+ * Results:
+ *     None.
+ *
+ * Side effects:
+ *     May register the entire vfs code (if not previously registered).
+ *     Registers some cleanup action for when this interpreter is
+ *     deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+static void 
+Vfs_RegisterWithInterp(interp)
+    Tcl_Interp *interp;
+{
+    ClientData vfsAlreadyRegistered;
+    /* 
+     * We need to know if the interpreter is deleted, so we can
+     * remove all interp-specific mounts.
+     */
+    Tcl_SetAssocData(interp, "vfs::inUse", (Tcl_InterpDeleteProc*) 
+                    Vfs_UnregisterWithInterp, (ClientData) 1);
+    /* 
+     * Perform one-off registering of our filesystem if that
+     * has not happened before.
+     */
+    vfsAlreadyRegistered = Tcl_FSData(&vfsFilesystem);
+    if (vfsAlreadyRegistered == NULL) {
+       Tcl_FSRegister((ClientData)1, &vfsFilesystem);
+       Tcl_CreateExitHandler(VfsExitProc, (ClientData)NULL);
+       Tcl_CreateThreadExitHandler(VfsThreadExitProc, NULL);
+    }
+}
+   
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Vfs_UnregisterWithInterp --
+ *
+ *     Remove all of the mount points that this interpreter handles.
+ *
+ * Results:
+ *     None.
+ *
+ * Side effects:
+ *     None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void 
+Vfs_UnregisterWithInterp(dummy, interp)
+    ClientData dummy;
+    Tcl_Interp *interp;
+{
+    int res = TCL_OK;
+    /* Remove all of this interpreters mount points */
+    while (res == TCL_OK) {
+        res = Vfs_RemoveMount(NULL, interp);
+    }
+    /* Make sure our assoc data has been deleted */
+    Tcl_DeleteAssocData(interp, "vfs::inUse");
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Vfs_AddMount --
+ *
+ *     Adds a new vfs mount point.  After this call all filesystem
+ *     access within that mount point will be redirected to the
+ *     interpreter/mountCmd pair.
+ *     
+ *     This command must not be called unless 'interp' has already
+ *     been registered with 'Vfs_RegisterWithInterp' above.  This 
+ *     usually happens automatically with a 'package require vfs'.
+ *
+ * Results:
+ *     TCL_OK unless the inputs are bad or a memory allocation
+ *     error occurred, or the interpreter is not vfs-registered.
+ *
+ * Side effects:
+ *     A new volume may be added to the list of available volumes.
+ *     Future filesystem access inside the mountPoint will be 
+ *     redirected.  Tcl is informed that a new mount has been added
+ *     and this will make all cached path representations invalid.
+ *
+ *----------------------------------------------------------------------
+ */
+static int 
+Vfs_AddMount(mountPoint, isVolume, interp, mountCmd)
+    Tcl_Obj* mountPoint;
+    int isVolume;
+    Tcl_Interp* interp;
+    Tcl_Obj* mountCmd;
+{
+    char *strRep;
+    int len;
+    VfsMount *newMount;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    
+    if (mountPoint == NULL || interp == NULL || mountCmd == NULL) {
+       return TCL_ERROR;
+    }
+    /* 
+     * Check whether this intepreter can properly clean up
+     * mounts on exit.  If not, throw an error.
+     */
+    if (Tcl_GetAssocData(interp, "vfs::inUse", NULL) == NULL) {
+        return TCL_ERROR;
+    }
+    
+    newMount = (VfsMount*) ckalloc(sizeof(VfsMount));
+    
+    if (newMount == NULL) {
+       return TCL_ERROR;
+    }
+    strRep = Tcl_GetStringFromObj(mountPoint, &len);
+    newMount->mountPoint = (char*) ckalloc(1+(unsigned)len);
+    newMount->mountLen = len;
+    
+    if (newMount->mountPoint == NULL) {
+       ckfree((char*)newMount);
+       return TCL_ERROR;
+    }
+    
+    strcpy((char*)newMount->mountPoint, strRep);
+    newMount->interpCmd.mountCmd = mountCmd;
+    newMount->interpCmd.interp = interp;
+    newMount->isVolume = isVolume;
+    Tcl_IncrRefCount(mountCmd);
+    
+    newMount->nextMount = tsdPtr->listOfMounts;
+    tsdPtr->listOfMounts = newMount;
+
+    if (isVolume) {
+       Vfs_AddVolume(mountPoint);
+    }
+    Tcl_FSMountsChanged(&vfsFilesystem);
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Vfs_RemoveMount --
+ *
+ *     This procedure searches for a matching mount point and removes
+ *     it if one is found.  If 'mountPoint' is given, then both it and
+ *     the interpreter must match for a mount point to be removed.
+ *     
+ *     If 'mountPoint' is NULL, then the first mount point for the
+ *     given interpreter is removed (if any).
+ *
+ * Results:
+ *     TCL_OK if a mount was removed, TCL_ERROR otherwise.
+ *
+ * Side effects:
+ *     A volume may be removed from the current list of volumes
+ *     (as returned by 'file volumes').  A vfs may be removed from
+ *     the filesystem.  If successful, Tcl will be informed that
+ *     the list of current mounts has changed, and all cached file
+ *     representations will be made invalid.
+ *
+ *----------------------------------------------------------------------
+ */
+static int 
+Vfs_RemoveMount(mountPoint, interp)
+    Tcl_Obj* mountPoint;
+    Tcl_Interp *interp;
+{
+    /* These two are only used if mountPoint is non-NULL */
+    char *strRep = NULL;
+    int len = 0;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    
+    VfsMount *mountIter;
+    /* Set to NULL just to avoid warnings */
+    VfsMount *lastMount = NULL;
+    
+    if (mountPoint != NULL) {
+       strRep = Tcl_GetStringFromObj(mountPoint, &len);
+    }
+
+    mountIter = tsdPtr->listOfMounts;
+    
+    while (mountIter != NULL) {
+       if ((interp == mountIter->interpCmd.interp) 
+           && ((mountPoint == NULL) ||
+               (mountIter->mountLen == len && 
+                !strcmp(mountIter->mountPoint, strRep)))) {
+           /* We've found the mount. */
+           if (mountIter == tsdPtr->listOfMounts) {
+               tsdPtr->listOfMounts = mountIter->nextMount;
+           } else {
+               lastMount->nextMount = mountIter->nextMount;
+           }
+           /* Free the allocated memory */
+           if (mountIter->isVolume) {
+               if (mountPoint == NULL) {
+                   Tcl_Obj *volObj = Tcl_NewStringObj(mountIter->mountPoint, 
+                                                      mountIter->mountLen);
+                   Tcl_IncrRefCount(volObj);
+                   Vfs_RemoveVolume(volObj);
+                   Tcl_DecrRefCount(volObj);
+               } else {
+                   Vfs_RemoveVolume(mountPoint);
+               }
+           }
+           ckfree((char*)mountIter->mountPoint);
+           Tcl_DecrRefCount(mountIter->interpCmd.mountCmd);
+           ckfree((char*)mountIter);
+           Tcl_FSMountsChanged(&vfsFilesystem);
+           return TCL_OK;
+       }
+       lastMount = mountIter;
+       mountIter = mountIter->nextMount;
+    }
+    return TCL_ERROR;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Vfs_FindMount --
+ *
+ *     This procedure searches all currently mounted paths for one
+ *     which matches the given path.  The given path must be the
+ *     absolute, normalized, unique representation for the given path.
+ *     If 'len' is -1, we use the entire string representation of the
+ *     mountPoint, otherwise we treat 'len' as the length of the mount
+ *     we are comparing.
+ *
+ * Results:
+ *     Returns the interpreter, command-prefix pair for the given
+ *     mount point, if one is found, otherwise NULL.
+ *
+ * Side effects:
+ *     None.
+ *
+ *----------------------------------------------------------------------
+ */
+static Vfs_InterpCmd* 
+Vfs_FindMount(pathMount, mountLen)
+    Tcl_Obj *pathMount;
+    int mountLen;
+{
+    VfsMount *mountIter;
+    char *mountStr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    
+    if (pathMount == NULL) {
+       return NULL;
+    }
+    
+    if (mountLen == -1) {
+        mountStr = Tcl_GetStringFromObj(pathMount, &mountLen);
+    } else {
+       mountStr = Tcl_GetString(pathMount);
+    }
+
+    mountIter = tsdPtr->listOfMounts;
+    while (mountIter != NULL) {
+       if (mountIter->mountLen == mountLen && 
+         !strncmp(mountIter->mountPoint, mountStr, (size_t)mountLen)) {
+           Vfs_InterpCmd *ret = &mountIter->interpCmd;
+           return ret;
+       }
+       mountIter = mountIter->nextMount;
+    }
+    return NULL;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Vfs_ListMounts --
+ *
+ *     Returns a valid Tcl list, with refCount of zero, containing
+ *     all currently mounted paths.
+ *     
+ *----------------------------------------------------------------------
+ */
+static Tcl_Obj* 
+Vfs_ListMounts(void) 
+{
+    VfsMount *mountIter;
+    Tcl_Obj *res = Tcl_NewObj();
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    /* Build list of mounts */
+    mountIter = tsdPtr->listOfMounts;
+    while (mountIter != NULL) {
+       Tcl_Obj* mount = Tcl_NewStringObj(mountIter->mountPoint, 
+                                         mountIter->mountLen);
+       Tcl_ListObjAppendElement(NULL, res, mount);
+       mountIter = mountIter->nextMount;
+    }
+    return res;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * VfsFilesystemObjCmd --
+ *
+ *     This procedure implements the "vfs::filesystem" command.  It is
+ *     used to mount/unmount particular interfaces to new filesystems,
+ *     or to query for what is mounted where.
+ *
+ * Results:
+ *     A standard Tcl result.
+ *
+ * Side effects:
+ *     Inserts or removes a filesystem from Tcl's stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+VfsFilesystemObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;
+    Tcl_Interp *interp;
+    int                objc;
+    Tcl_Obj    *CONST objv[];
+{
+    int index;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    static CONST char *optionStrings[] = {
+       "info", "internalerror", "mount", "unmount", 
+       "fullynormalize", "posixerror", 
+       NULL
+    };
+    
+    enum options {
+       VFS_INFO, VFS_INTERNAL_ERROR, VFS_MOUNT, VFS_UNMOUNT, 
+       VFS_NORMALIZE, VFS_POSIXERROR
+    };
+
+    if (objc < 2) {
+       Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+       return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
+           &index) != TCL_OK) {
+       return TCL_ERROR;
+    }
+
+    switch ((enum options) index) {
+       case VFS_INTERNAL_ERROR: {
+           if (objc > 3) {
+               Tcl_WrongNumArgs(interp, 2, objv, "?script?");
+               return TCL_ERROR;
+           }
+           if (objc == 2) {
+               /* Return the current script */
+               if (tsdPtr->internalErrorScript != NULL) {
+                   Tcl_SetObjResult(interp, tsdPtr->internalErrorScript);
+               }
+           } else {
+               /* Set the script */
+               int len;
+               if (tsdPtr->internalErrorScript != NULL) {
+                   Tcl_DecrRefCount(tsdPtr->internalErrorScript);
+               }
+               Tcl_GetStringFromObj(objv[2], &len);
+               if (len == 0) {
+                   /* Clear our script */
+                   tsdPtr->internalErrorScript = NULL;
+               } else {
+                   /* Set it */
+                   tsdPtr->internalErrorScript = objv[2];
+                   Tcl_IncrRefCount(tsdPtr->internalErrorScript);
+               }
+           }
+           return TCL_OK;
+       }
+       case VFS_POSIXERROR: {
+           int posixError = -1;
+           if (objc != 3) {
+               Tcl_WrongNumArgs(interp, 2, objv, "errorcode");
+               return TCL_ERROR;
+           }
+           if (Tcl_GetIntFromObj(NULL, objv[2], &posixError) != TCL_OK) {
+               return TCL_ERROR;
+           }
+           Tcl_SetErrno(posixError);
+           /*
+            * This special error code propagate to the Tcl_Eval* calls in
+            * other parts of the vfs C code to indicate a posix error
+            * being raised by some vfs implementation.
+            */
+           return TCLVFS_POSIXERROR;
+       }
+       case VFS_NORMALIZE: {
+           Tcl_Obj *path;
+           if (objc != 3) {
+               Tcl_WrongNumArgs(interp, 2, objv, "path");
+               return TCL_ERROR;
+           }
+           path = VfsFullyNormalizePath(interp, objv[2]);
+           if (path == NULL) {
+               Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+                       "not a valid path \"", Tcl_GetString(objv[2]), 
+                       "\"", (char *) NULL);
+           } else {
+               Tcl_SetObjResult(interp, path);
+               Tcl_DecrRefCount(path);
+               return TCL_OK;
+           }
+       }
+        case VFS_MOUNT: {
+           if (objc < 4 || objc > 5) {
+               Tcl_WrongNumArgs(interp, 1, objv, "mount ?-volume? path cmd");
+               return TCL_ERROR;
+           }
+           if (objc == 5) {
+               char *option = Tcl_GetString(objv[2]);
+               if (strcmp("-volume", option)) {
+                   Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+                           "bad option \"", option,
+                           "\": must be -volume", (char *) NULL);
+                   return TCL_ERROR;
+               }
+               return Vfs_AddMount(objv[3], 1, interp, objv[4]);
+           } else {
+               Tcl_Obj *path;
+               int retVal;
+               path = VfsFullyNormalizePath(interp, objv[2]);
+               retVal = Vfs_AddMount(path, 0, interp, objv[3]);
+               if (path != NULL) { Tcl_DecrRefCount(path); }
+               return retVal;
+           }
+           break;
+       }
+       case VFS_INFO: {
+           if (objc > 3) {
+               Tcl_WrongNumArgs(interp, 2, objv, "path");
+               return TCL_ERROR;
+           }
+           if (objc == 2) {
+               Tcl_SetObjResult(interp, Vfs_ListMounts());
+           } else {
+               Vfs_InterpCmd *val;
+               
+               val = Vfs_FindMount(objv[2], -1);
+               if (val == NULL) {
+                   Tcl_Obj *path;
+                   path = VfsFullyNormalizePath(interp, objv[2]);
+                   val = Vfs_FindMount(path, -1);
+                   Tcl_DecrRefCount(path);
+                   if (val == NULL) {
+                       Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+                               "no such mount \"", Tcl_GetString(objv[2]), 
+                               "\"", (char *) NULL);
+                       return TCL_ERROR;
+                   }
+               }
+               Tcl_SetObjResult(interp, val->mountCmd);
+           }
+           break;
+       }
+       case VFS_UNMOUNT: {
+           if (objc != 3) {
+               Tcl_WrongNumArgs(interp, 2, objv, "path");
+               return TCL_ERROR;
+           }
+           if (Vfs_RemoveMount(objv[2], interp) == TCL_ERROR) {
+               Tcl_Obj *path;
+               int retVal;
+               path = VfsFullyNormalizePath(interp, objv[2]);
+               retVal = Vfs_RemoveMount(path, interp);
+               Tcl_DecrRefCount(path);
+               if (retVal == TCL_ERROR) {
+                   Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+                           "no such mount \"", Tcl_GetString(objv[2]), 
+                           "\"", (char *) NULL);
+                   return TCL_ERROR;
+               }
+           }
+           return TCL_OK;
+       }
+    }
+    return TCL_OK;
+}
+\f
+/* Handle an error thrown by a tcl vfs implementation */
+static void
+VfsInternalError(Tcl_Interp* interp)
+{
+    if (interp != NULL) {
+       ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+       if (tsdPtr->internalErrorScript != NULL) {
+           Tcl_EvalObjEx(interp, tsdPtr->internalErrorScript,
+                         TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+       }
+    }
+}
+\f
+/* Return fully normalized path owned by the caller */
+static Tcl_Obj*
+VfsFullyNormalizePath(Tcl_Interp *interp, Tcl_Obj *pathPtr) {
+    Tcl_Obj *path;
+    int counter = 0;
+
+    Tcl_IncrRefCount(pathPtr);
+    while (1) {
+       path = Tcl_FSLink(pathPtr,NULL,0);
+       if (path == NULL) {
+           break;
+       }
+       if (Tcl_FSGetPathType(path) != TCL_PATH_ABSOLUTE) {
+           /* 
+            * This is more complex, we need to find the path
+            * relative to the original file, effectively:
+            * 
+            *  file join [file dirname $pathPtr] $path
+            *  
+            * or 
+            * 
+            *  file join $pathPtr .. $path
+            *  
+            * So...
+            */
+           Tcl_Obj *dotdotPtr, *joinedPtr;
+           Tcl_Obj *joinElements[2];
+           
+           dotdotPtr = Tcl_NewStringObj("..",2);
+           Tcl_IncrRefCount(dotdotPtr);
+           
+           joinElements[0] = dotdotPtr;
+           joinElements[1] = path;
+
+           joinedPtr = Tcl_FSJoinToPath(pathPtr, 2, joinElements);
+           
+           if (joinedPtr != NULL) {
+               Tcl_IncrRefCount(joinedPtr);
+               Tcl_DecrRefCount(path);
+               path = joinedPtr;
+           } else {
+               /* We failed, and our action is undefined */
+           }
+           Tcl_DecrRefCount(dotdotPtr);
+       }
+       Tcl_DecrRefCount(pathPtr);
+       pathPtr = path;
+       counter++;
+       if (counter > 10) {
+           /* Too many links */
+           Tcl_DecrRefCount(pathPtr);
+           return NULL;
+       }
+    }
+    path = Tcl_FSGetNormalizedPath(interp, pathPtr);
+    Tcl_IncrRefCount(path);
+    Tcl_DecrRefCount(pathPtr);
+    return path;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * VfsPathInFilesystem --
+ *
+ *     Check whether a path is in any of the mounted points in this
+ *     vfs.
+ *     
+ *     If it is in the vfs, set the clientData given to our private
+ *     internal representation for a vfs path.
+ *     
+ * Results:
+ *     Returns TCL_OK on success, or 'TCLVFS_POSIXERROR' on failure.
+ *     If Tcl is exiting, we always return a failure code.
+ *
+ * Side effects:
+ *     On success, we allocate some memory for our internal
+ *     representation structure.  Tcl will call us to free this
+ *     when necessary.
+ *
+ *----------------------------------------------------------------------
+ */
+static int 
+VfsPathInFilesystem(Tcl_Obj *pathPtr, ClientData *clientDataPtr) {
+    Tcl_Obj *normedObj;
+    int len, splitPosition;
+    char *normed;
+    VfsNativeRep *nativeRep;
+    Vfs_InterpCmd *interpCmd = NULL;
+    
+    if (TclInExit()) {
+       /* 
+        * Even Tcl_FSGetNormalizedPath may fail due to lack of system
+        * encodings, so we just say we can't handle anything if we are
+        * in the middle of the exit sequence.  We could perhaps be
+        * more subtle than this!
+        */
+       return TCLVFS_POSIXERROR;
+    }
+
+    normedObj = Tcl_FSGetNormalizedPath(NULL, pathPtr);
+    if (normedObj == NULL) {
+        return TCLVFS_POSIXERROR;
+    }
+    normed = Tcl_GetStringFromObj(normedObj, &len);
+    splitPosition = len;
+
+    /* 
+     * Find the most specific mount point for this path.
+     * Mount points are specified by unique strings, so
+     * we have to use a unique normalised path for the
+     * checks here.
+     * 
+     * Given mount points are paths, 'most specific' means
+     * longest path, so we scan from end to beginning
+     * checking for valid mount points at each separator.
+     */
+    while (1) {
+       /* 
+        * We need this test here both for an empty string being
+        * passed in above, and so that if we are testing a unix
+        * absolute path /foo/bar we will come around the loop
+        * with splitPosition at 0 for the last iteration, and we
+        * must return then.
+        */
+       if (splitPosition == 0) {
+           return TCLVFS_POSIXERROR;
+       }
+       
+       /* Is the path up to 'splitPosition' a valid moint point? */
+       interpCmd = Vfs_FindMount(normedObj, splitPosition);
+       if (interpCmd != NULL) break;
+
+       while (normed[--splitPosition] != VFS_SEPARATOR) {
+           if (splitPosition == 0) {
+               /* 
+                * We've reached the beginning of the string without
+                * finding a mount, so we've failed.
+                */
+               return TCLVFS_POSIXERROR;
+           }
+       }
+       
+       /* 
+        * We now know that normed[splitPosition] is a separator.
+        * However, we might have mounted a root filesystem with a
+        * name (for example 'ftp://') which actually includes a
+        * separator.  Therefore we test whether the path with
+        * a separator is a mount point.
+        * 
+        * Since we must have decremented splitPosition at least once
+        * already (above) 'splitPosition+1 <= len' so this won't
+        * access invalid memory.
+        */
+       interpCmd = Vfs_FindMount(normedObj, splitPosition+1);
+       if (interpCmd != NULL) {
+           splitPosition++;
+           break;
+       }
+    }
+    
+    /* 
+     * If we reach here we have a valid mount point, since the
+     * only way to escape the above loop is through a 'break' when
+     * an interpCmd is non-NULL.
+     */
+    nativeRep = (VfsNativeRep*) ckalloc(sizeof(VfsNativeRep));
+    nativeRep->splitPosition = splitPosition;
+    nativeRep->fsCmd = interpCmd;
+    *clientDataPtr = (ClientData)nativeRep;
+    return TCL_OK;
+}
+
+/* 
+ * Simple helper function to extract the native vfs representation of a
+ * path object, or NULL if no such representation exists.
+ */
+static VfsNativeRep* 
+VfsGetNativePath(Tcl_Obj* pathPtr) {
+    return (VfsNativeRep*) Tcl_FSGetInternalRep(pathPtr, &vfsFilesystem);
+}
+
+static void 
+VfsFreeInternalRep(ClientData clientData) {
+    VfsNativeRep *nativeRep = (VfsNativeRep*)clientData;
+    if (nativeRep != NULL) {
+       /* Free the native memory allocation */
+       ckfree((char*)nativeRep);
+    }
+}
+
+static ClientData 
+VfsDupInternalRep(ClientData clientData) {
+    VfsNativeRep *original = (VfsNativeRep*)clientData;
+
+    VfsNativeRep *nativeRep = (VfsNativeRep*) ckalloc(sizeof(VfsNativeRep));
+    nativeRep->splitPosition = original->splitPosition;
+    nativeRep->fsCmd = original->fsCmd;
+    
+    return (ClientData)nativeRep;
+}
+
+static Tcl_Obj* 
+VfsFilesystemPathType(Tcl_Obj *pathPtr) {
+    VfsNativeRep* nativeRep = VfsGetNativePath(pathPtr);
+    if (nativeRep == NULL) {
+       return NULL;
+    } else {
+       return nativeRep->fsCmd->mountCmd;
+    }
+}
+
+static Tcl_Obj*
+VfsFilesystemSeparator(Tcl_Obj* pathPtr) {
+    char sep=VFS_SEPARATOR;
+    return Tcl_NewStringObj(&sep,1);
+}
+
+static int
+VfsStat(pathPtr, bufPtr)
+    Tcl_Obj *pathPtr;          /* Path of file to stat (in current CP). */
+    Tcl_StatBuf *bufPtr;       /* Filled with results of stat call. */
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "stat", pathPtr);
+    if (mountCmd == NULL) {
+       return TCLVFS_POSIXERROR;
+    }
+
+    Tcl_SaveResult(interp, &savedResult);
+    /* Now we execute this mount point's callback. */
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal == TCL_OK) {
+       int statListLength;
+       Tcl_Obj* resPtr = Tcl_GetObjResult(interp);
+       if (Tcl_ListObjLength(interp, resPtr, &statListLength) == TCL_ERROR) {
+           returnVal = TCL_ERROR;
+       } else if (statListLength & 1) {
+           /* It is odd! */
+           returnVal = TCL_ERROR;
+       } else {
+           /* 
+            * The st_mode field is set part by the 'mode'
+            * and part by the 'type' stat fields.
+            */
+           bufPtr->st_mode = 0;
+           while (statListLength > 0) {
+               Tcl_Obj *field, *val;
+               char *fieldName;
+               statListLength -= 2;
+               Tcl_ListObjIndex(interp, resPtr, statListLength, &field);
+               Tcl_ListObjIndex(interp, resPtr, statListLength+1, &val);
+               fieldName = Tcl_GetString(field);
+               if (!strcmp(fieldName,"dev")) {
+                   long v;
+                   if (Tcl_GetLongFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_dev = v;
+               } else if (!strcmp(fieldName,"ino")) {
+                   long v;
+                   if (Tcl_GetLongFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_ino = (unsigned short)v;
+               } else if (!strcmp(fieldName,"mode")) {
+                   int v;
+                   if (Tcl_GetIntFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_mode |= v;
+               } else if (!strcmp(fieldName,"nlink")) {
+                   long v;
+                   if (Tcl_GetLongFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_nlink = (short)v;
+               } else if (!strcmp(fieldName,"uid")) {
+                   long v;
+                   if (Tcl_GetLongFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_uid = (short)v;
+               } else if (!strcmp(fieldName,"gid")) {
+                   long v;
+                   if (Tcl_GetLongFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_gid = (short)v;
+               } else if (!strcmp(fieldName,"size")) {
+                   Tcl_WideInt v;
+                   if (Tcl_GetWideIntFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_size = v;
+               } else if (!strcmp(fieldName,"atime")) {
+                   long v;
+                   if (Tcl_GetLongFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_atime = v;
+               } else if (!strcmp(fieldName,"mtime")) {
+                   long v;
+                   if (Tcl_GetLongFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_mtime = v;
+               } else if (!strcmp(fieldName,"ctime")) {
+                   long v;
+                   if (Tcl_GetLongFromObj(interp, val, &v) != TCL_OK) {
+                       returnVal = TCL_ERROR;
+                       break;
+                   }
+                   bufPtr->st_ctime = v;
+               } else if (!strcmp(fieldName,"type")) {
+                   char *str;
+                   str = Tcl_GetString(val);
+                   if (!strcmp(str,"directory")) {
+                       bufPtr->st_mode |= S_IFDIR;
+                   } else if (!strcmp(str,"file")) {
+                       bufPtr->st_mode |= S_IFREG;
+#ifdef S_ISLNK
+                   } else if (!strcmp(str,"link")) {
+                       bufPtr->st_mode |= S_IFLNK;
+#endif
+                   } else {
+                       /* 
+                        * Do nothing.  This means we do not currently
+                        * support anything except files and directories
+                        */
+                   }
+               } else {
+                   /* Ignore additional stat arguments */
+               }
+           }
+       }
+    }
+    
+    if (returnVal != TCL_OK && returnVal != TCLVFS_POSIXERROR) {
+       VfsInternalError(interp);
+    }
+
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+    
+    if (returnVal != TCL_OK && returnVal != TCLVFS_POSIXERROR) {
+       Tcl_SetErrno(ENOENT);
+        return TCLVFS_POSIXERROR;
+    } else {
+       return returnVal;
+    }
+}
+
+static int
+VfsAccess(pathPtr, mode)
+    Tcl_Obj *pathPtr;          /* Path of file to access (in current CP). */
+    int mode;                   /* Permission setting. */
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "access", pathPtr);
+    if (mountCmd == NULL) {
+       return TCLVFS_POSIXERROR;
+    }
+
+    Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewIntObj(mode));
+    /* Now we execute this mount point's callback. */
+    Tcl_SaveResult(interp, &savedResult);
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCL_OK && returnVal != TCLVFS_POSIXERROR) {
+       VfsInternalError(interp);
+    }
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+
+    if (returnVal != 0) {
+       Tcl_SetErrno(ENOENT);
+       return TCLVFS_POSIXERROR;
+    } else {
+       return returnVal;
+    }
+}
+
+static Tcl_Obj*
+VfsGetMode(int mode) {
+    Tcl_Obj *ret = Tcl_NewObj();
+    if (mode & O_RDONLY) {
+        Tcl_AppendToObj(ret, "r", 1);
+    } else if (mode & O_WRONLY || mode & O_RDWR) {
+       if (mode & O_TRUNC) {
+           Tcl_AppendToObj(ret, "w", 1);
+       } else {
+           Tcl_AppendToObj(ret, "a", 1);
+       }
+       if (mode & O_RDWR) {
+           Tcl_AppendToObj(ret, "+", 1);
+       }
+    }
+    return ret;
+}
+
+static Tcl_Channel
+VfsOpenFileChannel(cmdInterp, pathPtr, mode, permissions)
+    Tcl_Interp *cmdInterp;              /* Interpreter for error reporting;
+                                        * can be NULL. */
+    Tcl_Obj *pathPtr;                   /* Name of file to open. */
+    int mode;                          /* POSIX open mode. */
+    int permissions;                    /* If the open involves creating a
+                                        * file, with what modes to create
+                                        * it? */
+{
+    Tcl_Channel chan = NULL;
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_Obj *closeCallback = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "open", pathPtr);
+    if (mountCmd == NULL) {
+       return NULL;
+    }
+
+    Tcl_ListObjAppendElement(interp, mountCmd, VfsGetMode(mode));
+    Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewIntObj(permissions));
+    Tcl_SaveResult(interp, &savedResult);
+    /* Now we execute this mount point's callback. */
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal == TCL_OK) {
+       int reslen;
+       Tcl_Obj *resultObj;
+       /* 
+        * There may be file channel leaks on these two 
+        * error conditions, if the open command actually
+        * created a channel, but then passed us a bogus list.
+        */
+       resultObj =  Tcl_GetObjResult(interp);
+       if ((Tcl_ListObjLength(interp, resultObj, &reslen) == TCL_ERROR) 
+         || (reslen > 2) || (reslen == 0)) {
+           returnVal = TCL_ERROR;
+       } else {
+           Tcl_Obj *element;
+           Tcl_ListObjIndex(interp, resultObj, 0, &element);
+           chan = Tcl_GetChannel(interp, Tcl_GetString(element), 0);
+           
+           if (chan == NULL) {
+               returnVal = TCL_ERROR;
+           } else {
+               if (reslen == 2) {
+                   Tcl_ListObjIndex(interp, resultObj, 1, &element);
+                   closeCallback = element;
+                   Tcl_IncrRefCount(closeCallback);
+               }
+           }
+       }
+       Tcl_RestoreResult(interp, &savedResult);
+    } else {
+       /* Leave an error message if the cmdInterp is non NULL */
+       if (cmdInterp != NULL) {
+           if (returnVal == TCLVFS_POSIXERROR) {
+               Tcl_ResetResult(cmdInterp);
+               Tcl_AppendResult(cmdInterp, "couldn't open \"", 
+                                Tcl_GetString(pathPtr), "\": ",
+                                Tcl_PosixError(cmdInterp), (char *) NULL);
+           } else {
+               Tcl_Obj* error = Tcl_GetObjResult(interp);
+               /* 
+                * Copy over the error message to cmdInterp,
+                * duplicating it in case of threading issues.
+                */
+               Tcl_SetObjResult(cmdInterp, Tcl_DuplicateObj(error));
+           }
+       } else {
+           /* Report any error, since otherwise it is lost */
+           if (returnVal != TCLVFS_POSIXERROR) {
+               VfsInternalError(interp);
+           }
+       }
+       if (interp == cmdInterp) {
+           /* 
+            * We want our error message to propagate up,
+            * so we want to forget this result
+            */
+           Tcl_DiscardResult(&savedResult);
+       } else {
+           Tcl_RestoreResult(interp, &savedResult);
+       }
+    }
+
+    Tcl_DecrRefCount(mountCmd);
+
+    if (chan != NULL) {
+       /*
+        * We got the Channel from some Tcl code.  This means it was
+        * registered with the interpreter.  But we want a pristine
+        * channel which hasn't been registered with anyone.  We use
+        * Tcl_DetachChannel to do this for us.  We must use the
+        * correct interpreter.
+        */
+       if (Tcl_IsStandardChannel(chan)) {
+           /*
+            * If we have somehow ended up with a VFS channel being a std
+            * channel, it is likely auto-inherited, which we need to reverse.
+            * [Bug 1468291]
+            */
+           if (chan == Tcl_GetStdChannel(TCL_STDIN)) {
+               Tcl_SetStdChannel(NULL, TCL_STDIN);
+           } else if (chan == Tcl_GetStdChannel(TCL_STDOUT)) {
+               Tcl_SetStdChannel(NULL, TCL_STDOUT);
+           } else if (chan == Tcl_GetStdChannel(TCL_STDERR)) {
+               Tcl_SetStdChannel(NULL, TCL_STDERR);
+           }
+           Tcl_UnregisterChannel(NULL, chan);
+       }
+       Tcl_DetachChannel(interp, chan);
+
+       if (closeCallback != NULL) {
+           VfsChannelCleanupInfo *channelRet = NULL;
+           channelRet = (VfsChannelCleanupInfo*) 
+                           ckalloc(sizeof(VfsChannelCleanupInfo));
+           channelRet->channel = chan;
+           channelRet->interp = interp;
+           channelRet->closeCallback = closeCallback;
+           /* The channelRet structure will be freed in the callback */
+           Tcl_CreateCloseHandler(chan, &VfsCloseProc, 
+                                  (ClientData)channelRet);
+       }
+    }
+    return chan;
+}
+
+/* 
+ * IMPORTANT: This procedure must *not* modify the interpreter's result
+ * this leads to the objResultPtr being corrupted (somehow), and curious
+ * crashes in the future (which are very hard to debug ;-).
+ * 
+ * This is particularly important since we are evaluating arbitrary
+ * Tcl code in the callback.
+ * 
+ * Also note we are relying on the close-callback to occur just before
+ * the channel is about to be properly closed, but after all output
+ * has been flushed.  That way we can, in the callback, read in the
+ * entire contents of the channel and, say, compress it for storage
+ * into a tclkit or zip archive.
+ */
+static void 
+VfsCloseProc(ClientData clientData) {
+    VfsChannelCleanupInfo * channelRet = (VfsChannelCleanupInfo*) clientData;
+    int returnVal;
+    Tcl_SavedResult savedResult;
+    Tcl_Channel chan = channelRet->channel;
+    Tcl_Interp * interp = channelRet->interp;
+
+    Tcl_SaveResult(interp, &savedResult);
+
+    /* 
+     * The interpreter needs to know about the channel, else the Tcl
+     * callback will fail, so we register the channel (this allows
+     * the Tcl code to use the channel's string-name).
+     */
+    if (!Tcl_IsStandardChannel(chan)) {
+       Tcl_RegisterChannel(interp, chan);
+    }
+
+    if (!(Tcl_GetChannelMode(chan) & TCL_READABLE)) {
+       /* 
+        * We need to make this channel readable, since tclvfs
+        * documents that close callbacks are allowed to read
+        * from the channels we create.
+        */
+       
+       /* Currently if we reach here we have a bug */
+    }
+    
+    returnVal = Tcl_EvalObjEx(interp, channelRet->closeCallback, 
+                 TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCL_OK) {
+       VfsInternalError(interp);
+    }
+    Tcl_DecrRefCount(channelRet->closeCallback);
+
+    /* 
+     * More complications; we can't just unregister the channel,
+     * because it is in the middle of being cleaned up, and the cleanup
+     * code doesn't like a channel to be closed again while it is
+     * already being closed.  So, we do the same trick as above to
+     * unregister it without cleanup.
+     */
+    if (!Tcl_IsStandardChannel(chan)) {
+       Tcl_DetachChannel(interp, chan);
+    }
+
+    Tcl_RestoreResult(interp, &savedResult);
+    ckfree((char*)channelRet);
+}
+
+static int
+VfsMatchInDirectory(
+    Tcl_Interp *cmdInterp,     /* Interpreter to receive error msgs. */
+    Tcl_Obj *returnPtr,                /* Object to receive results. */
+    Tcl_Obj *dirPtr,           /* Contains path to directory to search. */
+    CONST char *pattern,       /* Pattern to match against. */
+    Tcl_GlobTypeData *types)   /* Object containing list of acceptable types.
+                                * May be NULL. */
+{
+    if ((types != NULL) && (types->type & TCL_GLOB_TYPE_MOUNT)) {
+       VfsMount *mountIter;
+       int len;
+       CONST char *prefix;
+       ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+       prefix = Tcl_GetStringFromObj(Tcl_FSGetNormalizedPath(NULL, dirPtr), 
+                                     &len);
+       if (prefix[len-1] == '/') {
+           /* 
+            * It's a root directory; we must subtract one for
+            * our comparisons below
+            */
+           len--;
+       }
+
+       /* Build list of mounts */
+       mountIter = tsdPtr->listOfMounts;
+       while (mountIter != NULL) {
+           if (mountIter->mountLen > (len+1) 
+               && !strncmp(mountIter->mountPoint, prefix, (size_t)len) 
+               && mountIter->mountPoint[len] == '/'
+               && strchr(mountIter->mountPoint+len+1, '/') == NULL
+               && Tcl_StringCaseMatch(mountIter->mountPoint+len+1, 
+                                      pattern, 0)) {
+               Tcl_Obj* mount = Tcl_NewStringObj(mountIter->mountPoint, 
+                                                 mountIter->mountLen);
+               Tcl_ListObjAppendElement(NULL, returnPtr, mount);
+           }
+           mountIter = mountIter->nextMount;
+       }
+       return TCL_OK;
+    } else {
+       Tcl_Obj *mountCmd = NULL;
+       Tcl_SavedResult savedResult;
+       int returnVal;
+       Tcl_Interp* interp;
+       int type = 0;
+       Tcl_Obj *vfsResultPtr = NULL;
+       
+       mountCmd = VfsBuildCommandForPath(&interp, "matchindirectory", dirPtr);
+       if (mountCmd == NULL) {
+           return TCLVFS_POSIXERROR;
+       }
+
+       if (types != NULL) {
+           type = types->type;
+       }
+
+       if (pattern == NULL) {
+           Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewObj());
+       } else {
+           Tcl_ListObjAppendElement(interp, mountCmd, 
+                                    Tcl_NewStringObj(pattern,-1));
+       }
+       Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewIntObj(type));
+       Tcl_SaveResult(interp, &savedResult);
+       /* Now we execute this mount point's callback. */
+       returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                                 TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+       if (returnVal != TCLVFS_POSIXERROR) {
+           vfsResultPtr = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
+       }
+       Tcl_RestoreResult(interp, &savedResult);
+       Tcl_DecrRefCount(mountCmd);
+
+       if (vfsResultPtr != NULL) {
+           if (returnVal == TCL_OK) {
+               Tcl_IncrRefCount(vfsResultPtr);
+               Tcl_ListObjAppendList(cmdInterp, returnPtr, vfsResultPtr);
+               Tcl_DecrRefCount(vfsResultPtr);
+           } else {
+               if (cmdInterp != NULL) {
+                   Tcl_SetObjResult(cmdInterp, vfsResultPtr);
+               } else {
+                   Tcl_DecrRefCount(vfsResultPtr);
+               }
+           }
+       }
+       return returnVal;
+    }
+}
+
+static int
+VfsDeleteFile(
+    Tcl_Obj *pathPtr)          /* Pathname of file to be removed */
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "deletefile", pathPtr);
+    if (mountCmd == NULL) {
+       return TCLVFS_POSIXERROR;
+    }
+
+    /* Now we execute this mount point's callback. */
+    Tcl_SaveResult(interp, &savedResult);
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCL_OK && returnVal != TCLVFS_POSIXERROR) {
+       VfsInternalError(interp);
+    }
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+    return returnVal;
+}
+
+static int
+VfsCreateDirectory(
+    Tcl_Obj *pathPtr)          /* Pathname of directory to create */
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "createdirectory", pathPtr);
+    if (mountCmd == NULL) {
+       return TCLVFS_POSIXERROR;
+    }
+
+    /* Now we execute this mount point's callback. */
+    Tcl_SaveResult(interp, &savedResult);
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCL_OK && returnVal != TCLVFS_POSIXERROR) {
+       VfsInternalError(interp);
+    }
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+    return returnVal;
+}
+
+static int
+VfsRemoveDirectory(
+    Tcl_Obj *pathPtr,          /* Pathname of directory to be removed
+                                * (UTF-8). */
+    int recursive,             /* If non-zero, removes directories that
+                                * are nonempty.  Otherwise, will only remove
+                                * empty directories. */
+    Tcl_Obj **errorPtr)                /* Location to store name of file
+                                * causing error. */
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "removedirectory", pathPtr);
+    if (mountCmd == NULL) {
+       return TCLVFS_POSIXERROR;
+    }
+
+    Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewIntObj(recursive));
+    /* Now we execute this mount point's callback. */
+    Tcl_SaveResult(interp, &savedResult);
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCL_OK && returnVal != TCLVFS_POSIXERROR) {
+       VfsInternalError(interp);
+    }
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+
+    if (returnVal == TCL_ERROR) {
+       /* Assume there was a problem with the directory being non-empty */
+        if (errorPtr != NULL) {
+            *errorPtr = pathPtr;
+           Tcl_IncrRefCount(*errorPtr);
+        }
+       Tcl_SetErrno(EEXIST);
+    }
+    return returnVal;
+}
+
+static CONST char * CONST86 *
+VfsFileAttrStrings(pathPtr, objPtrRef)
+    Tcl_Obj* pathPtr;
+    Tcl_Obj** objPtrRef;
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "fileattributes", pathPtr);
+    if (mountCmd == NULL) {
+       *objPtrRef = NULL;
+       return NULL;
+    }
+
+    Tcl_SaveResult(interp, &savedResult);
+    /* Now we execute this mount point's callback. */
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCL_OK && returnVal != TCLVFS_POSIXERROR) {
+       VfsInternalError(interp);
+    }
+    if (returnVal == TCL_OK) {
+       *objPtrRef = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
+    } else {
+       *objPtrRef = NULL;
+    }
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+    return NULL;
+}
+
+static int
+VfsFileAttrsGet(cmdInterp, index, pathPtr, objPtrRef)
+    Tcl_Interp *cmdInterp;     /* The interpreter for error reporting. */
+    int index;                 /* index of the attribute command. */
+    Tcl_Obj *pathPtr;          /* filename we are operating on. */
+    Tcl_Obj **objPtrRef;       /* for output. */
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "fileattributes", pathPtr);
+    if (mountCmd == NULL) {
+       return TCLVFS_POSIXERROR;
+    }
+
+    Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewIntObj(index));
+    Tcl_SaveResult(interp, &savedResult);
+    /* Now we execute this mount point's callback. */
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCLVFS_POSIXERROR) {
+       *objPtrRef = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
+    }
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+    
+    if (returnVal != TCLVFS_POSIXERROR) {
+       if (returnVal == TCL_OK) {
+           /* 
+            * Our caller expects a ref count of zero in
+            * the returned object pointer.
+            */
+       } else {
+           /* Leave error message in correct interp */
+           if (cmdInterp != NULL) {
+               Tcl_SetObjResult(cmdInterp, *objPtrRef);
+           } else {
+               Tcl_DecrRefCount(*objPtrRef);
+           }
+           *objPtrRef = NULL;
+       }
+    } else {
+       if (cmdInterp != NULL) {
+           Tcl_ResetResult(cmdInterp);
+           Tcl_AppendResult(cmdInterp, "couldn't read attributes for \"", 
+                            Tcl_GetString(pathPtr), "\": ",
+                            Tcl_PosixError(cmdInterp), (char *) NULL);
+       }
+    }
+    
+    return returnVal;
+}
+
+static int
+VfsFileAttrsSet(cmdInterp, index, pathPtr, objPtr)
+    Tcl_Interp *cmdInterp;     /* The interpreter for error reporting. */
+    int index;                 /* index of the attribute command. */
+    Tcl_Obj *pathPtr;          /* filename we are operating on. */
+    Tcl_Obj *objPtr;           /* for input. */
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    Tcl_Obj *errorPtr = NULL;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "fileattributes", pathPtr);
+    if (mountCmd == NULL) {
+       return TCLVFS_POSIXERROR;
+    }
+
+    Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewIntObj(index));
+    Tcl_ListObjAppendElement(interp, mountCmd, objPtr);
+    Tcl_SaveResult(interp, &savedResult);
+    /* Now we execute this mount point's callback. */
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCLVFS_POSIXERROR && returnVal != TCL_OK) {
+       errorPtr = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
+    }
+
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+    
+    if (cmdInterp != NULL) {
+       if (returnVal == TCLVFS_POSIXERROR) {
+           Tcl_ResetResult(cmdInterp);
+           Tcl_AppendResult(cmdInterp, "couldn't set attributes for \"", 
+                            Tcl_GetString(pathPtr), "\": ",
+                            Tcl_PosixError(cmdInterp), (char *) NULL);
+       } else if (errorPtr != NULL) {
+           /* 
+            * Leave error message in correct interp, errorPtr was
+            * duplicated above, in case of threading issues.
+            */
+           Tcl_SetObjResult(cmdInterp, errorPtr);
+       }
+    } else if (errorPtr != NULL) {
+       Tcl_DecrRefCount(errorPtr);
+    }
+    return returnVal;
+}
+
+static int 
+VfsUtime(pathPtr, tval)
+    Tcl_Obj* pathPtr;
+    struct utimbuf *tval;
+{
+    Tcl_Obj *mountCmd = NULL;
+    Tcl_SavedResult savedResult;
+    int returnVal;
+    Tcl_Interp* interp;
+    
+    mountCmd = VfsBuildCommandForPath(&interp, "utime", pathPtr);
+    if (mountCmd == NULL) {
+       return TCLVFS_POSIXERROR;
+    }
+
+    Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewLongObj(tval->actime));
+    Tcl_ListObjAppendElement(interp, mountCmd, Tcl_NewLongObj(tval->modtime));
+    /* Now we execute this mount point's callback. */
+    Tcl_SaveResult(interp, &savedResult);
+    returnVal = Tcl_EvalObjEx(interp, mountCmd, 
+                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    if (returnVal != TCL_OK && returnVal != TCLVFS_POSIXERROR) {
+       VfsInternalError(interp);
+    }
+    Tcl_RestoreResult(interp, &savedResult);
+    Tcl_DecrRefCount(mountCmd);
+
+    return returnVal;
+}
+
+static Tcl_Obj*
+VfsListVolumes(void)
+{
+    Tcl_Obj *retVal;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->vfsVolumes != NULL) {
+       Tcl_IncrRefCount(tsdPtr->vfsVolumes);
+       retVal = tsdPtr->vfsVolumes;
+    } else {
+       retVal = NULL;
+    }
+
+    return retVal;
+}
+
+static void
+Vfs_AddVolume(volume)
+    Tcl_Obj *volume;
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->vfsVolumes == NULL) {
+        tsdPtr->vfsVolumes = Tcl_NewObj();
+       Tcl_IncrRefCount(tsdPtr->vfsVolumes);
+    } else {
+#if 0
+       if (Tcl_IsShared(tsdPtr->vfsVolumes)) {
+           /* 
+            * Another thread is using this object, so we duplicate the
+            * object and reduce the refCount on the shared one.
+            */
+           Tcl_Obj *oldVols = tsdPtr->vfsVolumes;
+           tsdPtr->vfsVolumes = Tcl_DuplicateObj(oldVols);
+           Tcl_IncrRefCount(tsdPtr->vfsVolumes);
+           Tcl_DecrRefCount(oldVols);
+       }
+#endif
+    }
+    Tcl_ListObjAppendElement(NULL, tsdPtr->vfsVolumes, volume);
+}
+
+static int
+Vfs_RemoveVolume(volume)
+    Tcl_Obj *volume;
+{
+    int i, len;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    Tcl_ListObjLength(NULL, tsdPtr->vfsVolumes, &len);
+    for (i = 0;i < len; i++) {
+       Tcl_Obj *vol;
+        Tcl_ListObjIndex(NULL, tsdPtr->vfsVolumes, i, &vol);
+       if (!strcmp(Tcl_GetString(vol),Tcl_GetString(volume))) {
+           /* It's in the list, at index i */
+           if (len == 1) {
+               /* An optimization here */
+               Tcl_DecrRefCount(tsdPtr->vfsVolumes);
+               tsdPtr->vfsVolumes = NULL;
+           } else {
+               /*
+                * Make ourselves the unique owner
+                * XXX: May be unnecessary now that it is tsd
+                */
+               if (Tcl_IsShared(tsdPtr->vfsVolumes)) {
+                   Tcl_Obj *oldVols = tsdPtr->vfsVolumes;
+                   tsdPtr->vfsVolumes = Tcl_DuplicateObj(oldVols);
+                   Tcl_IncrRefCount(tsdPtr->vfsVolumes);
+                   Tcl_DecrRefCount(oldVols);
+               }
+               /* Remove the element */
+               Tcl_ListObjReplace(NULL, tsdPtr->vfsVolumes, i, 1, 0, NULL);
+               return TCL_OK;
+           }
+       }
+    }
+
+    return TCL_ERROR;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * VfsBuildCommandForPath --
+ *
+ *     Given a path object which we know belongs to the vfs, and a 
+ *     command string (one of the standard filesystem operations
+ *     "stat", "matchindirectory" etc), build the standard vfs
+ *     Tcl command and arguments to carry out that operation.
+ *     
+ *     If the command is successfully built, it is returned to the
+ *     caller with a refCount of 1.  The caller also needs to know
+ *     which Tcl interpreter to evaluate the command in; this
+ *     is returned in the 'iRef' provided.
+ *     
+ *     Each mount-point dictates a command prefix to use for a 
+ *     particular file.  We start with that and then add 4 parameters,
+ *     as follows:
+ *     
+ *     (1) the 'cmd' to use
+ *     (2) the mount point of this path (which is the portion of the
+ *     path string which lies outside the vfs).
+ *     (3) the remainder of the path which lies inside the vfs
+ *     (4) the original (possibly unnormalized) path string used
+ *     in the command.
+ *     
+ *     Example (i):
+ *     
+ *     If 'C:/Apps/data.zip' is mounted on top of
+ *     itself, then if we do:
+ *     
+ *     cd C:/Apps
+ *     file exists data.zip/foo/bar.txt
+ *     
+ *     this will lead to:
+ *     
+ *     <mountcmd> "access" C:/Apps/data.zip foo/bar.txt data.zip/foo/bar.txt
+ *     
+ *     Example (ii)
+ *     
+ *     If 'ftp://' is mounted as a new volume,
+ *     then 'glob -dir ftp://ftp.scriptics.com *' will lead to:
+ *     
+ *     <mountcmd> "matchindirectory" ftp:// ftp.scriptics.com \
+ *       ftp://ftp.scriptics.com
+ *       
+ *     
+ * Results:
+ *     Returns a list containing the command, or NULL if an
+ *     error occurred.  If the interpreter for this vfs command
+ *     is in the process of being deleted, we always return NULL.
+ *
+ * Side effects:
+ *     None except memory allocation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj* 
+VfsBuildCommandForPath(Tcl_Interp **iRef, CONST char* cmd, Tcl_Obj *pathPtr) {
+    Tcl_Obj *normed;
+    Tcl_Obj *mountCmd;
+    int len;
+    int splitPosition;
+    int dummyLen;
+    VfsNativeRep *nativeRep;
+    Tcl_Interp *interp;
+    
+    char *normedString;
+
+    nativeRep = VfsGetNativePath(pathPtr);
+    if (nativeRep == NULL) {
+       return NULL;
+    }
+    
+    interp = nativeRep->fsCmd->interp;
+    
+    if (Tcl_InterpDeleted(interp)) {
+        return NULL;
+    }
+    
+    splitPosition = nativeRep->splitPosition;
+    normed = Tcl_FSGetNormalizedPath(NULL, pathPtr);
+    normedString = Tcl_GetStringFromObj(normed, &len);
+    
+    mountCmd = Tcl_DuplicateObj(nativeRep->fsCmd->mountCmd);
+    Tcl_IncrRefCount(mountCmd);
+    if (Tcl_ListObjLength(NULL, mountCmd, &dummyLen) == TCL_ERROR) {
+       Tcl_DecrRefCount(mountCmd);
+       return NULL;
+    }
+    Tcl_ListObjAppendElement(NULL, mountCmd, Tcl_NewStringObj(cmd,-1));
+    if (splitPosition == len) {
+       Tcl_ListObjAppendElement(NULL, mountCmd, normed);
+       Tcl_ListObjAppendElement(NULL, mountCmd, Tcl_NewStringObj("",0));
+    } else {
+       Tcl_ListObjAppendElement(NULL, mountCmd, 
+               Tcl_NewStringObj(normedString,splitPosition));
+       if ((normedString[splitPosition] != VFS_SEPARATOR) 
+           || (VFS_SEPARATOR ==':')) {
+           /* This will occur if we mount 'ftp://' */
+           splitPosition--;
+       }
+       Tcl_ListObjAppendElement(NULL, mountCmd, 
+               Tcl_NewStringObj(normedString+splitPosition+1,
+                                len-splitPosition-1));
+    }
+    Tcl_ListObjAppendElement(NULL, mountCmd, pathPtr);
+
+    if (iRef != NULL) {
+        *iRef = interp;
+    }
+    
+    return mountCmd;
+}
+
+static void 
+VfsExitProc(ClientData clientData)
+{
+    Tcl_FSUnregister(&vfsFilesystem);
+}
+
+static void
+VfsThreadExitProc(ClientData clientData)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    /*
+     * This is probably no longer needed, because each individual
+     * interp's cleanup will trigger removal of all volumes which
+     * belong to it.
+     */
+    if (tsdPtr->vfsVolumes != NULL) {
+       Tcl_DecrRefCount(tsdPtr->vfsVolumes);
+       tsdPtr->vfsVolumes = NULL;
+    }
+    if (tsdPtr->internalErrorScript != NULL) {
+       Tcl_DecrRefCount(tsdPtr->internalErrorScript);
+       tsdPtr->internalErrorScript = NULL;
+    }
+}
diff --git a/8.x/tclvfs/http2.6/http.n b/8.x/tclvfs/http2.6/http.n
new file mode 100644 (file)
index 0000000..06260f1
--- /dev/null
@@ -0,0 +1,544 @@
+'\"
+'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-2000 by Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+'\" RCS: @(#) $Id: http.n,v 1.2 2008/03/11 02:15:22 hobbs Exp $
+'\" 
+.so man.macros
+.TH "Http" n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Http \- Client-side implementation of the HTTP/1.1 protocol.
+.SH SYNOPSIS
+\fBpackage require http ?2.6?\fP
+.sp
+\fB::http::config \fI?options?\fR
+.sp
+\fB::http::geturl \fIurl ?options?\fR
+.sp
+\fB::http::formatQuery \fIlist\fR
+.sp
+\fB::http::reset \fItoken\fR
+.sp
+\fB::http::wait \fItoken\fR
+.sp
+\fB::http::status \fItoken\fR
+.sp
+\fB::http::size \fItoken\fR
+.sp
+\fB::http::code \fItoken\fR
+.sp
+\fB::http::ncode \fItoken\fR
+.sp
+\fB::http::data \fItoken\fR
+.sp
+\fB::http::error \fItoken\fR
+.sp
+\fB::http::cleanup \fItoken\fR
+.sp
+\fB::http::register \fIproto port command\fR
+.sp
+\fB::http::unregister \fIproto\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBhttp\fR package provides the client side of the HTTP/1.1
+protocol.  The package implements the GET, POST, and HEAD operations
+of HTTP/1.1.  It allows configuration of a proxy host to get through
+firewalls.  The package is compatible with the \fBSafesock\fR security
+policy, so it can be used by untrusted applets to do URL fetching from
+a restricted set of hosts. This package can be extened to support
+additional HTTP transport protocols, such as HTTPS, by providing
+a custom \fBsocket\fR command, via \fBhttp::register\fR.
+.PP
+The \fB::http::geturl\fR procedure does a HTTP transaction.
+Its \fIoptions \fR determine whether a GET, POST, or HEAD transaction
+is performed.  
+The return value of \fB::http::geturl\fR is a token for the transaction.
+The value is also the name of an array in the ::http namespace
+that contains state information about the transaction.  The elements
+of this array are described in the STATE ARRAY section.
+.PP
+If the \fB-command\fP option is specified, then
+the HTTP operation is done in the background.
+\fB::http::geturl\fR returns immediately after generating the
+HTTP request and the callback is invoked
+when the transaction completes.  For this to work, the Tcl event loop
+must be active.  In Tk applications this is always true.  For pure-Tcl
+applications, the caller can use \fB::http::wait\fR after calling
+\fB::http::geturl\fR to start the event loop.
+.SH COMMANDS
+.TP
+\fB::http::config\fP ?\fIoptions\fR?
+The \fB::http::config\fR command is used to set and query the name of the
+proxy server and port, and the User-Agent name used in the HTTP
+requests.  If no options are specified, then the current configuration
+is returned.  If a single argument is specified, then it should be one
+of the flags described below.  In this case the current value of
+that setting is returned.  Otherwise, the options should be a set of
+flags and values that define the configuration:
+.RS
+.TP
+\fB\-accept\fP \fImimetypes\fP
+The Accept header of the request.  The default is */*, which means that
+all types of documents are accepted.  Otherwise you can supply a 
+comma separated list of mime type patterns that you are
+willing to receive.  For example, "image/gif, image/jpeg, text/*".
+.TP
+\fB\-proxyhost\fP \fIhostname\fP
+The name of the proxy host, if any.  If this value is the
+empty string, the URL host is contacted directly.
+.TP
+\fB\-proxyport\fP \fInumber\fP
+The proxy port number.
+.TP
+\fB\-proxyfilter\fP \fIcommand\fP
+The command is a callback that is made during
+\fB::http::geturl\fR
+to determine if a proxy is required for a given host.  One argument, a
+host name, is added to \fIcommand\fR when it is invoked.  If a proxy
+is required, the callback should return a two element list containing
+the proxy server and proxy port.  Otherwise the filter should return
+an empty list.  The default filter returns the values of the
+\fB\-proxyhost\fR and \fB\-proxyport\fR settings if they are
+non-empty.
+.TP
+\fB\-useragent\fP \fIstring\fP
+The value of the User-Agent header in the HTTP request.  The default
+is \fB"Tcl http client package 2.2."\fR
+.RE
+.TP
+\fB::http::geturl\fP \fIurl\fP ?\fIoptions\fP? 
+The \fB::http::geturl\fR command is the main procedure in the package.
+The \fB\-query\fR option causes a POST operation and
+the \fB\-validate\fR option causes a HEAD operation;
+otherwise, a GET operation is performed.  The \fB::http::geturl\fR command
+returns a \fItoken\fR value that can be used to get
+information about the transaction.  See the STATE ARRAY and ERRORS section for
+details.  The \fB::http::geturl\fR command blocks until the operation
+completes, unless the \fB\-command\fR option specifies a callback
+that is invoked when the HTTP transaction completes.
+\fB::http::geturl\fR takes several options:
+.RS
+.TP
+\fB\-binary\fP \fIboolean\fP
+Specifies whether to force interpreting the url data as binary.  Normally
+this is auto-detected (anything not beginning with a \fBtext\fR content
+type or whose content encoding is \fBgzip\fR or \fBcompress\fR is
+considered binary data).
+.TP
+\fB\-blocksize\fP \fIsize\fP
+The blocksize used when reading the URL.
+At most \fIsize\fR bytes are read at once.  After each block, a call to the
+\fB\-progress\fR callback is made (if that option is specified).
+.TP
+\fB\-channel\fP \fIname\fP
+Copy the URL contents to channel \fIname\fR instead of saving it in
+\fBstate(body)\fR.
+.TP
+\fB\-command\fP \fIcallback\fP
+Invoke \fIcallback\fP after the HTTP transaction completes.
+This option causes \fB::http::geturl\fP to return immediately.
+The \fIcallback\fP gets an additional argument that is the \fItoken\fR returned
+from \fB::http::geturl\fR. This token is the name of an array that is
+described in the STATE ARRAY section.  Here is a template for the
+callback:
+.RS
+.CS
+proc httpCallback {token} {
+    upvar #0 $token state
+    # Access state as a Tcl array
+}
+.CE
+.RE
+.TP
+\fB\-handler\fP \fIcallback\fP
+Invoke \fIcallback\fP whenever HTTP data is available; if present, nothing
+else will be done with the HTTP data.  This procedure gets two additional
+arguments: the socket for the HTTP data and the \fItoken\fR returned from
+\fB::http::geturl\fR.  The token is the name of a global array that is described
+in the STATE ARRAY section.  The procedure is expected to return the number
+of bytes read from the socket.  Here is a template for the callback:
+.RS
+.CS
+proc httpHandlerCallback {socket token} {
+    upvar #0 $token state
+    # Access socket, and state as a Tcl array
+    ...
+    (example: set data [read $socket 1000];set nbytes [string length $data])
+    ...
+    return nbytes
+}
+.CE
+.RE
+.TP
+\fB\-headers\fP \fIkeyvaluelist\fP
+This option is used to add extra headers to the HTTP request.  The
+\fIkeyvaluelist\fR argument must be a list with an even number of
+elements that alternate between keys and values.  The keys become
+header field names.  Newlines are stripped from the values so the
+header cannot be corrupted.  For example, if \fIkeyvaluelist\fR is
+\fBPragma no-cache\fR then the following header is included in the
+HTTP request:
+.CS
+Pragma: no-cache
+.CE
+.TP
+\fB\-progress\fP \fIcallback\fP
+The \fIcallback\fR is made after each transfer of data from the URL.
+The callback gets three additional arguments: the \fItoken\fR from
+\fB::http::geturl\fR, the expected total size of the contents from the
+\fBContent-Length\fR meta-data, and the current number of bytes
+transferred so far.  The expected total size may be unknown, in which
+case zero is passed to the callback.  Here is a template for the
+progress callback:
+.RS
+.CS
+proc httpProgress {token total current} {
+    upvar #0 $token state
+}
+.CE
+.RE
+.TP
+\fB\-query\fP \fIquery\fP
+This flag causes \fB::http::geturl\fR to do a POST request that passes the
+\fIquery\fR to the server. The \fIquery\fR must be a x-url-encoding
+formatted query.  The \fB::http::formatQuery\fR procedure can be used to
+do the formatting.
+.TP
+\fB\-queryblocksize\fP \fIsize\fP
+The blocksize used when posting query data to the URL.
+At most 
+\fIsize\fR
+bytes are written at once.  After each block, a call to the
+\fB\-queryprogress\fR
+callback is made (if that option is specified).
+.TP
+\fB\-querychannel\fP \fIchannelID\fP
+This flag causes \fB::http::geturl\fR to do a POST request that passes the
+data contained in \fIchannelID\fR to the server. The data contained in \fIchannelID\fR must be a x-url-encoding
+formatted query unless the \fB\-type\fP option below is used.
+If a Content-Length header is not specified via the \fB\-headers\fR options,
+\fB::http::geturl\fR attempts to determine the size of the post data
+in order to create that header.  If it is
+unable to determine the size, it returns an error.
+.TP
+\fB\-queryprogress\fP \fIcallback\fP
+The \fIcallback\fR is made after each transfer of data to the URL
+(i.e. POST) and acts exactly like the \fB\-progress\fR option (the
+callback format is the same).
+.TP
+\fB\-timeout\fP \fImilliseconds\fP
+If \fImilliseconds\fR is non-zero, then \fB::http::geturl\fR sets up a timeout
+to occur after the specified number of milliseconds.
+A timeout results in a call to \fB::http::reset\fP and to
+the \fB-command\fP callback, if specified.
+The return value of \fB::http::status\fP is \fBtimeout\fP
+after a timeout has occurred.
+.TP
+\fB\-type\fP \fImime-type\fP
+Use \fImime-type\fR as the \fBContent-Type\fR value, instead of the
+default value (\fBapplication/x-www-form-urlencoded\fR) during a
+POST operation.
+.TP
+\fB\-validate\fP \fIboolean\fP
+If \fIboolean\fR is non-zero, then \fB::http::geturl\fR does an HTTP HEAD
+request.  This request returns meta information about the URL, but the
+contents are not returned.  The meta information is available in the
+\fBstate(meta) \fR variable after the transaction.  See the STATE
+ARRAY section for details.
+.TP
+\fB\-protocol\fP \fIversion\fP 
+Select the HTTP protocol version to use. This can really only be 1.0
+or 1.1. The default is 1.1. Should only be necessary for servers that
+do not understand or otherwise complain about HTTP/1.1.
+.TP
+\fB\-keepalive\fP \fIboolean\fP
+If true, attempt to keep the connection open for servicing multiple
+requests.
+.TP
+\fB\-socketvar\fP \fIvariablename\fP
+Provide a name of a variable to hold the channel used for multiple
+requests. After the first HTTP transaction the named variable will
+contain the channel name. Further requests can be made on the open
+channel until either a request is made with the \fB-keepalive\fR flag
+set to false or until the remote host closes the connection. Once the
+connection is closed the variable will be reset to the empty
+string. See MULTIPLE REQUESTS.
+.RE
+.TP
+\fB::http::formatQuery\fP \fIkey value\fP ?\fIkey value\fP ...?
+This procedure does x-url-encoding of query data.  It takes an even
+number of arguments that are the keys and values of the query.  It
+encodes the keys and values, and generates one string that has the
+proper & and = separators.  The result is suitable for the
+\fB\-query\fR value passed to \fB::http::geturl\fR.
+.TP
+\fB::http::reset\fP \fItoken\fP ?\fIwhy\fP?
+This command resets the HTTP transaction identified by \fItoken\fR, if
+any.  This sets the \fBstate(status)\fP value to \fIwhy\fP, which defaults to \fBreset\fR, and then calls the registered \fB\-command\fR callback.
+.TP
+\fB::http::wait\fP \fItoken\fP
+This is a convenience procedure that blocks and waits for the
+transaction to complete.  This only works in trusted code because it
+uses \fBvwait\fR.  Also, it's not useful for the case where
+\fB::http::geturl\fP is called \fIwithout\fP the \fB-command\fP option
+because in this case the \fB::http::geturl\fP call doesn't return
+until the HTTP transaction is complete, and thus there's nothing to
+wait for.
+.TP
+\fB::http::data\fP \fItoken\fP
+This is a convenience procedure that returns the \fBbody\fP element
+(i.e., the URL data) of the state array.
+.TP
+\fB::http::error\fP \fItoken\fP
+This is a convenience procedure that returns the \fBerror\fP element
+of the state array.
+.TP
+\fB::http::status\fP \fItoken\fP
+This is a convenience procedure that returns the \fBstatus\fP element of
+the state array.
+.TP
+\fB::http::code\fP \fItoken\fP
+This is a convenience procedure that returns the \fBhttp\fP element of the
+state array.
+.TP
+\fB::http::ncode\fP \fItoken\fP
+This is a convenience procedure that returns just the numeric return
+code (200, 404, etc.) from the \fBhttp\fP element of the state array.
+.TP
+\fB::http::size\fP \fItoken\fP
+This is a convenience procedure that returns the \fBcurrentsize\fP
+element of the state array, which represents the number of bytes
+received from the URL in the \fB::http::geturl\fP call.
+.TP
+\fB::http::cleanup\fP \fItoken\fP
+This procedure cleans up the state associated with the connection
+identified by \fItoken\fP.  After this call, the procedures
+like \fB::http::data\fP cannot be used to get information
+about the operation.  It is \fIstrongly\fP recommended that you call
+this function after you're done with a given HTTP request.  Not doing
+so will result in memory not being freed, and if your app calls
+\fB::http::geturl\fP enough times, the memory leak could cause a
+performance hit...or worse.
+.TP
+\fB::http::register\fP \fIproto port command\fP
+This procedure allows one to provide custom HTTP transport types
+such as HTTPS, by registering a prefix, the default port, and the
+command to execute to create the Tcl \fBchannel\fR. E.g.:
+.RS
+.CS
+package require http
+package require tls
+
+http::register https 443 ::tls::socket
+
+set token [http::geturl https://my.secure.site/]
+.CE
+.RE
+.TP
+\fB::http::unregister\fP \fIproto\fP
+This procedure unregisters a protocol handler that was previously
+registered via \fBhttp::register\fR.
+
+.SH "ERRORS"
+The \fBhttp::geturl\fP procedure will raise errors in the following cases:
+invalid command line options,
+an invalid URL,
+a URL on a non-existent host,
+or a URL at a bad port on an existing host.
+These errors mean that it
+cannot even start the network transaction.
+It will also raise an error if it gets an I/O error while
+writing out the HTTP request header.
+For synchronous \fB::http::geturl\fP calls (where \fB-command\fP is
+not specified), it will raise an error if it gets an I/O error while
+reading the HTTP reply headers or data.  Because \fB::http::geturl\fP
+doesn't return a token in these cases, it does all the required
+cleanup and there's no issue of your app having to call
+\fB::http::cleanup\fP.
+.PP
+For asynchronous \fB::http::geturl\fP calls, all of the above error
+situations apply, except that if there's any error while 
+reading the
+HTTP reply headers or data, no exception is thrown.  This is because
+after writing the HTTP headers, \fB::http::geturl\fP returns, and the
+rest of the HTTP transaction occurs in the background.  The command
+callback can check if any error occurred during the read by calling
+\fB::http::status\fP to check the status and if it's \fIerror\fP,
+calling \fB::http::error\fP to get the error message.
+.PP
+Alternatively, if the main program flow reaches a point where it needs
+to know the result of the asynchronous HTTP request, it can call
+\fB::http::wait\fP and then check status and error, just as the
+callback does.
+.PP
+In any case, you must still call
+\fBhttp::cleanup\fP to delete the state array when you're done.
+.PP
+There are other possible results of the HTTP transaction
+determined by examining the status from \fBhttp::status\fP.
+These are described below.
+.TP
+ok
+If the HTTP transaction completes entirely, then status will be \fBok\fP.
+However, you should still check the \fBhttp::code\fP value to get
+the HTTP status.  The \fBhttp::ncode\fP procedure provides just
+the numeric error (e.g., 200, 404 or 500) while the \fBhttp::code\fP
+procedure returns a value like "HTTP 404 File not found".
+.TP
+eof
+If the server closes the socket without replying, then no error
+is raised, but the status of the transaction will be \fBeof\fP.
+.TP
+error
+The error message will also be stored in the \fBerror\fP status
+array element, accessible via \fB::http::error\fP.
+.PP
+Another error possibility is that \fBhttp::geturl\fP is unable to
+write all the post query data to the server before the server
+responds and closes the socket.
+The error message is saved in the \fBposterror\fP status array
+element and then  \fBhttp::geturl\fP attempts to complete the
+transaction.
+If it can read the server's response
+it will end up with an \fBok\fP status, otherwise it will have
+an \fBeof\fP status.
+
+.SH "STATE ARRAY"
+The \fB::http::geturl\fR procedure returns a \fItoken\fR that can be used to
+get to the state of the HTTP transaction in the form of a Tcl array.
+Use this construct to create an easy-to-use array variable:
+.CS
+upvar #0 $token state
+.CE
+Once the data associated with the url is no longer needed, the state
+array should be unset to free up storage.
+The \fBhttp::cleanup\fP procedure is provided for that purpose.
+The following elements of
+the array are supported:
+.RS
+.TP
+\fBbody\fR
+The contents of the URL.  This will be empty if the \fB\-channel\fR
+option has been specified.  This value is returned by the \fB::http::data\fP command.
+.TP
+\fBcharset\fR
+The value of the charset attribute from the \fBContent-Type\fR meta-data
+value.  If none was specified, this defaults to the RFC standard
+\fBiso8859-1\fR, or the value of \fB$::http::defaultCharset\fR.  Incoming
+text data will be automatically converted from this charset to utf-8.
+.TP
+\fBcoding\fR
+A copy of the \fBContent-Encoding\fR meta-data value.
+.TP
+\fBcurrentsize\fR
+The current number of bytes fetched from the URL.
+This value is returned by the \fB::http::size\fP command.
+.TP
+\fBerror\fR
+If defined, this is the error string seen when the HTTP transaction
+was aborted.
+.TP
+\fBhttp\fR
+The HTTP status reply from the server.  This value
+is returned by the \fB::http::code\fP command.  The format of this value is:
+.RS
+.CS
+\fIHTTP/1.0 code string\fP
+.CE
+The \fIcode\fR is a three-digit number defined in the HTTP standard.
+A code of 200 is OK.  Codes beginning with 4 or 5 indicate errors.
+Codes beginning with 3 are redirection errors.  In this case the
+\fBLocation\fR meta-data specifies a new URL that contains the
+requested information.
+.RE
+.TP
+\fBmeta\fR
+The HTTP protocol returns meta-data that describes the URL contents.
+The \fBmeta\fR element of the state array is a list of the keys and
+values of the meta-data.  This is in a format useful for initializing
+an array that just contains the meta-data:
+.RS
+.CS
+array set meta $state(meta)
+.CE
+Some of the meta-data keys are listed below, but the HTTP standard defines
+more, and servers are free to add their own.
+.TP
+\fBContent-Type\fR
+The type of the URL contents.  Examples include \fBtext/html\fR,
+\fBimage/gif,\fR \fBapplication/postscript\fR and
+\fBapplication/x-tcl\fR.
+.TP
+\fBContent-Length\fR
+The advertised size of the contents.  The actual size obtained by
+\fB::http::geturl\fR is available as \fBstate(size)\fR.
+.TP
+\fBLocation\fR
+An alternate URL that contains the requested data.
+.RE
+.TP
+\fBposterror\fR
+The error, if any, that occurred while writing
+the post query data to the server.
+.TP
+\fBstatus\fR
+Either \fBok\fR, for successful completion, \fBreset\fR for
+user-reset, \fBtimeout\fP if a timeout occurred before the transaction
+could complete, or \fBerror\fR for an error condition.  During the
+transaction this value is the empty string.
+.TP
+\fBtotalsize\fR
+A copy of the \fBContent-Length\fR meta-data value.
+.TP
+\fBtype\fR
+A copy of the \fBContent-Type\fR meta-data value.
+.TP
+\fBurl\fR
+The requested URL.
+.RE
+.SH EXAMPLE
+.DS
+# Copy a URL to a file and print meta-data
+proc ::http::copy { url file {chunk 4096} } {
+    set out [open $file w]
+    set token [geturl $url -channel $out -progress ::http::Progress \\
+       -blocksize $chunk]
+    close $out
+    # This ends the line started by http::Progress
+    puts stderr ""
+    upvar #0 $token state
+    set max 0
+    foreach {name value} $state(meta) {
+       if {[string length $name] > $max} {
+           set max [string length $name]
+       }
+       if {[regexp -nocase ^location$ $name]} {
+           # Handle URL redirects
+           puts stderr "Location:$value"
+           return [copy [string trim $value] $file $chunk]
+       }
+    }
+    incr max
+    foreach {name value} $state(meta) {
+       puts [format "%-*s %s" $max $name: $value]
+    }
+
+    return $token
+}
+proc ::http::Progress {args} {
+    puts -nonewline stderr . ; flush stderr
+}
+.DE
+
+.SH "SEE ALSO"
+safe(n), socket(n), safesock(n)
+
+.SH KEYWORDS
+security policy, socket
diff --git a/8.x/tclvfs/http2.6/http.tcl b/8.x/tclvfs/http2.6/http.tcl
new file mode 100644 (file)
index 0000000..3fcaa65
--- /dev/null
@@ -0,0 +1,1441 @@
+# http.tcl --
+#
+#      Client-side HTTP for GET, POST, and HEAD commands. These routines can
+#      be used in untrusted code that uses the Safesock security policy. These
+#      procedures use a callback interface to avoid using vwait, which is not
+#      defined in the safe base.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: http.tcl,v 1.8 2008/08/11 22:14:26 patthoyts Exp $
+
+# Rough version history post-core-split:
+# 2.5   Added HTTP/1.1 support for persistent connections. New options
+#       -protocol, -keepalive, -socketvar. (Pat Thoyts)
+# 2.6   Added support for HTTP/1.1 extensions.  New option -method used
+#       for WebDav. (Vince Darley)
+# 2.6.1 Synchronized with Tcl http 2.4.4 (encoding enhancements)
+# 2.6.2 Removed to -socketvar option and now handle socket usage internally
+# 2.6.3 Added support for chunked encoding.
+# 2.6.4 Merged in jcw's webdav mods to fix the chunked transfer
+# 2.6.5 Merged up to 2.5.3 from tcl cvs (formMap, url decomposition)
+# 2.6.6 Support content-encoding gzip. Handle 0 length body in chunked.
+# 2.6.7 Merged up to 2.5.5 from tcl cvs, whitespace corrections
+# 2.6.8 Merged with core version in 8.5.2 and 8.4.19 and above changes.
+#      Core is 2.7, this v2.6.8 has defaultKeepalive 1 and different
+#      default -useragent.
+# 2.6.9 Merged fix for zlib crc check on 64bit systems.
+
+package require Tcl 8.4
+# keep this in sync with pkgIndex.tcl
+package provide http 2.6.9
+
+namespace eval http {
+    # Allow resourcing to not clobber existing data
+
+    variable http
+    if {![info exists http]} {
+       array set http {
+           -accept */*
+           -proxyhost {}
+           -proxyport {}
+           -proxyfilter http::ProxyRequired
+           -urlencoding utf-8
+       }
+       # Use a Mozilla compatible useragent header to avoid problems with
+       # some web sites.
+        set http(-useragent) \
+            "Mozilla/5.0 ([string totitle $::tcl_platform(platform)]; U;\
+             $::tcl_platform(os) $::tcl_platform(osVersion))\
+             http/[package provide http] Tcl/[package provide Tcl]"
+    }
+
+    proc init {} {
+       # Set up the map for quoting chars. RFC3986 Section 2.3 say percent
+       # encode all except: "... percent-encoded octets in the ranges of ALPHA
+       # (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E),
+       # underscore (%5F), or tilde (%7E) should not be created by URI
+       # producers ..."
+       for {set i 0} {$i <= 256} {incr i} {
+           set c [format %c $i]
+           if {![string match {[-._~a-zA-Z0-9]} $c]} {
+               set map($c) %[format %.2x $i]
+           }
+       }
+       # These are handled specially
+       set map(\n) %0d%0a
+       variable formMap [array get map]
+
+       # Create a map for HTTP/1.1 open sockets
+       variable socketmap
+       if {[info exists socketmap]} {
+           # Close but don't remove open sockets on re-init
+           foreach {url sock} [array get socketmap] {
+               catch {close $sock}
+           }
+       }
+       array set socketmap {}
+    }
+    init
+
+    variable urlTypes
+    if {![info exists urlTypes]} {
+       set urlTypes(http) [list 80 ::socket]
+    }
+
+    variable encodings [string tolower [encoding names]]
+    # This can be changed, but iso8859-1 is the RFC standard.
+    variable defaultCharset
+    if {![info exists defaultCharset]} {
+       set defaultCharset "iso8859-1"
+    }
+
+    # Force RFC 3986 strictness in geturl url verification?
+    variable strict
+    if {![info exists strict]} {
+       set strict 1
+    }
+
+    # Let user control default keepalive for compatibility
+    variable defaultKeepalive
+    if {![info exists defaultKeepalive]} {
+       set defaultKeepalive 0
+    }
+
+    namespace export geturl config reset wait formatQuery register unregister
+    # Useful, but not exported: data size status code
+}
+
+# http::Log --
+#
+#      Debugging output -- define this to observe HTTP/1.1 socket usage.
+#      Should echo any args received.
+#
+# Arguments:
+#     msg      Message to output
+#
+proc http::Log {args} {}
+
+# http::register --
+#
+#     See documentation for details.
+#
+# Arguments:
+#     proto           URL protocol prefix, e.g. https
+#     port            Default port for protocol
+#     command         Command to use to create socket
+# Results:
+#     list of port and command that was registered.
+
+proc http::register {proto port command} {
+    variable urlTypes
+    set urlTypes($proto) [list $port $command]
+}
+
+# http::unregister --
+#
+#     Unregisters URL protocol handler
+#
+# Arguments:
+#     proto           URL protocol prefix, e.g. https
+# Results:
+#     list of port and command that was unregistered.
+
+proc http::unregister {proto} {
+    variable urlTypes
+    if {![info exists urlTypes($proto)]} {
+       return -code error "unsupported url type \"$proto\""
+    }
+    set old $urlTypes($proto)
+    unset urlTypes($proto)
+    return $old
+}
+
+# http::config --
+#
+#      See documentation for details.
+#
+# Arguments:
+#      args            Options parsed by the procedure.
+# Results:
+#        TODO
+
+proc http::config {args} {
+    variable http
+    set options [lsort [array names http -*]]
+    set usage [join $options ", "]
+    if {[llength $args] == 0} {
+       set result {}
+       foreach name $options {
+           lappend result $name $http($name)
+       }
+       return $result
+    }
+    set options [string map {- ""} $options]
+    set pat ^-([join $options |])$
+    if {[llength $args] == 1} {
+       set flag [lindex $args 0]
+       if {[regexp -- $pat $flag]} {
+           return $http($flag)
+       } else {
+           return -code error "Unknown option $flag, must be: $usage"
+       }
+    } else {
+       foreach {flag value} $args {
+           if {[regexp -- $pat $flag]} {
+               set http($flag) $value
+           } else {
+               return -code error "Unknown option $flag, must be: $usage"
+           }
+       }
+    }
+}
+
+# http::Finish --
+#
+#      Clean up the socket and eval close time callbacks
+#
+# Arguments:
+#      token       Connection token.
+#      errormsg    (optional) If set, forces status to error.
+#       skipCB      (optional) If set, don't call the -command callback. This
+#                   is useful when geturl wants to throw an exception instead
+#                   of calling the callback. That way, the same error isn't
+#                   reported to two places.
+#
+# Side Effects:
+#        Closes the socket
+
+proc http::Finish { token {errormsg ""} {skipCB 0}} {
+    variable $token
+    upvar 0 $token state
+    global errorInfo errorCode
+    if {$errormsg ne ""} {
+       set state(error) [list $errormsg $errorInfo $errorCode]
+       set state(status) "error"
+    }
+    if {($state(status) eq "timeout") || ($state(status) eq "error")
+        || ([info exists state(connection)] && ($state(connection) eq "close"))
+    } {
+        CloseSocket $state(sock) $token
+    }
+    if {[info exists state(after)]} { after cancel $state(after) }
+    if {[info exists state(-command)] && !$skipCB} {
+       if {[catch {eval $state(-command) {$token}} err]} {
+           if {$errormsg eq ""} {
+               set state(error) [list $err $errorInfo $errorCode]
+               set state(status) error
+           }
+       }
+       # Command callback may already have unset our state
+       unset -nocomplain state(-command)
+    }
+}
+
+# http::CloseSocket -
+#
+#      Close a socket and remove it from the persistent sockets table.
+#      If possible an http token is included here but when we are called
+#      from a fileevent on remote closure we need to find the correct
+#      entry - hence the second section.
+
+proc ::http::CloseSocket {s {token {}}} {
+    variable socketmap
+    catch {fileevent $s readable {}}
+    set conn_id {}
+    if {$token ne ""} {
+        variable $token
+        upvar 0 $token state
+        if {[info exists state(socketinfo)]} {
+            set conn_id $state(socketinfo)
+        }
+    } else {
+        set map [array get socketmap]
+        set ndx [lsearch -exact $map $s]
+        if {$ndx != -1} {
+            incr ndx -1
+            set conn_id [lindex $map $ndx]
+        }
+    }
+    if {$conn_id eq {} || ![info exists socketmap($conn_id)]} {
+        Log "Closing socket $s (no connection info)"
+        if {[catch {close $s} err]} { Log "Error: $err" }
+    } else {
+       if {[info exists socketmap($conn_id)]} {
+           Log "Closing connection $conn_id (sock $socketmap($conn_id))"
+           if {[catch {close $socketmap($conn_id)} err]} { Log "Error: $err" }
+           unset socketmap($conn_id)
+       } else {
+           Log "Cannot close connection $conn_id - no socket in socket map"
+       }
+    }
+}
+
+# http::reset --
+#
+#      See documentation for details.
+#
+# Arguments:
+#      token   Connection token.
+#      why     Status info.
+#
+# Side Effects:
+#       See Finish
+
+proc http::reset { token {why reset} } {
+    variable $token
+    upvar 0 $token state
+    set state(status) $why
+    catch {fileevent $state(sock) readable {}}
+    catch {fileevent $state(sock) writable {}}
+    Finish $token
+    if {[info exists state(error)]} {
+       set errorlist $state(error)
+       unset state
+       eval ::error $errorlist
+    }
+}
+
+# http::geturl --
+#
+#      Establishes a connection to a remote url via http.
+#
+# Arguments:
+#       url            The http URL to goget.
+#       args           Option value pairs. Valid options include:
+#                              -blocksize, -validate, -headers, -timeout
+# Results:
+#      Returns a token for this connection. This token is the name of an array
+#      that the caller should unset to garbage collect the state.
+
+proc http::geturl { url args } {
+    variable http
+    variable urlTypes
+    variable defaultCharset
+    variable defaultKeepalive
+    variable strict
+
+    # Initialize the state variable, an array. We'll return the name of this
+    # array as the token for the transaction.
+
+    if {![info exists http(uid)]} {
+       set http(uid) 0
+    }
+    set token [namespace current]::[incr http(uid)]
+    variable $token
+    upvar 0 $token state
+    reset $token
+
+    # Process command options.
+
+    array set state {
+       -binary         false
+       -blocksize      8192
+       -queryblocksize 8192
+       -validate       0
+       -headers        {}
+       -timeout        0
+       -type           application/x-www-form-urlencoded
+       -queryprogress  {}
+       -protocol       1.1
+       binary          0
+       state           header
+       meta            {}
+       coding          {}
+       currentsize     0
+       totalsize       0
+       querylength     0
+       queryoffset     0
+       type            text/html
+       body            {}
+       status          ""
+       http            ""
+       connection      close
+    }
+    set state(-keepalive) $defaultKeepalive
+    set state(-strict) $strict
+    # These flags have their types verified [Bug 811170]
+    array set type {
+       -binary         boolean
+       -blocksize      integer
+       -queryblocksize integer
+       -strict         boolean
+       -timeout        integer
+       -validate       boolean
+    }
+    set state(charset) $defaultCharset
+    set options {
+       -binary -blocksize -channel -command -handler -headers -keepalive
+       -method -myaddr -progress -protocol -query -queryblocksize
+       -querychannel -queryprogress -strict -timeout -type -validate
+    }
+    set usage [join [lsort $options] ", "]
+    set options [string map {- ""} $options]
+    set pat ^-([join $options |])$
+    foreach {flag value} $args {
+       if {[regexp -- $pat $flag]} {
+           # Validate numbers
+           if {[info exists type($flag)] &&
+               ![string is $type($flag) -strict $value]} {
+               unset $token
+               return -code error "Bad value for $flag ($value), must be $type($flag)"
+           }
+           set state($flag) $value
+       } else {
+           unset $token
+           return -code error "Unknown option $flag, can be: $usage"
+       }
+    }
+
+    # Make sure -query and -querychannel aren't both specified
+
+    set isQueryChannel [info exists state(-querychannel)]
+    set isQuery [info exists state(-query)]
+    if {$isQuery && $isQueryChannel} {
+       unset $token
+       return -code error "Can't combine -query and -querychannel options!"
+    }
+
+    # Validate URL, determine the server host and port, and check proxy case
+    # Recognize user:pass@host URLs also, although we do not do anything with
+    # that info yet.
+
+    # URLs have basically four parts.
+    # First, before the colon, is the protocol scheme (e.g. http)
+    # Second, for HTTP-like protocols, is the authority
+    #  The authority is preceded by // and lasts up to (but not including)
+    #  the following / and it identifies up to four parts, of which only one,
+    #  the host, is required (if an authority is present at all). All other
+    #  parts of the authority (user name, password, port number) are optional.
+    # Third is the resource name, which is split into two parts at a ?
+    #  The first part (from the single "/" up to "?") is the path, and the
+    #  second part (from that "?" up to "#") is the query. *HOWEVER*, we do
+    #  not need to separate them; we send the whole lot to the server.
+    # Fourth is the fragment identifier, which is everything after the first
+    #  "#" in the URL. The fragment identifier MUST NOT be sent to the server
+    #  and indeed, we don't bother to validate it (it could be an error to
+    #  pass it in here, but it's cheap to strip).
+    #
+    # An example of a URL that has all the parts:
+    #   http://jschmoe:xyzzy@www.bogus.net:8000/foo/bar.tml?q=foo#changes
+    # The "http" is the protocol, the user is "jschmoe", the password is
+    # "xyzzy", the host is "www.bogus.net", the port is "8000", the path is
+    # "/foo/bar.tml", the query is "q=foo", and the fragment is "changes".
+    #
+    # Note that the RE actually combines the user and password parts, as
+    # recommended in RFC 3986. Indeed, that RFC states that putting passwords
+    # in URLs is a Really Bad Idea, something with which I would agree utterly.
+    # Also note that we do not currently support IPv6 addresses.
+    #
+    # From a validation perspective, we need to ensure that the parts of the
+    # URL that are going to the server are correctly encoded.
+    # This is only done if $state(-strict) is true (inherited from
+    # $::http::strict).
+
+    set URLmatcher {(?x)               # this is _expanded_ syntax
+       ^
+       (?: (\w+) : ) ?                 # <protocol scheme>
+       (?: //
+           (?:
+               (
+                   [^@/\#?]+           # <userinfo part of authority>
+               ) @
+           )?
+           ( [^/:\#?]+ )               # <host part of authority>
+           (?: : (\d+) )?              # <port part of authority>
+       )?
+       ( / [^\#?]* (?: \? [^\#?]* )?)? # <path> (including query)
+       (?: \# (.*) )?                  # <fragment>
+       $
+    }
+
+    # Phase one: parse
+    if {![regexp -- $URLmatcher $url -> proto user host port srvurl]} {
+       unset $token
+       return -code error "Unsupported URL: $url"
+    }
+    # Phase two: validate
+    if {$host eq ""} {
+       # Caller has to provide a host name; we do not have a "default host"
+       # that would enable us to handle relative URLs.
+       unset $token
+       return -code error "Missing host part: $url"
+       # Note that we don't check the hostname for validity here; if it's
+       # invalid, we'll simply fail to resolve it later on.
+    }
+    if {$port ne "" && $port > 65535} {
+       unset $token
+       return -code error "Invalid port number: $port"
+    }
+    # The user identification and resource identification parts of the URL can
+    # have encoded characters in them; take care!
+    if {$user ne ""} {
+       # Check for validity according to RFC 3986, Appendix A
+       set validityRE {(?xi)
+           ^
+           (?: [-\w.~!$&'()*+,;=:] | %[0-9a-f][0-9a-f] )+
+           $
+       }
+       if {$state(-strict) && ![regexp -- $validityRE $user]} {
+           unset $token
+           # Provide a better error message in this error case
+           if {[regexp {(?i)%(?![0-9a-f][0-9a-f]).?.?} $user bad]} {
+               return -code error \
+                       "Illegal encoding character usage \"$bad\" in URL user"
+           }
+           return -code error "Illegal characters in URL user"
+       }
+    }
+    if {$srvurl ne ""} {
+       # Check for validity according to RFC 3986, Appendix A
+       set validityRE {(?xi)
+           ^
+           # Path part (already must start with / character)
+           (?:       [-\w.~!$&'()*+,;=:@/]  | %[0-9a-f][0-9a-f] )*
+           # Query part (optional, permits ? characters)
+           (?: \? (?: [-\w.~!$&'()*+,;=:@/?] | %[0-9a-f][0-9a-f] )* )?
+           $
+       }
+       if {$state(-strict) && ![regexp -- $validityRE $srvurl]} {
+           unset $token
+           # Provide a better error message in this error case
+           if {[regexp {(?i)%(?![0-9a-f][0-9a-f])..} $srvurl bad]} {
+               return -code error \
+                       "Illegal encoding character usage \"$bad\" in URL path"
+           }
+           return -code error "Illegal characters in URL path"
+       }
+    } else {
+       set srvurl /
+    }
+    if {$proto eq ""} {
+       set proto http
+    }
+    if {![info exists urlTypes($proto)]} {
+       unset $token
+       return -code error "Unsupported URL type \"$proto\""
+    }
+    set defport [lindex $urlTypes($proto) 0]
+    set defcmd [lindex $urlTypes($proto) 1]
+
+    if {$port eq ""} {
+       set port $defport
+    }
+    if {![catch {$http(-proxyfilter) $host} proxy]} {
+       set phost [lindex $proxy 0]
+       set pport [lindex $proxy 1]
+    }
+
+    # OK, now reassemble into a full URL
+    set url ${proto}://
+    if {$user ne ""} {
+       append url $user
+       append url @
+    }
+    append url $host
+    if {$port != $defport} {
+       append url : $port
+    }
+    append url $srvurl
+    # Don't append the fragment!
+    set state(url) $url
+
+    # If a timeout is specified we set up the after event and arrange for an
+    # asynchronous socket connection.
+
+    set sockopts [list]
+    if {$state(-timeout) > 0} {
+       set state(after) [after $state(-timeout) \
+               [list http::reset $token timeout]]
+       lappend sockopts -async
+    }
+
+    # If we are using the proxy, we must pass in the full URL that includes
+    # the server name.
+
+    if {[info exists phost] && ($phost ne "")} {
+       set srvurl $url
+       set targetAddr [list $phost $pport]
+    } else {
+       set targetAddr [list $host $port]
+    }
+    # Proxy connections aren't shared among different hosts.
+    set state(socketinfo) $host:$port
+
+    # See if we are supposed to use a previously opened channel.
+    if {$state(-keepalive)} {
+       variable socketmap
+       if {[info exists socketmap($state(socketinfo))]} {
+           if {[catch {fconfigure $socketmap($state(socketinfo))}]} {
+               Log "WARNING: socket for $state(socketinfo) was closed"
+               unset socketmap($state(socketinfo))
+           } else {
+               set sock $socketmap($state(socketinfo))
+               Log "reusing socket $sock for $state(socketinfo)"
+               catch {fileevent $sock writable {}}
+               catch {fileevent $sock readable {}}
+           }
+       }
+       # don't automatically close this connection socket
+       set state(connection) {}
+    }
+    if {![info exists sock]} {
+       # Pass -myaddr directly to the socket command
+       if {[info exists state(-myaddr)]} {
+           lappend sockopts -myaddr $state(-myaddr)
+       }
+        if {[catch {eval $defcmd $sockopts $targetAddr} sock]} {
+            # something went wrong while trying to establish the
+            # connection. Clean up after events and such, but DON'T call the
+            # command callback (if available) because we're going to throw an
+            # exception from here instead.
+
+           set state(sock) $sock
+            Finish $token "" 1
+            cleanup $token
+            return -code error $sock
+        }
+    }
+    set state(sock) $sock
+    Log "Using $sock for $state(socketinfo)" \
+        [expr {$state(-keepalive)?"keepalive":""}]
+    if {$state(-keepalive)} {
+        set socketmap($state(socketinfo)) $sock
+    }
+
+    # Wait for the connection to complete.
+
+    if {$state(-timeout) > 0} {
+       fileevent $sock writable [list http::Connect $token]
+       http::wait $token
+
+       if {![info exists state]} {
+           # If we timed out then Finish has been called and the users
+           # command callback may have cleaned up the token. If so
+           # we end up here with nothing left to do.
+           return $token
+       } elseif {$state(status) eq "error"} {
+           # Something went wrong while trying to establish the connection.
+           # Clean up after events and such, but DON'T call the command
+           # callback (if available) because we're going to throw an
+           # exception from here instead.
+           set err [lindex $state(error) 0]
+           cleanup $token
+           return -code error $err
+       } elseif {$state(status) ne "connect"} {
+           # Likely to be connection timeout
+           return $token
+       }
+       set state(status) ""
+    }
+
+    # Send data in cr-lf format, but accept any line terminators
+
+    fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize)
+
+    # The following is disallowed in safe interpreters, but the socket is
+    # already in non-blocking mode in that case.
+
+    catch {fconfigure $sock -blocking off}
+    set how GET
+    if {$isQuery} {
+       set state(querylength) [string length $state(-query)]
+       if {$state(querylength) > 0} {
+           set how POST
+           set contDone 0
+       } else {
+           # There's no query data.
+           unset state(-query)
+           set isQuery 0
+       }
+    } elseif {$state(-validate)} {
+       set how HEAD
+    } elseif {$isQueryChannel} {
+       set how POST
+       # The query channel must be blocking for the async Write to
+       # work properly.
+       fconfigure $state(-querychannel) -blocking 1 -translation binary
+       set contDone 0
+    }
+    if {[info exists state(-method)] && $state(-method) ne ""} {
+       set how $state(-method)
+    }
+
+    if {[catch {
+       puts $sock "$how $srvurl HTTP/$state(-protocol)"
+       puts $sock "Accept: $http(-accept)"
+       array set hdrs $state(-headers)
+       if {[info exists hdrs(Host)]} {
+           # Allow Host spoofing [Bug 928154]
+           puts $sock "Host: $hdrs(Host)"
+       } elseif {$port == $defport} {
+           # Don't add port in this case, to handle broken servers.
+           # [Bug #504508]
+           puts $sock "Host: $host"
+       } else {
+           puts $sock "Host: $host:$port"
+       }
+       unset hdrs
+       puts $sock "User-Agent: $http(-useragent)"
+        if {$state(-protocol) == 1.0 && $state(-keepalive)} {
+            puts $sock "Connection: keep-alive"
+        }
+        if {$state(-protocol) > 1.0 && !$state(-keepalive)} {
+            puts $sock "Connection: close" ;# RFC2616 sec 8.1.2.1
+        }
+        if {[info exists phost] && ($phost ne "") && $state(-keepalive)} {
+            puts $sock "Proxy-Connection: Keep-Alive"
+        }
+        set accept_encoding_seen 0
+       foreach {key value} $state(-headers) {
+           if {[string equal -nocase $key "host"]} { continue }
+            if {[string equal -nocase $key "accept-encoding"]} {
+                set accept_encoding_seen 1
+            }
+           set value [string map [list \n "" \r ""] $value]
+           set key [string trim $key]
+           if {[string equal -nocase $key "content-length"]} {
+               set contDone 1
+               set state(querylength) $value
+           }
+           if {[string length $key]} {
+               puts $sock "$key: $value"
+           }
+       }
+       # Soft zlib dependency check - no package require
+        if {!$accept_encoding_seen && [llength [package provide zlib]]
+            && !([info exists state(-channel)] || [info exists state(-handler)])
+        } {
+            puts $sock "Accept-Encoding: gzip, identity, *;q=0.1"
+        }
+       if {$isQueryChannel && $state(querylength) == 0} {
+           # Try to determine size of data in channel. If we cannot seek, the
+           # surrounding catch will trap us
+
+           set start [tell $state(-querychannel)]
+           seek $state(-querychannel) 0 end
+           set state(querylength) \
+                   [expr {[tell $state(-querychannel)] - $start}]
+           seek $state(-querychannel) $start
+       }
+
+       # Flush the request header and set up the fileevent that will either
+       # push the POST data or read the response.
+       #
+       # fileevent note:
+       #
+       # It is possible to have both the read and write fileevents active at
+       # this point. The only scenario it seems to affect is a server that
+       # closes the connection without reading the POST data. (e.g., early
+       # versions TclHttpd in various error cases). Depending on the platform,
+       # the client may or may not be able to get the response from the server
+       # because of the error it will get trying to write the post data.
+       # Having both fileevents active changes the timing and the behavior,
+       # but no two platforms (among Solaris, Linux, and NT) behave the same,
+       # and none behave all that well in any case. Servers should always read
+       # their POST data if they expect the client to read their response.
+
+       if {$isQuery || $isQueryChannel} {
+           puts $sock "Content-Type: $state(-type)"
+           if {!$contDone} {
+               puts $sock "Content-Length: $state(querylength)"
+           }
+           puts $sock ""
+           fconfigure $sock -translation {auto binary}
+           fileevent $sock writable [list http::Write $token]
+       } else {
+           puts $sock ""
+           flush $sock
+           fileevent $sock readable [list http::Event $sock $token]
+       }
+
+       if {! [info exists state(-command)]} {
+           # geturl does EVERYTHING asynchronously, so if the user calls it
+           # synchronously, we just do a wait here.
+
+           wait $token
+           if {$state(status) eq "error"} {
+               # Something went wrong, so throw the exception, and the
+               # enclosing catch will do cleanup.
+               return -code error [lindex $state(error) 0]
+           }
+       }
+    } err]} {
+       # The socket probably was never connected, or the connection dropped
+       # later.
+
+       # Clean up after events and such, but DON'T call the command callback
+       # (if available) because we're going to throw an exception from here
+       # instead.
+
+       # if state(status) is error, it means someone's already called Finish
+       # to do the above-described clean up.
+       if {$state(status) ne "error"} {
+           Finish $token $err 1
+       }
+       cleanup $token
+       return -code error $err
+    }
+
+    return $token
+}
+
+# Data access functions:
+# Data - the URL data
+# Status - the transaction status: ok, reset, eof, timeout
+# Code - the HTTP transaction code, e.g., 200
+# Size - the size of the URL data
+
+proc http::data {token} {
+    variable $token
+    upvar 0 $token state
+    return $state(body)
+}
+proc http::status {token} {
+    if {![info exists $token]} { return "error" }
+    variable $token
+    upvar 0 $token state
+    return $state(status)
+}
+proc http::code {token} {
+    variable $token
+    upvar 0 $token state
+    return $state(http)
+}
+proc http::ncode {token} {
+    variable $token
+    upvar 0 $token state
+    if {[regexp {[0-9]{3}} $state(http) numeric_code]} {
+       return $numeric_code
+    } else {
+       return $state(http)
+    }
+}
+proc http::size {token} {
+    variable $token
+    upvar 0 $token state
+    return $state(currentsize)
+}
+proc http::meta {token} {
+    variable $token
+    upvar 0 $token state
+    return $state(meta)
+}
+proc http::error {token} {
+    variable $token
+    upvar 0 $token state
+    if {[info exists state(error)]} {
+       return $state(error)
+    }
+    return ""
+}
+
+# http::cleanup
+#
+#      Garbage collect the state associated with a transaction
+#
+# Arguments
+#      token   The token returned from http::geturl
+#
+# Side Effects
+#      unsets the state array
+
+proc http::cleanup {token} {
+    variable $token
+    upvar 0 $token state
+    if {[info exists state]} {
+       unset state
+    }
+}
+
+# http::Connect
+#
+#      This callback is made when an asyncronous connection completes.
+#
+# Arguments
+#      token   The token returned from http::geturl
+#
+# Side Effects
+#      Sets the status of the connection, which unblocks
+#      the waiting geturl call
+
+proc http::Connect {token} {
+    variable $token
+    upvar 0 $token state
+    global errorInfo errorCode
+    if {[eof $state(sock)] ||
+       [string length [fconfigure $state(sock) -error]]} {
+           Finish $token "connect failed [fconfigure $state(sock) -error]" 1
+    } else {
+       set state(status) connect
+       fileevent $state(sock) writable {}
+    }
+    return
+}
+
+# http::Write
+#
+#      Write POST query data to the socket
+#
+# Arguments
+#      token   The token for the connection
+#
+# Side Effects
+#      Write the socket and handle callbacks.
+
+proc http::Write {token} {
+    variable $token
+    upvar 0 $token state
+    set sock $state(sock)
+
+    # Output a block.  Tcl will buffer this if the socket blocks
+    set done 0
+    if {[catch {
+       # Catch I/O errors on dead sockets
+
+       if {[info exists state(-query)]} {
+           # Chop up large query strings so queryprogress callback can give
+           # smooth feedback.
+
+           puts -nonewline $sock \
+               [string range $state(-query) $state(queryoffset) \
+                    [expr {$state(queryoffset) + $state(-queryblocksize) - 1}]]
+           incr state(queryoffset) $state(-queryblocksize)
+           if {$state(queryoffset) >= $state(querylength)} {
+               set state(queryoffset) $state(querylength)
+               puts $sock ""
+               set done 1
+           }
+       } else {
+           # Copy blocks from the query channel
+
+           set outStr [read $state(-querychannel) $state(-queryblocksize)]
+           puts -nonewline $sock $outStr
+           incr state(queryoffset) [string length $outStr]
+           if {[eof $state(-querychannel)]} {
+               set done 1
+           }
+       }
+    } err]} {
+       # Do not call Finish here, but instead let the read half of the socket
+       # process whatever server reply there is to get.
+
+       set state(posterror) $err
+       set done 1
+    }
+    if {$done} {
+       catch {flush $sock}
+       fileevent $sock writable {}
+       fileevent $sock readable [list http::Event $sock $token]
+    }
+
+    # Callback to the client after we've completely handled everything.
+
+    if {[string length $state(-queryprogress)]} {
+       eval $state(-queryprogress) \
+           [list $token $state(querylength) $state(queryoffset)]
+    }
+}
+
+# http::Event
+#
+#      Handle input on the socket
+#
+# Arguments
+#      sock    The socket receiving input.
+#      token   The token returned from http::geturl
+#
+# Side Effects
+#      Read the socket and handle callbacks.
+
+proc http::Event {sock token} {
+    variable $token
+    upvar 0 $token state
+
+    if {![info exists state]} {
+       Log "Event $sock with invalid token '$token' - remote close?"
+       if {! [eof $sock]} {
+           if {[string length [set d [read $sock]]] != 0} {
+               Log "WARNING: additional data left on closed socket"
+           }
+       }
+       CloseSocket $sock
+       return
+    }
+    if {$state(state) eq "header"} {
+       if {[catch {gets $sock line} n]} {
+           return [Finish $token $n]
+       } elseif {$n == 0} {
+           # We have now read all headers
+           # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3
+           if {$state(http) == "" || [lindex $state(http) 1] == 100} { return }
+
+           set state(state) body
+
+           # If doing a HEAD, then we won't get any body
+           if {$state(-validate)} {
+               Eof $token
+               return
+           }
+
+           # For non-chunked transfer we may have no body -- in this case we
+           # may get no further file event if the connection doesn't close and
+           # no more data is sent. We can tell and must finish up now - not
+           # later.
+           if {!(([info exists state(connection)]
+                  && ($state(connection) eq "close"))
+                 || [info exists state(transfer)])
+               &&  $state(totalsize) == 0
+           } then {
+               Log "body size is 0 and no events likely - complete."
+               Eof $token
+               return
+           }
+
+           # We have to use binary translation to count bytes properly.
+           fconfigure $sock -translation binary
+
+           if {$state(-binary) || ![string match -nocase text* $state(type)]} {
+               # Turn off conversions for non-text data
+               set state(binary) 1
+           }
+           if {$state(binary) || [string match *gzip* $state(coding)]
+               || [string match *compress* $state(coding)]} {
+               if {[info exists state(-channel)]} {
+                   fconfigure $state(-channel) -translation binary
+               }
+           }
+           if {[info exists state(-channel)] &&
+               ![info exists state(-handler)]} {
+               # Initiate a sequence of background fcopies
+               fileevent $sock readable {}
+               CopyStart $sock $token
+               return
+           }
+       } elseif {$n > 0} {
+           # Process header lines
+           if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
+               switch -- [string tolower $key] {
+                   content-type {
+                       set state(type) [string trim [string tolower $value]]
+                       # grab the optional charset information
+                       regexp -nocase {charset\s*=\s*(\S+?);?} \
+                           $state(type) -> state(charset)
+                   }
+                   content-length {
+                       set state(totalsize) [string trim $value]
+                   }
+                   content-encoding {
+                       set state(coding) [string trim $value]
+                   }
+                   transfer-encoding {
+                       set state(transfer) \
+                           [string trim [string tolower $value]]
+                   }
+                   proxy-connection -
+                   connection {
+                       set state(connection) \
+                           [string trim [string tolower $value]]
+                   }
+               }
+               lappend state(meta) $key [string trim $value]
+           } elseif {[string match HTTP* $line]} {
+               set state(http) $line
+           }
+       }
+    } else {
+       # Now reading body
+       if {[catch {
+           if {[info exists state(-handler)]} {
+               set n [eval $state(-handler) [list $sock $token]]
+           } elseif {[info exists state(transfer_final)]} {
+               set line [getTextLine $sock]
+               set n [string length $line]
+               if {$n > 0} {
+                   Log "found $n bytes following final chunk"
+                   append state(transfer_final) $line
+               } else {
+                   Log "final chunk part"
+                   Eof $token
+               }
+           } elseif {[info exists state(transfer)]
+                     && $state(transfer) eq "chunked"} {
+               set size 0
+               set chunk [getTextLine $sock]
+               set n [string length $chunk]
+               if {[string trim $chunk] ne ""} {
+                   scan $chunk %x size
+                   if {$size != 0} {
+                       set bl [fconfigure $sock -blocking]
+                       fconfigure $sock -blocking 1
+                       set chunk [read $sock $size]
+                       fconfigure $sock -blocking $bl
+                       set n [string length $chunk]
+                       if {$n >= 0} {
+                           append state(body) $chunk
+                       }
+                       if {$size != [string length $chunk]} {
+                           Log "WARNING: mis-sized chunk:\
+                               was [string length $chunk], should be $size"
+                       }
+                       getTextLine $sock
+                   } else {
+                       set state(transfer_final) {}
+                   }
+               }
+           } else {
+               #Log "read non-chunk $state(currentsize) of $state(totalsize)"
+               set block [read $sock $state(-blocksize)]
+               set n [string length $block]
+               if {$n >= 0} {
+                   append state(body) $block
+               }
+           }
+           if {[info exists state]} {
+               if {$n >= 0} {
+                   incr state(currentsize) $n
+               }
+               # If Content-Length - check for end of data.
+               if {($state(totalsize) > 0)
+                   && ($state(currentsize) >= $state(totalsize))} {
+                   Eof $token
+               }
+           }
+       } err]} {
+           return [Finish $token $err]
+       } else {
+           if {[info exists state(-progress)]} {
+               eval $state(-progress) \
+                   [list $token $state(totalsize) $state(currentsize)]
+           }
+       }
+    }
+
+    # catch as an Eof above may have closed the socket already
+    if {![catch {eof $sock} eof] && $eof} {
+       if {[info exists $token]} {
+           set state(connection) close
+           Eof $token
+       } else {
+           # open connection closed on a token that has been cleaned up.
+           CloseSocket $sock
+       }
+       return
+    }
+}
+
+# http::getTextLine --
+#
+#      Get one line with the stream in blocking crlf mode
+#
+# Arguments
+#      sock    The socket receiving input.
+#
+# Results:
+#      The line of text, without trailing newline
+
+proc http::getTextLine {sock} {
+    set tr [fconfigure $sock -translation]
+    set bl [fconfigure $sock -blocking]
+    fconfigure $sock -translation crlf -blocking 1
+    set r [gets $sock]
+    fconfigure $sock -translation $tr -blocking $bl
+    return $r
+}
+
+# http::CopyStart
+#
+#      Error handling wrapper around fcopy
+#
+# Arguments
+#      sock    The socket to copy from
+#      token   The token returned from http::geturl
+#
+# Side Effects
+#      This closes the connection upon error
+
+proc http::CopyStart {sock token} {
+    variable $token
+    upvar 0 $token state
+    if {[catch {
+       fcopy $sock $state(-channel) -size $state(-blocksize) -command \
+           [list http::CopyDone $token]
+    } err]} {
+       Finish $token $err
+    }
+}
+
+# http::CopyDone
+#
+#      fcopy completion callback
+#
+# Arguments
+#      token   The token returned from http::geturl
+#      count   The amount transfered
+#
+# Side Effects
+#      Invokes callbacks
+
+proc http::CopyDone {token count {error {}}} {
+    variable $token
+    upvar 0 $token state
+    set sock $state(sock)
+    incr state(currentsize) $count
+    if {[info exists state(-progress)]} {
+       eval $state(-progress) \
+           [list $token $state(totalsize) $state(currentsize)]
+    }
+    # At this point the token may have been reset
+    if {[string length $error]} {
+       Finish $token $error
+    } elseif {[catch {eof $sock} iseof] || $iseof} {
+       Eof $token
+    } else {
+       CopyStart $sock $token
+    }
+}
+
+# http::Eof
+#
+#      Handle eof on the socket
+#
+# Arguments
+#      token   The token returned from http::geturl
+#
+# Side Effects
+#      Clean up the socket
+
+proc http::Eof {token {force 0}} {
+    variable $token
+    upvar 0 $token state
+    if {$state(state) eq "header"} {
+       # Premature eof
+       set state(status) eof
+    } else {
+       set state(status) ok
+    }
+
+    if {($state(coding) eq "gzip") && [string length $state(body)] > 0} {
+        if {[catch {
+            set state(body) [Gunzip $state(body)]
+        } err]} {
+            return [Finish $token $err]
+        }
+    }
+
+    if {!$state(binary)} {
+
+        # If we are getting text, set the incoming channel's
+        # encoding correctly.  iso8859-1 is the RFC default, but
+        # this could be any IANA charset.  However, we only know
+        # how to convert what we have encodings for.
+
+        set enc [CharsetToEncoding $state(charset)]
+        if {$enc ne "binary"} {
+            set state(body) [encoding convertfrom $enc $state(body)]
+        }
+
+        # Translate text line endings.
+        set state(body) [string map {\r\n \n \r \n} $state(body)]
+    }
+
+    Finish $token
+}
+
+# http::wait --
+#
+#      See documentation for details.
+#
+# Arguments:
+#      token   Connection token.
+#
+# Results:
+#        The status after the wait.
+
+proc http::wait {token} {
+    variable $token
+    upvar 0 $token state
+
+    if {![info exists state(status)] || $state(status) eq ""} {
+       # We must wait on the original variable name, not the upvar alias
+       vwait ${token}(status)
+    }
+
+    return [status $token]
+}
+
+# http::formatQuery --
+#
+#      See documentation for details.  Call http::formatQuery with an even
+#      number of arguments, where the first is a name, the second is a value,
+#      the third is another name, and so on.
+#
+# Arguments:
+#      args    A list of name-value pairs.
+#
+# Results:
+#      TODO
+
+proc http::formatQuery {args} {
+    set result ""
+    set sep ""
+    foreach i $args {
+       append result $sep [mapReply $i]
+       if {$sep eq "="} {
+           set sep &
+       } else {
+           set sep =
+       }
+    }
+    return $result
+}
+
+# http::mapReply --
+#
+#      Do x-www-urlencoded character mapping
+#
+# Arguments:
+#      string  The string the needs to be encoded
+#
+# Results:
+#       The encoded string
+
+proc http::mapReply {string} {
+    variable http
+    variable formMap
+
+    # The spec says: "non-alphanumeric characters are replaced by '%HH'". Use
+    # a pre-computed map and [string map] to do the conversion (much faster
+    # than [regsub]/[subst]). [Bug 1020491]
+
+    if {$http(-urlencoding) ne ""} {
+       set string [encoding convertto $http(-urlencoding) $string]
+       return [string map $formMap $string]
+    }
+    set converted [string map $formMap $string]
+    if {[string match "*\[\u0100-\uffff\]*" $converted]} {
+       regexp {[\u0100-\uffff]} $converted badChar
+       # Return this error message for maximum compatability... :^/
+       return -code error \
+           "can't read \"formMap($badChar)\": no such element in array"
+    }
+    return $converted
+}
+
+# http::ProxyRequired --
+#      Default proxy filter.
+#
+# Arguments:
+#      host    The destination host
+#
+# Results:
+#       The current proxy settings
+
+proc http::ProxyRequired {host} {
+    variable http
+    if {[info exists http(-proxyhost)] && [string length $http(-proxyhost)]} {
+       if {![info exists http(-proxyport)] || \
+               ![string length $http(-proxyport)]} {
+           set http(-proxyport) 8080
+       }
+       return [list $http(-proxyhost) $http(-proxyport)]
+    }
+}
+
+# http::CharsetToEncoding --
+#
+#      Tries to map a given IANA charset to a tcl encoding.
+#      If no encoding can be found, returns binary.
+#
+
+proc http::CharsetToEncoding {charset} {
+    variable encodings
+
+    set charset [string tolower $charset]
+    if {[regexp {iso-?8859-([0-9]+)} $charset - num]} {
+       set encoding "iso8859-$num"
+    } elseif {[regexp {iso-?2022-(jp|kr)} $charset - ext]} {
+       set encoding "iso2022-$ext"
+    } elseif {[regexp {shift[-_]?js} $charset -]} {
+       set encoding "shiftjis"
+    } elseif {[regexp {(windows|cp)-?([0-9]+)} $charset - - num]} {
+       set encoding "cp$num"
+    } elseif {$charset eq "us-ascii"} {
+       set encoding "ascii"
+    } elseif {[regexp {(iso-?)?lat(in)?-?([0-9]+)} $charset - - - num]} {
+       switch -- $num {
+           5 {set encoding "iso8859-9"}
+           1 -
+           2 -
+           3 {set encoding "iso8859-$num"}
+       }
+    } else {
+       # other charset, like euc-xx, utf-8,...  may directly maps to encoding
+       set encoding $charset
+    }
+    set idx [lsearch -exact $encodings $encoding]
+    if {$idx >= 0} {
+       return $encoding
+    } else {
+       return "binary"
+    }
+}
+
+# http::Gunzip --
+#
+#      Decompress data transmitted using the gzip transfer coding.
+#
+
+# FIX ME: redo using zlib sinflate
+proc http::Gunzip {data} {
+    binary scan $data Scb5icc magic method flags time xfl os
+    set pos 10
+    if {$magic != 0x1f8b} {
+        return -code error "invalid data: supplied data is not in gzip format"
+    }
+    if {$method != 8} {
+        return -code error "invalid compression method"
+    }
+
+    foreach {f_text f_crc f_extra f_name f_comment} [split $flags ""] break
+    set extra ""
+    if { $f_extra } {
+       binary scan $data @${pos}S xlen
+        incr pos 2
+        set extra [string range $data $pos $xlen]
+        set pos [incr xlen]
+    }
+
+    set name ""
+    if { $f_name } {
+        set ndx [string first \0 $data $pos]
+        set name [string range $data $pos $ndx]
+        set pos [incr ndx]
+    }
+
+    set comment ""
+    if { $f_comment } {
+        set ndx [string first \0 $data $pos]
+        set comment [string range $data $pos $ndx]
+        set pos [incr ndx]
+    }
+
+    set fcrc ""
+    if { $f_crc } {
+       set fcrc [string range $data $pos [incr pos]]
+        incr pos
+    }
+
+    binary scan [string range $data end-7 end] ii crc size
+    set inflated [zlib inflate [string range $data $pos end-8]]
+    set chk [zlib crc32 $inflated]
+    if { ($crc & 0xffffffff) != ($chk & 0xffffffff)} {
+       return -code error "invalid data: checksum mismatch $crc != $chk"
+    }
+    return $inflated
+}
+
+# Local variables:
+# indent-tabs-mode: t
+# End:
diff --git a/8.x/tclvfs/http2.6/pkgIndex.tcl b/8.x/tclvfs/http2.6/pkgIndex.tcl
new file mode 100644 (file)
index 0000000..7e44dd0
--- /dev/null
@@ -0,0 +1,8 @@
+# pkgIndex.tcl - index for http package
+#
+# Use to use lazy loading by defining the load command as:
+# package ifneeded http 2.6 [list tclPkgSetup $dir http 2.6 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister}}}]
+#
+if {![package vsatisfies [package provide Tcl] 8.4]} {return}
+package ifneeded http 2.6.9 [list source [file join $dir http.tcl]]
+
diff --git a/8.x/tclvfs/library/ftpvfs.tcl b/8.x/tclvfs/library/ftpvfs.tcl
new file mode 100644 (file)
index 0000000..34ba618
--- /dev/null
@@ -0,0 +1,341 @@
+
+package provide vfs::ftp 1.0
+
+package require vfs 1.0
+package require ftp
+
+namespace eval vfs::ftp {
+    # Number of milliseconds for which to cache listings
+    variable cacheListingsFor 1000
+}
+
+proc vfs::ftp::Mount {dirurl local} {
+    set dirurl [string trim $dirurl]
+    ::vfs::log "ftp-vfs: attempt to mount $dirurl at $local"
+    if {[string index $dirurl end] != "/"} {
+       ::vfs::log "ftp-vfs: adding missing directory delimiter to mount point"
+       append dirurl "/"
+    }
+    
+    set urlRE {(?:ftp://)?(?:([^@:]*)(?::([^@]*))?@)?([^/:]+)(?::([0-9]*))?/(.*/)?$} 
+    if {![regexp $urlRE $dirurl - user pass host port path]} {
+       return -code error "Sorry I didn't understand\
+         the url address \"$dirurl\""
+    }
+    
+    if {![string length $user]} {
+       set user anonymous
+    }
+    
+    if {![string length $port]} {
+       set port 21
+    }
+    
+    set fd [::ftp::Open $host $user $pass -port $port -output ::vfs::ftp::log]
+    if {$fd == -1} {
+       error "Mount failed"
+    }
+    
+    if {$path != ""} {
+       if {[catch {
+           ::ftp::Cd $fd $path
+       } err]} {
+           ftp::Close $fd
+           error "Opened ftp connection, but then received error: $err"
+       }
+    }
+    
+    if {![catch {vfs::filesystem info $dirurl}]} {
+       # unmount old mount
+       ::vfs::log "ftp-vfs: unmounted old mount point at $dirurl"
+       vfs::unmount $dirurl
+    }
+    ::vfs::log "ftp $host, $path mounted at $fd"
+    vfs::filesystem mount $local [list vfs::ftp::handler $fd $path]
+    # Register command to unmount
+    vfs::RegisterMount $local [list ::vfs::ftp::Unmount $fd]
+    return $fd
+}
+
+# Need this because vfs::log takes just one argument
+proc vfs::ftp::log {args} {
+    ::vfs::log $args
+}
+
+proc vfs::ftp::Unmount {fd local} {
+    vfs::filesystem unmount $local
+    ::ftp::Close $fd
+}
+
+proc vfs::ftp::handler {fd path cmd root relative actualpath args} {
+    if {$cmd == "matchindirectory"} {
+       eval [list $cmd $fd $relative $actualpath] $args
+    } else {
+       eval [list $cmd $fd $relative] $args
+    }
+}
+
+proc vfs::ftp::attributes {fd} { return [list "state"] }
+proc vfs::ftp::state {fd args} {
+    vfs::attributeCantConfigure "state" "readwrite" $args
+}
+
+# If we implement the commands below, we will have a perfect
+# virtual file system for remote ftp sites.
+
+proc vfs::ftp::stat {fd name} {
+    ::vfs::log "stat $name"
+    if {$name == ""} {
+       return [list type directory mtime 0 size 0 mode 0777 ino -1 \
+         depth 0 name "" dev -1 uid -1 gid -1 nlink 1]
+    }
+    # get information on the type of this file
+    set ftpInfo [_findFtpInfo $fd $name]
+    if {$ftpInfo == ""} { 
+       vfs::filesystem posixerror $::vfs::posix(ENOENT)
+    }
+    ::vfs::log $ftpInfo
+    set perms [lindex $ftpInfo 0]
+    if {[string index $perms 0] == "d"} {
+       lappend res type directory size 0
+       set mtime 0
+    } else {
+       lappend res type file size [ftp::FileSize $fd $name]
+       set mtime [ftp::ModTime $fd $name]
+    }
+    lappend res dev -1 uid -1 gid -1 nlink 1 depth 0 \
+      atime $mtime ctime $mtime mtime $mtime mode 0777
+    return $res
+}
+
+proc vfs::ftp::access {fd name mode} {
+    ::vfs::log "ftp-access $name $mode"
+    if {$name == ""} { return 1 }
+    set info [_findFtpInfo $fd $name]
+    if {[string length $info]} {
+       return 1
+    } else {
+       vfs::filesystem posixerror $::vfs::posix(ENOENT)
+    }
+}
+
+# We've chosen to implement these channels by using a memchan.
+# The alternative would be to use temporary files.
+proc vfs::ftp::open {fd name mode permissions} {
+    ::vfs::log "open $name $mode $permissions"
+    # return a list of two elements:
+    # 1. first element is the Tcl channel name which has been opened
+    # 2. second element (optional) is a command to evaluate when
+    #    the channel is closed.
+    switch -glob -- $mode {
+       "" -
+       "r" {
+           ftp::Get $fd $name -variable tmp
+
+           set filed [vfs::memchan]
+           fconfigure $filed -translation binary
+           puts -nonewline $filed $tmp
+
+           fconfigure $filed -translation auto
+           seek $filed 0
+           return [list $filed]
+       }
+       "a" {
+           # Try to append nothing to the file
+           if {[catch [list ::ftp::Append $fd -data "" $name] err] || !$err} {
+               error "Can't open $name for appending"
+           }
+
+           set filed [vfs::memchan]
+           return [list $filed [list ::vfs::ftp::_closing $fd $name $filed Append]]
+       }
+       "w*" {
+           # Try to write an empty file
+           if {[catch [list ::ftp::Put $fd -data "" $name] err] || !$err} {
+               error "Can't open $name for writing"
+           }
+
+           set filed [vfs::memchan]
+           return [list $filed [list ::vfs::ftp::_closing $fd $name $filed Put]]
+       }
+       default {
+           return -code error "illegal access mode \"$mode\""
+       }
+    }
+}
+
+proc vfs::ftp::_closing {fd name filed action} {
+    seek $filed 0
+    set contents [read $filed]
+    set trans [fconfigure $filed -translation]
+    if {$trans == "binary"} {
+       set oldType [::ftp::Type $fd]
+       ::ftp::Type $fd binary
+    }
+    if {![::ftp::$action $fd -data $contents $name]} {
+       # Would be better if we could be more specific here, with
+       # one of ENETRESET ENETDOWN ENETUNREACH or whatever.
+       vfs::filesystem posixerror $::vfs::posix(EIO)
+       #error "Failed to write to $name"
+    }
+    if {[info exists oldType]} {
+       ::ftp::Type $fd $oldType
+    }
+}
+
+proc vfs::ftp::_findFtpInfo {fd name} {
+    ::vfs::log "findFtpInfo $fd $name"
+    set ftpList [cachedList $fd [file dirname $name]]
+    foreach p $ftpList {
+       foreach {pname other} [_parseListLine $p] {}
+       if {$pname == [file tail $name]} {
+           return $other
+       }
+    }
+    return ""
+}
+
+proc vfs::ftp::cachedList {fd dir} {
+    variable cacheList
+    variable cacheListingsFor
+    
+    # Caches response to prevent going back to the ftp server
+    # for common use cases: foreach {f} [glob *] { file stat $f s }
+    if {[info exists cacheList($dir)]} {
+       return $cacheList($dir)
+    }
+    set listing [ftp::List $fd $dir]
+
+    set cacheList($dir) $listing
+    after $cacheListingsFor [list unset -nocomplain ::vfs::ftp::cacheList($dir)]
+    return $listing
+}
+
+# Currently returns a list of name and a list of other
+# information.  The other information is currently a 
+# list of:
+# () permissions
+# () size
+proc vfs::ftp::_parseListLine {line} {
+    # Check for filenames with spaces
+    if {[regexp {([^ ]|[^0-9] )+$} $line name]} {
+       # Check for links
+       if {[set idx [string first " -> " $name]] != -1} {
+           incr idx -1
+           set name [string range $name 0 $idx]
+       }
+    }
+    regsub -all "\[ \t\]+" $line " " line
+    set items [split $line " "]
+
+    if {![info exists name]} {set name [lindex $items end]}
+    lappend other [lindex $items 0]
+    if {[string is integer [lindex $items 4]]} {
+       lappend other [lindex $items 4]
+    }
+    
+    return [list $name $other]
+}
+
+proc vfs::ftp::matchindirectory {fd path actualpath pattern type} {
+    ::vfs::log "matchindirectory $fd $path $actualpath $pattern $type"
+    set res [list]
+    if {![string length $pattern]} {
+       # matching a single file
+       set ftpInfo [_findFtpInfo $fd $path]
+       if {$ftpInfo != ""} {
+           # Now check if types match
+           set perms [lindex $ftpInfo 0]
+           if {[string index $perms 0] == "d"} {
+               if {[::vfs::matchDirectories $type]} {
+                   lappend res $actualpath
+               }
+           } else {
+               if {[::vfs::matchFiles $type]} {
+                   lappend res $actualpath
+               }
+           }
+       }
+    } else {
+       # matching all files in the given directory
+       set ftpList [cachedList $fd $path]
+       ::vfs::log "ftpList: $ftpList"
+
+       foreach p $ftpList {
+           foreach {name perms} [_parseListLine $p] {}
+           if {![string match $pattern $name]} {
+               continue 
+           } 
+           if {[::vfs::matchDirectories $type]} {
+               if {[string index $perms 0] == "d"} {
+                   lappend res [file join $actualpath $name]
+               }
+           }
+           if {[::vfs::matchFiles $type]} {
+               if {[string index $perms 0] != "d"} {
+                   lappend res [file join $actualpath $name]
+               }
+           }
+           
+       }
+    }
+    return $res
+}
+
+proc vfs::ftp::createdirectory {fd name} {
+    ::vfs::log "createdirectory $name"
+    if {![ftp::MkDir $fd $name]} {
+       # Can we be more specific here?
+       vfs::filesystem posixerror $::vfs::posix(EACCES)
+    }
+}
+
+proc vfs::ftp::removedirectory {fd name recursive} {
+    ::vfs::log "removedirectory $name $recursive"
+    if {![ftp::RmDir $fd $name]} {
+       # Can we be more specific here?
+       if {$recursive} {
+           vfs::filesystem posixerror $::vfs::posix(EACCES)
+       } else {
+           vfs::filesystem posixerror $::vfs::posix(EACCES)
+       }
+    }
+}
+
+proc vfs::ftp::deletefile {fd name} {
+    ::vfs::log "deletefile $name"
+    if {![ftp::Delete $fd $name]} {
+       # Can we be more specific here?
+       vfs::filesystem posixerror $::vfs::posix(EACCES)
+    }
+}
+
+proc vfs::ftp::fileattributes {fd path args} {
+    ::vfs::log "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+           return [list]
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+           vfs::filesystem posixerror $::vfs::posix(ENODEV)
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+           vfs::filesystem posixerror $::vfs::posix(ENODEV)
+       }
+    }
+}
+
+proc vfs::ftp::utime {fd path actime mtime} {
+    # Will throw an error if ftp package is old and only
+    # handles 2 arguments.  But that is ok -- Tcl will give the
+    # user an appropriate error message.
+    ftp::ModTime $fd $path $mtime
+}
+
diff --git a/8.x/tclvfs/library/httpvfs.tcl b/8.x/tclvfs/library/httpvfs.tcl
new file mode 100644 (file)
index 0000000..b9760cb
--- /dev/null
@@ -0,0 +1,432 @@
+
+package provide vfs::http 0.6
+
+package require vfs 1.0
+package require http
+
+# This works for basic operations, using http GET and HEAD requests
+# to serve http data in a read-only file system.
+
+namespace eval vfs::http {
+    # Allow for options when mounting an http URL
+    variable options
+    # -urlencode means automatically parse "foo/my file (2).txt" as
+    # "foo/my%20file%20%282%29.txt", per RFC 3986, for the user.
+    set options(-urlencode) 1
+    # -urlparse would further parse URLs for ? (query string) and # (anchor)
+    # components, leaving those unencoded. Only works when -urlencode is true.
+    set options(-urlparse) 0
+}
+
+proc vfs::http::Mount {dirurl local args} {
+    ::vfs::log "http-vfs: attempt to mount $dirurl at $local (args: $args)"
+    variable options
+    foreach {key val} $args {
+       # only do exact option name matching for now
+       # We could consider allowing general http options here,
+       # but those would be per-mount
+       if {[info exists options($key)]} {
+           # currently only boolean values
+           if {![string is boolean -strict $val]} {
+               return -code error "invalid boolean value \"$val\" for $key"
+           }
+           set options($key) $val
+       }
+    }
+
+    # Break the url into parts, verifying url
+    array set parts [urlparse $dirurl]
+
+    if {[info exists parts(query)] || [info exists parts(anchor)]} {
+       return -code error "invalid url \"$dirurl\":\
+               no query string or anchor fragments allowed"
+    }
+
+    if {[info exists parts(user)]} {
+       # At this point we need base64 for HTTP Basic AUTH
+       package require base64
+       foreach {user passwd} [split $parts(user) :] { break }
+       set auth "Basic [base64::encode $user:$passwd]"
+       set headers [list Authorization $auth]
+    } else {
+       set headers ""
+    }
+
+    set token [::http::geturl $parts(url) -validate 1 -headers $headers]
+    http::wait $token
+    set status [http::status $token]
+    http::cleanup $token
+    if {$status ne "ok"} {
+       # we'll take whatever http agrees is "ok"
+       return -code error "received status \"$status\" for \"$parts(url)\""
+    }
+
+    # Add a / to make sure the url and names are clearly separated later
+    if {[string index $parts(url) end] ne "/"} {
+       append parts(url) "/"
+    }
+
+    if {![catch {vfs::filesystem info $parts(url)}]} {
+       # unmount old mount
+       ::vfs::log "ftp-vfs: unmounted old mount point at $parts(url)"
+       vfs::unmount $parts(url)
+    }
+    ::vfs::log "http $dirurl ($parts(url)) mounted at $local"
+    # Pass headers along as they may include authentication
+    vfs::filesystem mount $local \
+       [list vfs::http::handler $parts(url) $headers $parts(file)]
+    # Register command to unmount - headers not needed
+    vfs::RegisterMount $local [list ::vfs::http::Unmount $parts(url)]
+    return $parts(url)
+}
+
+proc vfs::http::Unmount {url local} {
+    vfs::filesystem unmount $local
+}
+
+proc vfs::http::handler {url headers path cmd root relative actualpath args} {
+    if {$cmd eq "matchindirectory"} {
+       eval [linsert $args 0 $cmd $url $headers $relative $actualpath]
+    } else {
+       eval [linsert $args 0 $cmd $url $headers $relative]
+    }
+}
+
+proc vfs::http::urlparse {url} {
+    # Taken from http 2.5.3
+
+    # Validate URL by parts.  We suck out user:pass if it exists as the
+    # core http package does not automate HTTP Basic Auth yet.
+
+    # Returns data in [array get] format.  The url, host and file keys are
+    # guaranteed to exist.  proto, port, query, anchor, and user should be
+    # checked with [info exists]. (user may contain password)
+
+    # URLs have basically four parts.
+    # First, before the colon, is the protocol scheme (e.g. http)
+    # Second, for HTTP-like protocols, is the authority
+    #  The authority is preceded by // and lasts up to (but not including)
+    #  the following / and it identifies up to four parts, of which only one,
+    #  the host, is required (if an authority is present at all). All other
+    #  parts of the authority (user name, password, port number) are optional.
+    # Third is the resource name, which is split into two parts at a ?
+    #  The first part (from the single "/" up to "?") is the path, and the
+    #  second part (from that "?" up to "#") is the query. *HOWEVER*, we do
+    #  not need to separate them; we send the whole lot to the server.
+    # Fourth is the fragment identifier, which is everything after the first
+    #  "#" in the URL. The fragment identifier MUST NOT be sent to the server
+    #  and indeed, we don't bother to validate it (it could be an error to
+    #  pass it in here, but it's cheap to strip).
+    #
+    # An example of a URL that has all the parts:
+    #   http://jschmoe:xyzzy@www.bogus.net:8000/foo/bar.tml?q=foo#changes
+    # The "http" is the protocol, the user is "jschmoe", the password is
+    # "xyzzy", the host is "www.bogus.net", the port is "8000", the path is
+    # "/foo/bar.tml", the query is "q=foo", and the fragment is "changes".
+    #
+    # Note that the RE actually combines the user and password parts, as
+    # recommended in RFC 3986. Indeed, that RFC states that putting passwords
+    # in URLs is a Really Bad Idea, something with which I would agree utterly.
+    # Also note that we do not currently support IPv6 addresses.
+    #
+    # From a validation perspective, we need to ensure that the parts of the
+    # URL that are going to the server are correctly encoded.
+
+    set URLmatcher {(?x)               # this is _expanded_ syntax
+       ^
+       (?: (\w+) : ) ?                 # <protocol scheme>
+       (?: //
+           (?:
+               (
+                   [^@/\#?]+           # <userinfo part of authority>
+               ) @
+           )?
+           ( [^/:\#?]+ )               # <host part of authority>
+           (?: : (\d+) )?              # <port part of authority>
+       )?
+       ( / [^\#?]* (?: \? [^\#?]* )?)? # <path> (including query)
+       (?: \# (.*) )?                  # <fragment> (aka anchor)
+       $
+    }
+
+    # Phase one: parse
+    if {![regexp -- $URLmatcher $url -> proto user host port srvurl anchor]} {
+       unset $token
+       return -code error "Unsupported URL: $url"
+    }
+    # Phase two: validate
+    if {$host eq ""} {
+       # Caller has to provide a host name; we do not have a "default host"
+       # that would enable us to handle relative URLs.
+       unset $token
+       return -code error "Missing host part: $url"
+       # Note that we don't check the hostname for validity here; if it's
+       # invalid, we'll simply fail to resolve it later on.
+    }
+    if {$port ne "" && $port>65535} {
+       unset $token
+       return -code error "Invalid port number: $port"
+    }
+    # The user identification and resource identification parts of the URL can
+    # have encoded characters in them; take care!
+    if {$user ne ""} {
+       # Check for validity according to RFC 3986, Appendix A
+       set validityRE {(?xi)
+           ^
+           (?: [-\w.~!$&'()*+,;=:] | %[0-9a-f][0-9a-f] )+
+           $
+       }
+       if {![regexp -- $validityRE $user]} {
+           unset $token
+           # Provide a better error message in this error case
+           if {[regexp {(?i)%(?![0-9a-f][0-9a-f]).?.?} $user bad]} {
+               return -code error \
+                       "Illegal encoding character usage \"$bad\" in URL user"
+           }
+           return -code error "Illegal characters in URL user"
+       }
+    }
+    if {$srvurl ne ""} {
+       # Check for validity according to RFC 3986, Appendix A
+       set validityRE {(?xi)
+           ^
+           # Path part (already must start with / character)
+           (?:       [-\w.~!$&'()*+,;=:@/]  | %[0-9a-f][0-9a-f] )*
+           # Query part (optional, permits ? characters)
+           (?: \? (?: [-\w.~!$&'()*+,;=:@/?] | %[0-9a-f][0-9a-f] )* )?
+           $
+       }
+       if {![regexp -- $validityRE $srvurl]} {
+           unset $token
+           # Provide a better error message in this error case
+           if {[regexp {(?i)%(?![0-9a-f][0-9a-f])..} $srvurl bad]} {
+               return -code error \
+                       "Illegal encoding character usage \"$bad\" in URL path"
+           }
+           return -code error "Illegal characters in URL path"
+       }
+    } else {
+       set srvurl /
+    }
+    if {$proto eq ""} {
+       set proto http
+    } else {
+       set result(proto) $proto
+    }
+
+    # Here we vary from core http
+
+    # vfs::http - we only support http at this time.  Perhaps https later?
+    if {$proto ne "http"} {
+       return -code error "Unsupported URL type \"$proto\""
+    }
+
+    # OK, now reassemble into a full URL, with result containing the
+    # parts that exist and will be returned to the user
+    array set result {}
+    set url ${proto}://
+    if {$user ne ""} {
+       set result(user) $user
+       # vfs::http will do HTTP basic auth on their existence,
+       # but we pass these through as they are innocuous
+       append url $user
+       append url @
+    }
+    append url $host
+    set result(host) $host
+    if {$port ne ""} {
+       # don't bother with adding default port
+       append url : $port
+       set result(port) $port
+    }
+    append url $srvurl
+    if {$anchor ne ""} {
+       # XXX: Don't append see the anchor, as it is generally a client-side
+       # XXX: item.  The user can add it back if they want.
+       #append url \# $anchor
+       set result(anchor) $anchor
+    }
+
+    set idx [string first ? $srvurl]
+    if {$idx >= 0} {
+       set query [string range [expr {$idx+1}] end]
+       set file  [string range 0 [expr {$idx-1}]]
+       set result(file) $file
+       set result(query) $query
+    } else {
+       set result(file) $srvurl
+    }
+
+    set result(url) $url
+
+    # return array format list of items
+    return [array get result]
+}
+
+proc vfs::http::urlname {name} {
+    # Parse the passed in name into a suitable URL name based on mount opts
+    variable options
+    if {$options(-urlencode)} {
+       set querystr ""
+       if {$options(-urlparse)} {
+           # check for ? and split if necessary so that the query_string
+           # part doesn't get encoded.  Anchors come after this as well.
+           set idx [string first ? $name]
+           if {$idx >= 0} {
+               set querystr [string range $name $idx end] ; # includes ?
+               set name [string range $name 0 [expr {$idx-1}]]
+           }
+       }
+       set urlparts [list]
+       foreach part [file split $name] {
+           lappend urlparts [http::mapReply $part]
+       }
+       set urlname "[join $urlparts /]$querystr"
+    } else {
+       set urlname $name
+    }
+    return $urlname
+}
+
+proc vfs::http::geturl {url args} {
+    # a wrapper around http::geturl that handles 404 or !ok status check
+    # returns error on no success, or a fully ready http token otherwise
+    set token [eval [linsert $args 0 ::http::geturl $url]]
+    http::wait $token
+
+    if {[http::ncode $token] == 404 || [http::status $token] ne "ok"} {
+       # 404 Not Found
+       set code [http::code $token]
+       http::cleanup $token
+       vfs::filesystem posixerror $::vfs::posix(ENOENT)
+       return -code error \
+           "could not read \"$url\": no such file or directory ($code)"
+    }
+
+    # treat returned token like a regular http token
+    # call http::cleanup on it when done
+    return $token
+}
+
+# If we implement the commands below, we will have a perfect
+# virtual file system for remote http sites.
+
+proc vfs::http::stat {dirurl headers name} {
+    set urlname [urlname $name]
+    ::vfs::log "stat $name ($urlname)"
+
+    # get information on the type of this file.  We describe everything
+    # as a file (not a directory) since with http, even directories
+    # really behave as the index.html they contain.
+
+    # this will through an error if the file doesn't exist
+    set token [geturl "$dirurl$urlname" -validate 1 -headers $headers]
+    http::cleanup $token
+    set mtime 0
+    lappend res type file
+    lappend res dev -1 uid -1 gid -1 nlink 1 depth 0 \
+      atime $mtime ctime $mtime mtime $mtime mode 0777
+    return $res
+}
+
+proc vfs::http::access {dirurl headers name mode} {
+    set urlname [urlname $name]
+    ::vfs::log "access $name $mode ($urlname)"
+    if {$mode & 2} {
+       vfs::filesystem posixerror $::vfs::posix(EROFS)
+       return -code error "read-only"
+    }
+    if {$name == ""} { return 1 }
+    # this will through an error if the file doesn't exist
+    set token [geturl "$dirurl$urlname" -validate 1 -headers $headers]
+    http::cleanup $token
+    return 1
+}
+
+# We've chosen to implement these channels by using a memchan.
+# The alternative would be to use temporary files.
+proc vfs::http::open {dirurl headers name mode permissions} {
+    set urlname [urlname $name]
+    ::vfs::log "open $name $mode $permissions ($urlname)"
+    # return a list of two elements:
+    # 1. first element is the Tcl channel name which has been opened
+    # 2. second element (optional) is a command to evaluate when
+    #    the channel is closed.
+    switch -glob -- $mode {
+       "" -
+       "r" {
+           set token [geturl "$dirurl$urlname" -headers $headers]
+           set filed [vfs::memchan]
+           fconfigure $filed -translation binary
+           puts -nonewline $filed [::http::data $token]
+           http::cleanup $token
+
+           fconfigure $filed -translation auto
+           seek $filed 0
+           # XXX: the close command should free vfs::memchan somehow??
+           return [list $filed]
+       }
+       "a" -
+       "w*" {
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+       default {
+           return -code error "illegal access mode \"$mode\""
+       }
+    }
+}
+
+proc vfs::http::matchindirectory {dirurl headers path actualpath pattern type} {
+    ::vfs::log "matchindirectory $path $pattern $type"
+    set res [list]
+
+    if {[string length $pattern]} {
+       # need to match all files in a given remote http site.
+    } else {
+       # single file
+       if {![catch {access $dirurl $path 0}]} {
+           lappend res $path
+       }
+    }
+
+    return $res
+}
+
+proc vfs::http::createdirectory {dirurl headers name} {
+    ::vfs::log "createdirectory $name"
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
+
+proc vfs::http::removedirectory {dirurl headers name recursive} {
+    ::vfs::log "removedirectory $name"
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
+
+proc vfs::http::deletefile {dirurl headers name} {
+    ::vfs::log "deletefile $name"
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
+
+proc vfs::http::fileattributes {dirurl headers path args} {
+    ::vfs::log "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+           return [list]
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+    }
+}
+
+proc vfs::http::utime {dirurl headers path actime mtime} {
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
diff --git a/8.x/tclvfs/library/mk4vfs.tcl b/8.x/tclvfs/library/mk4vfs.tcl
new file mode 100644 (file)
index 0000000..d122dfc
--- /dev/null
@@ -0,0 +1,624 @@
+# mk4vfs.tcl -- Mk4tcl Virtual File System driver
+# Copyright (C) 1997-2003 Sensus Consulting Ltd. All Rights Reserved.
+# Matt Newman <matt@sensus.org> and Jean-Claude Wippler <jcw@equi4.com>
+#
+# $Id: mk4vfs.tcl,v 1.43 2008/12/22 01:19:34 patthoyts Exp $
+#
+# 05apr02 jcw  1.3     fixed append mode & close,
+#                      privatized memchan_handler
+#                      added zip, crc back in
+# 28apr02 jcw  1.4     reorged memchan and pkg dependencies
+# 22jun02 jcw  1.5     fixed recursive dir deletion
+# 16oct02 jcw  1.6     fixed periodic commit once a change is made
+# 20jan03 jcw  1.7     streamed zlib decompress mode, reduces memory usage
+# 01feb03 jcw  1.8     fix mounting a symlink, cleanup mount/unmount procs
+# 04feb03 jcw  1.8     whoops, restored vfs::mk4::Unmount logic
+# 17mar03 jcw  1.9     start with mode translucent or readwrite
+# 18oct05 jcw  1.10    add fallback to MK Compatible Lite driver (vfs::mkcl)
+
+# Removed provision of the backward compatible name. Moved to separate
+# file/package.
+package provide vfs::mk4 1.10.1
+package require vfs
+
+# need this so init failure in interactive mode does not mess up errorInfo
+if {[info exists env(VFS_DEBUG)] && [info commands history] == ""} {
+    proc history {args} {}
+}
+
+namespace eval vfs::mk4 {
+    proc Mount {mkfile local args} {
+        # 2005-10-19 switch to MK Compatible Lite driver if there is no Mk4tcl 
+       if {[catch { package require Mk4tcl }]} {
+         package require vfs::mkcl
+         return [eval [linsert $args 0 vfs::mkcl::Mount $mkfile $local]]
+       }
+
+       if {$mkfile != ""} {
+         # dereference a symlink, otherwise mounting on it fails (why?)
+         catch {
+           set mkfile [file join [file dirname $mkfile] \
+                                 [file readlink $mkfile]]
+         }
+         set mkfile [file normalize $mkfile]
+       }
+       set db [eval [list ::mk4vfs::_mount $mkfile] $args]
+       ::vfs::filesystem mount $local [list ::vfs::mk4::handler $db]
+       ::vfs::RegisterMount $local [list ::vfs::mk4::Unmount $db]
+       return $db
+    }
+
+    proc Unmount {db local} {
+       vfs::filesystem unmount $local
+       ::mk4vfs::_umount $db
+    }
+
+    proc attributes {db} { return [list "state" "commit"] }
+    
+    # Can use this to control commit/nocommit or whatever.
+    # I'm not sure yet of what functionality jcw needs.
+    proc commit {db args} {
+       switch -- [llength $args] {
+           0 {
+               if {$::mk4vfs::v::mode($db) == "readonly"} {
+                   return 0
+               } else {
+                   # To Do: read the commit state
+                   return 1
+               }
+           }
+           1 {
+               set val [lindex $args 0]
+               if {$val != 0 && $val != 1} {
+                   return -code error \
+                     "invalid commit value $val, must be 0,1"
+               }
+               # To Do: set the commit state.
+           }
+           default {
+               return -code error "Wrong num args"
+           }
+       }
+    }
+    
+    proc state {db args} {
+       switch -- [llength $args] {
+           0 {
+               return $::mk4vfs::v::mode($db)
+           }
+           1 {
+               set val [lindex $args 0]
+               if {[lsearch -exact [::vfs::states] $val] == -1} {
+                   return -code error \
+                     "invalid state $val, must be one of: [vfs::states]"
+               }
+               set ::mk4vfs::v::mode($db) $val
+               ::mk4vfs::setupCommits $db
+           }
+           default {
+               return -code error "Wrong num args"
+           }
+       }
+    }
+    
+    proc handler {db cmd root relative actualpath args} {
+       #puts stderr "handler: $db - $cmd - $root - $relative - $actualpath - $args"
+       if {$cmd == "matchindirectory"} {
+           eval [list $cmd $db $relative $actualpath] $args
+       } elseif {$cmd == "fileattributes"} {
+           eval [list $cmd $db $root $relative] $args
+       } else {
+           eval [list $cmd $db $relative] $args
+       }
+    }
+
+    proc utime {db path actime modtime} {
+       ::mk4vfs::stat $db $path sb
+       
+       if { $sb(type) == "file" } {
+           mk::set $sb(ino) date $modtime
+       }
+    }
+
+    proc matchindirectory {db path actualpath pattern type} {
+       set newres [list]
+       if {![string length $pattern]} {
+           # check single file
+           if {[catch {access $db $path 0}]} {
+               return {}
+           }
+           set res [list $actualpath]
+           set actualpath ""
+       } else {
+           set res [::mk4vfs::getdir $db $path $pattern]
+       }
+       foreach p [::vfs::matchCorrectTypes $type $res $actualpath] {
+           lappend newres [file join $actualpath $p]
+       }
+       return $newres
+    }
+
+    proc stat {db name} {
+       ::mk4vfs::stat $db $name sb
+
+       set sb(ino) 0
+       array get sb
+    }
+
+    proc access {db name mode} {
+       if {$mode & 2} {
+           if {$::mk4vfs::v::mode($db) == "readonly"} {
+               vfs::filesystem posixerror $::vfs::posix(EROFS)
+           }
+       }
+       # We can probably do this more efficiently, can't we?
+       ::mk4vfs::stat $db $name sb
+    }
+
+    proc open {db file mode permissions} {
+       # return a list of two elements:
+       # 1. first element is the Tcl channel name which has been opened
+       # 2. second element (optional) is a command to evaluate when
+       #  the channel is closed.
+       switch -glob -- $mode {
+           {}  -
+           r {
+               ::mk4vfs::stat $db $file sb
+
+               if { $sb(csize) != $sb(size) } {
+                   if {$::mk4vfs::zstreamed} {
+                     set fd [mk::channel $sb(ino) contents r]
+                     set fd [vfs::zstream decompress $fd $sb(csize) $sb(size)]
+                   } else {
+                     set fd [vfs::memchan]
+                     fconfigure $fd -translation binary
+                     set s [mk::get $sb(ino) contents]
+                     puts -nonewline $fd [vfs::zip -mode decompress $s]
+
+                     fconfigure $fd -translation auto
+                     seek $fd 0
+                   }
+               } elseif { $::mk4vfs::direct } {
+                   set fd [vfs::memchan]
+                   fconfigure $fd -translation binary
+                   puts -nonewline $fd [mk::get $sb(ino) contents]
+
+                   fconfigure $fd -translation auto
+                   seek $fd 0
+               } else {
+                   set fd [mk::channel $sb(ino) contents r]
+               }
+               return [list $fd]
+           }
+           a {
+               if {$::mk4vfs::v::mode($db) == "readonly"} {
+                   vfs::filesystem posixerror $::vfs::posix(EROFS)
+               }
+               if { [catch {::mk4vfs::stat $db $file sb }] } {
+                   # Create file
+                   ::mk4vfs::stat $db [file dirname $file] sb
+                   set tail [file tail $file]
+                   set fview $sb(ino).files
+                   if {[info exists mk4vfs::v::fcache($fview)]} {
+                       lappend mk4vfs::v::fcache($fview) $tail
+                   }
+                   set now [clock seconds]
+                   set sb(ino) [mk::row append $fview \
+                           name $tail size 0 date $now ]
+
+                   if { [string match *z* $mode] || $mk4vfs::compress } {
+                       set sb(csize) -1  ;# HACK - force compression
+                   } else {
+                       set sb(csize) 0
+                   }
+               }
+
+               set fd [vfs::memchan]
+               fconfigure $fd -translation binary
+               set s [mk::get $sb(ino) contents]
+
+               if { $sb(csize) != $sb(size) && $sb(csize) > 0 } {
+                   append mode z
+                   puts -nonewline $fd [vfs::zip -mode decompress $s]
+               } else {
+                   if { $mk4vfs::compress } { append mode z }
+                   puts -nonewline $fd $s
+                   #set fd [mk::channel $sb(ino) contents a]
+               }
+               fconfigure $fd -translation auto
+               seek $fd 0 end
+               return [list $fd [list mk4vfs::do_close $db $fd $mode $sb(ino)]]
+           }
+           w*  {
+               if {$::mk4vfs::v::mode($db) == "readonly"} {
+                   vfs::filesystem posixerror $::vfs::posix(EROFS)
+               }
+               if { [catch {::mk4vfs::stat $db $file sb }] } {
+                   # Create file
+                   ::mk4vfs::stat $db [file dirname $file] sb
+                   set tail [file tail $file]
+                   set fview $sb(ino).files
+                   if {[info exists mk4vfs::v::fcache($fview)]} {
+                       lappend mk4vfs::v::fcache($fview) $tail
+                   }
+                   set now [clock seconds]
+                   set sb(ino) [mk::row append $fview \
+                           name $tail size 0 date $now ]
+               }
+
+               if { [string match *z* $mode] || $mk4vfs::compress } {
+                   append mode z
+                   set fd [vfs::memchan]
+               } else {
+                   set fd [mk::channel $sb(ino) contents w]
+               }
+               return [list $fd [list mk4vfs::do_close $db $fd $mode $sb(ino)]]
+           }
+           default   {
+               error "illegal access mode \"$mode\""
+           }
+       }
+    }
+
+    proc createdirectory {db name} {
+       mk4vfs::mkdir $db $name
+    }
+
+    proc removedirectory {db name recursive} {
+       mk4vfs::delete $db $name $recursive
+    }
+
+    proc deletefile {db name} {
+       mk4vfs::delete $db $name
+    }
+
+    proc fileattributes {db root relative args} {
+       switch -- [llength $args] {
+           0 {
+               # list strings
+               return [::vfs::listAttributes]
+           }
+           1 {
+               # get value
+               set index [lindex $args 0]
+               return [::vfs::attributesGet $root $relative $index]
+
+           }
+           2 {
+               # set value
+               if {$::mk4vfs::v::mode($db) == "readonly"} {
+                   vfs::filesystem posixerror $::vfs::posix(EROFS)
+               }
+               set index [lindex $args 0]
+               set val [lindex $args 1]
+               return [::vfs::attributesSet $root $relative $index $val]
+           }
+       }
+    }
+}
+
+namespace eval mk4vfs {
+    variable compress 1     ;# HACK - needs to be part of "Super-Block"
+    variable flush    5000  ;# Auto-Commit frequency
+    variable direct   0            ;# read through a memchan, or from Mk4tcl if zero
+    variable zstreamed 0    ;# decompress on the fly (needs zlib 1.1)
+
+    namespace eval v {
+       variable seq      0
+       variable mode       ;# array key is db, value is mode 
+                            # (readwrite/translucent/readonly)
+       variable timer      ;# array key is db, set to afterid, periodicCommit
+
+       array set cache {}
+       array set fcache {}
+
+       array set mode {exe translucent}
+    }
+
+    proc init {db} {
+       mk::view layout $db.dirs \
+               {name:S parent:I {files {name:S size:I date:I contents:M}}}
+
+       if { [mk::view size $db.dirs] == 0 } {
+           mk::row append $db.dirs name <root> parent -1
+       }
+    }
+
+    proc _mount {{file ""} args} {
+       set db mk4vfs[incr v::seq]
+
+       if {$file == ""} {
+           mk::file open $db
+           init $db
+           set v::mode($db) "translucent"
+       } else {
+           eval [list mk::file open $db $file] $args
+           
+           init $db
+           
+           set mode 0
+           foreach arg $args {
+               switch -- $arg {
+                   -readonly   { set mode 1 }
+                   -nocommit   { set mode 2 }
+               }
+           }
+           if {$mode == 0} {
+               periodicCommit $db
+           }
+           set v::mode($db) [lindex {translucent readwrite readwrite} $mode]
+       }
+       return $db
+    }
+
+    proc periodicCommit {db} {
+       variable flush
+       set v::timer($db) [after $flush [list ::mk4vfs::periodicCommit $db]]
+       mk::file commit $db
+       return ;# 2005-01-20 avoid returning a value
+    }
+
+    proc _umount {db args} {
+       catch {after cancel $v::timer($db)}
+       array unset v::mode $db
+       array unset v::timer $db
+       array unset v::cache $db,*
+       array unset v::fcache $db.*
+       mk::file close $db
+    }
+
+    proc stat {db path {arr ""}} {
+       set sp [::file split $path]
+       set tail [lindex $sp end]
+
+       set parent 0
+       set view $db.dirs
+       set type directory
+
+       foreach ele [lrange $sp 0 end-1] {
+           if {[info exists v::cache($db,$parent,$ele)]} {
+               set parent $v::cache($db,$parent,$ele)
+           } else {
+               set row [mk::select $view -count 1 parent $parent name $ele]
+               if { $row == "" } {
+                   vfs::filesystem posixerror $::vfs::posix(ENOENT)
+               }
+               set v::cache($db,$parent,$ele) $row
+               set parent $row
+           }
+       }
+       
+       # Now check if final comp is a directory or a file
+       # CACHING is required - it can deliver a x15 speed-up!
+       
+       if { [string equal $tail "."] || [string equal $tail ":"] \
+         || [string equal $tail ""] } {
+           set row $parent
+
+       } elseif { [info exists v::cache($db,$parent,$tail)] } {
+           set row $v::cache($db,$parent,$tail)
+       } else {
+           # File?
+           set fview $view!$parent.files
+           # create a name cache of files in this directory
+           if {![info exists v::fcache($fview)]} {
+               # cache only a limited number of directories
+               if {[array size v::fcache] >= 10} {
+                   array unset v::fcache *
+               }
+               set v::fcache($fview) {}
+               mk::loop c $fview {
+                   lappend v::fcache($fview) [mk::get $c name]
+               }
+           }
+           set row [lsearch -exact $v::fcache($fview) $tail]
+           #set row [mk::select $fview -count 1 name $tail]
+           #if {$row == ""} { set row -1 }
+           if { $row != -1 } {
+               set type file
+               set view $view!$parent.files
+           } else {
+               # Directory?
+               set row [mk::select $view -count 1 parent $parent name $tail]
+               if { $row != "" } {
+                   set v::cache($db,$parent,$tail) $row
+               } else { 
+                   vfs::filesystem posixerror $::vfs::posix(ENOENT)
+               }
+           }
+       }
+        if {![string length $arr]} {
+            # The caller doesn't need more detailed information.
+            return 1
+        }
+       set cur $view!$row
+
+       upvar 1 $arr sb
+
+       set sb(type)    $type
+       set sb(view)    $view
+       set sb(ino)     $cur
+
+       if { [string equal $type "directory"] } {
+           set sb(atime) 0
+           set sb(ctime) 0
+           set sb(gid)   0
+           set sb(mode)  0777
+           set sb(mtime) 0
+           set sb(nlink) [expr { [mk::get $cur files] + 1 }]
+           set sb(size)  0
+           set sb(csize) 0
+           set sb(uid)   0
+       } else {
+           set mtime   [mk::get $cur date]
+           set sb(atime) $mtime
+           set sb(ctime) $mtime
+           set sb(gid)   0
+           set sb(mode)  0777
+           set sb(mtime) $mtime
+           set sb(nlink) 1
+           set sb(size)  [mk::get $cur size]
+           set sb(csize) [mk::get $cur -size contents]
+           set sb(uid)   0
+       }
+    }
+
+    proc do_close {db fd mode cur} {
+       if {![regexp {[aw]} $mode]} {
+           error "mk4vfs::do_close called with bad mode: $mode"
+       }
+
+       mk::set $cur size -1 date [clock seconds]
+       flush $fd
+       if { [string match *z* $mode] } {
+           fconfigure $fd -translation binary
+           seek $fd 0
+           set data [read $fd]
+           set cdata [vfs::zip -mode compress $data]
+           set len [string length $data]
+           set clen [string length $cdata]
+           if { $clen < $len } {
+               mk::set $cur size $len contents $cdata
+           } else {
+               mk::set $cur size $len contents $data
+           }
+       } else {
+           mk::set $cur size [mk::get $cur -size contents]
+       }
+       # 16oct02 new logic to start a periodic commit timer if not yet running
+       setupCommits $db
+       return ""
+    }
+
+    proc setupCommits {db} {
+       if {$v::mode($db) eq "readwrite" && ![info exists v::timer($db)]} {
+           periodicCommit $db
+           mk::file autocommit $db
+       }
+    }
+
+    proc mkdir {db path} {
+       if {$v::mode($db) == "readonly"} {
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+       set sp [::file split $path]
+       set parent 0
+       set view $db.dirs
+
+       set npath {}
+       # This actually does more work than is needed. Tcl's
+       # vfs only requires us to create the last piece, and
+       # Tcl already knows it is not a file.
+       foreach ele $sp {
+           set npath [file join $npath $ele]
+
+           if {![catch {stat $db $npath sb}] } {
+               if { $sb(type) != "directory" } {
+                   vfs::filesystem posixerror $::vfs::posix(EROFS)
+               }
+               set parent [mk::cursor position sb(ino)]
+               continue
+           }
+           #set parent [mk::cursor position sb(ino)]
+           set cur [mk::row append $view name $ele parent $parent]
+           set parent [mk::cursor position cur]
+       }
+       setupCommits $db
+       return ""
+    }
+
+    proc getdir {db path {pat *}} {
+       if {[catch { stat $db $path sb }] || $sb(type) != "directory" } {
+           return
+       }
+
+       # Match directories
+       set parent [mk::cursor position sb(ino)] 
+       foreach row [mk::select $sb(view) parent $parent -glob name $pat] {
+           set hits([mk::get $sb(view)!$row name]) 1
+       }
+       # Match files
+       set view $sb(view)!$parent.files
+       foreach row [mk::select $view -glob name $pat] {
+           set hits([mk::get $view!$row name]) 1
+       }
+       return [lsort [array names hits]]
+    }
+
+    proc mtime {db path time} {
+       if {$v::mode($db) == "readonly"} {
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+       stat $db $path sb
+       if { $sb(type) == "file" } {
+           mk::set $sb(ino) date $time
+       }
+       return $time
+    }
+
+    proc delete {db path {recursive 0}} {
+       #puts stderr "mk4delete db $db path $path recursive $recursive"
+       if {$v::mode($db) == "readonly"} {
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+       stat $db $path sb
+       if {$sb(type) == "file" } {
+           mk::row delete $sb(ino)
+           if {[regexp {(.*)!(\d+)} $sb(ino) - v r] \
+                   && [info exists v::fcache($v)]} {
+               set v::fcache($v) [lreplace $v::fcache($v) $r $r]
+           }
+       } else {
+           # just mark dirs as deleted
+           set contents [getdir $db $path *]
+           if {$recursive} {
+               # We have to delete these manually, else
+               # they (or their cache) may conflict with
+               # something later
+               foreach f $contents {
+                   delete $db [file join $path $f] $recursive
+               }
+           } else {
+               if {[llength $contents]} {
+                   vfs::filesystem posixerror $::vfs::posix(ENOTEMPTY)
+               }
+           }
+           array unset v::cache \
+                   "$db,[mk::get $sb(ino) parent],[file tail $path]"
+           
+           # flag with -99, because parent -1 is not reserved for the root dir
+           # deleted entries never get re-used, should be cleaned up one day
+           mk::set $sb(ino) parent -99 name ""
+           # get rid of file entries to release the space in the datafile
+           mk::view size $sb(ino).files 0
+       }
+       setupCommits $db
+       return ""
+    }
+}
+
+# DEPRECATED - please don't use.
+
+namespace eval mk4vfs {
+
+    namespace export mount umount
+
+    # deprecated, use vfs::mk4::Mount (first two args are reversed!)
+    proc mount {local mkfile args} {
+       uplevel [list ::vfs::mk4::Mount $mkfile $local] $args
+    }
+
+    # deprecated: unmounts, but only if vfs was mounted on itself
+    proc umount {local} {
+       foreach {db path} [mk::file open] {
+           if {[string equal $local $path]} {
+               vfs::filesystem unmount $local
+               _umount $db
+               return
+           }
+       }
+       tclLog "umount $local? [mk::file open]"
+    }
+}
diff --git a/8.x/tclvfs/library/starkit.tcl b/8.x/tclvfs/library/starkit.tcl
new file mode 100644 (file)
index 0000000..793dfb8
--- /dev/null
@@ -0,0 +1,156 @@
+# Starkit support, see http://www.equi4.com/starkit/
+# by Jean-Claude Wippler, July 2002
+
+package provide starkit 1.3.3
+
+package require vfs
+
+# Starkit scripts can launched in a number of ways:
+#   - wrapped or unwrapped
+#   - using tclkit, or from tclsh/wish with a couple of pkgs installed
+#   - with real MetaKit support, or with a read-only fake (ReadKit)
+#   - as 2-file starkit deployment, or as 1-file starpack
+#
+# Furthermore, there are three variations:
+#   current:  starkits
+#   older:    VFS-based "scripted documents"
+#   oldest:   pre-VFS "scripted documents"
+#
+# The code in here is only called directly from the current starkits.
+
+namespace eval starkit {
+    # these variables are defined after the call to starkit::startup
+    # they are special in that a second call will not alter them
+    # (as needed when a starkit sources others for more packages)
+    variable topdir    ;# root directory (while the starkit is mounted)
+    variable mode      ;# startup mode (starkit, sourced, etc)
+
+    # called from the header of a starkit
+    proc header {driver args} {
+       if {[catch {
+           set self [fullnormalize [info script]]
+
+           package require vfs::${driver}
+           eval [list ::vfs::${driver}::Mount $self $self] $args
+
+           uplevel [list source [file join $self main.tcl]]
+       }]} {
+           panic $::errorInfo
+       }
+    }
+
+    proc fullnormalize {path} {
+       # SNARFED from tcllib, fileutil.
+       # 8.5
+       # return [file join {expand}[lrange [file split
+       #    [file normalize [file join $path __dummy__]]] 0 end-1]]
+
+       return [file dirname [file normalize [file join $path __dummy__]]]
+    }
+
+    # called from the startup script of a starkit to init topdir and auto_path
+    # 2003/10/21, added in 1.3: remember startup mode in starkit::mode
+    proc startup {} {
+       if {![info exists starkit::mode]} { variable mode }
+       set mode [_startup]
+    }
+
+    # returns how the script was launched: starkit, starpack, unwrapped, or
+    # sourced (2003: also tclhttpd, plugin, or service)
+    proc _startup {} {
+       global argv0
+
+       # 2003/02/11: new behavior, if starkit::topdir exists, don't disturb it
+       if {![info exists starkit::topdir]} { variable topdir }
+
+       set script [fullnormalize [info script]]
+       set topdir [file dirname $script]
+
+       if {$topdir eq [fullnormalize [info nameofexe]]} { return starpack }
+
+       # pkgs live in the $topdir/lib/ directory
+       set lib [file join $topdir lib]
+       if {[file isdir $lib]} { autoextend $lib }
+
+       set a0 [fullnormalize $argv0]
+       if {$topdir eq $a0} { return starkit }
+       if {$script eq $a0} { return unwrapped }
+
+       # detect when sourced from tclhttpd
+       if {[info procs ::Httpd_Server] ne ""} { return tclhttpd }
+
+       # detect when sourced from the plugin (tentative)
+       if {[info exists ::embed_args]} { return plugin }
+
+       # detect when run as an NT service
+       if {[info exists ::tcl_service]} { return service }
+
+       return sourced
+    }
+
+    # append an entry to auto_path if it's not yet listed
+    proc autoextend {dir} {
+       global auto_path
+       set dir [fullnormalize $dir]
+       if {[lsearch $auto_path $dir] < 0} {
+           lappend auto_path $dir
+       }
+    }
+
+    # remount a starkit with different options
+    proc remount {args} {
+       variable topdir
+       foreach {drv arg} [vfs::filesystem info $topdir] { break }
+       vfs::unmount $topdir
+
+       eval [list [string map {handler Mount} $drv] $topdir $topdir] $args
+    }
+
+    # terminate with an error message, using most appropriate mechanism
+    proc panic {msg} {
+       if {[info commands wm] ne ""} {
+           catch { wm withdraw . }
+           tk_messageBox -icon error -message $msg -title "Fatal error"
+       } elseif {[info commands ::eventlog] ne ""} {
+           eventlog error $msg
+       } else {
+           puts stderr $msg
+       }
+       exit
+    }
+
+    # the following proc was copied from the critcl package:
+
+    # return a platform designator, including both OS and machine
+    #
+    # only use first element of $tcl_platform(os) - we don't care
+    # whether we are on "Windows NT" or "Windows XP" or whatever
+    #
+    # transforms $tcl_platform(machine) for some special cases
+    #  - on SunOS, matches for sun4* are transformed to sparc
+    #  - on all OS's matches for intel and i*86* are transformed to x86
+    #  - on MacOS X "Power Macintosh" is transformed to ppc
+    #
+    proc platform {} {
+        global tcl_platform
+        set plat [lindex $tcl_platform(os) 0]
+        set mach $tcl_platform(machine)
+        switch -glob -- $mach {
+            sun4* { set mach sparc }
+            intel -
+            i*86* { set mach x86 }
+            "Power Macintosh" { set mach ppc }
+        }
+       switch -- $plat {
+         AIX   { set mach ppc }
+         HP-UX { set mach hppa }
+       }
+        return "$plat-$mach"
+    }
+
+    # load extension from a platform-specific subdirectory
+    proc pload {dir name args} {
+      set f [file join $dir [platform] $name[info sharedlibext]]
+      uplevel 1 [linsert $args 0 load $f]
+    }
+}
diff --git a/8.x/tclvfs/library/tarvfs.tcl b/8.x/tclvfs/library/tarvfs.tcl
new file mode 100644 (file)
index 0000000..606dd05
--- /dev/null
@@ -0,0 +1,432 @@
+################################################################################
+# This is the first try to provide access to tar-files via
+# the vfs-mechanism.
+# This file is copied and adapted from zipvfs.tcl
+# (and ftpvfs.tcl). The internal structure for the tar-data is stored
+# analog to zipvfs so that many functions can be the same as in zipvfs.
+#
+# Jan 13 2003: Stefan Vogel (stefan.vogel@avinci.de)
+# (reformatted to tabsize 8 by Vince).
+# 
+# TODOs:
+# * add writable access (should be easy with tar-files)
+# * add gzip-support (?)
+# * more testing :-(
+################################################################################
+
+package require vfs
+package provide vfs::tar 0.91
+
+# Using the vfs, memchan and Trf extensions, we're able
+# to write a Tcl-only tar filesystem.  
+
+namespace eval vfs::tar {}
+
+proc vfs::tar::Mount {tarfile local} {
+    set fd [vfs::tar::_open [::file normalize $tarfile]]
+    vfs::filesystem mount $local [list ::vfs::tar::handler $fd]
+    # Register command to unmount
+    vfs::RegisterMount $local [list ::vfs::tar::Unmount $fd]
+    return $fd
+}
+
+proc vfs::tar::Unmount {fd local} {
+    vfs::filesystem unmount $local
+    vfs::tar::_close $fd
+}
+
+proc vfs::tar::handler {tarfd cmd root relative actualpath args} {
+    if {$cmd == "matchindirectory"} {
+       # e.g. called from "glob *"
+       eval [list $cmd $tarfd $relative $actualpath] $args
+    } else {
+       # called for all other commands: access, stat
+       eval [list $cmd $tarfd $relative] $args
+    }
+}
+
+proc vfs::tar::attributes {tarfd} { return [list "state"] }
+proc vfs::tar::state {tarfd args} {
+    vfs::attributeCantConfigure "state" "readonly" $args
+}
+
+# If we implement the commands below, we will have a perfect
+# virtual file system for tar files.
+# Completely copied from zipvfs.tcl
+
+proc vfs::tar::matchindirectory {tarfd path actualpath pattern type} {
+    # This call to vfs::tar::_getdir handles empty patterns properly as asking
+    # for the existence of a single file $path only
+    set res [vfs::tar::_getdir $tarfd $path $pattern]
+    if {![string length $pattern]} {
+       if {![vfs::tar::_exists $tarfd $path]} { return {} }
+       set res [list $actualpath]
+       set actualpath ""
+    }
+
+    set newres [list]
+    foreach p [::vfs::matchCorrectTypes $type $res $actualpath] {
+       lappend newres [file join $actualpath $p]
+    }
+    return $newres
+}
+
+# return the necessary "array"
+proc vfs::tar::stat {tarfd name} {
+    vfs::tar::_stat $tarfd $name sb
+    array get sb
+}
+
+proc vfs::tar::access {tarfd name mode} {
+    if {$mode & 2} {
+       vfs::filesystem posixerror $::vfs::posix(EROFS)
+    }
+    # Readable, Exists and Executable are treated as 'exists'
+    # Could we get more information from the archive?
+    if {[vfs::tar::_exists $tarfd $name]} {
+       return 1
+    } else {
+       error "No such file"
+    }
+}
+
+proc vfs::tar::open {tarfd name mode permissions} {
+    # return a list of two elements:
+    # 1. first element is the Tcl channel name which has been opened
+    # 2. second element (optional) is a command to evaluate when
+    #    the channel is closed.
+
+    switch -- $mode {
+       "" -
+       "r" {
+           if {![vfs::tar::_exists $tarfd $name]} {
+               vfs::filesystem posixerror $::vfs::posix(ENOENT)
+           }
+
+           vfs::tar::_stat $tarfd $name sb
+
+           set nfd [vfs::memchan]
+           fconfigure $nfd -translation binary
+
+           # get the starting point from structure
+           seek $tarfd $sb(start) start
+           vfs::tar::_data $tarfd sb data
+
+           puts -nonewline $nfd $data
+
+           fconfigure $nfd -translation auto
+           seek $nfd 0
+           return [list $nfd]
+       }
+       default {
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+    }
+}
+
+proc vfs::tar::createdirectory {tarfd name} {
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+    #error "tar-archives are read-only (not implemented)"
+}
+
+proc vfs::tar::removedirectory {tarfd name recursive} {
+    #::vfs::log "removedirectory $name"
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+    #error "tar-archives are read-only (not implemented)"
+}
+
+proc vfs::tar::deletefile {tarfd name} {
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+    #error "tar-archives are read-only (not implemented)"
+}
+
+# don't care about platform-specific attributes
+proc vfs::tar::fileattributes {tarfd name args} {
+    #::vfs::log "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+           return [list]
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+           return ""
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+    }
+}
+
+# set the 'mtime' of a file.
+proc vfs::tar::utime {fd path actime mtime} {
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
+
+#
+# tar decoder:
+#
+# Format of tar file:
+# see http://www.gnu.org/manual/tar/html_node/tar_123.html
+# "comments" are put into the the arrays for readability
+# the fields in aPosixHeader are stored inside a
+# 512-byte-block. Not all header-fields are used here.
+#
+# Here are some excerpts from the above resource for information
+# only:
+#
+# name, linkname, magic, uname, and gname are null-terminated strings.
+# All other fileds are zero-filled octal numbers in ASCII.
+# Each numeric field of width w contains
+#   w minus 2 digits, a space, and a null,
+#   except size, and mtime, which do not contain the trailing null
+
+# mtime field is the modification time of the file at the time it was
+# archived. It is the ASCII representation of the octal value of the
+# last time the file was modified, represented as an integer number
+# of seconds since January 1, 1970, 00:00 Coordinated Universal Time
+
+
+namespace eval vfs::tar {
+    set HEADER_SIZE 500
+    set BLOCK_SIZE 512
+
+    # fields of header with start/end-index in "comments": length of
+    # field in bytes (just for documentation) prefix is the
+    # "datatype": s == null-terminated string o == zero-filled octal
+    # number (numeric but leave it octal e.g mode) n == numeric -->
+    # integer change to decimal) "not used" is marked when the field
+    # is not needed anywhere here
+    array set aPosixHeader {
+       name      {s 0    99}     # 100
+       mode      {o 100 107}     # "8   - not used now"
+       uid       {n 108 115}     # 8
+       gid       {n 116 123}     # 8
+       size      {n 124 135}     # 12
+       mtime     {n 136 147}     # 12
+       chksum    {o 148 155}     # "8   - not used"
+       typeflag  {o 156 156}     # 1
+       linkname  {s 157 256}     # "100 - not used"
+       magic     {s 257 262}     # "6   - not used"
+       version   {o 263 264}     # "2   - not used"
+       uname     {s 265 296}     # "32  - not used"
+       gname     {s 297 328}     # "32  - not used"
+       devmajor  {o 329 336}     # "8   - not used"
+       devminor  {o 337 344}     # "8   - not used"
+       prefix    {o 345 499}     # "155 - not used"
+    }
+
+    # just for compatibility with posix-header
+    # only DIRTYPE is used
+    array set aTypeFlag {
+       REGTYPE  0            # "regular file"
+       AREGTYPE \000         # "regular file"
+       LNKTYPE  1            # link
+       SYMTYPE  2            # reserved
+       CHRTYPE  3            # "character special"
+       BLKTYPE  4            # "block special"
+       DIRTYPE  5            # directory
+       FIFOTYPE 6            # "FIFO special"
+       CONTTYPE 7            # reserved
+    }
+}
+
+proc vfs::tar::_data {fd arr {varPtr ""}} {
+    upvar 1 $arr sb
+
+    if {$varPtr eq ""} {
+       seek $fd $sb(size) current
+    } else {
+       upvar 1 $varPtr data
+       set data [read $fd $sb(size)]
+    }
+}
+
+proc vfs::tar::TOC {fd arr toc} {
+    variable aPosixHeader
+    variable aTypeFlag
+    variable HEADER_SIZE
+    variable BLOCK_SIZE
+    
+    upvar 1 $arr sb
+    upvar 1 $toc _toc
+    
+    set pos 0
+    set sb(nitems) 0
+    
+    # loop through file in blocks of BLOCK_SIZE
+    while {![eof $fd]} {
+       seek $fd $pos
+       set hdr [read $fd $BLOCK_SIZE]
+
+       # read header-fields from block (see aPosixHeader)
+       foreach key {name typeflag size mtime uid gid} {
+           set type [lindex $aPosixHeader($key) 0]
+           set positions [lrange $aPosixHeader($key) 1 2]
+           switch $type {
+               s {
+                   set $key [eval [list string range $hdr] $positions]
+                   # cut the trailing Nulls
+                   set $key [string range [set $key] 0 [expr [string first "\000" [set $key]]-1]]
+               }
+               o {
+                   # leave it as is (octal value)
+                   set $key [eval [list string range $hdr] $positions]
+               }
+               n {
+                   set $key [eval [list string range $hdr] $positions]
+                   # change to integer
+                   scan [set $key] "%o" $key
+                   # if not set, set default-value "0"
+                   # (size == "" is not a very good value)
+                   if {![string is integer [set $key]] || [set $key] == ""} { set $key 0 }
+               }
+               default {
+                   error "tar::TOC: '$fd' wrong type for header-field: '$type'"
+               }
+           }
+       }
+
+       # only the last three octals are interesting for mode
+       # ignore mode now, should this be added??
+       # set mode 0[string range $mode end-3 end]
+
+       # get the increment to the next valid block
+       # (ignore file-blocks in between)
+       # if size == 0 the minimum incr is 512
+       set incr [expr {int(ceil($size/double($BLOCK_SIZE)))*$BLOCK_SIZE+$BLOCK_SIZE}]
+
+       set startPosition [expr {$pos+$BLOCK_SIZE}]
+       # make it relative to this working-directory, remove the
+       # leading "relative"-paths
+       regexp -- {^(?:\.\.?/)*/?(.*)} $name -> name
+
+       if {$name != ""} {
+           incr sb(nitems)
+           set sb($name,start) [expr {$pos+$BLOCK_SIZE}]
+           set sb($name,size) $size
+           set type "file"
+           # the mode should be 0777?? or must be changed to decimal?
+           if {$typeflag == $aTypeFlag(DIRTYPE)} {
+               # directory! append this without /
+               # leave mode: 0777
+               # (else we might not be able to walk through archive)
+               set type "directory"
+               lappend _toc([string trimright $name "/"]) \
+                 name [string trimright $name "/"] \
+                 type $type mtime $mtime size $size mode 0777 \
+                 ino -1 start $startPosition \
+                 depth [llength [file split $name]] \
+                 uid $uid gid $gid
+           }
+           lappend _toc($name) \
+             name $name \
+             type $type mtime $mtime size $size mode 0777 \
+             ino -1 start $startPosition depth [llength [file split $name]] \
+             uid $uid gid $gid
+       }
+       incr pos $incr
+    }
+    return
+}
+
+proc vfs::tar::_open {path} {
+    set fd [::open $path]
+    
+    if {[catch {
+       upvar #0 vfs::tar::$fd.toc toc
+       fconfigure $fd -translation binary ;#-buffering none
+       vfs::tar::TOC $fd sb toc
+    } err]} {
+       close $fd
+       return -code error $err
+    }
+    
+    return $fd
+}
+
+proc vfs::tar::_exists {fd path} {
+    #::vfs::log "$fd $path"
+    if {$path == ""} {
+       return 1
+    } else {
+       upvar #0 vfs::tar::$fd.toc toc
+       return [expr {[info exists toc($path)] || [info exists toc([string trimright $path "/"]/)]}]
+    }
+}
+
+proc vfs::tar::_stat {fd path arr} {
+    upvar #0 vfs::tar::$fd.toc toc
+    upvar 1 $arr sb
+
+    if { $path == "" || $path == "." } {
+       array set sb {
+           type directory mtime 0 size 0 mode 0777 
+           ino -1 depth 0 name ""
+       }
+    } elseif {![info exists toc($path)] } {
+       return -code error "could not read \"$path\": no such file or directory"
+    } else {
+       array set sb $toc($path)
+    }
+
+    # set missing attributes
+    set sb(dev) -1
+    set sb(nlink) 1
+    set sb(atime) $sb(mtime)
+    set sb(ctime) $sb(mtime)
+
+    return ""
+}
+
+# Treats empty pattern as asking for a particular file only.
+# Directly copied from zipvfs.
+proc vfs::tar::_getdir {fd path {pat *}} {
+    upvar #0 vfs::tar::$fd.toc toc
+    
+    if { $path == "." || $path == "" } {
+       set path $pat
+    } else {
+       set path [string tolower $path]
+       if {$pat != ""} {
+           append path /$pat
+       }
+    }
+    set depth [llength [file split $path]]
+    
+    if {$depth} {
+       set ret {}
+       foreach key [array names toc $path] {
+           if {[string index $key end] eq "/"} {
+               # Directories are listed twice: both with and without
+               # the trailing '/', so we ignore the one with
+               continue
+           }
+           array set sb $toc($key)
+
+           if { $sb(depth) == $depth } {
+               if {[info exists toc(${key}/)]} {
+                   array set sb $toc(${key}/)
+               }
+               # remove sb(name) (because == $key)
+               lappend ret [file tail $key]
+           }
+           unset sb
+       }
+       return $ret
+    } else {
+       # just the 'root' of the zip archive.  This obviously exists and
+       # is a directory.
+       return [list {}]
+    }
+}
+
+proc vfs::tar::_close {fd} {
+    variable $fd.toc
+    unset -nocomplain $fd.toc
+    ::close $fd
+}
diff --git a/8.x/tclvfs/library/tclprocvfs.tcl b/8.x/tclvfs/library/tclprocvfs.tcl
new file mode 100644 (file)
index 0000000..99845fa
--- /dev/null
@@ -0,0 +1,206 @@
+
+package provide vfs::ns 0.5.1
+
+package require vfs 1.0
+
+# Thanks to jcw for the idea here.  This is a 'file system' which
+# is actually a representation of the Tcl command namespace hierarchy.
+# Namespaces are directories, and procedures are files.  Tcl allows
+# procedures with the same name as a namespace, which are hidden in
+# a filesystem representation.
+
+namespace eval vfs::ns {}
+
+proc vfs::ns::Mount {ns local} {
+    if {![namespace exists ::$ns]} {
+       error "No such namespace"
+    }
+    ::vfs::log "ns $ns mounted at $local"
+    vfs::filesystem mount $local [list vfs::ns::handler $ns]
+    vfs::RegisterMount $local [list vfs::ns::Unmount]
+    return $local
+}
+
+proc vfs::ns::Unmount {local} {
+    vfs::filesystem unmount $local
+}
+
+proc vfs::ns::handler {ns cmd root relative actualpath args} {
+    regsub -all / $relative :: relative
+    if {$cmd == "matchindirectory"} {
+       eval [list $cmd $ns $relative $actualpath] $args
+    } else {
+       eval [list $cmd $ns $relative] $args
+    }
+}
+
+# If we implement the commands below, we will have a perfect
+# virtual file system for namespaces.
+
+proc vfs::ns::stat {ns name} {
+    ::vfs::log "stat $name"
+    if {[namespace exists ::${ns}::${name}]} {
+       return [list type directory size 0 mode 0777 \
+         ino -1 depth 0 name $name atime 0 ctime 0 mtime 0 dev -1 \
+         uid -1 gid -1 nlink 1]
+    } elseif {[llength [info procs ::${ns}::${name}]]} {
+       return [list type file]
+    } else {
+       return -code error "could not read \"$name\": no such file or directory"
+    }
+}
+
+proc vfs::ns::access {ns name mode} {
+    ::vfs::log "access $name $mode"
+    if {[namespace exists ::${ns}::${name}]} {
+       return 1
+    } elseif {[llength [info procs ::${ns}::${name}]]} {
+       if {$mode & 2} {
+           error "read-only"
+       }
+       return 1
+    } else {
+       error "No such file"
+    }
+}
+
+proc vfs::ns::exists {ns name} {
+    if {[namespace exists ::${ns}::${name}]} {
+       return 1
+    } elseif {[llength [info procs ::${ns}::${name}]]} {
+       return 1
+    } else {
+       return 0
+    }
+}
+
+proc vfs::ns::open {ns name mode permissions} {
+    ::vfs::log "open $name $mode $permissions"
+    # return a list of two elements:
+    # 1. first element is the Tcl channel name which has been opened
+    # 2. second element (optional) is a command to evaluate when
+    #    the channel is closed.
+    switch -- $mode {
+       "" -
+       "r" {
+           set nfd [vfs::memchan]
+           fconfigure $nfd -translation binary
+           puts -nonewline $nfd [_generate ::${ns}::${name}]
+           fconfigure $nfd -translation auto
+           seek $nfd 0
+           return [list $nfd]
+       }
+       default {
+           return -code error "illegal access mode \"$mode\""
+       }
+    }
+}
+
+proc vfs::ns::_generate {p} {
+    lappend a proc $p
+    set argslist [list]
+    foreach arg [info args $p] {
+       if {[info default $p $arg v]} {
+           lappend argslist [list $arg $v]
+       } else {
+           lappend argslist $arg
+       }
+    }
+    lappend a $argslist [info body $p]
+}
+
+proc vfs::ns::matchindirectory {ns path actualpath pattern type} {
+    ::vfs::log "matchindirectory $path $actualpath $pattern $type"
+    set res [list]
+
+    set ns ::[string trim $ns :]
+    set nspath ${ns}::${path}
+    if {![namespace exists $nspath]} {return {}}
+     set slash 1
+    if {[::vfs::matchDirectories $type]} {
+       # add matching directories to $res
+       if {[string length $pattern]} {
+           eval [linsert [namespace children $nspath $pattern] 0 lappend res]
+       } elseif {[namespace exists $nspath]} {
+           lappend res $nspath
+       }
+    }
+
+    if {[::vfs::matchFiles $type]} {
+       # add matching files to $res
+       if {[string length $pattern]} {
+           eval [linsert [info procs ${nspath}::$pattern] 0 lappend res]
+       } elseif {[llength [info procs $nspath]]} {
+           lappend res $nspath
+           set slash 0
+       }
+    }
+
+    # There is a disconnect between 8.4 and 8.5 with the / handling
+    # Make sure actualpath gets just one trailing /
+    if {$slash && ![string match */ $actualpath]} { append actualpath / }
+
+    set realres [list]
+    foreach r $res {
+       regsub "^(::)?${ns}(::)?${path}(::)?" $r $actualpath rr
+       lappend realres $rr
+    }
+    #::vfs::log $realres
+
+    return $realres
+}
+
+proc vfs::ns::createdirectory {ns name} {
+    ::vfs::log "createdirectory $name"
+    namespace eval ::${ns}::${name} {}
+}
+
+proc vfs::ns::removedirectory {ns name recursive} {
+    ::vfs::log "removedirectory $name"
+    namespace delete ::${ns}::${name}
+}
+
+proc vfs::ns::deletefile {ns name} {
+    ::vfs::log "deletefile $name"
+    rename ::${ns}::${name} {}
+}
+
+proc vfs::ns::fileattributes {ns name args} {
+    ::vfs::log "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+           return [list -args -body]
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+           switch -- $index {
+               0 {
+                   ::info args ::${ns}::${name}
+               }
+               1 {
+                   ::info body ::${ns}::${name}
+               }
+           }
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+           switch -- $index {
+               0 {
+                   error "read-only"
+               }
+               1 {
+                   error "unimplemented"
+               }
+           }
+       }
+    }
+}
+
+proc vfs::ns::utime {what name actime mtime} {
+    ::vfs::log "utime $name"
+    error ""
+}
diff --git a/8.x/tclvfs/library/template/chrootvfs.tcl b/8.x/tclvfs/library/template/chrootvfs.tcl
new file mode 100644 (file)
index 0000000..2162fde
--- /dev/null
@@ -0,0 +1,127 @@
+#/usr/bin/env tclsh
+
+if 0 {
+########################
+
+chrootvfs.tcl --
+
+Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+License: Tcl license
+Version 1.5
+
+A chroot virtual filesystem.
+
+This virual filesystem has an effect similar to a "chroot" command; it makes the named existing directory appear
+to be the top of the filesystem and makes the rest of the real filesystem invisible.
+
+This vfs does not block access by the "exec" command to the real filesystem outside the chroot directory,
+or that of the "open" command when its command pipeline syntax is used.
+
+At the end of this file is example code showing one way to set up a safe slave interpreter suitable for
+running a process safely with limited filesystem access: its file access commands are re-enabled, the exec
+command remains disabled, the open command is aliased so that it can only open files and can't spawn new 
+processes, and mounted volumes besides the volume on which the chroot directory resides are aliased so 
+that they act as mirrors of the chroot directory.
+
+Such an interpreter should be advantageous for applications such as a web server: which requires some 
+filesystem access but presents security threats that make access limitations desirable.
+
+ Install: This code requires the vfs::template package included in the Tclvfs distribution.
+
+ Usage: mount ?-volume? <existing "chroot" directory>  <virtual directory>
+
+ examples:
+
+       mount $::env(HOME) /
+
+       mount {C:\My Music} C:/
+
+       mount -volume /var/www/htdocs chroot://
+
+########################
+}
+
+namespace eval ::vfs::template::chroot {
+
+package require vfs::template 1.5
+package provide vfs::template::chroot 1.5.2
+
+# read template procedures into current namespace. Do not edit:
+foreach templateProc [namespace eval ::vfs::template {info procs}] {
+       set infoArgs [info args ::vfs::template::$templateProc]
+       set infoBody [info body ::vfs::template::$templateProc]
+       proc $templateProc $infoArgs $infoBody
+}
+
+proc file_attributes {file {attribute {}} args} {eval file attributes \$file $attribute $args}
+
+catch {rename redirect_handler {}}
+catch {rename handler redirect_handler}
+
+proc handler args {
+       set path [lindex $args 0]
+       set to [lindex $args 2]
+       set volume [lindex $::vfs::template::mount($to) 1]
+       if {$volume != "-volume"} {set volume {}}
+       set startDir [pwd]
+
+       ::vfs::filesystem unmount $to
+
+       set err [catch {set rv [uplevel ::vfs::template::chroot::redirect_handler $args]} result] ; set errorCode $::errorCode
+
+       eval ::vfs::filesystem mount $volume [list $to] \[list [namespace current]::handler \[file normalize \$path\]\]
+       if {[pwd] != $startDir} {catch {cd $startDir}}
+       if {$err && ([lindex $errorCode 0] == "POSIX")} {vfs::filesystem posixerror $::vfs::posix([lindex $errorCode 1])}
+       if $err {return -code $err $result}
+       return $rv
+}
+
+
+# Example code to set up a safe interpreter with limited filesystem access:
+proc chroot_slave {} {
+       file mkdir /tmp
+       package require vfs::template
+       ::vfs::template::chroot::mount -volume /tmp C:/
+       set vols [lsort -unique [file volumes]]
+       foreach vol $vols {
+               if {$vol == "C:/"} {continue}
+               ::vfs::template::mount C:/ $vol
+       }
+       set slave [interp create -safe]
+       $slave expose cd  
+       $slave expose encoding
+       $slave expose fconfigure
+       $slave expose file
+       $slave expose glob
+       $slave expose load
+       $slave expose pwd
+       $slave expose socket
+       $slave expose source
+
+       $slave alias exit exit_safe $slave
+       $slave alias open open_safe $slave
+
+       interp share {} stdin $slave
+       interp share {} stdout $slave
+       interp share {} stderr $slave
+}
+
+proc exit_safe {slave} {
+       interp delete $slave
+}
+
+proc open_safe {args} {
+       set slave [lindex $args 0]
+       set handle [lindex $args 1]
+       set args [lrange $args 1 end]
+       if {[string index $handle 0] != "|"} {
+               eval [eval list interp invokehidden $slave open $args]
+       } else {
+               error "permission denied"
+       }
+}
+
+
+}
+# end namespace ::vfs::template::chroot
+
diff --git a/8.x/tclvfs/library/template/collatevfs.tcl b/8.x/tclvfs/library/template/collatevfs.tcl
new file mode 100644 (file)
index 0000000..770f11e
--- /dev/null
@@ -0,0 +1,371 @@
+if 0 {
+########################
+
+collatevfs.tcl --
+
+Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+License: Tcl license
+Version 1.5.3
+
+A collate/broadcast/collect/catchup virtual filesystem.  Requires the template vfs in templatevfs.tcl.
+
+Collate: reads from multiple specified directories and presents the results as one at the mount location.
+
+Broadcast: applies all writes in the mount location to multiple specified directories.
+
+Collect: copies any file read from or written to any of the above locations to specified directories. 
+
+Catchup: If any specified directory is not available during any write action, the action is recorded in 
+a catchup queue.  With each subsequent write action, the queue is examined, and if any directory has 
+become available, the action is performed, allowing offline directories to "catch up."
+
+Usage: mount ?-read <directories> -write <directories> -collect <directories> -catchup <directories>? <virtual directory>
+
+Each pathname in <directories> is meant to stand individually, the <directories> symbol is not meant to indicate a 
+Tcl list.  The sets of specified locations are independent; they can overlap or not as desired.  Note each
+option flag is optional, one could for example use only the -read flag to create a read-only directory.  Directories
+do not have to exist and may go missing after mount, non-reachable locations will be ignored.
+
+Options:
+
+-read
+When an individual file is opened for reading, each of the directories specified is searched in 
+order for the file; the first file found with the appropriate name is opened.  When a subdirectory listing is 
+generated, the combined files of the corresponding subdirectory of all specified directories are listed together.
+
+-write
+When an individual file is opened for writing, each of the directories specified is searched in 
+order for the file; the first file found with the appropriate name is opened.  If the file doesn't exist, 
+it is created in the first specified write location.  When the file is closed, a copy of it is distributed to 
+each specified write directory.
+
+-collect
+Auto-generates one or more file caches; a copy of any file opened for reading or writing in any of the above 
+specified directories is made to each directory specified with the -collect flag.  Collect locations are 
+not included in file or directory listings, and are not searched for read access; so in order to make an 
+active read cache, for example, one would have to include one directory location in both the -read and -collect sets.
+
+-catchup
+If this flag is included, the catchup function is activated, and a copy of the catchup queue is stored in a
+file in each of the specified directories.  File writes, directory creations and file/directory deletes are
+stored in the catchup queue if any write location is offline; at the next write/creation/delete the queue is 
+examined, and if any skipped action can be completed due to a location becoming available again, it 
+will be.  A catchup attempt will be made at mount time if this flag is included.
+
+The values of each option can be changed dynamically after mount by using the "file attributes" command on the
+mount virtual directory. Each option is editable as an attribute; i.e., "file attributes C:/collate -write C:/tmp"
+
+The collate vfs inherits the -cache and -volume options of the template vfs.
+
+
+Example use: specify parallel locations on a hard drive, on a CD-ROM mount and an ftp vfs as the read list.
+Files will be read first from the hard drive, if not found there the CD-ROM and ftp site will be searched in turn.
+The hard drive can be specified as the single write location, and no writes to the CD-ROM or 
+ftp site will ever be attempted:
+
+mount -read C:/install/package/docs CDROM:/package/docs FTP:/pub/releases/package/docs -write C:/install/package/docs C:/collate/docs
+
+
+Example collect location use: specify a single hard drive location as a read and collect directory.  
+Specify a ftp vfs as a secondary read directory.  As ftp files are downloaded they are copied to the 
+collect directory; the local copies are accessed first on subsequent reads: hence the collect
+specification produces a self-generating local cache:
+
+mount -read C:/install/package/images FTP:/pub/releases/package/images -collect C:/install/package/images C:/collate/images
+
+
+########################
+}
+
+package require vfs::template 1.5
+
+namespace eval ::vfs::template::collate {
+
+# read template procedures into current namespace. Do not edit:
+foreach templateProc [namespace eval ::vfs::template {info procs}] {
+       set infoArgs [info args ::vfs::template::$templateProc]
+       set infoBody [info body ::vfs::template::$templateProc]
+       proc $templateProc $infoArgs $infoBody
+}
+
+# edit following procedures:
+proc close_ {channel} {
+       upvar root root relative relative
+       foreach file [lrange [WriteFile $root $relative close] 1 end] {
+               if ![WriteTest $file] {continue}
+               file mkdir [file dirname $file]
+               set f [open $file w]
+               fconfigure $f -translation binary
+               seek $channel 0
+               fcopy $channel $f
+               close $f
+       }
+       return
+}
+proc file_atime {file time} {
+       upvar root root relative relative
+       foreach file [WriteFile $root $relative open] {
+               file atime $file $time
+       }
+}
+proc file_mtime {file time} {
+       upvar root root relative relative
+       foreach file [WriteFile $root $relative open] {
+               file mtime $file $time
+       }
+}
+proc file_attributes {file {attribute {}} args} {
+       upvar root root relative relative
+       if {($relative == {}) && ([string map {-read 1 -write 1 -collect 1 -catchup 1} $attribute] == 1)} {
+               set attribute [string range $attribute 1 end]
+               if {$args == {}} {eval return \$::vfs::template::collate::${attribute}(\$root)}
+               set ::vfs::template::collate::${attribute}($root) [lindex $args 0]
+               set ::vfs::template::collate::catchup [file isdirectory [lindex $::vfs::template::collate::catchupstore 0]]
+               return
+       }
+       if {$args != {}} {
+               foreach file [WriteFile $root $relative open] {
+                       file attributes $file $attribute $args
+               }
+               return
+       }
+       set file [AcquireFile $root $relative]
+       set returnValue [eval file attributes \$file $attribute $args]
+       if {($relative == {}) && ($attribute == {})} {set returnValue [concat $returnValue [list -read $::vfs::template::collate::read($root) -write $::vfs::template::collate::write($root) -collect $::vfs::template::collate::collect($root) -catchup $::vfs::template::collate::catchupstore($root)]]}
+       return $returnValue
+}
+proc file_delete {file} {
+       upvar root root relative relative
+       foreach file [WriteFile $root $relative delete] {
+               file delete -force -- $file
+       }
+}
+proc file_executable {file} {
+       upvar root root relative relative
+       set file [AcquireFile $root $relative]
+       file executable $file
+}
+proc file_exists {file} {
+       upvar root root relative relative
+       expr ![catch {AcquireFile $root $relative}]
+}
+proc file_mkdir {file} {
+       upvar root root relative relative
+       foreach file [WriteFile $root $relative mkdir] {
+               file mkdir $file
+       }
+}
+proc file_readable {file} {
+       upvar root root relative relative
+       set file [AcquireFile $root $relative]
+       file readable $file
+}
+proc file_stat {file array} {
+       upvar root root relative relative
+       set file [AcquireFile $root $relative]
+       upvar $array fs ; file stat $file fs
+}
+proc file_writable {file} {
+       upvar root root relative relative
+       expr ![catch {WriteFile $root $relative open}]
+}
+proc glob_ {directory dir nocomplain tails types typeString dashes pattern} {
+       upvar root root relative relative
+       set allFiles {}
+       set newFiles {}
+       foreach path $::vfs::template::collate::read($root) {
+               if ![file exists $path] {continue}
+               set allFiles [concat $allFiles [glob -directory [file join $path $relative] -nocomplain -tails -types $typeString -- $pattern]]
+       }
+       set allFiles [lsort -unique $allFiles]
+       return $allFiles
+}
+proc open_ {file mode} {
+       upvar root root relative relative
+       if [string match w* $mode] {
+               set file [lindex [WriteFile $root $relative open] 0]
+               file mkdir [file dirname $file]
+               return [open $file $mode]
+       }
+       if [string match r* $mode] {
+               set file [AcquireFile $root $relative]
+               if {$mode == "r"} {
+                       foreach cpath $::vfs::template::collate::collect($root) {
+                               set cfile [file join $cpath $relative]
+                               if {$file == $cfile} {continue}
+                               if ![file exists $cpath] {continue}
+                               file mkdir [::file dirname $cfile]
+                               file copy -force -- $file $cfile
+                       }
+                       return [open $file r]
+               }
+               set wfile [lindex [WriteFile $root $relative open] 0]
+               file mkdir [file dirname $wfile]
+               if {$wfile != $file} {file copy -force -- $file $wfile}
+               return [open $wfile $mode]
+       }
+       if [string match a* $mode] {
+               set wfile [lindex [WriteFile $root $relative open] 0]
+               file mkdir [file dirname $wfile]
+               if ![catch {set file [AcquireFile $root $relative]}] {
+                       if {$wfile != $file} {file copy -force -- $file $wfile}
+               } 
+               return [open $wfile $mode]
+       }
+}
+
+proc MountProcedure {args} {
+       upvar volume volume
+
+# take real and virtual directories from command line args.
+       set to [lindex $args end]
+       if [string equal $volume {}] {set to [::file normalize $to]}
+
+# add custom handling for new vfs args here.
+
+       set ::vfs::template::collate::catchup($to) 0
+       set ::vfs::template::collate::read($to) {}
+       set ::vfs::template::collate::write($to) {}
+       set ::vfs::template::collate::collect($to) {}
+       set ::vfs::template::collate::catchupstore($to) {}
+
+       set args [lrange $args 0 end-1]
+       set argsIndex [llength $args]
+       for {set i 0} {$i < $argsIndex} {incr i} {
+               set arg [lindex $args $i]
+
+               switch -- $arg {
+                       -read {
+                               set type read
+                       }
+                       -write {
+                               set type write
+                       }
+                       -collect {
+                               set type collect
+                       }
+                       -catchup {
+                               set ::vfs::template::collate::catchup($to) 1
+                               set type catchupstore
+                       }
+                       default {
+                               eval lappend ::vfs::template::collate::${type}(\$to) \[::file normalize \$arg\]
+                       }
+               }
+       }
+
+       WriteFile $to {} mkdir
+
+# return two-item list consisting of real and virtual locations.
+       lappend pathto {}
+       lappend pathto $to
+       return $pathto
+}
+
+proc UnmountProcedure {path to} {
+# add custom unmount handling of new vfs elements here.
+       unset -nocomplain ::vfs::template::collate::read($to)
+       unset -nocomplain ::vfs::template::collate::write($to)
+       unset -nocomplain ::vfs::template::collate::collect($to)
+       unset -nocomplain ::vfs::template::collate::catchup($to)
+       unset -nocomplain ::vfs::template::collate::catchupstore($to)
+       return
+}
+
+proc AcquireFile {root relative} {
+       foreach path $::vfs::template::collate::read($root) {
+               set file [::file join $path $relative]
+               if [::file exists $file] {
+                       return $file
+               }
+       }
+       vfs::filesystem posixerror $::vfs::posix(ENOENT) ; return -code error $::vfs::posix(ENOENT)
+}
+
+proc WriteFile {root relative action} {
+       set allWriteLocations {}
+       foreach awl [concat $::vfs::template::collate::write($root) $::vfs::template::collate::collect($root)] {
+               if {[lsearch $allWriteLocations $awl] < 0} {lappend allWriteLocations $awl}
+       }
+       if ![llength $allWriteLocations] {
+               vfs::filesystem posixerror $::vfs::posix(EROFS) ; return -code error $::vfs::posix(EROFS)
+       }
+       if {$vfs::template::collate::catchup($root) && ([file tail $relative] != ".vfs_catchup") && ($action != "open")} {
+               set catchupActivate 1
+               set addCatchup {}
+               set newCatchup {}
+       } else {
+               set catchupActivate 0
+       }
+       set returnValue {}
+       foreach path $allWriteLocations  {
+               if {$catchupActivate && ![file exists $path]} {
+                       append addCatchup "[list $action $path $relative]\n"
+                       continue
+               }
+               set rvfile [file join $path $relative]
+               if {[lsearch $returnValue $rvfile] == -1} {lappend returnValue $rvfile}
+       }
+       if {$returnValue == {}} {vfs::filesystem posixerror $::vfs::posix(EROFS) ; return -code error $::vfs::posix(EROFS)}
+       if $catchupActivate {
+               set catchup {}
+               set ::vfs::template::vfs_retrieve 1
+
+               foreach store $::vfs::template::collate::catchupstore($root) {
+                       set store [file join $store ".vfs_catchup"]
+                       if [file readable $store] {
+                               set f [open $store r]
+                               unset ::vfs::template::vfs_retrieve
+                               seek $f 0
+                               set catchup [read $f]
+                               close $f
+                               break
+                       }
+               }
+               catch {set currentRead [AcquireFile $root {}]} result
+               foreach {action path rel} $catchup {
+                       if {$relative == $rel} {continue}
+                       if ![file exists $path] {append newCatchup "[list $action $path $rel]\n" ; continue}
+                       if {[lsearch $allWriteLocations  $path] < 0} {continue}
+                       switch -- $action {
+                               close {
+                                       if {![info exists currentRead] || ([set source [file join $currentRead $rel]] == [set target [file join $path $rel]])} {
+                                               append newCatchup "[list $action $path $rel]\n" ; continue
+                                       }
+                                       if ![file exists $source] {continue}
+                                       file mkdir [file dirname $target]
+                                       file copy -force -- $source $target
+                               }
+                               delete {
+                                       file delete -force -- [file join $path $rel]
+                               }
+                               mkdir {
+                                       file mkdir [file join $path $rel]
+                               }
+                       }
+               }
+               append newCatchup $addCatchup
+               foreach path $::vfs::template::collate::catchupstore($root) {
+                       set vfscatchup [file join $path ".vfs_catchup"]
+                       set ::vfs::template::vfs_retrieve 1
+                       set err [catch {
+                               if {$newCatchup != {}} {
+                                       set f [open $vfscatchup w]
+                                       puts $f $newCatchup
+                                       close $f
+                               } else {
+                                       file delete $vfscatchup
+                               }
+                       } result]
+                       unset ::vfs::template::vfs_retrieve
+               }
+       }
+       return $returnValue
+}
+
+proc WriteTest {args} {
+       return 1
+}
+
+}
+# end namespace ::vfs::template::collate
diff --git a/8.x/tclvfs/library/template/deltavfs.tcl b/8.x/tclvfs/library/template/deltavfs.tcl
new file mode 100644 (file)
index 0000000..755a24e
--- /dev/null
@@ -0,0 +1,288 @@
+if 0 {
+########################
+
+deltavfs.tcl --
+
+Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+License: Tcl license
+Version 1.5.2
+
+A delta virtual filesystem.  Requires the template vfs in templatevfs.tcl.
+
+Mount the delta vfs first, then mount the versioning vfs using the virtual location created by the 
+delta vfs as its existing directory.
+
+As the versioning filesystem generates a new separate file for every file edit, this filesystem will 
+invisibly generate and manage deltas of the separate versions to save space.
+
+
+Usage: mount <existing directory> <virtual directory>
+
+
+The delta vfs inherits the -cache and -volume options of the template vfs.
+
+########################
+}
+
+package require vfs::template 1.5
+package require vfs::template::version 1.5
+
+package provide vfs::template::version::delta 1.5.2
+
+namespace eval ::vfs::template::version::delta {
+
+# read template procedures into current namespace. Do not edit:
+foreach templateProc [namespace eval ::vfs::template {info procs}] {
+       set infoArgs [info args ::vfs::template::$templateProc]
+       set infoBody [info body ::vfs::template::$templateProc]
+       proc $templateProc $infoArgs $infoBody
+}
+
+# edit following procedures:
+proc close_ {channel} {
+       upvar path path relative relative
+       set file [file join $path $relative]
+       set fileName $file
+       set f [open $fileName w]
+       fconfigure $f -translation binary
+       seek $f 0
+       seek $channel 0
+       fcopy $channel $f
+       close $f
+       Delta $fileName
+       return
+}
+proc file_atime {file time} {
+       set file [GetFileName $file]
+       file atime $file $time
+}
+proc file_mtime {file time} {
+       set file [GetFileName $file]
+       file mtime $file $time
+}
+proc file_attributes {file {attribute {}} args} {
+       set file [GetFileName $file]
+       eval file attributes \$file $attribute $args
+}
+proc file_delete {file} {
+       if [file isdirectory $file] {catch {file delete $file}}
+
+       set fileName [GetFileName $file]
+       set timeStamp [lindex [split [file tail $fileName] \;] 1]
+       if [string equal $timeStamp {}] {
+               catch {file delete $fileName} result
+               return
+       }
+       set targetFile [Reconstitute $fileName]
+       set referenceFiles [glob -directory [file dirname $fileName] -nocomplain *vfs&delta$timeStamp]
+       if {[lindex [file system $fileName] 0] != "tclvfs"} {append referenceFiles " [glob -directory [file dirname $fileName] -nocomplain -type hidden *vfs&delta$timeStamp]"}
+       foreach referenceFile $referenceFiles {
+               regsub {\;vfs&delta[0-9]*$} $referenceFile "" reconFile]
+               set f [open $referenceFile r]
+               fconfigure $f -translation binary
+               set signature [read $f]
+               close $f
+               tpatch $targetFile $signature $reconFile
+               file delete $referenceFile
+       }
+       close $targetFile
+
+       file delete -force -- $fileName
+}
+proc file_executable {file} {
+       set file [GetFileName $file]
+       file executable $file
+}
+proc file_exists {file} {
+       set file [GetFileName $file]
+       file exists $file
+}
+proc file_mkdir {file} {file mkdir $file}
+proc file_readable {file} {
+       set file [GetFileName $file]
+       file readable $file
+}
+proc file_stat {file array} {
+       upvar $array fs
+       set fileName [GetFileName $file]
+
+       set endtag [lindex [split $fileName \;] end]
+       if {[string first "vfs&delta" $endtag] || [string equal "vfs&delta" $endtag]} {file stat $fileName fs ; return}
+       set f [open $fileName r]
+       fconfigure $f -translation binary
+       set copyinstructions [read $f]
+       close $f
+       array set fileStats [lindex $copyinstructions 3]
+       unset copyinstructions
+       set size $fileStats(size)
+       file stat $fileName fs
+       set fs(size) $size
+       return 
+}
+proc file_writable {file} {
+       set file [GetFileName $file]
+       file writable $file
+}
+proc glob_ {directory dir nocomplain tails types typeString dashes pattern} {
+       set globList [glob -directory $dir -nocomplain -tails -types $typeString -- $pattern]
+       set newGlobList {}
+       foreach gL $globList {
+               regsub {\;vfs&delta.*$} $gL "" gL
+               lappend newGlobList $gL
+       }
+       return $newGlobList
+}
+proc open_ {file mode} {
+       set fileName [GetFileName $file]
+
+       set newFile 0
+       if ![file exists $fileName] {set newFile 1}
+       set fileName $file
+       set channelID [Reconstitute $fileName]
+       if [string equal $channelID {}] {set channelID [open $fileName $mode] ; close $channelID ; set channelID [memchan]}
+       if $newFile {catch {file attributes $fileName -permissions $permissions}}
+       return $channelID
+}
+
+
+proc MountProcedure {args} {
+       upvar volume volume
+
+# take real and virtual directories from command line args.
+       set to [lindex $args end]
+       if [string equal $volume {}] {set to [::file normalize $to]}
+       set path [::file normalize [lindex $args end-1]]
+
+# make sure mount location exists:
+       ::file mkdir $path
+
+# add custom handling for new vfs args here.
+       package require trsync
+       namespace import -force ::trsync::tdelta ::trsync::tpatch
+
+# return two-item list consisting of real and virtual locations.
+       lappend pathto $path
+       lappend pathto $to
+       return $pathto
+}
+
+
+proc UnmountProcedure {path to} {
+# add custom unmount handling of new vfs elements here.
+
+       return
+}
+
+proc Delta {filename} {
+       set fileRoot [lindex [split [file tail $filename] \;] 0]
+       set fileNames [glob -nocomplain -path [file join [file dirname $filename] $fileRoot] *]
+       if {[lindex [file system $filename] 0] != "tclvfs"} {append fileNames " [glob -nocomplain -path [file join [file dirname $filename] $fileRoot] -type hidden *]"}
+       set nonDeltas {}
+       foreach fn $fileNames {
+               set endtag [lindex [split $fn \;] end]
+               if ![string first "vfs&delta" $endtag] {continue}
+               lappend nonDeltas $fn
+               set atimes($fn) [file atime $fn]
+       }
+       if {[set deltaIndex [llength $nonDeltas]] < 2} {return}
+       set nonDeltas [lsort -dictionary $nonDeltas]
+       incr deltaIndex -1
+       set i 0
+       while {$i < $deltaIndex} {
+               set referenceFile [lindex $nonDeltas $i]
+               set targetFile [lindex $nonDeltas [incr i]]
+               set signature [tdelta $referenceFile $targetFile $::trsync::blockSize 1 1]
+               set targetTimeStamp [lindex [split $targetFile \;] 1]
+
+               file stat $referenceFile fileStats
+               set signatureSize [string length $signature]
+               if {$signatureSize > $fileStats(size)} {
+                       set fileName $referenceFile\;vfs&delta
+                       file rename $referenceFile $fileName
+                       continue
+               }
+
+               array set fileStats [file attributes $referenceFile]
+
+               set fileName $referenceFile\;vfs&delta$targetTimeStamp
+               set f [open $fileName w]
+               fconfigure $f -translation binary
+               puts -nonewline $f $signature
+               close $f
+               file delete $referenceFile
+               array set fileAttributes [file attributes $fileName]
+               if [info exists fileAttributes(-readonly)] {catch {file attributes $fileName -readonly 0}}
+               if [info exists fileAttributes(-permissions)] {catch {file attributes $fileName -permissions rw-rw-rw-}}
+               catch {file attributes $fileName -owner $fileStats(uid)}
+               catch {file attributes $fileName -group $fileStats(gid)}
+               
+               catch {file mtime $fileName $fileStats(mtime)}
+               catch {file atime $fileName $fileStats(atime)}
+
+               foreach attr [array names fileStats] {
+                       if [string first "-" $attr] {continue}
+                       if [string equal [array get fileStats $attr] [array get fileAttributes $attr]] {continue}
+                       if [string equal "-permissions" $attr] {continue}
+                       catch {file attributes $fileName $attr $fileStats($attr)}
+               }
+               catch {file attributes $fileName -permissions $fileStats(mode)}
+               catch {file attributes $fileName -readonly $fileStats(-readonly)}
+       }
+       foreach fn [array names atimes] {
+               if ![file exists $fn] {continue}
+               file atime $fn $atimes($fn)
+       }
+}
+
+proc GetFileName {file} {
+       set isdir 0
+       if {([string first \; $file] == -1) && ![set isdir [file isdirectory $file]]} {return {}}
+       if $isdir {return $file}
+       set fileNames [glob -nocomplain -path $file *]
+       if {[lindex [file system $file] 0] != "tclvfs"} {append fileNames " [glob -nocomplain -path $file -type hidden *]"}
+       set fileName [lindex $fileNames 0]
+       if [set i [expr [lsearch -exact $fileNames $file] + 1]] {set fileName [lindex $fileNames [incr i -1]]}
+       return $fileName
+}
+
+proc Reconstitute {fileName} {
+       if ![catch {set channelID [open $fileName r]}] {return $channelID}
+       if ![catch {set channelID [open $fileName\;vfs&delta r]}] {return $channelID}
+       set targetFiles [glob -nocomplain -path $fileName *]
+       if {[lindex [file system $fileName] 0] != "tclvfs"} {append targetFiles " [glob -nocomplain -path $fileName -type hidden *]"}
+       set targetFile [lindex $targetFiles 0]
+
+       set targetFile [string trim $targetFile]
+       if [string equal $targetFile {}] {return}
+       set fileStack {}
+       while {[string first "\;vfs&delta" $targetFile] > -1} {
+               if ![regexp {\;vfs&delta([0-9]+)$} $targetFile trash targetTime] {break}
+               set fileStack "[list $targetFile] $fileStack"
+               set targetFiles [glob -directory [file dirname $fileName] *\;$targetTime*]
+               if {[lindex [file system $fileName] 0] != "tclvfs"} {append targetFiles " [glob -directory [file dirname $fileName] -nocomplain -type hidden *\;$targetTime*]"}
+               set targetFile [lindex $targetFiles 0]
+
+               set atimes($targetFile) [file atime $targetFile]
+       }
+       set targetFile [open $targetFile r]
+       foreach fs $fileStack {
+               set f [open $fs r]
+               fconfigure $f -translation binary
+               set copyInstructions [read $f]
+               close $f
+               set fileToConstruct [memchan]
+               tpatch $targetFile $copyInstructions $fileToConstruct
+               catch {close $targetFile}
+               set targetFile $fileToConstruct
+       }
+       foreach fn [array names atimes] {
+               file atime $fn $atimes($fn)
+       }
+       fconfigure $targetFile -translation auto
+       seek $targetFile 0
+       return $targetFile
+}
+
+}
+# end namespace ::vfs::template::version::delta
+
diff --git a/8.x/tclvfs/library/template/fishvfs.tcl b/8.x/tclvfs/library/template/fishvfs.tcl
new file mode 100644 (file)
index 0000000..3a87de2
--- /dev/null
@@ -0,0 +1,535 @@
+#! /usr/bin/env tclsh
+
+if 0 {
+########################
+
+fishvfs.tcl --
+
+ A "FIles transferred over SHell" virtual filesystem
+ This is not an official "FISH" protocol client as described at:
+       http://mini.net/tcl/12792
+ but it utilizes the same concept of turning any computer that offers
+ access via ssh, rsh or similar shell into a file server.
+       Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+       License: Tcl license
+       Version 1.5.2
+ Usage: mount ?-volume? \
+       ?-cache <number>? \             # cache retention seconds
+       ?-exec? \                               # location of executable
+       ?-transport <protocol>? \       # can be ssh, rsh or plink
+       ?-user <username>? \            # remote computer login name
+       ?-password <password>? \        # remote computer login password
+       ?-host <remote hostname>? \     # remote computer domain name
+       ?-port <port number>? \         # override default port
+       ?<option> <value>?
+       <remote directory> \            # an existing directory on the remote filesystem
+       <virtual mount directory or URL>
+Options:
+
+-cache
+Sets number of seconds file information will dwell in cache after being retrieved.
+Default is 2.  This value is viewable and editable after mount by calling 
+"file attributes <virtual directory> -cache ?value?"
+
+-volume
+Volume specified in virtual directory pathname will be mounted as a virtual volume.
+
+-exec
+Full pathname of ssh or equivalent program.  Default is name of the -transport option,
+which is assumed to be the name of the executable program findable in the PATH.
+
+-transport
+Protocol used to transport commands to remote computer.  Built-in allowable values are
+ssh, rsh or plink.  Extensible to new protocols with addition of a single command line
+formatting proc.
+
+The ssh option assumes rsa login protocol is set up so no interactive password entry
+is necessary.
+
+-user 
+Login name at remote computer if necessary.
+
+-password
+Password for remote login name if necessary.
+
+-host
+Hostname of remote computer.  Only necessary if not specified in virtual mount URL.
+
+-port
+Override default port if necessary.
+
+Arbitrary option/value pairs can be included in the command line; they may be useful if 
+a custom new transport protocol handler is added which requires info not included in the
+provided set.
+
+The vfs can be mounted as a local directory, or as a URL in conjunction with 
+the "-volume" option.
+The URL can be of the form:
+transport://[user[:password]@]host[:port][/filename]
+Option switches can be used in conjunction with a URL to specify connection 
+information; the option switch values will override the URL values.
+
+
+Examples:
+ mount -transport ssh -user root -host tcl.tk / /mnt/vfs/tcl
+ mount -volume /home/foo rsh://foo@localcomp
+ mount -volume -password foopass /home/foo plink://foo@bar.org:2323/remotemount
+ mount -cache 60 -transport plink -user foo -password foopass -host bar.org /home/foo C:/Tcl/mount/foo
+
+Client configuration:
+ If the -exec option is not used, the shell client must be in the PATH; it must be
+ configured for non-interactive (no password prompt) use.
+ The value of the -transport option is used to load an appropriate handler 
+ procedure which is called to handle the specifics of the particular client.
+ Handlers for the supported transports (ssh, rsh, plink) already exist.
+ New clients can be added simply by providing a suitable handler procedure.
+ server configuration:
+ The remote computer is assumed to be running an SSH server, have a sh-type shell and 
+ the standard GNU fileutils, but otherwise no configuration is needed. 
+
+########################
+}
+
+package require vfs::template 1.5
+package provide vfs::template::fish 1.5.2
+
+namespace eval ::vfs::template::fish {
+
+# read template procedures into current namespace. Do not edit:
+foreach templateProc [namespace eval ::vfs::template {info procs}] {
+       set infoArgs [info args ::vfs::template::$templateProc]
+       set infoBody [info body ::vfs::template::$templateProc]
+       proc $templateProc $infoArgs $infoBody
+}
+
+proc close_ {channelID} {
+       upvar root root path path relative relative
+       set fileName [file join $path $relative]
+
+       fconfigure $channelID -translation binary
+       seek $channelID 0 end
+       set channelSize [tell $channelID]
+
+# use cat to pump channel contents to target file:
+       set command "cat>'$fileName'\;cat>/dev/null"
+       Transport $root $command stdin $channelID
+
+# check file size to ensure proper transmission:
+       set command "ls -l '$fileName' | ( read a b c d x e\; echo \$x )"
+       set fileSize [Transport $root $command]
+       if {$channelSize != $fileSize} {error "couldn't save \"$fileName\": Input/output error" "Input/output error" {POSIX EIO {Input/output error}}}
+       return
+}
+
+proc file_atime {file time} {
+       upvar root root
+       set atime [clock format $time -format %Y%m%d%H%M.%S -gmt 1]
+       set command "TZ=UTC\; export TZ\; touch -a -c -t $atime '$file'"
+       Transport $root $command
+       return $time
+}
+
+proc file_mtime {file time} {
+       upvar root root
+       set mtime [clock format $time -format %Y%m%d%H%M.%S -gmt 1]
+       set command "TZ=UTC\; export TZ\; touch -c -m -t $mtime '$file'"
+       Transport $root $command
+       return $time
+}
+
+proc file_attributes {file {attribute {}} args} {
+       upvar root root
+       set tail [file tail $file]
+       set value $args
+
+# retrive info option:
+       if {([string equal $attribute {}]) || ([string equal $value {}])} {
+               set command "find '$file' -maxdepth 1 -name '$tail' -printf '%u %g %m\\n'"
+
+# set info option:
+       } elseif ![string first $attribute "-group"] {
+               set command "chgrp $value '$file'"
+       } elseif ![string first $attribute "-owner"] {
+               set command "chown $value '$file'"
+       } elseif ![string first $attribute "-permissions"] {
+               set command "chmod $value '$file'"
+       }
+
+       set returnValue [Transport $root $command]
+
+# format retrieved info:
+       if [string equal $attribute {}] {
+               return "-group [lindex $returnValue 1] -owner [lindex $returnValue 0] -permissions [lindex $returnValue 2]"
+       }
+       if [string equal $value {}] {
+               if ![string first $attribute "-group"] {
+                       return [lindex $returnValue 1]
+               } elseif ![string first $attribute "-owner"] {
+                       return [lindex $returnValue 0]
+               } elseif ![string first $attribute "-permissions"] {
+                       return [lindex $returnValue 2]
+               }
+       }
+       return
+}
+
+proc file_delete {file} {
+       upvar root root                 
+       set command "rm -rf '$file'"
+       Transport $root $command
+}
+proc file_executable {file} {  
+       file_access $file executable
+}
+proc file_exists {file} {
+       file_access $file exists
+}
+proc file_mkdir {file} {
+       upvar root root                 
+       set  command "mkdir -p '$file'"
+       Transport $root $command
+}
+proc file_readable {file} {
+       file_access $file readable
+}
+
+if 0 {
+###
+In the interest of efficiency, the stat call grabs a lot of info.
+Since many operations require a stat call and then an access call, this proc
+grabs the file's access info as well as the stat info and caches it.  Stat info
+for every file in the target directory is grabbed in one call and cached for
+possible future use.
+###
+}
+proc file_stat {file arrayName} {
+       upvar $arrayName array
+       upvar path path root root relative relative
+       set secs [clock seconds]
+       set cache $::vfs::template::fish::cache($root)
+
+# combined command retrieves access and stat info:
+       set command "if \[ -r '$file' \]\; then echo 1\; else echo 0\; fi \; if \[ -w '$file' \]\; then echo 1\; else echo 0\; fi \; if \[ -x '$file' \]\; then echo 1\; else echo 0\; fi \;  if \[ -e '$file' \]\; then echo 1\; else echo 0\; fi \; find '[::file dirname $file]' -maxdepth 1 -xtype d -printf '%A@ %C@ %G %i %m %T@ %n %s %U  \{%f\}\\n' \; echo / \; find '[::file dirname $file]' -maxdepth 1 -xtype f -printf '%A@ %C@ %G %i %m %T@ %n %s %U  \{%f\}\\n'"
+
+# see if info is in cache:
+       set returnValue [CacheGet ::vfs::template::fish::stat [::file join $root $relative] $cache $secs]
+
+#if not, retrieve it:
+       if [string equal $returnValue {}] {
+               set returnValue [Transport $root $command]
+
+               set dir 1
+               set returnValue [split $returnValue \n]
+
+# split off access info and cache it:
+               set access [lrange $returnValue 0 3]
+               set returnValue [lrange $returnValue 4 end]
+               CacheSet ::vfs::template::fish::readable [file join $root $relative] [lindex $access 0] $secs
+               CacheSet ::vfs::template::fish::writable [file join $root $relative] [lindex $access 1] $secs
+               CacheSet ::vfs::template::fish::executable [file join $root $relative] [lindex $access 2] $secs
+               CacheSet ::vfs::template::fish::exists [file join $root $relative] [lindex $access 3] $secs
+
+# current dir info is first entry, discard it if file is not root:
+               if ![string equal $file "/"] {set returnValue [lrange $returnValue 1 end]}
+
+# format and cache info for each file in dir containing target file:
+               set pathLength [llength [file split $path]]
+               foreach rV $returnValue {
+                       if [string equal $rV "/"] {set dir 0 ; continue}
+                       set fileTail [lindex $rV end]
+                       set fN [::file join $root [join [lrange [file split [file join [file dirname $file] $fileTail]] $pathLength end] /]]
+
+                       set value "mtime [lindex $rV 5] gid [lindex $rV 2] nlink [lindex $rV 6] atime [lindex $rV 0] mode [lindex $rV 4] type [if $dir {set type directory} else {set type file}] ctime [lindex $rV 1] uid [lindex $rV 8] ino [lindex $rV 3] size [lindex $rV 7] dev -1"
+                       CacheSet ::vfs::template::fish::stat $fN $value $secs
+
+               }
+# grab info for target file from cache:
+               set returnValue $::vfs::template::fish::stat([file join $root $relative],value)
+       }
+# feed info into upvar'd array:
+       array set array $returnValue
+       return
+}
+
+proc file_writable {file} {
+       file_access $file writable
+}
+
+if 0 {
+###
+glob call aims to increase efficiency by grabbing stat info of listed files, under
+assumption that a file listing is likely to be followed by an operation on one
+of the listed files:
+###
+}
+proc glob_ {d directory nocomplain tails types typeString dashes pattern} {
+
+       upvar 1 path path root root relative relative
+
+# list files along with their stat info:
+       set command "find '$directory' -maxdepth 1 -mindepth 1 -xtype d -printf '%A@ %C@ %G %i %m %T@ %n %s %U  \{%f\}\\n' \; echo / \; find '$directory' -maxdepth 1 -mindepth 1 -xtype f -printf '%A@ %C@ %G %i %m %T@ %n %s %U  \{%f\}\\n'"
+
+       set returnValue [Transport $root $command]
+       set secs [clock seconds]
+       set virtualName [file join $root $relative]
+
+       set dirs {}
+       set files {}
+       set dir 1
+
+# loop through file list and cache stat info:
+       foreach rV [split $returnValue \n] {
+               if [string equal $rV "/"] {set dir 0 ; continue}
+       
+               set fileTail [lindex $rV end]
+               set fN [file join $virtualName $fileTail]
+
+               set value "mtime [lindex $rV 5] gid [lindex $rV 2] nlink [lindex $rV 6] atime [lindex $rV 0] mode [lindex $rV 4] type [if $dir {set type directory} else {set type file}] ctime [lindex $rV 1] uid [lindex $rV 8] ino [lindex $rV 3] size [lindex $rV 7] dev -1"
+               CacheSet ::vfs::template::fish::stat $fN $value $secs
+
+               if $dir {lappend dirs $fileTail} else {lappend files $fileTail}
+       }
+
+# decide to return dirs, files or both:
+       set dir [lsearch $typeString "d"]
+       set file [lsearch $typeString "f"]
+       incr dir ; incr file
+
+       if $dir {set values $dirs}
+       if $file {set values $files}
+       if {$dir && $file} {set values [concat $dirs $files]}
+
+# give filenames virtual paths:
+       set fileNames {}
+       foreach fileName $values {
+               if [string equal $fileName "."] {continue}
+               if [string equal $fileName ".."] {continue}
+               if ![string match $pattern $fileName] {continue}
+               lappend fileNames $fileName
+       }
+       return $fileNames
+}
+
+proc open_ {file mode} {
+       upvar root root
+
+# check existence and file size before retrieval:
+       set command "ls -l '$file' | ( read a b c d x e\; echo \$x )"
+       if {([catch {set fileSize [Transport $root $command]}]) && ($mode == "r")} {error "couldn't open \"$file\": no such file or directory" "no such file or directory" {POSIX ENOENT {no such file or directory}}}
+
+       set channelID [memchan]
+
+# file must exist after open procedure, ensure it:
+       set command "touch -a '$file'"
+       Transport $root $command
+
+# if write mode, don't need to retrieve contents:
+       if [string match w* $mode] {return $channelID}
+
+# cat file contents to stdout and transfer to channelID:
+       fconfigure $channelID -translation binary
+       set command "cat '$file'"
+       Transport $root $command stdout $channelID
+
+# check if entire file contents transported:
+       seek $channelID 0 end
+       set channelSize [tell $channelID]
+       if {[info exists fileSize] && ($channelSize != $fileSize)} {error "Input/output error" "Input/output error" {POSIX EIO {Input/output error}}}
+       return $channelID
+}
+
+# all file access procs are redirected here for ease of programming:
+proc file_access {file type} {
+       upvar 2 root root relative relative
+
+       set command "if \[ -r '$file' \]\; then echo 1\; else echo 0\; fi \; if \[ -w '$file' \]\; then echo 1\; else echo 0\; fi \; if \[ -x '$file' \]\; then echo 1\; else echo 0\; fi \; if \[ -e '$file' \]\; then echo 1\; else echo 0\; fi"
+       set returnValue [Transport $root $command]
+       set access [split $returnValue \n]
+       set secs [clock seconds]
+
+       CacheSet ::vfs::template::fish::readable [file join $root $relative] [lindex $access 0] $secs
+       CacheSet ::vfs::template::fish::writable [file join $root $relative] [lindex $access 1] $secs
+       CacheSet ::vfs::template::fish::executable [file join $root $relative] [lindex $access 2] $secs
+       CacheSet ::vfs::template::fish::exists [file join $root $relative] [lindex $access 3] $secs
+
+       eval return \$::vfs::template::fish::${type}(\[file join \$root \$relative\],value)
+}
+
+proc MountProcedure {args} {
+       upvar volume volume
+
+       set to [lindex $args end]
+       set path [lindex $args end-1]
+       if [string equal $volume {}] {set to [file normalize $to]}
+
+# if virtual mount contains mount info, retrieve it:
+       array set params [FileTransport $to]
+
+# retrieve all option/value pairs from args list:
+       if {[llength $args] > 2} {
+               set args [lrange $args 0 end-2]
+               set argsIndex [llength $args]
+               for {set i 0} {$i < $argsIndex} {incr i} {
+                       set arg [lindex $args $i]
+                       if {[string index $arg 0] == "-"} {
+                               set arg [string range $arg 1 end]
+                               set params($arg) [lindex $args [incr i]]
+                       }
+               }
+       }
+
+# local option if no other transport given, useful for testing:
+       if [string equal $params(transport) {}] {set params(transport) local}
+
+# default executable name is transport name:
+       if ![info exists params(exec)] {set params(exec) $params(transport)}
+
+# store parameters:
+       set ::vfs::template::fish::params($to) [array get params]
+       set ::vfs::template::fish::transport($to) $params(transport)
+
+# rewrite template vfshandler so appropriate transport proc is imported with each file operation:
+       set body "set trans \$::vfs::template::fish::transport(\$root) \; namespace import -force ::vfs::template::fish::\$\{trans\}::Transport \n"     
+       append body [info body handler]
+       proc handler [info args handler] $body
+       
+       lappend pathto $path
+       lappend pathto $to
+       return $pathto
+}
+
+proc UnmountProcedure {path to} {
+       unset ::vfs::template::fish::params($to)
+       unset ::vfs::template::fish::transport($to)
+       return
+}
+
+# execute commands, handle stdin/stdout if necessary:
+proc ExecCommand {root command args} {
+       array set params [lindex $args 0]
+       if [info exists params(stdin)] {
+               set execID [eval ::open \"|$command\" w]
+               fconfigure $execID -translation binary
+               seek $params(stdin) 0
+               puts -nonewline $execID [read $params(stdin)]
+               ::close $execID
+               return
+       }
+
+       if [info exists params(stdout)] {
+               set execID [eval ::open \"|$command\" r]
+               fconfigure $execID -translation binary
+               seek $params(stdout) 0
+               puts -nonewline $params(stdout) [read $execID]
+               ::close $execID
+               return
+       }
+       eval exec $command
+}
+# analyze virtual URL for mount information:
+proc FileTransport {filename} {
+       if {[string first : $filename] < 0} {return [list transport {} user {} password {} host {} port {} filename [file normalize $filename]]}
+       if {[string first [string range $filename 0 [string first : $filename]] [file volume]] > -1} {return [list transport {} user {} password {} host {} port {} filename [file normalize $filename]]}
+
+       set filename $filename/f
+       set transport {} ; set user {} ; set password {} ; set host {} ; set port {}
+       
+       regexp {(^[^:]+)://} $filename trash transport
+       regsub {(^[^:]+://)} $filename "" userpasshost
+       set userpass [lindex [split $userpasshost @] 0]
+       set user $userpass
+       regexp {(^[^:]+):(.+)$} $userpass trash user password
+
+       if {[string first @ $userpasshost] == -1} {set user {} ; set password {}}
+
+       regsub {([^/]+)(:[^/]+)(@[^/]+)} $filename \\1\\3 filename
+
+       if [regexp {(^[^:]+)://([^/:]+)(:[^/:]*)*(.+$)} $filename trash transport host port filename] {
+               regexp {([0-9]+)} $port trash port
+               if {[string first [lindex [file split $filename] 1] [file volume]] > -1} {set filename [string range $filename 1 end]}
+       } else {
+               set host [lindex [split $filename /] 0]
+               set filename [string range $filename [string length $host] end]
+               set port [lindex [split $host :] 1]
+               set host [lindex [split $host :] 0]
+       }
+       regexp {^.+@(.+)} $host trash host
+       set filename [string range $filename 0 end-2]
+       return [list transport $transport user $user password $password host $host port $port filename $filename ]
+}
+
+
+}
+# end namespace ::vfs::template::fish
+
+
+# Each transport procedure has its own namespace and Transport proc.
+# Copy and customize for new transport methods:
+
+namespace eval ::vfs::template::fish::local {
+       proc Transport {root command {std none} {chan none}} {
+               array set params "$std $chan"
+               return [::vfs::template::fish::ExecCommand $root $command [array get params]]
+       }
+       namespace export *
+}
+
+namespace eval ::vfs::template::fish::plink {
+       proc Transport {root command {std none} {chan none}} {
+               array set params $::vfs::template::fish::params($root)
+               array set params "$std $chan"
+
+               set port {}
+               if ![string equal $params(port) {}] {set port "-P $params(port)"}
+               set commandLine "[list $params(exec)] -ssh $port -l $params(user) -batch -pw $params(password) $params(host) [list $command]"
+
+               return [::vfs::template::fish::ExecCommand $root $commandLine [array get params]]
+       }
+       namespace export *
+}
+
+namespace eval ::vfs::template::fish::rsh {
+       proc Transport {root command {std none} {chan none}} {
+
+               array set params $::vfs::template::fish::params($root)
+               array set params "$std $chan"
+
+               set user {}
+               if ![string equal $params(user) {}] {set user "-l $params(user)"}
+               set commandLine "[list $params(exec)] $user $params(host) [list ${command}]"
+               return [::vfs::template::fish::ExecCommand $root $commandLine [array get params]]
+       }
+       namespace export *
+}
+
+namespace eval ::vfs::template::fish::ssh {
+       proc Transport {root command {std none} {chan none}} {
+
+               array set params $::vfs::template::fish::params($root)
+               array set params "$std $chan"
+
+               set port {}
+               if ![string equal $params(port) {}] {set port "-D $params(port)"}
+               set user {}
+               if ![string equal $params(user) {}] {set user "-l $params(user)"}
+               set commandLine "[list $params(exec)] $port $user $params(host) [list ${command}]"
+               return [::vfs::template::fish::ExecCommand $root $commandLine [array get params]]
+       }
+       namespace export *
+}
+
diff --git a/8.x/tclvfs/library/template/globfind.tcl b/8.x/tclvfs/library/template/globfind.tcl
new file mode 100644 (file)
index 0000000..c558eb5
--- /dev/null
@@ -0,0 +1,338 @@
+if 0 {
+########################
+
+globfind.tcl --
+
+Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+License: Tcl license
+Version 1.5
+
+The proc globfind is a replacement for tcllib's fileutil::find
+
+Usage: globfind ?basedir ?filtercmd? ?switches??
+
+Options:
+
+basedir - the directory from which to start the search.  Defaults to current directory.
+
+filtercmd - Tcl command; for each file found in the basedir, the filename will be
+appended to filtercmd and the result will be evaluated.  The evaluation should return
+0 or 1; only files whose return code is 1 will be included in the final return result.
+
+switches - The switches will "prefilter" the results before the filtercmd is applied.  The
+available switches are:
+
+       -depth   - sets the number of levels down from the basedir into which the 
+                    filesystem hierarchy will be searched. A value of zero is interpreted
+                    as infinite depth.
+
+       -pattern - a glob-style filename-matching wildcard. ex: -pattern *.pdf
+
+       -types   - any value acceptable to the "types" switch of the glob command.
+                    ex: -types {d hidden}
+
+Side effects:
+
+If somewhere within the search space a directory is a link to another directory within
+the search space, then the variable ::globfind::REDUNDANCY will be set to 1 (otherwise
+it will be set to 0).  The name of the redundant directory will be appended to the
+variable ::globfind::redundant_files.  This may be used to help track down and eliminate
+infinitely looping links in the search space.
+
+Unlike fileutil::find, the name of the basedir will be included in the results if it fits
+the prefilter and filtercmd criteria (thus emulating the behavior of the standard Unix 
+GNU find utility).
+
+----
+
+globfind is designed as a fast and simple alternative to fileutil::find.  It takes 
+advantage of glob's ability to use multiple patterns to scan deeply into a directory 
+structure in a single command, hence the name.
+
+It reports symbolic links along with other files by default, but checks for nesting of
+links which might otherwise lead to infinite search loops.  It reports hidden files by
+default unless the -types switch is used to specify exactly what is wanted.
+
+globfind may be used with Tcl versions earlier than 8.4, but emulation of missing
+features of the glob command in those versions will result in slower performance.
+
+globfind is generally two to three times faster than fileutil::find, and fractionally
+faster than perl's File::Find function for comparable searches.
+
+The filtercmd may be omitted if only prefiltering is desired; in this case it may be a 
+bit faster to use the proc globtraverse, which uses the same basedir value and 
+command-line switches as globfind, but does not take a filtercmd value.
+
+If one wanted to search for pdf files for example, one could use the command:
+
+       globfind $basedir {string match -nocase *.pdf}
+
+It would, however, in this case be much faster to use:
+
+       globtraverse $basedir -pattern *.pdf
+
+########################
+}
+
+
+package provide fileutil::globfind 1.5
+
+namespace eval ::fileutil::globfind {
+
+namespace export globfind globtraverse
+
+proc globfind {{basedir .} {filtercmd {}} args} {
+       set returnFiles {}
+       set types {}
+       set basedir [file normalize $basedir]
+
+       # account for possibility that filtercmd is missing by 
+       # reformatting $args variable: 
+       set args [concat [list $filtercmd] $args]
+       if [expr fmod([llength $args],2)] {
+               set filtercmd [lindex $args 0]
+               set args [lrange $args 1 end]
+       } else {
+               set filtercmd {}
+       }
+
+       set filt [string length $filtercmd]
+       set 83ok [package vsatisfies [package present Tcl] 8.3]
+
+       # process command-line switches:
+       foreach {flag value} $args {
+               if {[string first $flag -types] >= 0} {set flag "-types"}
+               if {[string first $flag -pattern] >= 0} {set flag "-pattern"}
+               if {[string first $flag -depth] >= 0} {set flag "-depth"}
+
+               switch -- $flag {
+                       -types {
+                               set types [list $value]
+
+                               # can't use -types pre-8.3, because it doesn't exist in glob command.
+                               # thus if it is specified, error out:
+                               if !$83ok {error {error: "-types" flag not supported in version 8.2 and earlier}}
+
+                               # bug in 8.3, if -types {hidden f} is used, possible crash.  So disallow:
+                               if {(![package vcompare [package present Tcl] 8.3]) && ($tcl_platform(platform) == "unix") && ([lsearch $types "hidden"] >= 0) && ([lsearch $types "f"] >= 0)} {
+                                       error {Tcl 8.3 bug: potential program crash if "-types {hidden f}" used}
+                               }
+
+                               set types "-types $types"
+                       }
+                       -pattern {set pattern [list $value]}
+                       -depth {set depth [expr [list $value]]}
+                       default {error "$flag: incorrect flag value"}
+               }
+       }
+
+       # add basedir to result if it satisfies prefilter conditions:
+       set returnFiles [eval [eval list globtraverse [list [file dirname $basedir]] $args -depth 1]]
+       if {[lsearch -exact $returnFiles $basedir] >= 0} {set returnFiles [list $basedir]} else {set returnFiles {}}
+       # get all files in basedir that satisfy prefilter conditions:
+       set returnFiles [concat $returnFiles [eval [eval list globtraverse \$basedir $args]]]
+
+       # get hidden files if no specific types requested:
+       if {$types == {}} {
+               
+               # save redundant file values already gathered:
+               set redundant_files {}
+               if [set REDUNDANCY $[namespace current]::REDUNDANCY] {
+                       set redundant_files $[namespace current]::redundant_files
+               }
+
+               # get hidden files:
+               set returnFiles [concat $returnFiles [eval [eval list globtraverse \$basedir $args -type hidden]]]
+
+               # virtual filesystems ignore hidden tag, so just in case, filter out duplicates:
+               set returnFiles [lsort -unique $returnFiles]
+
+               # collate redundant file info:
+               if $[namespace current]::REDUNDANCY {
+                       set [namespace current]::redundant_files [concat $[namespace current]::redundant_files $redundant_files]
+               } else {
+                       set [namespace current]::redundant_files $redundant_files
+               }
+               set [namespace current]::REDUNDANCY [expr ($[namespace current]::REDUNDANCY || $REDUNDANCY)]
+       }
+
+       # apply filtercmd to prefiltered results if one is specified:
+       if $filt {
+               set filterFiles {}
+               foreach filename $returnFiles {
+                       if [uplevel $filtercmd [list $filename]] {
+                               lappend filterFiles $filename
+                       }
+               }
+       } else {
+               set filterFiles $returnFiles
+       }
+
+       return $filterFiles
+}
+
+proc globtraverse {{basedir .} args} {
+       set [namespace current]::REDUNDANCY 0
+       unset -nocomplain [namespace current]::redundant_files
+       set depth 0
+
+       # search 16 directory levels per iteration, glob can't handle more patterns than that at once.
+       set maxDepth 16
+
+       set pattern *
+       set types {}
+       set resultList {}
+
+       set basedir [file normalize $basedir]
+       if ![file isdirectory $basedir] {return}
+
+       set baseDepth [llength [file split $basedir]] ; # calculate starting depth
+
+       lappend checkDirs $basedir ; # initialize list of dirs to check
+
+       # format basedir variable for later infinite loop checking:
+       set basedir $basedir/
+       set basedir [string map {// /} $basedir]
+
+       set 83ok [package vsatisfies [package present Tcl] 8.3]
+
+       # process command-line switches:
+       foreach {flag value} $args {
+               if {[string first $flag -types] >= 0} {set flag "-types"}
+               if {[string first $flag -pattern] >= 0} {set flag "-pattern"}
+               if {[string first $flag -depth] >= 0} {set flag "-depth"}
+
+               switch -- $flag {
+                       -types {
+                               set types [list $value]
+                               if !$83ok {error {error: "-types" flag not supported in version 8.2 and earlier}}
+                               if {(![package vcompare [package present Tcl] 8.3]) && ($tcl_platform(platform) == "unix") && ([lsearch $types "hidden"] >= 0) && ([lsearch $types "f"] >= 0)} {
+                                       error {Tcl 8.3 bug: potential program crash if "-types {hidden f}" used}
+                               }
+                               set types "-types $types"
+                       }
+                       -pattern {set pattern [list $value]}
+                       -depth {set depth [expr [list $value]]}
+                       default {error "$flag: incorrect flag value"}
+               }
+       }
+
+       # Main result-gathering loop:
+       while {[llength $checkDirs]} {
+               set currentDir [lindex $checkDirs 0]
+
+               set currentDepth [expr [llength [file split $currentDir]] - $baseDepth] ; # distance from start depth
+
+               set searchDepth [expr $depth - $currentDepth] ; # distance from max depth to search to
+
+               # build multi-pattern argument to feed to glob command:
+               set globPatternTotal {}
+               set globPattern *
+               set incrPattern /*
+               for {set i 1} {$i <= $maxDepth} {incr i} {
+                       set customPattern [string range $globPattern 0 end-1]
+                       append customPattern $pattern
+                       lappend globPatternTotal $customPattern
+                       append globPattern $incrPattern
+                       incr searchDepth -1
+                       if {$searchDepth == 0} {break}
+               }
+
+               # save pattern to use for iterative dir search later:
+               set dirPattern [string range $globPattern 0 end-2]
+
+               # glob pre-8.3 doesn't support -directory switch; emulate it if necessary:
+               if $83ok {
+                       set contents [eval glob -nocomplain -directory \$currentDir $types -- $globPatternTotal]
+               } else {
+                       set wd [pwd]
+                       set newContents {}
+                       cd $currentDir
+                       if [catch {set contents [eval glob -nocomplain -- $globPatternTotal]} err] {
+                               cd $wd
+                               error $err
+                       }
+                       cd $wd
+                       foreach item $contents {
+                               set item [file join $currentDir $item]
+                               lappend newContents $item
+                       }
+                       set contents $newContents
+                       unset newContents
+               }
+               set resultList [concat $resultList $contents]
+
+               # check if iterative dir search is necessary (if specified depth not yet reached):
+               set contents {}
+               set findDirs 1
+               if {([expr $currentDepth + [llength [file split $dirPattern]]] >= $depth) && ($depth > 0)} {set findDirs 0}
+
+               # find dirs at current depth boundary to prime iterative search.
+               # Pre-8.3 glob doesn't support -type or -dir switches; emulate if necessary:
+               if {$83ok && $findDirs} {
+                       set contents [glob -nocomplain -directory $currentDir -type d -- $dirPattern]
+               } elseif $findDirs {
+                       set wd [pwd]
+                       set newContents {}
+                       cd $currentDir
+                       if [catch {set contents [glob -nocomplain -- $dirPattern/]} err] {
+                               cd $wd
+                               error $err
+                       }
+                       cd $wd
+                       foreach item $contents {
+                               set item [file join $currentDir [string range $item 0 end-1]]
+                               lappend newContents $item
+                       }
+                       set contents $newContents
+                       unset newContents
+               }
+
+               # check for redundant links in dir list:
+               set contentLength [llength $contents]
+               set i 0
+               while {$i < $contentLength} {
+                       set item [lindex $contents end-$i]
+                       incr i
+                       
+                       # kludge to fully resolve link to native name:
+                       set linkValue [file dirname [file normalize [file join $item __dummy__]]]
+
+                       # if item is a link, and native name is already in the search space, skip it:
+                       if {($linkValue != $item) && (![string first $basedir $linkValue])} {
+                               set [namespace current]::REDUNDANCY 1
+                               lappend [namespace current]::redundant_files $item
+                               continue
+                       }
+
+                       lappend checkDirs $item                 
+               }
+
+               # remove current search dir from search list to prime for next iteration:
+               set checkDirs [lrange $checkDirs 1 end]
+       }       
+       return $resultList
+}
+
+# Tcl pre-8.4 lacks [file normalize] command; emulate it if necessary:
+proc ::fileutil::globfind::file {args} {
+       if {[lindex $args 0] == "normalize"} {
+               set filename [lindex $args 1]
+               set tail [file tail $filename]
+               set filename [::fileutil::fullnormalize [file dirname $filename]]
+               set filename [file join $filename $tail]
+               return $filename
+       } else {
+               return [uplevel ::file $args]
+       }
+}
+
+# Eliminate emulation of [file normalize] if version 8.4 or better:
+if [package vsatisfies [package present Tcl] 8.4] {
+       rename ::fileutil::globfind::file {}
+} else {
+       package require fileutil 1.13
+}
+
+}
+# end namespace ::fileutil::globfind
diff --git a/8.x/tclvfs/library/template/quotavfs.tcl b/8.x/tclvfs/library/template/quotavfs.tcl
new file mode 100644 (file)
index 0000000..e978a8d
--- /dev/null
@@ -0,0 +1,559 @@
+if 0 {
+########################
+
+quotavfs.tcl --
+
+Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+License: Tcl license
+Version 1.5.2
+
+A quota-enforcing virtual filesystem.  Requires the template vfs in templatevfs.tcl.
+
+Quotas can be set on any quantity returned by "file stat" or "file attributes",
+plus the attribute "filename", which is the fully normalized pathname of the file.
+
+Two types of quota can be set: an incremented count of files matching a certain criterion, and
+a running total of a certain quantity.  Each quota is defined by a set of switches composing 
+a "quota group," any number of quota groups can be defined.  A file must fit within all quotas defined
+to avoid triggering quota enforcement.
+
+The quotas are enforced as a FIFO stack of files; that is, if a new file is copied to the vfs whose
+attributes exceed a quota, the file is not rejected, rather, the already present files with 
+the oldest access times that contribute to the quota are deleted until there is room within 
+the quota limit for the addition of the new file.
+
+The exception for the running total variety is if the file's attribute is large enough to 
+exceed the quota by itself, it is barred without first deleting all other files contributing to 
+the quota.
+
+At mount time, all files in the existing directory are examined and quotas calculated.  Files may be
+deleted to keep quotas under their defined limits.  After mount, when a new file is moved into the 
+virtual directory or an existing file edited, its properties are examined with respect to the defined 
+quotas; if no room can be made for it, the move or edit is rejected.
+
+Usage: mount <quota group> ?<quota group>... ? <existing directory> <virtual directory>
+
+Quota group definition:
+
+-<quantity> <rule> -[quota|ruletotal] <quota number>
+or
+-<quantity> -total <quota number>
+
+Options:
+
+-<quantity>
+Where <quantity> is any item returned by the "file stat" or "file attributes" commands, with the dash
+prepended as needed, for example: -archive, -permissions, -size, -mtime etc.  The attribute "filename"
+is assumed to exist as well, defined as the file's full pathname.  The quantity need not exist, so the 
+same command line could be used on Unix or Windows, for example.  Nonexistent quantities have no effect
+and are ignored.
+
+<rule>
+The rule is the criterion a file must meet to have the quota applied to it.  It may take the form of a 
+list of glob patterns as used by the "string match" command: if the quantity value matches all the 
+patterns, the quota is applied.  The rule may be Tcl code, to which the quantity value will be 
+appended and then evaluated.  The code should return 1 if the file is judged to meet the 
+quota criterion, or 0 if not.  If glob patterns are used, each pattern in the list may, in 
+addition to symbols used by "string match", have a "!" prepended to it, which will negate the 
+sense of the match.
+
+-quota
+If the quota group contains this switch, then the vfs will keep a running count of all files that satisfy 
+the quota group's rule.  It will not allow more than the number of files specified in <quota number> to 
+exist in the virtual file space.
+
+-total
+If the quota group contains this switch, then the vfs will track the sum of the values of the specified
+quantity of all files.  It will not allow the sum specified in <quota number> to 
+be exceeded in the virtual file space.
+
+-ruletotal
+Like -total, but a rule is defined, and only files satisfying the rule have their values added to the quota sum.
+
+The quota vfs inherits the -cache and -volume options of the template vfs.
+
+
+Examples -- to set a 10 MB size limit on your ftp upload directory:
+mount -size -total 10000000 C:/temp/upload C:/vfs/ftp/pub
+
+To allow only PNG or JPEG files in a photo collection:
+mount -filename {!*.png !*.jpg !*.jpeg} -quota 0 /home/shuntley/photos /vfs/photo
+
+To ban GIF files from your web site images subdirectory:
+mount -filename {C:/Program Files/Apache/htdocs/images/*.gif} -quota 0 {C:/Program Files/Apache/htdocs} /docroot
+
+To disallow creation of subdirectories:
+mount -type directory -quota 0 /ftp/upload /intake
+
+Use a rule to allow only 1 MB of files greater than 10kB in size:
+mount -size {expr 10000 <} -ruletotal 1000000 /tmp /vfs/dump
+
+Use two quota groups to allow only log files and keep only 1 more than one week:
+mount -filename !*.log -quota 0 -mtime {expr [clock scan {7 days ago}] >} -quota 1 /var/log /vfs/history
+
+########################
+}
+
+package require vfs::template 1.5
+package require fileutil::globfind
+
+package provide vfs::template::quota 1.5.2
+
+namespace eval ::vfs::template::quota {
+
+# read template procedures into current namespace. Do not edit:
+foreach templateProc [namespace eval ::vfs::template {info procs}] {
+       set infoArgs [info args ::vfs::template::$templateProc]
+       set infoBody [info body ::vfs::template::$templateProc]
+       proc $templateProc $infoArgs $infoBody
+}
+
+# edit following procedures:
+proc close_ {channel} {
+       upvar path path root root relative relative
+       fconfigure $channel -translation binary
+       seek $channel 0 end
+       set quotaSize [tell $channel]
+       seek $channel 0
+       set filechannel [lindex $::vfs::template::quota::channels($channel) 0]
+       set newFile [lindex $::vfs::template::quota::channels($channel) 1]
+       unset ::vfs::template::quota::channels($channel)
+       set file [file join $path $relative]
+
+# Check if edited size violates any size quotas before allowing commit:
+       if [catch {QuotaAdd $file}] {
+               close $filechannel
+               if $newFile {catch {file delete -force $file}}
+               error "Disk quota exceeded"
+       }
+       seek $filechannel 0
+       fcopy $channel $filechannel
+       close $filechannel
+       return
+}
+proc file_atime {file time} {
+       upvar root root
+       file atime $file $time
+       append ::vfs::template::quota::atimes($root) " $time [list $file]"
+       if {$::vfs::template::quota::files($file) < $time} {set ::vfs::template::quota::files($file) $time ; return}
+       set ::vfs::template::quota::files($file) $time
+       set aList {}
+       foreach {atime afile} $::vfs::template::quota::atimes($root) {
+               lappend aList "$atime [list $afile]"
+       }
+       set atimes {}
+       foreach aset [lsort -dictionary $aList] {
+               set atime [lindex $aset 0]
+               set afile [lindex $aset 1]
+               append atimes " $atime [list $afile]"
+       }
+       set ::vfs::template::quota::atimes($root) $atimes
+}
+proc file_mtime {file time} {file mtime $file $time}
+proc file_attributes {file {attribute {}} args} {eval file attributes \$file $attribute $args}
+proc file_delete {file} {
+       upvar root root
+       array set quotaArray $::vfs::template::quota::quota($root)
+       QuotaDelete $file
+       set ::vfs::template::quota::quota($root) [array get quotaArray]
+       return
+}
+proc file_executable {file} {file executable $file}
+proc file_exists {file} {file exists $file}
+proc file_mkdir {file} {
+       upvar root root
+       file mkdir $file
+       globfind $file QuotaAdd
+       return
+}
+proc file_readable {file} {file readable $file}
+proc file_stat {file array} {upvar $array fs ; ::file stat $file fs}
+proc file_writable {file} {file writable $file}
+proc glob_ {directory dir nocomplain tails types typeString dashes pattern} {glob -directory $dir -nocomplain -tails -types $typeString -- $pattern}
+proc open_ {file mode} {
+       upvar root root permissions permissions
+       upvar newFile newFile
+       if {$mode == "r"} {
+               set atime [clock seconds]
+               append ::vfs::template::quota::atimes($root) " $atime [list $file]"
+               set ::vfs::template::quota::files($file) $atime
+               return [open $file r]
+       }
+
+if $newFile {
+       set now [clock seconds]
+       set fstat "mtime $now atime $now mode $permissions type file ctime $now size 0"
+       QuotaAdd $file
+}
+       set channel [open $file $mode]
+
+# Check if new file violates any quotas by adding it to quota tallies:
+#      if $newFile {
+#              set err [catch {QuotaAdd $file} result]
+#              if $err {
+#                      close $channel
+#                      file delete -force -- $file
+#                      vfs::filesystem posixerror $::vfs::posix(EDQUOT)
+#                      error "Disk quota exceeded"
+#              }
+#      }
+# remove file from quota tallies until channel is closed:
+       array set quotaArray $::vfs::template::quota::quota($root)
+       QuotaDelete $file 0
+       set ::vfs::template::quota::quota($root) [array get quotaArray]
+
+# Use memchan to store edits so edit can be rejected if it violates size quotas:
+       set memchannel [memchan]
+       fconfigure $channel -translation binary
+       fconfigure $memchannel -translation binary
+       seek $channel 0
+       fcopy $channel $memchannel
+       set [namespace current]::channels($memchannel) "$channel $newFile"
+       return $memchannel
+}
+
+proc MountProcedure {args} {
+       upvar volume volume
+
+# take real and virtual directories from command line args.
+       set to [lindex $args end]
+       if [string equal $volume {}] {set to [::file normalize $to]}
+       set path [::file normalize [lindex $args end-1]]
+
+# make sure mount location exists:
+       ::file mkdir $path
+
+# add custom handling for new vfs args here.
+
+       namespace import -force ::fileutil::globfind::globfind
+       set quotaArgs [lrange $args 0 end-2]
+
+       ParseArgs ::vfs::template::quota::quota($to) $quotaArgs
+
+# Initialize quotas:
+       set root $to
+       set aList {}
+       foreach afile [globfind $path] {
+               file stat $afile fs
+               lappend aList "$fs(atime) [list $afile]"
+       }
+       set atimes {}
+       foreach aset [lsort -dictionary $aList] {
+               set atime [lindex $aset 0]
+               set afile [lindex $aset 1]
+               append atimes " $atime [list $afile]"
+               set ::vfs::template::quota::files($afile) $atime
+       }
+       set ::vfs::template::quota::atimes($root) $atimes
+
+       globfind $path QuotaAdd
+
+       set ::vfs::template::quota::atimes($root) $atimes
+
+# return two-item list consisting of real and virtual locations.
+       lappend pathto $path
+       lappend pathto $to
+       return $pathto
+}
+
+
+proc UnmountProcedure {path to} {
+# add custom unmount handling of new vfs elements here.
+
+       unset -nocomplain ::vfs::template::quota::quota($to)
+       unset -nocomplain ::vfs::template::quota::atimes($to)
+       return
+}
+
+# Default rule for quotas with pattern specified:
+proc CheckPattern {pattern value} {
+       foreach ptn $pattern {
+               set negate [string equal [string index $ptn 0] !]
+               if $negate {set ptn [string range $ptn 1 end]}
+               set match [string match $ptn $value]
+               if $negate {set match [expr !$match]}
+               if !$match {return 0}
+       }
+       return 1
+}
+
+# Used as argument to proc globfind to recurse down dir hierarchies and process each file and dir found:
+proc QuotaAdd {fileName} {
+       set caller [lindex [info level -1] 0]
+       if {$caller == "MountProcedure"} {set init 1} else {set init 0}
+       upvar path path root root quotaSize quotaSize fstat fstat
+       if ![string first ".vfs_" [file tail $fileName]] {return 0}
+       if {[info exists path] && ($fileName == $path)} {return 0}
+       array set quotaArray $::vfs::template::quota::quota($root)
+       set overLimit {}
+       set items [lsort -unique [string map {",type " " " ",rule " " " ",quota " " " ",current " " "} " [array names quotaArray] "]]
+
+       set delete 1
+if [info exists fstat] {
+       array set fs $fstat     
+} else {
+       set noexist [catch {file stat $fileName fs}]
+       if $noexist {return 0}
+}
+       set fs(filename) $fileName
+
+# if this call is being used to check edits, replace file size with channel size and don't delete file if edit too big:
+       if [info exists quotaSize] {set fs(size) $quotaSize ; set delete 0 ; unset quotaSize}
+
+# Update queue which tracks which files to try deleting first to make room for new files:
+       append ::vfs::template::quota::atimes($root) " $fs(atime) [list $fileName]"
+       set ::vfs::template::quota::files($fileName) $fs(atime)
+
+# Check each defined quota to see if given file violates it:
+       foreach item $items {
+               regexp {([0-9]*),(.*)} $item trash groupCount item
+               if ![info exists fs($item)] {if [file exists $fileName] {array set fs [file attributes $fileName]}}
+               if ![info exists fs($item)] {continue}
+               set contrib [eval $quotaArray($groupCount,$item,rule) [list $fs($item)]]
+               if $contrib     {       
+                       if {$quotaArray($groupCount,$item,type) == "total"} {
+
+                               # If file quantity by itself would violate quota, reject immediately:
+                               if {$fs($item) > $quotaArray($groupCount,$item,quota)} {
+                                       if $delete {catch {file delete -force -- $fileName} result}
+if [info exists ::vfs::template::quota::debug] {
+puts "\n$fileName violates quota by itself:
+$item: $fs($item)
+quota: $quotaArray($groupCount,$item,quota)"
+if $delete {puts "$fileName deleted: $result"}
+}
+                                       if $init {return 0} else {vfs::filesystem posixerror $::vfs::posix(EDQUOT)}
+                               }
+                               set quotaArray($groupCount,$item,current) [expr $quotaArray($groupCount,$item,current) + $fs($item)]
+                       } else {
+                               if {$quotaArray($groupCount,$item,quota) == 0} {
+                                       if $delete {catch {file delete -force -- $fileName} result}
+if [info exists ::vfs::template::quota::debug] {
+puts "\n$fileName violates quota by itself:
+$item: $fs($item)
+quota: $quotaArray($groupCount,$item,quota)"
+if $delete {puts "$fileName deleted: $result"}
+}
+                                       if $init {return 0} else {vfs::filesystem posixerror $::vfs::posix(EDQUOT)}
+                               }
+                               incr quotaArray($groupCount,$item,current)
+                       }
+                       # If file violates quota, store quota to see if room can be made by deleting older files:
+                       if {$quotaArray($groupCount,$item,current) > $quotaArray($groupCount,$item,quota)} {lappend overLimit "$groupCount,$item"}
+               }
+       }
+# if given file puts some quotas over limit, see if room can be made by deleting older files:
+
+       foreach item $overLimit {
+               set itm [lindex [split $item ,] 1]
+               if {$quotaArray($item,current) <= $quotaArray($item,quota)} {continue}
+
+               # examine queue of stored atimes to find older files:
+               foreach {atime afile} $::vfs::template::quota::atimes($root) {
+
+                       # If stored atime doesn't match latest value, delete record and move on:
+                       if {($::vfs::template::quota::files($afile) != $atime) || ![file exists $afile]} {
+                               set deleteLoc [lsearch -exact $::vfs::template::quota::atimes($root) $afile]
+                               set ::vfs::template::quota::atimes($root) [lreplace $::vfs::template::quota::atimes($root) [expr $deleteLoc - 1] $deleteLoc]
+                               if {[lsearch -exact $::vfs::template::quota::atimes($root) $afile] < 0} {unset ::vfs::template::quota::files($afile)}
+                               continue
+                       }
+                       
+                       # if file from queue is in fact newer than given file, skip it:
+                       if {$atime > $fs(atime)} {continue}
+
+                       # if stored filename is same as given filename, given filename violates quota and must be rejected:
+                       if {$afile == $fileName} {
+                               if !$delete {set quotaSize $fs(size)}
+                               catch {QuotaDelete $fileName $delete}
+                               set ::vfs::template::quota::quota($root) [array get quotaArray]
+                               if $init {return 0} else {vfs::filesystem posixerror $::vfs::posix(EDQUOT)}
+                       }
+
+                       # If stored file contributes to quota, delete it and remove from quota tally:
+
+                       if {$itm == "filename"} {
+                               set itm_val $afile
+                       } elseif {[string index $itm 0] == "-"} {
+                               set itm_val [file attributes $afile $itm]
+                       } else {
+                               file stat $afile iv
+                               set itm_val $iv($itm)
+                       }
+       
+                       set contrib [eval $quotaArray($item,rule) [list $itm_val]]
+                       if $contrib     {       
+                               if {$quotaArray($item,type) == "total"} {
+                                       set itm [lindex [split $item ,] 1]
+                                       if {[string index $itm 0] == "-"} {
+                                               set itm_val [file attributes $afile $itm]
+                                       } else {
+                                               file stat $afile iv
+                                               set itm_val $iv($itm)
+                                       }
+                                       if !$itm_val {continue}
+                               }
+                               set ::vfs::template::quota::quota($root) [array get quotaArray]
+                               QuotaDelete $afile
+                       }
+
+                       # If deletions make room for new file, then OK:
+                       if {$quotaArray($item,current) <= $quotaArray($item,quota)} {break}
+               }
+       }
+       set ::vfs::template::quota::quota($root) [array get quotaArray]
+       return 0
+}
+
+proc QuotaDelete {fileName {delete 1}} {
+       upvar quotaArray quotaArray quotaSize quotaSize
+       set items [lsort -unique [string map {",type " " " ",rule " " " ",quota " " " ",current " " "} " [array names quotaArray] "]]
+
+# If given fileName is a dir, must remove all contents from quota tallies before removing dir itself:
+       set files [lsort -decreasing [globfind $fileName]]
+       set type file
+
+# Must parse contents twice, eliminate files first, then dirs:
+       foreach file [concat $files //// $files] {
+               if {$file == "////"} {set type directory ; continue}
+       
+               # cache quantity info to save time on second pass:
+               if ![info exists stat($file)] {
+                       file stat $file fs
+                       set fs(filename) $fileName
+                       if [info exists quotaSize] {set fs(size) $quotaSize}
+                       set stat($file) [array get fs]
+               }
+               array set fs $stat($file)
+
+               # If file type is wrong for this pass, continue:
+               if {($type == "file") && ($fs(type) == "directory")} {continue}
+               if {($type == "directory") && ($fs(type) != "directory")} {continue}
+
+               # Check each quota to see if current file contributes to it:
+               foreach item $items {
+                       regexp {([0-9]*),(.*)} $item trash groupCount item
+                       if ![info exists fs($item)] {if [file exists $file] {array set fs [file attributes $file]} ; set stat($file) [array get fs]}
+                       if ![info exists fs($item)] {continue}
+                       set contrib [eval $quotaArray($groupCount,$item,rule) [list $fs($item)]]
+                       if $contrib     {
+                               if {$quotaArray($groupCount,$item,type) == "total"} {
+                                       set quotaArray($groupCount,$item,current) [expr $quotaArray($groupCount,$item,current) - $fs($item)]
+                               } else {
+                                       incr quotaArray($groupCount,$item,current) -1
+                               }
+if [info exists ::vfs::template::quota::debug] {
+puts "\n$file contributed to quota:
+rule: $quotaArray($groupCount,$item,rule)
+quota: $quotaArray($groupCount,$item,quota)
+current: $quotaArray($groupCount,$item,current)"
+}
+                       }
+               }
+
+               # After removing file from quota tallies, delete it:
+               if $delete {file delete -force -- $file}
+if {$delete && [info exists ::vfs::template::quota::debug]} {
+puts "\n$file deleted"
+}
+       }
+       return
+}
+
+# Decided on new command line syntax, rather than rewrite whole vfs,
+# this proc casts new syntax into old format, then processes as before:
+proc ParseArgs {argsStore args} {
+       upvar path path
+       set args [lindex $args 0]
+
+       array set attrs [file attributes $path]
+       set quotas {}
+       set totals {}
+       set rtotals {}
+       set newArgs {}
+
+# find location of each quota group:
+       set qPosition [lsearch -all $args "-quota"]
+       set tPosition [lsearch -all $args "-total"]
+       set rPosition [lsearch -all $args "-ruletotal"]
+
+# break group defs into separate categories:
+       foreach qp $qPosition {
+               incr qp
+               append quotas " [lrange $args [expr $qp - 3] $qp]" 
+       }
+
+       foreach tp $tPosition {
+               incr tp
+               append totals " [lrange $args [expr $tp - 2] $tp]" 
+       }
+
+       foreach rp $rPosition {
+               incr rp
+               append rtotals " [lrange $args [expr $rp - 3] $rp]" 
+       }
+
+# cast each category into old syntax:
+       foreach {type pr quota number} $quotas {
+               set patrul "-pattern"
+               if {[lsearch -exact [info commands [string trim [string range $pr 0 [string first { } $pr]]]] [string trim [string range $pr 0 [string first { } $pr]]]] > -1} {
+                       set patrul "-rule"
+               }
+               if ![info exists attrs($type)] {set type [string range $type 1 end]}
+               append newArgs " -number: -item $type $patrul [list $pr] -quota $number"
+       }
+
+       foreach {type total number} $totals {
+               if ![info exists attrs($type)] {set type [string range $type 1 end]}
+               append newArgs " -total: -item $type -quota $number"
+       }
+
+       foreach {type pr rtotal number} $rtotals {
+               set patrul "-pattern"
+               if {[lsearch -exact [info commands [string trim [string range $pr 0 [string first { } $pr]]]] [string trim [string range $pr 0 [string first { } $pr]]]] > -1} {
+                       set patrul "-rule"
+               }
+               if ![info exists attrs($type)] {set type [string range $type 1 end]}
+               append newArgs " -total: -item $type $patrul [list $pr] -quota $number"
+       }
+
+# process old syntax:
+       unset args
+       lappend args [string trim $newArgs]
+
+       set groupCount 0
+       set args [lindex $args 0]
+       set argsIndex [llength $args]
+       for {set i $argsIndex} {$i >= 0} {incr i -1} {
+               switch -- [lindex $args $i] {
+                       -number: -
+                       -total: {
+                               set item $itemSet(item)
+                               if ![info exists itemSet(rule)] {set itemSet(rule) "CheckPattern *"}
+                               set argsArray($groupCount,$item,type) [string range [lindex $args $i] 1 end-1]
+                               set argsArray($groupCount,$item,rule) $itemSet(rule)
+                               set argsArray($groupCount,$item,quota) $itemSet(quota)
+                               set argsArray($groupCount,$item,current) 0
+                               array unset itemSet
+                               incr groupCount
+                       }
+                       -item {
+                               set itemSet(item) [lindex $args [expr $i + 1]]
+                       }
+                       -pattern {
+                               set itemSet(rule) "CheckPattern [list [lindex $args [expr $i + 1]]]"
+                       }
+                       -quota {
+                               set itemSet(quota) [lindex $args [expr $i + 1]]
+                       }
+                       -rule {
+                               set itemSet(rule) [lindex $args [expr $i + 1]]
+                       }
+               }
+       }
+       set $argsStore [array get argsArray]
+}
+
+}
+# end namespace ::vfs::template::quota
+
diff --git a/8.x/tclvfs/library/template/tclIndex b/8.x/tclvfs/library/template/tclIndex
new file mode 100644 (file)
index 0000000..6cda2aa
--- /dev/null
@@ -0,0 +1,15 @@
+# Tcl autoload index file, version 2.0
+# This file is generated by the "auto_mkindex" command
+# and sourced to set up indexing information for one or
+# more commands.  Typically each line is a command that
+# sets an element in the auto_index array, where the
+# element name is the name of a command and the value is
+# a script that loads the command.
+
+set auto_index(::vfs::template::mount) [list package require vfs::template 1.5.3]
+set auto_index(::vfs::template::collate::mount) [list source [file join $dir collatevfs.tcl]]
+set auto_index(::vfs::template::quota::mount) [list source [file join $dir quotavfs.tcl]]
+set auto_index(::vfs::template::version::mount) [list source [file join $dir versionvfs.tcl]]
+set auto_index(::vfs::template::version::delta::mount) [list source [file join $dir deltavfs.tcl]]
+set auto_index(::vfs::template::chroot::mount) [list source [file join $dir chrootvfs.tcl]]
+set auto_index(::vfs::template::fish::mount) [list source [file join $dir fishvfs.tcl]]
diff --git a/8.x/tclvfs/library/template/tdelta.tcl b/8.x/tclvfs/library/template/tdelta.tcl
new file mode 100644 (file)
index 0000000..d8ad6f9
--- /dev/null
@@ -0,0 +1,430 @@
+# tdelta.tcl --
+#
+#      Produce an rdiff-style delta signature of one file with respect to another,
+#      and re-create one file by applying the delta to the other.
+#
+# Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+# License: Tcl license
+# Version 1.0
+#
+# Usage:
+#
+# tdelta <reference file | channel> <target file | channel> [sizecheck [fingerprint]]
+#      Returns a delta of the target file with respect to the reference file.
+#      i.e., using patch to apply the delta to the target file will re-create the reference file.
+#
+#      sizecheck and fingerprint are booleans which enable time-saving checks: 
+#
+#      if sizecheck is True then if the file size is
+#      less than five times the block size, then no delta calculation is done and the
+#      signature contains the full reference file contents.  
+#
+#      if fingerprint is True then 10 small strings ("fingerprints") are taken from the target
+#      file and searched for in the reference file.  If at least three aren't found, then
+#      no delta calculation is done and the signature contains the full reference file contents.
+#
+# tpatch <target file | channel> <delta signature> <output file (duplicate of reference file) | channel>
+#      Reconstitute original reference file by applying delta to target file.
+#
+#
+# global variables:
+#
+# blockSize
+#      Size of file segments to compare.
+#      Smaller blockSize tends to create smaller delta.
+#      Larger blockSize tends to take more time to compute delta.
+# md5Size
+#      Substring of md5 checksum to store in delta signature.
+#      If security is less of a concern, set md5Size to a number
+#      between 1-32 to create a more compact signature.
+
+package provide trsync 1.0
+
+namespace eval ::trsync {
+
+if ![info exists blockSize] {variable blockSize 100}
+if ![info exists Mod] {variable Mod [expr pow(2,16)]}
+if ![info exists md5Size] {variable md5Size 32}
+
+variable temp
+if ![info exists temp] {
+       catch {set temp $::env(TMP)}
+       catch {set temp $::env(TEMP)}
+       catch {set temp $::env(TRSYNC_TEMP)}
+       if [catch {file mkdir $temp}] {set temp [pwd]}
+}
+if ![file writable $temp] {error "temp location not writable"}
+
+proc Backup {args} {
+       return
+}
+
+proc ConstructFile {copyinstructions {eolNative 0} {backup {}}} {
+       if [catch {package present md5 2}] {package forget md5 ; package require md5 2}
+
+       set fileToConstruct [lindex $copyinstructions 0]
+       set existingFile [lindex $copyinstructions 1]
+       set blockSize [lindex $copyinstructions 2]
+       array set fileStats [lindex $copyinstructions 3]
+       array set digestInstructionArray [DigestInstructionsExpand [lindex $copyinstructions 4] $blockSize]
+       array set dataInstructionArray [lindex $copyinstructions 5]
+       unset copyinstructions
+
+       if {[lsearch [file channels] $existingFile] == -1} {
+               set existingFile [FileNameNormalize $existingFile]
+               if {$fileToConstruct == {}} {file delete -force $existingFile ; return}
+               catch {
+                       set existingID [open $existingFile r]
+                       fconfigure $existingID -translation binary
+               }
+       } else {
+               set existingID $existingFile
+               fconfigure $existingID -translation binary
+       }
+
+       set temp $::trsync::temp
+
+       if {[lsearch [file channels] $fileToConstruct] == -1} {
+               set fileToConstruct [FileNameNormalize $fileToConstruct]
+               set constructTag "trsync.[md5::md5 -hex "[clock seconds] [clock clicks]"]"
+               set constructID [open $temp/$constructTag w]
+       } else {
+               set constructID $fileToConstruct
+       }
+       fconfigure $constructID -translation binary
+
+       if $eolNative {set eolNative [string is ascii -strict [array get dataInstructionArray]]}
+
+       set filePointer 1
+       while {$filePointer <= $fileStats(size)} {
+               if {[array names dataInstructionArray $filePointer] != {}} {
+                       puts -nonewline $constructID $dataInstructionArray($filePointer)
+                       set segmentLength [string length $dataInstructionArray($filePointer)]
+                       array unset dataInstructionArray $filePointer
+                       set filePointer [expr $filePointer + $segmentLength]
+               } elseif {[array names digestInstructionArray $filePointer] != {}} {
+                       if ![info exists existingID] {error "Corrupt copy instructions."}
+                       set blockNumber [lindex $digestInstructionArray($filePointer) 0]
+                       set blockMd5Sum [lindex $digestInstructionArray($filePointer) 1]
+
+                       seek $existingID [expr $blockNumber * $blockSize]
+
+                       set existingBlock [read $existingID $blockSize]
+                       set existingBlockMd5Sum [string range [md5::md5 -hex -- $existingBlock] 0 [expr [string length $blockMd5Sum] - 1]]
+                       if ![string equal -nocase $blockMd5Sum $existingBlockMd5Sum] {error "digest file contents mismatch"}
+                       puts -nonewline $constructID $existingBlock
+
+                       if $eolNative {set eolNative [string is ascii -strict $existingBlock]}
+                       unset existingBlock
+                       set filePointer [expr $filePointer + $blockSize]
+               } else {
+                       error "Corrupt copy instructions."
+               }
+       }
+       catch {close $existingID}
+       set fileStats(eolNative) $eolNative
+       if {[lsearch [file channels] $fileToConstruct] > -1} {return [array get fileStats]}
+
+       close $constructID
+
+       if $eolNative {
+               fcopy [set fin [open $temp/$constructTag r]] [set fout [open $temp/${constructTag}fcopy w]]
+               close $fin
+               close $fout
+               file delete -force $temp/$constructTag
+               set constructTag "${constructTag}fcopy"
+       }
+
+       catch {file attributes $temp/$constructTag -readonly 0} result
+       catch {file attributes $temp/$constructTag -permissions rw-rw-rw-} result
+       catch {file attributes $temp/$constructTag -owner $fileStats(uid)} result
+       catch {file attributes $temp/$constructTag -group $fileStats(gid)} result
+       catch {file mtime $temp/$constructTag $fileStats(mtime)} result
+       catch {file atime $temp/$constructTag $fileStats(atime)} result
+       if [string equal $fileToConstruct $existingFile] {
+               catch {file attributes $existingFile -readonly 0} result
+               catch {file attributes $existingFile -permissions rw-rw-rw-} result
+       }
+
+       Backup $backup $fileToConstruct
+
+       file mkdir [file dirname $fileToConstruct]
+       file rename -force $temp/$constructTag $fileToConstruct
+       array set attributes $fileStats(attributes)
+       array set attrConstruct [file attributes $fileToConstruct]
+       foreach attr [array names attributes] {
+               if [string equal [array get attributes $attr] [array get attrConstruct $attr]] {continue}
+               if {[string equal $attr "-longname"] || [string equal $attr "-shortname"] || [string equal $attr "-permissions"]} {continue}
+               catch {file attributes $fileToConstruct $attr $attributes($attr)} result
+       }
+       catch {file attributes $fileToConstruct -permissions $fileStats(mode)} result
+       return
+}
+
+proc CopyInstructions {filename digest} {
+       if [catch {package present md5 2}] {package forget md5 ; package require md5 2}
+
+       if {[lsearch [file channels] $filename] == -1} {
+               set filename [FileNameNormalize $filename]
+               file stat $filename fileStats
+               array set fileAttributes [file attributes $filename]
+               array unset fileAttributes -longname
+               array unset fileAttributes -shortname
+               set arrayadd attributes ; lappend arrayadd [array get fileAttributes] ; array set fileStats $arrayadd
+               set f [open $filename r]
+       } else {
+               set f $filename
+               set fileStats(attributes) {}
+       }
+       fconfigure $f -translation binary
+       seek $f 0 end
+       set fileSize [tell $f]
+       seek $f 0
+       set fileStats(size) $fileSize
+       set digestFileName [lindex $digest 0]
+       set blockSize [lindex $digest 1]
+       set digest [lrange $digest 2 end]
+
+       if {[lsearch -exact $digest fingerprints] > -1} {
+               set fingerPrints [lindex $digest end]
+               set digest [lrange $digest 0 end-2]
+               set fileContents [read $f]
+               set matchCount 0
+               foreach fP $fingerPrints {
+                       if {[string first $fP $fileContents] > -1} {incr matchCount}
+                       if {$matchCount > 3} {break}
+               }
+               unset fileContents
+               seek $f 0
+               if {$matchCount < 3} {set digest {}}
+       }
+
+       set digestLength [llength $digest]
+       for {set i 0} {$i < $digestLength} {incr i} {
+               set arrayadd [lindex [lindex $digest $i] 1]
+               lappend arrayadd $i
+               array set Checksums $arrayadd
+       }
+       set digestInstructions {}
+       set dataInstructions {}
+       set weakChecksum {}
+       set startBlockPointer 0
+       set endBlockPointer 0
+
+       if ![array exists Checksums] {
+               set dataInstructions 1
+               lappend dataInstructions [read $f]
+               set endBlockPointer $fileSize
+       }
+
+       while {$endBlockPointer < $fileSize} {
+               set endBlockPointer [expr $startBlockPointer + $blockSize]
+               incr startBlockPointer
+               if {$weakChecksum == {}} {
+                       set blockContents [read $f $blockSize]
+                       set blockNumberSequence [SequenceBlock $blockContents]
+                       set weakChecksumInfo [WeakChecksum $blockNumberSequence]
+                       set weakChecksum [format %.0f [lindex $weakChecksumInfo 0]]
+                       set startDataPointer $startBlockPointer
+                       set endDataPointer $startDataPointer
+                       set dataBuffer {}
+               }
+               if {[array names Checksums $weakChecksum] != {}} {
+                       set md5Sum [md5::md5 -hex -- $blockContents]
+                       set blockIndex $Checksums($weakChecksum)
+                       set digestmd5Sum [lindex [lindex $digest $blockIndex] 0]
+                       if [string equal -nocase $digestmd5Sum $md5Sum] {
+                               if {$endDataPointer > $startDataPointer} {
+                                       lappend dataInstructions $startDataPointer
+                                       lappend dataInstructions $dataBuffer
+                               }
+                               lappend digestInstructions $startBlockPointer
+                               lappend digestInstructions "$blockIndex [string range $md5Sum 0 [expr $::trsync::md5Size - 1]]"
+                               set weakChecksum {}
+                               set startBlockPointer $endBlockPointer
+                               continue
+                       }
+               }
+               if {$endBlockPointer >= $fileSize} {
+                       lappend dataInstructions $startDataPointer
+                       lappend dataInstructions $dataBuffer$blockContents
+                       break
+               }
+               set rollChar [read $f 1]
+               binary scan $rollChar c* rollNumber
+               set rollNumber [expr ($rollNumber + 0x100)%0x100]
+               lappend blockNumberSequence $rollNumber
+               set blockNumberSequence [lrange $blockNumberSequence 1 end]
+
+               binary scan $blockContents a1a* rollOffChar blockContents
+               set blockContents $blockContents$rollChar
+               set dataBuffer $dataBuffer$rollOffChar
+               incr endDataPointer
+
+               set weakChecksumInfo "[eval RollChecksum [lrange $weakChecksumInfo 1 5] $rollNumber] [lindex $blockNumberSequence 0]"
+               set weakChecksum [format %.0f [lindex $weakChecksumInfo 0]]
+       }
+       close $f
+
+       lappend copyInstructions $filename
+       lappend copyInstructions $digestFileName
+       lappend copyInstructions $blockSize
+       lappend copyInstructions [array get fileStats]
+       lappend copyInstructions [DigestInstructionsCompress $digestInstructions $blockSize]
+       lappend copyInstructions $dataInstructions
+       return $copyInstructions
+}
+
+proc Digest {filename blockSize {sizecheck 0} {fingerprint 0}} {
+       if [catch {package present md5 2}] {package forget md5 ; package require md5 2}
+
+       set digest "[list $filename] $blockSize"
+       if {[lsearch [file channels] $filename] == -1} {
+               set filename [FileNameNormalize $filename]
+               set digest "[list $filename] $blockSize"
+               if {!([file isfile $filename] && [file readable $filename])} {return $digest}
+               set f [open $filename r]
+       } else {
+               set f $filename
+       }
+       fconfigure $f -translation binary
+       seek $f 0 end
+       set fileSize [tell $f]
+       seek $f 0
+       if {$sizecheck && ($fileSize < [expr $blockSize * 5])} {close $f ; return $digest}
+
+       while {![eof $f]} {
+               set blockContents [read $f $blockSize]
+               set md5Sum [md5::md5 -hex -- $blockContents]
+               set blockNumberSequence [SequenceBlock $blockContents]
+               set weakChecksum [lindex [WeakChecksum $blockNumberSequence] 0]
+               lappend digest "$md5Sum [format %.0f $weakChecksum]"
+       }
+       if $fingerprint {
+               set fileIncrement [expr $fileSize/10]
+               set fpLocation [expr $fileSize - 21]
+               set i 0
+               while {$i < 10} {
+                       if {$fpLocation < 0} {set fpLocation 0}
+                       seek $f $fpLocation
+                       lappend fingerPrints [read $f 20]
+                       set fpLocation [expr $fpLocation - $fileIncrement]
+                       incr i
+               }
+               lappend digest fingerprints
+               lappend digest [lsort -unique $fingerPrints]
+       }
+       close $f
+       return $digest
+}
+
+proc DigestInstructionsCompress {digestInstructions blockSize} {
+       if [string equal $digestInstructions {}] {return {}}
+       set blockSpan $blockSize
+       foreach {pointer blockInfo} $digestInstructions {
+               if ![info exists currentBlockInfo] {
+                       set currentPointer $pointer
+                       set currentBlockInfo $blockInfo
+                       set md5Size [string length [lindex $blockInfo 1]]
+                       continue
+               }
+               if {$pointer == [expr $currentPointer + $blockSpan]} {
+                       set md5 [lindex $blockInfo 1]
+                       lappend currentBlockInfo $md5
+                       incr blockSpan $blockSize
+               } else {
+                       lappend newDigestInstructions $currentPointer
+                       lappend newDigestInstructions "[lindex $currentBlockInfo 0] [list "$md5Size [string map {{ } {}} [lrange $currentBlockInfo 1 end]]"]"
+
+                       set currentPointer $pointer
+                       set currentBlockInfo $blockInfo
+                       set blockSpan $blockSize
+               }
+       }
+       lappend newDigestInstructions $currentPointer
+       lappend newDigestInstructions "[lindex $currentBlockInfo 0] [list "$md5Size [string map {{ } {}} [lrange $currentBlockInfo 1 end]]"]"
+       return $newDigestInstructions
+}
+
+proc DigestInstructionsExpand {digestInstructions blockSize} {
+       if [string equal $digestInstructions {}] {return {}}
+       foreach {pointer blockInfo} $digestInstructions {
+               set blockNumber [lindex $blockInfo 0]
+               set md5Size [lindex [lindex $blockInfo 1] 0]
+               set blockString [lindex [lindex $blockInfo 1] 1]
+               set blockLength [string length $blockString]
+
+               set expandedBlock {}
+               for {set i $md5Size} {$i <= $blockLength} {incr i $md5Size} {
+                       append expandedBlock " [string range $blockString [expr $i - $md5Size] [expr $i - 1]]"
+               }
+
+               set blockInfo "$blockNumber $expandedBlock"
+               foreach md5 [lrange $blockInfo 1 end] {
+                       lappend newDigestInstructions $pointer
+                       lappend newDigestInstructions "$blockNumber $md5"
+                       incr pointer $blockSize
+                       incr blockNumber
+               }
+       }
+       return $newDigestInstructions
+}
+
+proc FileNameNormalize {filename} {
+       file normalize $filename
+}
+
+proc RollChecksum {a(k,l)_ b(k,l)_ k l Xsub_k Xsub_l+1 } {
+       set Mod $trsync::Mod
+
+       set a(k+1,l+1)_ [expr ${a(k,l)_} - $Xsub_k + ${Xsub_l+1}]
+       set b(k+1,l+1)_ [expr ${b(k,l)_} - (($l - $k + 1) * $Xsub_k) + ${a(k+1,l+1)_}]
+
+       set a(k+1,l+1)_ [expr fmod(${a(k+1,l+1)_},$Mod)]
+       set b(k+1,l+1)_ [expr fmod(${b(k+1,l+1)_},$Mod)]
+       set s(k+1,l+1)_ [expr ${a(k+1,l+1)_} + ($Mod * ${b(k+1,l+1)_})]
+       return "${s(k+1,l+1)_} ${a(k+1,l+1)_} ${b(k+1,l+1)_} [incr k] [incr l]"
+}
+
+proc SequenceBlock {blockcontents} {
+       binary scan $blockcontents c* blockNumberSequence
+       set blockNumberSequenceLength [llength $blockNumberSequence]
+       for {set i 0} {$i < $blockNumberSequenceLength} {incr i} {
+               set blockNumberSequence [lreplace $blockNumberSequence $i $i [expr ([lindex $blockNumberSequence $i] + 0x100)%0x100]]
+       }
+       return $blockNumberSequence
+}
+
+proc WeakChecksum {Xsub_k...Xsub_l} {
+       set a(k,i)_ 0
+       set b(k,i)_ 0
+       set Mod $trsync::Mod
+       set k 1
+       set l [llength ${Xsub_k...Xsub_l}]
+       for {set i $k} {$i <= $l} {incr i} {
+               set Xsub_i [lindex ${Xsub_k...Xsub_l} [expr $i - 1]]
+               set a(k,i)_ [expr ${a(k,i)_} + $Xsub_i]
+               set b(k,i)_ [expr ${b(k,i)_} + (($l - $i + 1) * $Xsub_i)]
+       }
+       set a(k,l)_ [expr fmod(${a(k,i)_},$Mod)]
+       set b(k,l)_ [expr fmod(${b(k,i)_},$Mod)]
+       set s(k,l)_ [expr ${a(k,l)_} + ($Mod * ${b(k,l)_})]
+       return "${s(k,l)_} ${a(k,l)_} ${b(k,l)_} $k $l [lindex ${Xsub_k...Xsub_l} 0]"
+}
+
+proc tdelta {referenceFile targetFile blockSize {sizecheck 0} {fingerprint 0}} {
+       if {$::trsync::md5Size < 1} {error "md5Size must be greater than zero."}
+       set signature [Digest $targetFile $blockSize $sizecheck $fingerprint]
+       return [CopyInstructions $referenceFile $signature]
+}
+
+proc tpatch {targetFile copyInstructions fileToConstruct {eolNative 0}} {
+       set copyInstructions [lreplace $copyInstructions 0 1 $fileToConstruct $targetFile]
+       return [ConstructFile $copyInstructions $eolNative]
+}
+
+namespace export tdelta tpatch
+
+}
+# end namespace eval ::trsync
+
diff --git a/8.x/tclvfs/library/template/templatevfs.tcl b/8.x/tclvfs/library/template/templatevfs.tcl
new file mode 100644 (file)
index 0000000..f7c48c3
--- /dev/null
@@ -0,0 +1,581 @@
+#/usr/bin/env tclsh
+
+if 0 {
+########################
+
+templatevfs.tcl --
+
+Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+License: Tcl license
+Version 1.5.4
+
+The template virtual filesystem is designed as a prototype on which to build new virtual 
+filesystems.  Only a few simple, abstract procedures have to be overridden to produce a new
+vfs, requiring no knowledge of the Tclvfs API. 
+
+In addition, several behind-the-scenes functions are provided to make new vfs's more stable and
+scalable, including file information caching and management of close callback errors. 
+
+The template vfs provides a useful function of its own, it mirrors a real directory to a 
+virtual location, analogous to a Unix-style link.
+
+Usage: mount ?-cache <number>? ?-volume? <existing directory> <virtual directory>
+
+Options:
+
+-cache
+Sets number of seconds file stat and attributes information will dwell in cache after 
+being retrieved.  Default is 2.  Setting value of 0 will essentially disable caching.  This 
+value is viewable and editable after mount by calling "file attributes <virtual directory> -cache ?value?"
+
+-volume
+Volume specified in virtual directory pathname will be mounted as a virtual volume.
+
+The above options are inherited by all virtual filesystems built using the template.
+
+Side effects: Files whose names begin with ".vfs_" will be ignored and thus invisible to the 
+user unless the variable ::vfs::template::vfs_retrieve exists.
+
+Sourcing this file will run code that overloads the exit command with
+a procedure that ensures that all vfs's are explicitly unmounted before the
+shell terminates.
+
+When a vfs built on the template vfs is mounted, the mount command options are stored in an array named
+vfs::template::mount with the virtual mount point as the array index name.  Thus a vfs can be re-mounted
+by executing "eval" on the contents of the array element whose index is the vfs's virtual mount point.
+
+########################
+}
+
+package require vfs 1.0
+
+# force sourcing of vfsUtils.tcl: 
+set vfs::posix(load) x
+vfs::posixError load
+unset vfs::posix(load)
+
+package provide vfs::template 1.5.4
+
+namespace eval ::vfs::template {
+
+if 0 {
+########################
+
+In order to create a new virtual filesystem:
+
+1. copy the contents of this namespace eval statement to a
+new namespace eval statement with a unique new namespace defined
+
+2. rewrite the copied procedures to retrieve and handle virtual filesystem 
+information as desired and return it in the same format as the given native
+file commands.
+
+########################
+}
+
+package require vfs::template 1.5
+
+# read template procedures into current namespace. Do not edit:
+foreach templateProc [namespace eval ::vfs::template {info procs}] {
+       set infoArgs [info args ::vfs::template::$templateProc]
+       set infoBody [info body ::vfs::template::$templateProc]
+       proc $templateProc $infoArgs $infoBody
+}
+
+# edit following procedures:
+
+# Do not close channel within this procedure (will cause error).  Simply
+# read info from channel as needed and return.
+proc close_ {channel} {return}
+
+# Variable $time is always defined.  These procs only set time values.
+proc file_atime {file time} {file atime $file $time}
+proc file_mtime {file time} {file mtime $file $time}
+
+# Variables $attribute and $args may or may not be empty.
+# If $attribute is empty so is $args (retrieve all attributes and values).
+# If $args only is empty, retrieve value of specified attribute.
+# If $args has a value, set it as value of specified attribute.
+proc file_attributes {file {attribute {}} args} {eval file attributes \$file $attribute $args}
+
+# Variable $file may be a file or directory.
+# This proc only called if it is certain that deletion is the correct action.
+proc file_delete {file} {file delete -force -- $file}
+
+proc file_executable {file} {file executable $file}
+proc file_exists {file} {file exists $file}
+proc file_mkdir {file} {file mkdir $file}
+proc file_readable {file} {file readable $file}
+proc file_stat {file array} {upvar $array fs ; file stat $file fs}
+proc file_writable {file} {file writable $file}
+
+# All variables are always defined.
+# Return list of filenames only, not full pathnames.
+proc glob_ {directory dir nocomplain tails types typeString dashes pattern} {glob -directory $dir -nocomplain -tails -types $typeString -- $pattern}
+proc open_ {file mode} {open $file $mode}
+
+
+# MountProcedure is called once each time a vfs is newly mounted.
+proc MountProcedure {args} {
+       upvar volume volume
+
+# take real and virtual directories from command line args.
+       set to [lindex $args end]
+       if [string equal $volume {}] {set to [::file normalize $to]}
+       set path [::file normalize [lindex $args end-1]]
+
+# make sure mount location exists:
+       ::file mkdir $path
+
+# add custom handling for new vfs args here.
+
+# return two-item list consisting of real and virtual locations.
+       lappend pathto $path
+       lappend pathto $to
+       return $pathto
+}
+
+
+proc UnmountProcedure {path to} {
+# add custom unmount handling of new vfs elements here.
+
+       return
+}
+
+}
+# end namespace ::vfs::template
+
+
+# Below are template API procedures; there should be no need to edit them.
+
+namespace eval ::vfs::template {
+
+proc mount {args} {
+
+# handle template command line args:
+       set volume [lindex $args [lsearch $args "-volume"]]
+       set cache 2
+       if {[set cacheIndex [lsearch $args "-cache"]] != -1} {set cache [lindex $args [incr cacheIndex]]}
+       set args [string map "\" -volume \" { } \" -cache $cache \" { }" " $args "]
+# run unmount procedure if mount exists:
+       set to [lindex $args end]
+       if [info exists ::vfs::_unmountCmd($to)] {$::vfs::_unmountCmd($to) $to}
+
+# call custom mount procedure:
+       # ensure files named ".vfs_*" can be opened
+       set ::vfs::template::vfs_retrieve 1
+
+       set pathto [eval MountProcedure $args]
+
+       # re-hide ".vfs_*" files
+       unset -nocomplain ::vfs::template::vfs_retrieve
+
+       set path [lindex $pathto 0]
+       set to [lindex $pathto 1]
+       if [string equal $volume {}] {set to [file normalize $to]}
+
+# preserve mount info for later duplication if desired:
+       set ::vfs::template::mount($to) "[namespace current]::mount $volume -cache $cache $args"
+
+# if virtual location still mounted, unmount it by force:
+       if {[lsearch [::vfs::filesystem info] $to] != -1} {::vfs::filesystem unmount $to}
+       array unset ::vfs::_unmountCmd $to
+
+# set file info cache dwell time value:
+       set [namespace current]::cache($to) $cache
+
+# register location with Tclvfs package:
+       set div {}
+       if {$volume ne {}} {
+               if {[string index $to end] ne "/"} {
+                       set div /
+               }
+       }
+       eval ::vfs::filesystem mount $volume \$to$div \[list [namespace current]::handler \$path\]
+       ::vfs::RegisterMount $to [list [namespace current]::unmount]
+
+# ensure close callback background error appears at script execution level:
+       trace remove execution ::close leave ::vfs::template::CloseTrace
+       trace remove execution ::file leave ::vfs::template::FileTrace
+       trace add execution ::close leave vfs::template::CloseTrace
+       trace add execution ::file leave vfs::template::FileTrace
+
+       return $to
+}
+
+# undo Tclvfs API hooks:
+proc unmount {to} {
+       if {[lsearch [::vfs::filesystem info] $to] < 0} {
+               set to [::file normalize $to]
+       }
+       set path [lindex [::vfs::filesystem info $to] end]
+
+# call custom unmount procedure:
+       set ::vfs::template::vfs_retrieve 1
+       UnmountProcedure $path $to
+       unset -nocomplain ::vfs::template::vfs_retrieve
+
+       ::vfs::filesystem unmount $to
+       array unset ::vfs::_unmountCmd [::file normalize $to]
+
+# clear file info caches:
+       CacheClear $to
+}
+
+# vfshandler command required by Tclvfs API:
+proc handler {path cmd root relative actualpath args} {
+# puts [list $path $root $relative $cmd $args [namespace current]]
+
+       set fileName [::file join $path $relative]
+       set virtualName [::file join $root $relative]
+       switch -- $cmd {
+               access {
+                       set mode [lindex $args 0]
+                       set error [catch {Access $path $root $relative $actualpath $mode}]
+                       if $error {::vfs::filesystem posixerror $::vfs::posix(EACCES) ; return -code error $::vfs::posix(EACCES)}
+               }
+               createdirectory {
+                       CreateDirectory $path $root $relative $actualpath
+                       CacheClear $virtualName
+               }
+               deletefile {
+                       DeleteFile $path $root $relative $actualpath
+                       CacheClear $virtualName
+               }
+               fileattributes {
+                       set index [lindex $args 0]
+                       if {[llength $args] > 1} {set value [lindex $args 1]}
+                       set extra {}
+                       if [string equal $relative {}] {eval set extra \"-cache \$[namespace current]::cache(\$root)\"}
+
+                       # try to get values from cache first:
+                       array set attributes [CacheGet [namespace current]::attributes $virtualName [set [namespace current]::cache($root)]]
+                       # if not in cache, get them from file:
+                       if [string equal [array get attributes] {}] {
+                               array set attributes "[FileAttributes $path $root $relative $actualpath] $extra"
+                               CacheSet [namespace current]::attributes $virtualName [array get attributes]
+                       }
+
+                       set attribute [lindex [lsort [array names attributes]] $index]
+
+                       # if value given in args, set it and return:
+                       if [info exists value] {
+                               if [string equal $attribute "-cache"] {
+                                       set [namespace current]::cache($root) $value
+                               } else {
+                                       FileAttributesSet $path $root $relative $actualpath $attribute $value
+                               }
+                               CacheClear $virtualName
+                               return
+                       }
+
+                       # if attribute given in args, return its value:
+                       if ![string equal $index {}] {
+                               return $attributes($attribute)
+                       }
+                       # otherwise, just return all attribute names
+                       return [lsort [array names attributes]]
+               }
+               matchindirectory {
+                       set pattern [lindex $args 0]
+                       set types [lindex $args 1]
+                       return [MatchInDirectory $path $root $relative $actualpath $pattern $types]
+               } open {
+                       # ensure files named ".vfs_*" can't be opened ordinarily:
+                       if {![string first ".vfs_" [file tail $relative]] && ![info exists ::vfs::template::vfs_retrieve]} {vfs::filesystem posixerror $::vfs::posix(EACCES)}
+
+                       set mode [lindex $args 0]
+                       if {$mode == {}} {set mode r}
+
+                       # workaround: Tclvfs can't handle channels in write-only modes; see Tclvfs bug #1004273
+                       if {$mode == "w"} {set mode w+}
+                       if {$mode == "a"} {set mode a+}
+
+                       set permissions [lindex $args 1]
+                       set channelID [Open $path $root $relative $actualpath $mode $permissions]
+
+                       # ensure channel settings match file command defaults
+                       set eofChar {{} {}}
+                       if [string equal $::tcl_platform(platform) "windows"] {set eofChar "\x1a {}"}
+                       fconfigure $channelID -encoding [encoding system] -eofchar $eofChar -translation auto
+                       switch -glob -- $mode {
+                               "" -
+                               "r*" -
+                               "w*" {
+                                       seek $channelID 0
+                               }
+                               "a*" {
+                                       seek $channelID 0 end
+                               }
+                               default {
+                                       ::vfs::filesystem posixerror $::vfs::posix(EINVAL)
+                                       return -code error $::vfs::posix(EINVAL)
+                               }
+                       }
+
+                       set result $channelID
+                       # designate handler as close callback command
+                       lappend result [list [namespace current]::handler $path close $root $relative $actualpath $channelID $mode]
+
+
+                       # make sure all interpreters can catch errors in close callback:
+                       foreach int [interp slaves] {
+                               InterpSeed $int
+                       }
+
+                       CacheClear $virtualName
+                       return $result
+               } close {
+                       set channelID [lindex $args 0]
+                       set mode [lindex $args 1]
+                       if [string equal $mode "r"] {return}
+                       # never use real close command here, custom overloaded proc only.
+                       set err [catch {close_ $channelID} result]
+                       if $err {::vfs::template::closeerror $::errorInfo ; error $::errorInfo}
+                       return
+               }
+               removedirectory {
+                       set recursive [lindex $args 0]
+                       if !$recursive {
+                               if {[MatchInDirectory $path $root $relative $actualpath * 0] != {}} {
+                                       ::vfs::filesystem posixerror $::vfs::posix(EEXIST)
+                                       return -code error $::vfs::posix(EEXIST)
+                               }
+                       }
+                       if {$relative == {}} {unmount $root ; return}
+                       RemoveDirectory $path $root $relative $actualpath
+                       CacheClear $virtualName
+               }
+               stat {
+                       set stat [CacheGet [namespace current]::stat $virtualName [set [namespace current]::cache($root)]]
+                       if ![string equal $stat ""] {
+                               return $stat
+                       }
+                       set stat [Stat $path $root $relative $actualpath]
+                       CacheSet [namespace current]::stat $virtualName $stat
+                       return $stat
+               }
+               utime {
+                       set atime [lindex $args 0]
+                       set mtime [lindex $args 1]
+                       Utime $path $root $relative $actualpath $atime $mtime
+                       array unset [namespace current]::stat $virtualName,time ; array unset [namespace current]::stat $virtualName,value
+               }
+       }
+}
+
+# following commands carry out information processing requirements for each vfshandler subcommand:
+# note that all calls to file commands are redirected to simplified API procs at top of this script
+
+proc Access {path root relative actualpath mode} {
+       set fileName [::file join $path $relative]
+       set virtualName [::file join $root $relative]
+       set modeString [::vfs::accessMode $mode]
+       set modeString [split $modeString {}]
+       set modeString [string map "F exists R readable W writable X executable" $modeString]
+       set secs [clock seconds]
+       foreach mode $modeString {
+               set result [CacheGet [namespace current]::$mode $virtualName [set [namespace current]::cache($root)] $secs]
+               if [string equal $result ""] {
+                       set result [eval file_$mode \$fileName]
+                       CacheSet [namespace current]::$mode $virtualName $result $secs
+               }
+               if !$result {error error}
+       }
+       return
+}
+
+proc CreateDirectory {path root relative actualpath} {
+       file_mkdir [::file join $path $relative]
+}
+
+proc DeleteFile {path root relative actualpath} {
+       set fileName [::file join $path $relative]
+#      file delete -force -- $fileName
+       file_delete $fileName
+}
+
+proc FileAttributes {path root relative actualpath} {
+       set fileName [::file join $path $relative]
+       return [file_attributes $fileName]
+}
+
+proc FileAttributesSet {path root relative actualpath attribute value} {
+       set fileName [::file join $path $relative]
+       file_attributes $fileName $attribute $value
+}
+
+proc MatchInDirectory {path root relative actualpath pattern types} {
+# special case: check for existence (see Tclvfs bug #1405317)
+       if [string equal $pattern {}] {
+               if ![::vfs::matchDirectories $types] {return {}}
+               return [::file join $root $relative]
+       }
+
+# convert types bitstring back to human-readable alpha string:
+       foreach {type shift} {b 0 c 1 d 2 p 3 f 4 l 5 s 6} {
+               if [expr {$types == 0 ? 1 : $types & (1<<$shift)}] {lappend typeString $type}
+       }       
+       set pathName [::file join $path $relative]
+
+# get non-hidden files:
+       set globList [glob_ -directory $pathName -nocomplain -tails -types $typeString -- $pattern]
+# if underlying location is not itself a vfs, get hidden files (Tclvfs doesn't pass "hidden" type to handler)
+       if [catch {::vfs::filesystem info $path}] {set globList [concat $globList [glob_ -directory $pathName  -nocomplain -tails -types "$typeString hidden" -- $pattern]]}
+
+# convert real path to virtual path:
+       set newGlobList {}
+       foreach gL $globList {
+               if {![string first ".vfs_" $gL] && ![info exists ::vfs::template::vfs_retrieve]} {continue}
+               set gL [::file join $root $relative $gL]
+               lappend newGlobList $gL
+       }
+       set newGlobList [lsort -unique $newGlobList]
+       return $newGlobList
+}
+
+proc Open {path root relative actualpath mode permissions} {
+       set fileName [::file join $path $relative]
+       set newFile 0
+       if ![file exists $fileName] {set newFile 1}
+       set channelID [open_ $fileName $mode]
+       if $newFile {catch {file_attributes $fileName -permissions $permissions}}
+       return $channelID
+}
+
+proc RemoveDirectory {path root relative actualpath} {
+       set fileName [::file join $path $relative]
+#      file delete -force -- $fileName
+       file_delete $fileName
+}
+
+proc Stat {path root relative actualpath} {
+       file_stat [::file join $path $relative] fs
+       return [array get fs]
+}
+
+proc Utime {path root relative actualpath atime mtime} {
+       set fileName [::file join $path $relative]
+       file_atime $fileName $atime
+       file_mtime $fileName $mtime
+}
+
+# check value of ::errorInfo to ensure close callback didn't generate background 
+# error; if it did, force error break.
+proc CloseTrace {commandString code result op} {
+       if {[info exists ::vfs::template::vfs_error] && ($::vfs::template::vfs_error != {})} {
+               set vfs_error $::vfs::template::vfs_error
+               closeerror {}
+               error $vfs_error
+       }
+       return
+}
+
+# file copy and file rename may trigger close callbacks internally, so check for close errors
+# after these commands complete.
+proc FileTrace {commandString code result op} {
+       if {[string map {copy {} rename {}} [lindex $commandString 1]] != {}} {return}
+       if {[info exists ::vfs::template::vfs_error] && ($::vfs::template::vfs_error != {})} {
+               set vfs_error $::vfs::template::vfs_error
+               closeerror {}
+               error $vfs_error
+       }
+       return
+}
+
+# ensure ::errorInfo from background errors makes it into every child interpreter
+# so CloseTrace and FileTrace can intercept it.
+
+proc closeerror {errorInfo} {
+       set ::vfs::template::vfs_error $errorInfo
+       foreach int [interp slaves] {
+               InterpSeed $int set ::vfs::template::vfs_error $::vfs::template::vfs_error
+       }
+}
+
+# seed all interpreters with trace structures necessary to intercept close callback errors:
+proc InterpSeed {interp args} {
+       interp eval $interp {namespace eval ::vfs::template {}}
+       $interp alias ::vfs::template::closeerror ::vfs::template::closeerror
+       $interp alias ::vfs::template::FileTrace ::vfs::template::FileTrace
+       $interp alias ::vfs::template::CloseTrace ::vfs::template::CloseTrace
+       interp eval $interp trace remove execution ::file leave ::vfs::template::FileTrace 
+       interp eval $interp trace remove execution ::close leave ::vfs::template::CloseTrace 
+
+       interp eval $interp trace add execution ::close leave ::vfs::template::CloseTrace
+       interp eval $interp trace add execution ::file leave ::vfs::template::FileTrace 
+
+       interp eval $interp $args
+       foreach int [interp slaves $interp] {
+               InterpSeed $int $args
+       }
+}
+
+# cache management functions:
+proc CacheClear {file} {
+       foreach arr {exists readable writable executable stat attributes} {
+               array unset [namespace current]::$arr $file,time
+               array unset [namespace current]::$arr $file,value
+               array unset [namespace current]::$arr $file/*
+       }
+}
+
+proc CacheGet {array file cache args} {
+       if [string equal [array names $array $file,time] {}] {return}
+       if ![string equal $args {}] {set secs $args} else {set secs [clock seconds]}
+       set fileTime [lindex [array get $array $file,time] 1]
+       if {[expr $secs - $fileTime] < $cache} {return [lindex [array get $array $file,value] 1]}
+       array unset $array $file,time ; array unset $array $file,value
+       return
+}
+
+proc CacheSet {array file value args} {
+       if ![string equal $args {}] {set secs $args} else {set secs [clock seconds]}
+       set fileTime $file,time
+       array set $array [list $fileTime $secs]
+       set fileValue $file,value
+       array set $array [list $fileValue $value]
+}
+
+# map built-in file selection dialogs to pure Tk equivalents, so virtual
+# filesystems can be browsed with same-looking code:
+proc tk_getOpenFile {args} {
+       eval [eval list ::tk::dialog::file:: open $args]
+}
+
+proc tk_getSaveFile {args} {
+       eval [eval list ::tk::dialog::file:: save $args]
+}
+
+proc tk_chooseDirectory {args} {
+       eval [eval list ::tk::dialog::file::chooseDir:: $args]
+}
+
+# workaround for bug in tclkit:
+proc memchan {args} {
+       if {$::tcl_platform(platform) == "windows"} {
+               package require Memchan
+               set chan [uplevel 1 ::memchan $args]
+               return $chan
+       } else {
+               return [eval [linsert $args 0 ::vfs::memchan]]
+       }
+}
+
+}
+# end namespace eval ::vfs::template
+
+# overload exit command so that all vfs's are explicitly 
+# unmounted before program termination:
+catch {rename ::exit ::vfs::template::exit}
+
+proc ::exit {args} {
+       foreach vfs [::vfs::filesystem info] {
+               if [catch {$::vfs::_unmountCmd([file normalize $vfs]) $vfs} result] {
+                       puts "$vfs: $result"
+               }               
+       }
+       ::vfs::template::exit [lindex $args 0]
+}
+
diff --git a/8.x/tclvfs/library/template/versionvfs.tcl b/8.x/tclvfs/library/template/versionvfs.tcl
new file mode 100644 (file)
index 0000000..a270a23
--- /dev/null
@@ -0,0 +1,603 @@
+if 0 {
+########################
+
+versionvfs.tcl --
+
+Written by Stephen Huntley (stephen.huntley@alum.mit.edu)
+License: Tcl license
+Version 1.5.2
+
+A versioning virtual filesystem.  Requires the template vfs in templatevfs.tcl.
+
+Similar to historical versioning filesystems, each edited version of a file is saved separately;
+each version file is tagged with a timestamp, and optional project tags.
+A deleted file is represented by a new zero-length file with timestamp and a tag reading "deleted".
+By default only the latest version is visible.  If the latest version is marked deleted, it is invisible.
+
+Directories are versioned and tagged in the same way as files.
+
+Older versions can be retrieved by setting the -project and -time values appropriately.
+
+
+Usage: mount ?-keep <number> -project <list of tags> -time <timestamp or "clock scan" suitable phrase>? <existing directory> <virtual directory>
+
+Options:
+
+-keep
+maximum number of previous versions of a file to keep per project.
+
+-project
+a list of one or more version-identifying tags.  Any file created or edited in the virtual file space
+will be given these tags.  File versions with a tag matching the ones given here will be visible in 
+preference to other, possibly later versions without the tag.
+
+If a file version has project tags but none of them is included in this project tag list, it will be 
+invisible; the file itself will then be invisible unless a file version exists without any 
+project tags, in which case it will be treated as the default.
+
+In cases where several file versions each have multiple tags that match in the project
+list, the version with the greatest number of matches will be visible.
+
+Deleted files are marked with the tag "deleted".  If this value is in the project
+name list, then deleted files will become visible again.
+
+Newly-created and deleted directories are tagged and shown/hidden in the same way as files.
+
+-time
+A timestamp in the form returned by [clock seconds], or a string understandable by [clock scan].
+Versions of files as they existed at the given time will be visible, rather than the
+default latest version.  Version choices based on project tags will still be made, but
+versions later than the timestamp will be ignored in the decision process.
+
+
+The values of each option can be changed dynamically after mount by using the "file attributes" 
+command on the mount virtual directory. Each option is editable as an attribute; 
+i.e., "file attributes C:/version -project {version2 release}".  Display of visible files will 
+change dynamically based on decisions with new attribute values.
+
+In addition, new attributes are defined which can be queried for individual files:  
+
+The command "file attributes $file -version_filename" will show the exact filename of the 
+currently visible version of the given file as it is stored in the vfs, complete with 
+timestamp and project tags if any.
+
+The command "file attributes $file -versions" will return a list containing information on
+all stored versions of the given file.  Each element of the list is itself a three-element 
+list: 1) the unique millisecond-level timestamp of the version, 2) a human-readable date string
+showing the time represented by the timestamp (can be used a a value for the -time attribute), 
+and 3) a list of the project tags attached to the version, if any.
+
+The versioning vfs inherits the -cache and -volume options of the template vfs.
+
+########################
+}
+
+package require vfs::template 1.5
+package require fileutil::globfind
+
+package provide vfs::template::version 1.5.2
+
+namespace eval ::vfs::template::version {
+
+# read template procedures into current namespace. Do not edit:
+foreach templateProc [namespace eval ::vfs::template {info procs}] {
+       set infoArgs [info args ::vfs::template::$templateProc]
+       set infoBody [info body ::vfs::template::$templateProc]
+       proc $templateProc $infoArgs $infoBody
+}
+
+# edit following procedures:
+proc close_ {channelID} {
+       upvar path path root root relative relative
+
+# get hash of file as it existed before edit:
+       array set fileStats $::vfs::template::version::filestats($channelID)
+       unset ::vfs::template::version::filestats($channelID)
+
+# if new hash shows file is unchanged, return immediately:
+       fconfigure $channelID -translation binary
+       set hash [Hash $channelID]
+       if [string equal -nocase $hash $fileStats(hash)] {return}
+
+# create new unique filename for new version:
+       set fileName [VFileNameEncode [file join $path $relative]]\;[VCreateTag $root]
+       catch {array set oldAttributes [file attributes $fileStats(filename)]}
+
+# delete file version created by open_ if it's a new file:
+       if [string equal $fileStats(hash) {}] {
+               file delete -- $fileStats(filename)
+       }
+
+# save new version:
+       set f [open $fileName w]
+       fconfigure $f -translation binary
+       seek $channelID 0
+       fcopy $channelID $f
+       close $f
+
+# ensure attributes are the same for new version:
+       foreach {attr value} [file attributes $fileName] {
+               if ![info exists oldAttributes($attr)] {continue}
+               if {$oldAttributes($attr) != $value} {catch {file attributes $fileName $attr $oldAttributes($attr)}}
+       }
+
+       return
+}
+proc file_atime {file time} {  
+       upvar path path root root relative relative
+# check if current version is latest, if not disallow edit:
+       set latest [lindex [lindex [lsort [VersionsAll $path $relative]] end] 0]
+       set acquired [lindex [split [set fileName [VAcquireFile $path $root $relative]] \;] 1]
+       if ![string first .&dir [file tail $fileName]] {::vfs::filesystem posixerror $::vfs::posix(ENOENT)}
+       if {($acquired != {}) && ($latest != $acquired)} {::vfs::filesystem posixerror $::vfs::posix(EPERM)}
+
+       file atime $fileName $time
+}
+proc file_mtime {file time} {
+       upvar path path root root relative relative
+# check if current version is latest, if not disallow edit:
+       set latest [lindex [lindex [lsort [VersionsAll $path $relative]] end] 0]
+       set acquired [lindex [split [set fileName [VAcquireFile $path $root $relative]] \;] 1]
+       if ![string first .&dir [file tail $fileName]] {::vfs::filesystem posixerror $::vfs::posix(ENOENT)}
+       if {($acquired != {}) && ($latest != $acquired)} {::vfs::filesystem posixerror $::vfs::posix(EPERM)}
+
+       file mtime $fileName $time
+}
+proc file_attributes {file {attribute {}} args} {
+       upvar path path root root relative relative
+       set latest [lindex [lindex [lsort [set allVersions [VersionsAll $path $relative]]] end] 0]
+       set acquired [lindex [split [set fileName [VAcquireFile $path $root $relative]] \;] 1]
+       if ![string first .&dir [file tail $fileName]] {::vfs::filesystem posixerror $::vfs::posix(ENOENT)}
+# process vfs-specific attributes:
+       if {($relative == {}) && ([string map {-keep 1 -project 1 -time 1} $attribute] == 1)} {
+               set attribute [string range $attribute 1 end]
+               if {$args == {}} {
+                       if ![info exists ::vfs::template::version::${attribute}($root)] {return}
+                       eval return \$::vfs::template::version::${attribute}(\$root)
+               }
+               set ::vfs::template::version::${attribute}($root) [lindex $args 0]
+               if {[lindex $args 0] == {}} {unset ::vfs::template::version::${attribute}($root)}
+               return
+       }
+       # process read-only vfs-specific attributes:
+       if {$attribute == "-versions"} {
+               if {$args == {}} {return $allVersions}
+               error "cannot set attribute \"-versions\" for file \"[file tail $relative]\": attribute is readonly"
+       }
+       if {$attribute == "-version_filename"} {
+               if {$args == {}} {return [file tail $fileName]}
+               error "cannot set attribute \"-version_filename\" for file \"[file tail $relative]\": attribute is readonly"
+       }
+# check if current version is latest, if not disallow edit:
+       if {($args != {}) && ($acquired != {}) && ($latest != $acquired)} {::vfs::filesystem posixerror $::vfs::posix(EPERM)}
+       set returnValue [eval file attributes \$fileName $attribute $args]
+# collect values for vfs-specific attributes:
+       if {$attribute == {}} {
+               append returnValue " [list -versions $allVersions]"
+               if {$file != $fileName} {append returnValue " [list -version_filename [file tail $fileName]]"}
+               if {$relative != {}} {return $returnValue}
+               foreach atr "keep project time" {
+                       set $atr "-$atr {}"
+                       if [info exists ::vfs::template::version::${atr}($root)] {eval set $atr \[list "-$atr" \$::vfs::template::version::${atr}(\$root)\]}
+               }
+               append returnValue " $keep $project $time"
+       }
+       return $returnValue
+}
+
+proc file_delete {file} {
+       upvar path path root root relative relative
+       set dir 0
+
+# make sure subfiles of directory are deleted:
+       if [file isdirectory $file] {
+               set subfiles [globfind $file]
+               set subfiles [lsort -decreasing $subfiles]
+               set deleted {}
+               foreach sf $subfiles {
+                       if [file isdirectory $sf] {continue}
+                       globdelete $sf
+               }
+               set dir 1
+               return
+       }
+       set fileName [VAcquireFile $path $root $relative]
+
+# allow straight deletion of new zero-length file:
+       if {!$dir && ([llength [VersionsAll $path $relative]] == 1) && ![file size $fileName]} {
+               file delete -force -- $fileName
+               return
+       }
+
+# for all others, create new file with "deleted" tag
+       set file [VFileNameEncode $file]
+       set fileName $file\;[VCreateTag $root]
+       if $dir {set fileName [file join $file .&dir[file tail $file]]\;[VCreateTag $root]}
+       set fileName [split $fileName \;]
+       set fileName [linsert $fileName 2 "deleted"]
+       set fileName [join $fileName \;]
+       close [open $fileName w]
+       if $dir {catch {file attributes $fileName -hidden 1}}
+}
+proc file_executable {file} {
+       upvar path path root root relative relative
+       set fileName [VAcquireFile $path $root $relative]
+       if ![string first .&dir [file tail $fileName]] {return 0}
+       file executable $fileName
+}
+proc file_exists {file} {
+       upvar path path root root relative relative
+       set fileName [VAcquireFile $path $root $relative]
+       if ![string first .&dir [file tail $fileName]] {return 0}
+       if [file isdirectory $fileName] {return 1}
+       expr ![string equal [file join $path $relative] $fileName]
+}
+proc file_mkdir {file} {
+       upvar root root
+       file mkdir $file
+
+# create a file to store timestamps and tags for directory:
+       set fileName [VFileNameEncode $file]
+       set fileName [file join $fileName .&dir[file tail $fileName]]\;[VCreateTag $root]
+       close [open $fileName w]
+       catch {file attributes $fileName -hidden 1}
+       return
+}
+proc file_readable {file} {
+       upvar path path root root relative relative
+       set fileName [VAcquireFile $path $root $relative]
+       if ![string first .&dir [file tail $fileName]] {return 0}
+       file readable $fileName
+}
+proc file_stat {file array} {
+       upvar path path root root relative relative $array fs
+       set fileName [VAcquireFile $path $root $relative]
+       if ![string first .&dir [file tail $fileName]] {error "no such file or directory"}
+       file stat $fileName fs
+       if {$fs(type) == "directory"} {
+               return
+       }
+       if {$fileName == [file join $path $relative]} {error "no such file or directory"}
+       return
+}
+proc file_writable {file} {
+       upvar path path root root relative relative
+       set fileName [VAcquireFile $path $root $relative]
+       if ![string first .&dir [file tail $fileName]] {return 0}
+       file writable $fileName
+}
+proc glob_ {directory dir nocomplain tails types typeString dashes pattern} {
+       upvar path path root root relative relative
+       set globList [glob -directory $dir -nocomplain -types $typeString *]
+       set newGlobList {}
+       set acquireAttempts {}
+       foreach gL $globList {
+               if [file isdirectory $gL] {
+                       set acquiredFile [VAcquireFile $path $root [file join $relative [file tail $gL]]]
+                       if ![string equal $acquiredFile $gL] {continue}
+               } else {
+                       if ![string first .&dir [file tail $gL]] {continue}
+                       set gL [VFileNameDecode $gL]
+                       if {[lsearch $acquireAttempts $gL] > -1} {continue}
+                       lappend acquireAttempts $gL
+                       set acquiredFile [VAcquireFile $path $root [file join $relative [file tail $gL]]]
+                       if [string equal $acquiredFile $gL] {continue}
+               }
+               if [string match $pattern [file tail $gL]] {lappend newGlobList [file tail $gL]}
+       }
+       return $newGlobList
+}
+proc open_ {file mode} {
+       upvar path path root root relative relative 
+       set fileName [VAcquireFile $path $root $relative]
+       if {$mode == "r"} {return [open $fileName r]}
+       set hash {}
+
+# Use memchans so if file contents don't change we are free to delete file rather than commit to
+# creating new version which is identical to last.
+# If file is new, create new tag for it and return memchan:
+       if {$fileName == [file join $path $relative]} {
+               set fileName [VFileNameEncode [file join $path $relative]]\;[VCreateTag $root]
+               close [open $fileName $mode]
+               set channelID [memchan]
+               set ::vfs::template::version::filestats($channelID) "filename [list $fileName] hash [list $hash]"
+               return $channelID
+       }
+
+# otherwise, get hash of existing file and store it where close callback can grab it,
+# then return memchan:
+       set f [open $fileName r]
+       fconfigure $f -translation binary
+       set hash [Hash $f]
+       close $f
+       set filed [memchan]
+       if {[string index $mode 0] == "a"} {
+               set f [open $fileName r]
+               fconfigure $f -translation binary
+               fconfigure $filed -translation binary
+               fcopy $f $filed
+               close $f
+               seek $filed 0
+       }
+       set fileStats(hash) $hash
+       set fileStats(filename) $fileName
+       set ::vfs::template::version::filestats($filed) [array get fileStats]
+       return $filed
+}
+
+
+proc MountProcedure {args} {
+       upvar volume volume
+
+# take real and virtual directories from command line args.
+       set to [lindex $args end]
+       if [string equal $volume {}] {set to [::file normalize $to]}
+       set path [::file normalize [lindex $args end-1]]
+
+# make sure mount location exists:
+       ::file mkdir $path
+
+# add custom handling for new vfs args here.
+
+       namespace import -force ::fileutil::globfind::globfind
+
+       set argsLength [llength $args]
+       for {set i 0} {$i < $argsLength} {incr i} {
+               switch -- [lindex $args $i] {
+                       -keep {
+                               set keep [lindex $args [incr i]]
+                               if ![string is digit -strict $keep] {continue}
+                               set ::vfs::template::version::keep($to) $keep
+                       }
+                       -project {
+                               set project [lindex $args [incr i]]
+                               set ::vfs::template::version::project($to) $project
+                       }
+                       -time {
+                               set time [lindex $args [incr i]]
+                               SetTime $time
+                               set ::vfs::template::version::time($to) $time
+                       }
+               }
+       }
+
+       if [catch {glob -directory $path -type {f hidden} .&dir*}] {
+               set root $to
+               file_mkdir $path
+       }
+
+
+# return two-item list consisting of real and virtual locations.
+       lappend pathto $path
+       lappend pathto $to
+       return $pathto
+}
+
+
+proc UnmountProcedure {path to} {
+# add custom unmount handling of new vfs elements here.
+       if [info exists ::vfs::template::version::keep($to)] {unset ::vfs::template::version::keep($to)}
+       if [info exists ::vfs::template::version::project($to)] {unset ::vfs::template::version::project($to)}
+       if [info exists ::vfs::template::version::time($to)] {unset ::vfs::template::version::time($to)}
+       return
+}
+
+# utility proc called by file_delete for recursive deletion of dir contents:
+proc globdelete {file} {
+       upvar root root deleted deleted
+       set file [file join [file dirname $file] [lindex [split [file tail $file] \;] 0]]
+       if {[lsearch $deleted $file] > -1} {return}
+       lappend deleted $file
+       set fileName $file\;[VCreateTag $root]
+       set fileName [split $fileName \;] 
+       set fileName [linsert $fileName 2 "deleted"]
+       set fileName [join $fileName \;]
+       close [open $fileName w]
+       if ![string first {.&} [file tail $fileName]] {catch {file attributes $fileName -hidden 1}}
+}
+
+# Can replace this proc with one that uses different hash function if preferred.
+proc Hash {channel} {
+       seek $channel 0
+       if [catch {package present md5 2}] {package forget md5 ; package require md5 2}
+       ::md5::md5 -hex -- [read $channel]
+}
+
+# figure out if time is a string, milliseconds or seconds count, return seconds count
+proc SetTime {time} {
+       if ![string is digit -strict $time] {catch {set time [clock scan $time]}}
+       if ![string is digit -strict $time] {error "invalid time value."}
+       set time "[string range $time 0 [expr [string length [clock seconds]] - 1]]000"
+}
+
+# decide which version is preferred considering time and project settings:
+proc VAcquireFile {path root relative {actualpath {}}} {
+       set fileName [VFileNameEncode [file join $path $relative]]
+       if [file isdirectory [file join $path $relative]] {
+               set fileName [file join $fileName .&dir[file tail $fileName]]
+               set relative [file join $relative .&dir[file tail $relative]]
+       }
+
+# grab all versions:
+       set versions [glob -path $fileName -nocomplain -types f "\;*"]
+       if [catch {::vfs::filesystem info $path}] {append versions " [glob -path $fileName -nocomplain -types "f hidden" "\;*"]"}
+
+       set versions [string trim $versions]
+       if {$versions == {}} {return [file join $path $relative]}
+
+       set checkProject 0
+       if [info exists ::vfs::template::version::project($root)] {
+               set projects [string map {; &s} [string map {& &a} $::vfs::template::version::project($root)]]
+               set checkProject 1
+       }
+
+# find versions that have current project tags to see if keep setting requires deleting any:
+       foreach ver $versions {
+               set ver $root/[file tail $ver]
+               lappend versionFiles $ver
+               if !$checkProject {continue}
+               foreach project $projects {
+                       if {[lsearch [lrange [split $ver \;] 1 end] $project] > -1} {lappend projectFiles $ver}
+               }
+       }
+       unset versions
+
+# delete older versions if keep setting requires it:
+       if ![catch {if {[llength $projectFiles] <= $::vfs::template::version::keep($root)} {error}}] {
+               set keep $::vfs::template::version::keep($root)
+               set projectFiles [lsort -decreasing -dictionary $projectFiles]
+               set fileNumber [llength $projectFiles]
+               for {set i [incr fileNumber -1]} {$i >= 0} {incr i -1} {
+                       if {[llength $projectFiles] <= $keep} {break}
+                       set delFile [file join [file dirname [file join $path $relative]] [file tail [lindex $projectFiles $i]]]
+                       if ![catch {file delete -- $delFile}] {set projectFiles [lreplace $projectFiles $i $i]}
+               }
+       }
+
+# find version that's best match with time and project settings:
+       set fileName [file tail [lindex [lsort -command VersionSort $versionFiles] 0]]
+
+# if file version has "deleted" tag, return with no version info, indicating file doesn't exist:
+       if !$checkProject {
+               if {[lindex [split $fileName \;] 2] == "deleted"} {return [file join $path $relative]}
+       }
+
+# if project attribute is set, and version has project tags, ensure version belongs to one of the set projects,
+# otherwise it will be invisible:
+       if $checkProject {
+               if {([lindex [split $fileName \;] 2] == "deleted") && ([lsearch $projects "deleted"] == -1)} {return [file join $path $relative]}
+               set projectMember 0
+               set tags [lrange [split $fileName \;] 1 end]
+               if {[lindex $tags 1] == "deleted"} {set tags [lreplace $tags 1 1]}
+               foreach project $projects {
+                               if {[lsearch $tags $project] > -1} {set projectMember 1}
+               }
+               set projectLength [llength $tags]
+               if {($projectLength > 1) && !$projectMember} {return [file join $path $relative]}
+       }
+
+# if time tag value is before creation date of chosen version, make file invisible:
+       if {[info exists ::vfs::template::version::time($root)] && ([lindex [split $fileName \;] 1] > "$::vfs::template::version::time($root)000")} {
+               return [file join $path $relative]
+       }
+
+       if ![string first .&dir [file tail $relative]] {
+               set fileName [file join $path [file dirname $relative]]
+               return [file normalize $fileName]
+       }
+       return [file join [file dirname [file join $path $relative]] $fileName]
+}
+
+# create new version tag with millisecond-scale timestamp and curernt project tags:
+proc VCreateTag {root} {
+       set tag [clock seconds][string range [clock clicks -milliseconds] end-2 end]
+       if [info exists ::vfs::template::version::project($root)] {
+               set projects [string map {; &s} [string map {& &a} $::vfs::template::version::project($root)]]
+               set projectTag [join $projects \;]
+               set tag [join "$tag $projectTag" \;]
+       }
+       return $tag
+}
+
+# return info on all versions of a file:
+proc VersionsAll {path relative} {
+       set fileName [VFileNameEncode [file join $path $relative]]
+       if [file isdirectory [file join $path $relative]] {
+               set fileName [file join $fileName .&dir[file tail $fileName]]
+               set relative [file join $relative .&dir[file tail $relative]]
+       }
+       set versions [glob -path $fileName -nocomplain -types f "\;*"]
+       if [catch {::vfs::filesystem info $path}] {append versions " [glob -path $fileName -nocomplain -types "f hidden" "\;*"]"}
+
+       set versions [string trim $versions]
+
+       set newVersions {}
+       foreach ver $versions {
+               set ver [lrange [split $ver \;] 1 end]
+               set ver [file tail [VFileNameDecode $ver]]
+               set tag [lindex $ver 0]
+               set time [string range $tag 0 end-3]
+               set time [clock format $time -format "%Y%m%dT%H:%M:%S"]
+               lappend newVersions "$tag $time [list [lrange $ver 1 end]]"
+       }
+       return $newVersions
+}
+
+# specialized command for lsort, decide which of two versions is preferred given 
+# project and time settings:
+proc VersionSort {element1 element2} {
+       set root [file dirname $element1]
+       set element1 [file tail $element1]
+       set element2 [file tail $element2]
+       if [string equal $element1 $element2] {return 0}
+       set sorted [lsort -dictionary -decreasing "$element1 $element2"]
+
+# decision 1: choose latest timestamp:
+       if {[lindex $sorted 0] == $element1} {set returnValue -1}
+       if {[lindex $sorted 0] == $element2} {set returnValue 1}
+
+       set time1 [lindex [split $element1 \;] 1]
+       set time2 [lindex [split $element2 \;] 1]
+       set time $time1
+       if {$time2 > $time1} {set time $time2}
+
+# decision 2: if time setting exists, choose latest timestamp less than time setting:
+       if [info exists ::vfs::template::version::time($root)] {
+               set returnValue -1
+               set time $::vfs::template::version::time($root)
+               if {!([string is digit -strict $time] && ([string length $time] == [string length $time1]))} {
+                       set time [SetTime $::vfs::template::version::time($root)]
+               }
+
+               if {$time1 > $time} {set time1 [expr $time2 - 1]}
+               if {($time2 <= $time) && ($time2 > $time1)} {set returnValue 1}
+       }
+
+# decision 3: choose version with greatest number of project tag matches with project setting:
+       if [info exists ::vfs::template::version::project($root)] {
+               set projects [string map {; &s} [string map {& &a} $::vfs::template::version::project($root)]]
+               set project1 0
+               set project2 0
+               foreach project [lsort -unique $projects] {
+                       set sumproject1 [lsearch [lrange [split $element1 \;] 1 end] $project]
+                       set sumproject2 [lsearch [lrange [split $element2 \;] 1 end] $project]
+                       incr sumproject1 ; incr sumproject2
+                       if $sumproject1 {incr project1}
+                       if $sumproject2 {incr project2}
+               }
+               if {$project1 > $project2} {set project1 1 ; set project2 0}
+               if {$project1 < $project2} {set project1 0 ; set project2 1}
+
+               # don't count "deleted" as a project tag for purpose of choosing default:
+               set tagEnd1 [lindex [split $element1 \;] 2]
+               if {$tagEnd1 == "deleted"} {set tagEnd1 [lindex [split $element1 \;] 3]}
+               set tagEnd2 [lindex [split $element2 \;] 2]
+               if {$tagEnd2 == "deleted"} {set tagEnd2 [lindex [split $element2 \;] 3]}
+       
+               # set version with no project tags as default choice:
+               if {($tagEnd1 == {}) && !($tagEnd2 == {})} {set returnValue -1}
+               if {!($tagEnd1 == {}) && ($tagEnd2 == {})} {set returnValue 1}
+
+               # if a project tag match exists, replace default choice with it:
+               if {$project2 && !$project1 && ($time2 <= $time)} {set returnValue 1}
+               if {$project1 && !$project2 && ($time1 <= $time)} {set returnValue -1}
+       }
+       return $returnValue
+}
+
+# ampersand and semicolon are privileged chars in tagging, 
+# encode and decode filenames containing them:
+proc VFileNameEncode {filename} {
+       set filename [file dirname $filename]/[string map {& &a} [file tail $filename]]
+       set filename [file dirname $filename]/[string map {; &s} [file tail $filename]]
+}
+
+proc VFileNameDecode {filename} {
+       set filename [file dirname $filename]/[lindex [split [file tail $filename] \;] 0]
+       set filename [file dirname $filename]/[string map {&s ;} [file tail $filename]]
+       set filename [file dirname $filename]/[string map {&a &} [file tail $filename]]
+}
+
+}
+# end namespace ::vfs::template::version
+
diff --git a/8.x/tclvfs/library/testvfs.tcl b/8.x/tclvfs/library/testvfs.tcl
new file mode 100644 (file)
index 0000000..e57609c
--- /dev/null
@@ -0,0 +1,87 @@
+
+package provide vfs::test 1.0
+
+package require vfs 1.0
+
+namespace eval vfs::test {}
+
+proc vfs::test::Mount {what local} {
+    vfs::filesystem mount $local [list ::vfs::test::handler $what]
+    vfs::RegisterMount $local [list ::vfs::test::Unmount]
+}
+
+proc vfs::test::Unmount {local} {
+    vfs::filesystem unmount $local
+}
+
+proc vfs::test::handler {what cmd root relative actualpath args} {
+    eval [list $cmd $what $relative] $args
+}
+
+# If we implement the commands below, we will have a perfect
+# virtual file system.
+
+proc vfs::test::stat {what name} {
+    puts "stat $name"
+}
+
+proc vfs::test::access {what name mode} {
+    puts "access $name $mode"
+}
+
+proc vfs::test::open {what name mode permissions} {
+    puts "open $name $mode $permissions"
+    # return a list of two elements:
+    # 1. first element is the Tcl channel name which has been opened
+    # 2. second element (optional) is a command to evaluate when
+    #    the channel is closed.
+    return [list]
+}
+
+proc vfs::test::matchindirectory {what path pattern type} {
+    puts "matchindirectory $path $pattern $type"
+    set res [list]
+
+    if {[::vfs::matchDirectories $type]} {
+       # add matching directories to $res
+    }
+    
+    if {[::vfs::matchFiles $type]} {
+       # add matching files to $res
+    }
+    return $res
+}
+
+proc vfs::test::createdirectory {what name} {
+    puts "createdirectory $name"
+}
+
+proc vfs::test::removedirectory {what name recursive} {
+    puts "removedirectory $name"
+}
+
+proc vfs::test::deletefile {what name} {
+    puts "deletefile $name"
+}
+
+proc vfs::test::fileattributes {what args} {
+    puts "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+       }
+    }
+}
+
+proc vfs::test::utime {what name actime mtime} {
+    puts "utime $name"
+}
diff --git a/8.x/tclvfs/library/tkvfs.tcl b/8.x/tclvfs/library/tkvfs.tcl
new file mode 100644 (file)
index 0000000..1478773
--- /dev/null
@@ -0,0 +1,214 @@
+
+package provide vfs::tk 0.5
+
+package require vfs 1.0
+
+# Thanks to jcw for the idea here.  This is a 'file system' which
+# is actually a representation of the Tcl command namespace hierarchy.
+# Namespaces are directories, and procedures are files.  Tcl allows
+# procedures with the same name as a namespace, which are hidden in
+# a filesystem representation.
+
+namespace eval vfs::tk {}
+
+proc vfs::tk::Mount {tree local} {
+    if {![winfo exists $tree]} {
+       return -code error "No such window $tree"
+    }
+    ::vfs::log "tk widget hierarchy $tree mounted at $local"
+    if {$tree == "."} { set tree "" }
+    vfs::filesystem mount $local [list vfs::tk::handler $tree]
+    vfs::RegisterMount $local [list vfs::tk::Unmount]
+    return $local
+}
+
+proc vfs::tk::Unmount {local} {
+    vfs::filesystem unmount $local
+}
+
+proc vfs::tk::handler {widg cmd root relative actualpath args} {
+    regsub -all / $relative . relative
+    if {$cmd == "matchindirectory"} {
+       eval [list $cmd $widg $relative $actualpath] $args
+    } else {
+       eval [list $cmd $widg $relative] $args
+    }
+}
+
+# If we implement the commands below, we will have a perfect
+# virtual file system for namespaces.
+
+proc vfs::tk::stat {widg name} {
+    ::vfs::log "stat $name"
+    if {![winfo exists ${widg}.${name}]} {
+       return -code error "could not read \"$name\": no such file or directory"
+    }
+    set len [llength [winfo children ${widg}.${name}]]
+    if {$len || ([winfo class $widg.$name] == "Frame")} {
+       return [list type directory size $len mode 0777 \
+         ino -1 depth 0 name $name atime 0 ctime 0 mtime 0 dev -1 \
+         uid -1 gid -1 nlink 1]
+    } else {
+       return [list type file size 0 atime 0 ctime 0 mtime 0]
+    }
+}
+
+proc vfs::tk::access {widg name mode} {
+    ::vfs::log "access $name $mode"
+    if {[winfo exists ${widg}.${name}]} {
+       return 1
+    } else {
+       error "No such file"
+    }
+}
+
+proc vfs::tk::open {widg name mode permissions} {
+    ::vfs::log "open $name $mode $permissions"
+    # return a list of two elements:
+    # 1. first element is the Tcl channel name which has been opened
+    # 2. second element (optional) is a command to evaluate when
+    #    the channel is closed.
+    switch -- $mode {
+       "" -
+       "r" {
+           set nfd [vfs::memchan]
+           fconfigure $nfd -translation binary
+           puts -nonewline $nfd [_generate ${widg}.${name}]
+           fconfigure $nfd -translation auto
+           seek $nfd 0
+           return [list $nfd]
+       }
+       default {
+           return -code error "illegal access mode \"$mode\""
+       }
+    }
+}
+
+proc vfs::tk::_generate {p} {
+    lappend a [string tolower [winfo class $p]]
+    lappend a $p
+    foreach arg [$p configure] {
+       set item [lindex $arg 0]
+       lappend a $item [$p cget $item]
+    }
+    return $a
+}
+
+proc vfs::tk::matchindirectory {widg path actualpath pattern type} {
+    ::vfs::log [list matchindirectory $widg $path $actualpath $pattern $type]
+    set res [list]
+
+    if {$widg == "" && $path == ""} {
+       set wp ""
+    } else {
+       set wp $widg.$path
+    }
+    if {$wp == ""} { set wpp "." } else { set wpp $wp }
+    set l [string length $wp]
+    
+    if {$type == 0} {
+       foreach ch [winfo children $wpp] {
+           if {[string match $pattern [string range $ch $l end]]} {
+               lappend res $ch
+           }
+       }
+    } else {
+       if {[::vfs::matchDirectories $type]} {
+           # add matching directories to $res
+           if {[string length $pattern]} {
+               foreach ch [winfo children $wpp] {
+                   if {[string match $pattern [string range $ch $l end]]} {
+                       if {[llength [winfo children $ch]]} {
+                           lappend res $ch
+                       }
+                   }
+               }
+           } else {
+               if {[string match $pattern $wpp]} {
+                   if {[llength [winfo children $wpp]]} {
+                       lappend res $wpp
+                   }
+               }
+           }
+       }
+       if {[::vfs::matchFiles $type]} {
+           # add matching files to $res
+           if {[string length $pattern]} {
+               foreach ch [winfo children $wpp] {
+                   if {[string match $pattern [string range $ch $l end]]} {
+                       if {![llength [winfo children $ch]]} {
+                           lappend res $ch
+                       }
+                   }
+               }
+           } else {
+               if {[string match $pattern $wpp]} {
+                   if {![llength [winfo children $wpp]]} {
+                       lappend res $wpp
+                   }
+               }
+           }
+       }
+    }
+    
+    set realres [list]
+    set l [expr {1 + [string length $wp]}]
+    foreach r $res {
+       lappend realres [file join ${actualpath} [string range $r $l end]]
+    }
+    #::vfs::log $realres
+    
+    return $realres
+}
+
+proc vfs::tk::createdirectory {widg name} {
+    ::vfs::log "createdirectory $name"
+    frame ${widg}.${name}
+}
+
+proc vfs::tk::removedirectory {widg name recursive} {
+    ::vfs::log "removedirectory $name"
+    if {!$recursive} {
+       if {[llength [winfo children $widg.$name]]} {
+           vfs::filesystem posixerror $::vfs::posix(ENOTEMPTY)
+       }
+    }
+    destroy $widg.$name
+}
+
+proc vfs::tk::deletefile {widg name} {
+    ::vfs::log "deletefile $name"
+    destroy $widg.$name
+}
+
+proc vfs::tk::fileattributes {widg name args} {
+    ::vfs::log "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+           set res {}
+           foreach c [$widg.$name configure] {
+               lappend res [lindex $c 0]
+           }
+           return $res
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+           set arg [lindex [lindex [$widg.$name configure] $index] 0]
+           return [$widg.$name cget $arg]
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+           set arg [lindex [lindex [$widg.$name configure] $index] 0]
+           return [$widg.$name configure $arg $val]
+       }
+    }
+}
+
+proc vfs::tk::utime {what name actime mtime} {
+    ::vfs::log "utime $name"
+    error ""
+}
diff --git a/8.x/tclvfs/library/vfs.tcl.in b/8.x/tclvfs/library/vfs.tcl.in
new file mode 100644 (file)
index 0000000..cea8334
--- /dev/null
@@ -0,0 +1,36 @@
+# -*- tcl -*-
+
+# Activate the binary and Tcl parts of the package, in the proper
+# order.
+
+# The location of the Tcl parts can be redirected via the environment
+# variable VFS_LIBRARY. This is for use by testing of tclvfs without
+# having to actually install the package. In that case the location of
+# the binary part is redirected through the environment variable
+# TCLLIBPATH (indirect modification of the auto_path). Not used here
+# however, but by Tcl's package management code itself when searching
+# for the package.
+
+namespace eval ::vfs {
+    variable self    [file dirname [info script]]
+    variable redir   [info exists ::env(VFS_LIBRARY)]
+    variable corezip [package vsatisfies [package provide Tcl] 8.6]
+}
+
+if {[lsearch -exact $::auto_path $::vfs::self] == -1} {
+    lappend ::auto_path $::vfs::self
+}
+
+load [file join $::vfs::self @PKG_LIB_FILE@]
+
+if {$::vfs::redir} {
+    set ::vfs::self $::env(VFS_LIBRARY)
+}
+
+source [file join $::vfs::self vfsUtils.tcl]
+
+if {$::vfs::corezip} {
+    source [file join $::vfs::self vfslib.tcl]
+}
+
+unset ::vfs::self ::vfs::redir ::vfs::corezip
diff --git a/8.x/tclvfs/library/vfsUrl.tcl b/8.x/tclvfs/library/vfsUrl.tcl
new file mode 100644 (file)
index 0000000..749b110
--- /dev/null
@@ -0,0 +1,166 @@
+# The idea here is that we can mount 'ftp' or 'http' or 'file' types
+# of urls and that (provided we have separate vfs types for them) we
+# can then treat 'ftp://' as a mount point for ftp services.  For
+# example, we can do:
+#
+# % vfs::urltype::Mount ftp
+# Mounted at "ftp://"
+# % cd ftp://
+# % cd ftp.ucsd.edu   (or 'cd user:pass@ftp.foo.com')
+# (This now creates an ordinary ftp-vfs for the remote site)
+# ...
+#
+# Or all in one go:
+# 
+# % file copy ftp://ftp.ucsd.edu/pub/alpha/Readme .
+
+package provide vfs::urltype 1.0
+package require vfs
+
+namespace eval ::vfs::urltype {}
+
+proc vfs::urltype::Mount {type} {
+    set mountPoint [_typeToMount $type]
+    ::vfs::filesystem mount -volume $mountPoint [list vfs::urltype::handler $type]
+    return "Mounted at \"${mountPoint}\""
+}
+
+proc vfs::urltype::Unmount {type} {
+    set mountPoint [_typeToMount $type]
+    ::vfs::filesystem unmount $mountPoint
+}
+
+proc vfs::urltype::_typeToMount {type} {
+    set mountPoint "${type}://"
+    if {$type == "file"} {
+       append mountPoint "/"
+    }
+    return $mountPoint
+}
+
+proc vfs::urltype::handler {type cmd root relative actualpath args} {
+    ::vfs::log [list urltype $type $cmd $root $relative $actualpath $args]
+    if {[string length $relative]} {
+       # Find the highest level path so we can mount it:
+       set pathSplit [file split [file join $root $relative]]
+       set newRoot [eval [list file join] [lrange $pathSplit 0 1]]
+       ::vfs::log [list $newRoot $pathSplit]
+       # Get the package we will need
+       ::package require vfs::${type}
+       # Mount it.
+       ::vfs::${type}::Mount $newRoot $newRoot
+       # Now we want to find out the right handler
+       set typeHandler [::vfs::filesystem info $newRoot]
+       # Now we have to rearrange the root/relative for this path
+       set wholepath [eval [list file join] $pathSplit]
+       set newRelative [string range $wholepath [string length $newRoot] end]
+       if {[string index $newRelative 0] == "/"} {
+           set newRelative [string range $newRelative 1 end]
+       }
+       ::vfs::log [list $typeHandler $newRoot $newRelative]
+       eval $typeHandler [list $cmd $newRoot $newRelative $actualpath] $args
+    } else {
+       if {$cmd == "matchindirectory"} {
+           eval [list $cmd $type $root $relative $actualpath] $args
+       } else {
+           eval [list $cmd $type $root $relative] $args
+       }
+    }
+}
+
+# Stuff below not very well implemented, but works more or less.
+
+proc vfs::urltype::stat {type root name} {
+    ::vfs::log "stat $name"
+    if {![string length $name]} {
+       return [list type directory size 0 mode 0777 \
+         ino -1 depth 0 name $name atime 0 ctime 0 mtime 0 dev -1 \
+         uid -1 gid -1 nlink 1]
+       #return -code error "could not read \"$name\": no such file or directory"
+    } else {
+       error "Shouldn't get here"
+    }
+}
+
+proc vfs::urltype::open {type root name mode permissions} {
+    ::vfs::log "open $name $mode $permissions"
+    # There are no 'files' and everything is read-only
+    return -code error "illegal access mode \"$mode\""
+}
+
+proc vfs::urltype::access {type root name mode} {
+    ::vfs::log "access $name $mode"
+    if {![string length $name]} {
+       return 1
+    } else {
+       error "Shouldn't get here!"
+    }
+}
+
+proc vfs::urltype::matchindirectory {type root path actualpath pattern types} {
+    ::vfs::log [list matchindirectory $root $path $actualpath $pattern $types]
+
+    if {![vfs::matchDirectories $types]} { return [list] }
+
+    if {![string length $pattern]} {
+       return foo
+    }
+    
+    set res [list]
+    set len [string length $root]
+    
+    foreach m [::vfs::filesystem info] {
+       if {[string equal [string range $m 0 [expr {$len -1}]] $root]} {
+           set rest [string range $m $len end]
+           if {[string length $rest]} {
+               if {[string match $pattern $rest]} {
+                   lappend res "$m"
+               }
+           }
+       }
+    }
+    return $res
+}
+
+proc vfs::urltype::createdirectory {type root name} {
+    ::vfs::log "createdirectory $name"
+    # For ftp/http/file types we don't want to allow anything here.
+    error ""
+}
+
+proc vfs::urltype::removedirectory {type root name recursive} {
+    ::vfs::log "removedirectory $name"
+    # For ftp/http/file types we don't want to allow anything here.
+    error ""
+}
+
+proc vfs::urltype::deletefile {type root name} {
+    ::vfs::log "deletefile $name"
+    # For ftp/http/file types we don't want to allow anything here.
+    error ""
+}
+
+proc vfs::urltype::fileattributes {type root path args} {
+    ::vfs::log "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+           return [list]
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+       }
+    }
+}
+
+proc vfs::urltype::utime {type root name actime mtime} {
+    ::vfs::log "utime $name"
+    # For ftp/http/file types we don't want to allow anything here.
+    error ""
+}
diff --git a/8.x/tclvfs/library/vfsUtils.tcl b/8.x/tclvfs/library/vfsUtils.tcl
new file mode 100644 (file)
index 0000000..2a51bf2
--- /dev/null
@@ -0,0 +1,441 @@
+# vfsUtils.tcl --
+#
+# $Id: vfsUtils.tcl,v 1.28 2009/01/22 16:03:58 patthoyts Exp $
+
+package require Tcl 8.4
+package require vfs
+
+namespace eval ::vfs {
+    variable debug 0
+    if {[info exists ::env(VFS_DEBUG)]} {
+       set debug $::env(VFS_DEBUG)
+    }
+}
+
+# This can be overridden to use a different memchan implementation
+# With Tcl 8.6 will be overridden using [chan create] via vfslib.tcl
+proc ::vfs::memchan {args} {
+    ::package require Memchan
+    uplevel 1 [list ::memchan] $args
+}
+
+# This can be overridden to use a different crc implementation
+# With Tcl 8.6 will be overridden using [zlib crc32] via vfslib.tcl
+proc ::vfs::crc {args} {
+    ::package require crc32 ;# tcllib
+    uplevel 1 [linsert [linsert $args end-1 "--"] 0 ::crc::crc32]
+}
+
+# This can be overridden to use a different zip implementation
+# With Tcl 8.6 will be overridden using core zlib via vfslib.tcl
+proc ::vfs::zip {args} {
+    ::package require Trf
+    uplevel 1 [linsert [linsert $args end-1 "--"] 0 ::zip]
+}
+
+proc ::vfs::autoMountExtension {ext cmd {pkg ""}} {
+    variable extMounts
+    set extMounts($ext) [list $cmd $pkg]
+}
+
+proc ::vfs::autoMountUrl {type cmd {pkg ""}} {
+    variable urlMounts
+    set urlMounts($type) [list $cmd $pkg]
+}
+
+proc ::vfs::log {msg {lvl 0}} {
+    if {$lvl < ${::vfs::debug}} {
+       #tclLog "vfs($lvl): $msg"
+       puts stderr $msg
+    }
+}
+
+proc ::vfs::RegisterMount {mountpoint unmountcmd} {
+    variable _unmountCmd
+    set _unmountCmd([file normalize $mountpoint]) $unmountcmd
+}
+
+proc ::vfs::unmount {mountpoint} {
+    variable _unmountCmd
+    set norm [file normalize $mountpoint]
+    uplevel \#0 $_unmountCmd($norm) [list $norm]
+    unset _unmountCmd($norm)
+}
+
+proc vfs::states {} {
+    return [list "readwrite" "translucent" "readonly"]
+}
+
+# vfs::attributes mountpoint ?-opt val? ?...-opt val?
+proc ::vfs::attributes {mountpoint args} {
+    set handler [::vfs::filesystem info $mountpoint]
+    
+    set res {}
+    
+    if {[regsub -- "::handler" $handler ::attributes cmd]} {
+       set attrs [eval $cmd]
+    } else {
+       return -code error "No known attributes"
+    }
+
+    if {![llength $args]} {
+       foreach attr $attrs {
+           regsub -- "::handler" $handler ::$attr cmd
+           if {[catch $cmd val]} {
+               return -code error "error reading filesystem attribute\
+                 \"$attr\": $val"
+           } else {
+               lappend res -$attr $val
+           }
+       }
+       return $res
+    }
+    
+    while {[llength $args] > 1} {
+       set attr [string range [lindex $args 0] 1 end]
+       set val [lindex $args 1]
+       set args [lrange $args 2 end]
+       regsub -- "::handler" $handler ::$attr cmd
+       if {[catch {eval $cmd [list $val]} err]} {
+           return -code error "error setting filesystem attribute\
+             \"$attr\": $err"
+       } else {
+           set res $val
+       }
+    }
+    if {[llength $args]} {
+       set attr [string range [lindex $args 0] 1 end]
+       regsub -- "::handler" $handler ::$attr cmd
+       if {[catch $cmd val]} {
+           return -code error "error reading filesystem attribute\
+             \"$attr\": $val"
+       } else {
+           set res $val
+       }
+    }
+    return $res
+}
+
+proc vfs::attributeCantConfigure {attr val largs} {
+    switch -- [llength $largs] {
+       0 {
+           return $val
+       }
+       1 {
+           return -code error "Can't set $attr"
+       }
+       default {
+           return -code error "Wrong num args"
+       }
+    }
+}
+
+::vfs::autoMountExtension "" ::vfs::mk4::Mount vfs::mk4
+::vfs::autoMountExtension .bin ::vfs::mk4::Mount vfs::mk4
+::vfs::autoMountExtension .kit ::vfs::mk4::Mount vfs::mk4
+::vfs::autoMountExtension .tar ::vfs::tar::Mount vfs::tar
+::vfs::autoMountExtension .zip ::vfs::zip::Mount vfs::zip
+::vfs::autoMountUrl ftp ::vfs::ftp::Mount vfs::ftp
+::vfs::autoMountUrl file ::vfs::fileUrlMount vfs
+::vfs::autoMountUrl tclns ::vfs::tclprocMount vfs::ns
+
+proc ::vfs::haveMount {url} {
+    variable mounted
+    info exists mounted($url)
+}
+
+proc ::vfs::urlMount {url args} {
+    ::vfs::log "$url $args"
+    variable urlMounts
+    if {[regexp {^([a-zA-Z]+)://(.*)} $url "" urltype rest]} {
+       if {[info exists urlMounts($urltype)]} {
+           #::vfs::log "automounting $path"
+           foreach {cmd pkg} $urlMounts($urltype) {}
+           if {[string length $pkg]} {
+               package require $pkg
+           }
+           eval $cmd [list $url] $args
+           variable mounted
+           set mounted($url) 1
+           return
+       }
+       return -code error "Unknown url type '$urltype'"
+    }
+    return -code error "Couldn't parse url $url"
+}
+
+proc ::vfs::fileUrlMount {url args} {
+    # Strip off the leading 'file://'
+    set file [string range $url 7 end]
+    eval [list ::vfs::auto $file] $args
+}
+
+proc ::vfs::tclprocMount {url args} {
+    # Strip off the leading 'tclns://'
+    set ns [string range $url 8 end]
+    eval [list ::vfs::tclproc::Mount $ns] $args
+}
+
+proc ::vfs::auto {filename args} {
+    variable extMounts
+    
+    set np {}
+    set split [::file split $filename]
+    
+    foreach ele $split {
+       lappend np $ele
+       set path [::file normalize [eval [list ::file join] $np]]
+       if {[::file isdirectory $path]} {
+           # already mounted
+           continue
+       } elseif {[::file isfile $path]} {
+           set ext [string tolower [::file extension $ele]]
+           if {[::info exists extMounts($ext)]} {
+               #::vfs::log "automounting $path"
+               foreach {cmd pkg} $extMounts($ext) {}
+               if {[string length $pkg]} {
+                   package require $pkg
+               }
+               eval $cmd [list $path $path] $args
+           } else {
+               continue
+           }
+       } else {
+           # It doesn't exist, so just return
+           # return -code error "$path doesn't exist"
+           return
+       }
+    }
+}
+
+# Helper procedure for vfs matchindirectory
+# implementations.  It is very important that
+# we match properly when given 'directory'
+# specifications, since this is used for
+# recursive globbing by Tcl.
+proc vfs::matchCorrectTypes {types filelist {inDir ""}} {
+    if {$types != 0} {
+       # Which types to return.  We must do special
+       # handling of directories and files.
+       set file [matchFiles $types]
+       set dir [matchDirectories $types]
+       if {$file && $dir} {
+           return $filelist
+       }
+       if {$file == 0 && $dir == 0} {
+           return [list]
+       }
+       set newres [list]
+       set subcmd [expr {$file ? "isfile" : "isdirectory"}]
+       if {[string length $inDir]} {
+           foreach r $filelist {
+               if {[::file $subcmd [file join $inDir $r]]} {
+                   lappend newres $r
+               }
+           }
+       } else {
+           foreach r $filelist {
+               if {[::file $subcmd $r]} {
+                   lappend newres $r
+               }
+           }
+       }
+       set filelist $newres
+    }
+    return $filelist
+}
+
+# Convert integer mode to a somewhat preferable string.
+proc vfs::accessMode {mode} {
+    lindex [list F X W XW R RX RW] $mode
+}
+
+proc vfs::matchDirectories {types} {
+    return [expr {$types == 0 ? 1 : $types & (1<<2)}]
+}
+
+proc vfs::matchFiles {types} {
+    return [expr {$types == 0 ? 1 : $types & (1<<4)}]
+}
+
+proc vfs::modeToString {mode} {
+    # Turn a POSIX open 'mode' set of flags into a more readable
+    # string 'r', 'w', 'w+', 'a', etc.
+    set res ""
+    if {$mode & 1} {
+       append res "r"
+    } elseif {$mode & 2} {
+       if {$mode & 16} {
+           append res "w"
+       } else {
+           append res "a"
+       }
+    }
+    if {$mode & 4} {
+       append res "+"
+    }
+    set res
+}
+
+# These lists are used to convert attribute indices into the string equivalent.
+# They are copied from Tcl's C sources.  There is no need for them to be
+# the same as in the native filesystem; we can use completely different
+# attribute sets.  However some items, like '-longname' it is probably
+# best to implement.
+set vfs::attributes(windows) [list -archive -hidden -longname -readonly -shortname -system -vfs]
+set vfs::attributes(macintosh) [list -creator -hidden -readonly -type -vfs]
+set vfs::attributes(unix) [list -group -owner -permissions -vfs]
+
+proc vfs::listAttributes {} {
+    variable attributes
+    global tcl_platform
+    set attributes($tcl_platform(platform))
+}
+
+proc vfs::indexToAttribute {idx} {
+    return [lindex [listAttributes] $idx]
+}
+
+proc vfs::attributesGet {root stem index} {
+    # Return standard Tcl result, or error.
+    set attribute [indexToAttribute $index]
+    switch -- $attribute {
+       "-longname" {
+           # We always use the normalized form!
+           return [file join $root $stem]
+       }
+       "-shortname" {
+           set rootdir [file attributes [file dirname $root] -shortname]
+           return [file join $rootdir [file tail $root] $stem]
+       }
+       "-archive" {
+           return 0
+       }
+       "-hidden" {
+           return 0
+       }
+       "-readonly" {
+           return 0
+       }
+       "-system" {
+           return 0
+       }
+       "-vfs" {
+           return 1
+       }
+       "-owner" {
+           return
+       }
+       "-group" {
+           return
+       }
+    }
+}
+
+proc vfs::attributesSet {root stem index val} {
+    # Return standard Tcl result, or error.
+    set attribute [indexToAttribute $index]
+    #::vfs::log "$attribute"
+    switch -- $attribute {
+       "-owner"   -
+       "-group"   -
+       "-archive" -
+       "-hidden"  -
+       "-permissions" {
+           return
+       }
+       "-longname" {
+           return -code error "no such luck"
+       }
+       "-vfs" {
+           return -code error "read-only"
+       }
+    }
+}
+
+proc vfs::posixError {name} {
+    variable posix
+    return $posix($name)
+}
+
+set vfs::posix(EPERM)          1       ;# Operation not permitted
+set vfs::posix(ENOENT)         2       ;# No such file or directory
+set vfs::posix(ESRCH)          3       ;# No such process
+set vfs::posix(EINTR)          4       ;# Interrupted system call
+set vfs::posix(EIO)            5       ;# Input/output error
+set vfs::posix(ENXIO)          6       ;# Device not configured
+set vfs::posix(E2BIG)          7       ;# Argument list too long
+set vfs::posix(ENOEXEC)                8       ;# Exec format error
+set vfs::posix(EBADF)          9       ;# Bad file descriptor
+set vfs::posix(ECHILD)         10      ;# No child processes
+set vfs::posix(EDEADLK)                11      ;# Resource deadlock avoided
+                                       ;# 11 was EAGAIN
+set vfs::posix(ENOMEM)         12      ;# Cannot allocate memory
+set vfs::posix(EACCES)         13      ;# Permission denied
+set vfs::posix(EFAULT)         14      ;# Bad address
+set vfs::posix(ENOTBLK)                15      ;# Block device required
+set vfs::posix(EBUSY)          16      ;# Device busy
+set vfs::posix(EEXIST)         17      ;# File exists
+set vfs::posix(EXDEV)          18      ;# Cross-device link
+set vfs::posix(ENODEV)         19      ;# Operation not supported by device
+set vfs::posix(ENOTDIR)                20      ;# Not a directory
+set vfs::posix(EISDIR)         21      ;# Is a directory
+set vfs::posix(EINVAL)         22      ;# Invalid argument
+set vfs::posix(ENFILE)         23      ;# Too many open files in system
+set vfs::posix(EMFILE)         24      ;# Too many open files
+set vfs::posix(ENOTTY)         25      ;# Inappropriate ioctl for device
+set vfs::posix(ETXTBSY)                26      ;# Text file busy
+set vfs::posix(EFBIG)          27      ;# File too large
+set vfs::posix(ENOSPC)         28      ;# No space left on device
+set vfs::posix(ESPIPE)         29      ;# Illegal seek
+set vfs::posix(EROFS)          30      ;# Read-only file system
+set vfs::posix(EMLINK)         31      ;# Too many links
+set vfs::posix(EPIPE)          32      ;# Broken pipe
+set vfs::posix(EDOM)           33      ;# Numerical argument out of domain
+set vfs::posix(ERANGE)         34      ;# Result too large
+set vfs::posix(EAGAIN)         35      ;# Resource temporarily unavailable
+set vfs::posix(EWOULDBLOCK)    35      ;# Operation would block
+set vfs::posix(EINPROGRESS)    36      ;# Operation now in progress
+set vfs::posix(EALREADY)       37      ;# Operation already in progress
+set vfs::posix(ENOTSOCK)       38      ;# Socket operation on non-socket
+set vfs::posix(EDESTADDRREQ)   39      ;# Destination address required
+set vfs::posix(EMSGSIZE)       40      ;# Message too long
+set vfs::posix(EPROTOTYPE)     41      ;# Protocol wrong type for socket
+set vfs::posix(ENOPROTOOPT)    42      ;# Protocol not available
+set vfs::posix(EPROTONOSUPPORT)        43      ;# Protocol not supported
+set vfs::posix(ESOCKTNOSUPPORT)        44      ;# Socket type not supported
+set vfs::posix(EOPNOTSUPP)     45      ;# Operation not supported on socket
+set vfs::posix(EPFNOSUPPORT)   46      ;# Protocol family not supported
+set vfs::posix(EAFNOSUPPORT)   47      ;# Address family not supported by protocol family
+set vfs::posix(EADDRINUSE)     48      ;# Address already in use
+set vfs::posix(EADDRNOTAVAIL)  49      ;# Can't assign requested address
+set vfs::posix(ENETDOWN)       50      ;# Network is down
+set vfs::posix(ENETUNREACH)    51      ;# Network is unreachable
+set vfs::posix(ENETRESET)      52      ;# Network dropped connection on reset
+set vfs::posix(ECONNABORTED)   53      ;# Software caused connection abort
+set vfs::posix(ECONNRESET)     54      ;# Connection reset by peer
+set vfs::posix(ENOBUFS)                55      ;# No buffer space available
+set vfs::posix(EISCONN)                56      ;# Socket is already connected
+set vfs::posix(ENOTCONN)       57      ;# Socket is not connected
+set vfs::posix(ESHUTDOWN)      58      ;# Can't send after socket shutdown
+set vfs::posix(ETOOMANYREFS)   59      ;# Too many references: can't splice
+set vfs::posix(ETIMEDOUT)      60      ;# Connection timed out
+set vfs::posix(ECONNREFUSED)   61      ;# Connection refused
+set vfs::posix(ELOOP)          62      ;# Too many levels of symbolic links
+set vfs::posix(ENAMETOOLONG)   63      ;# File name too long
+set vfs::posix(EHOSTDOWN)      64      ;# Host is down
+set vfs::posix(EHOSTUNREACH)   65      ;# No route to host
+set vfs::posix(ENOTEMPTY)      66      ;# Directory not empty
+set vfs::posix(EPROCLIM)       67      ;# Too many processes
+set vfs::posix(EUSERS)         68      ;# Too many users
+set vfs::posix(EDQUOT)         69      ;# Disc quota exceeded
+set vfs::posix(ESTALE)         70      ;# Stale NFS file handle
+set vfs::posix(EREMOTE)                71      ;# Too many levels of remote in path
+set vfs::posix(EBADRPC)                72      ;# RPC struct is bad
+set vfs::posix(ERPCMISMATCH)   73      ;# RPC version wrong
+set vfs::posix(EPROGUNAVAIL)   74      ;# RPC prog. not avail
+set vfs::posix(EPROGMISMATCH)  75      ;# Program version wrong
+set vfs::posix(EPROCUNAVAIL)   76      ;# Bad procedure for program
+set vfs::posix(ENOLCK)         77      ;# No locks available
+set vfs::posix(ENOSYS)         78      ;# Function not implemented
+set vfs::posix(EFTYPE)         79      ;# Inappropriate file type or format
diff --git a/8.x/tclvfs/library/vfslib.tcl b/8.x/tclvfs/library/vfslib.tcl
new file mode 100644 (file)
index 0000000..c03d05c
--- /dev/null
@@ -0,0 +1,276 @@
+# Remnants of what used to be VFS init. This uses either the 8.6 core zlib
+# command or the tclkit zlib package with rechan to provide a memory channel
+# and a streaming decompression channel transform.
+
+package require Tcl 8.4; # vfs is all new for 8.4
+package provide vfslib 1.4
+
+# use zlib to define zip and crc if available
+if {[llength [info command zlib]] || ![catch {load "" zlib}]} {
+    proc vfs::zip {flag value args} {
+       switch -glob -- "$flag $value" {
+           {-mode d*} { set mode decompress }
+           {-mode c*} { set mode compress }
+           default { error "usage: zip -mode {compress|decompress} data" }
+       }
+       # kludge to allow "-nowrap 1" as second option, 5-9-2002
+       if {[llength $args] > 2 && [lrange $args 0 1] eq "-nowrap 1"} {
+           if {$mode eq "compress"} {
+               set mode deflate
+           } else {
+               set mode inflate
+           }
+       }
+       return [zlib $mode [lindex $args end]]
+    }
+
+    proc vfs::crc {data} {
+       return [zlib crc32 $data]
+    }
+}
+
+# Use 8.6 reflected channels or the rechan package in earlier versions to
+# provide a memory channel implementation.
+#
+if {[info command ::chan] ne {}} {
+
+    # As the core zlib channel stacking make non-seekable channels we cannot
+    # implement vfs::zstream and this feature is disabled in tclkit boot.tcl
+    # when the command is not present (it is only used by mk4vfs)
+    #
+    #proc vfs::zstream {mode ifd clen ilen} {
+    #    return -code error "vfs::zstream is unsupported with core zlib"
+    #}
+    proc vfs::memchan {{filename {}}} {
+        return [chan create {read write} \
+                    [list [namespace origin _memchan_handler] $filename]]
+    }
+    proc vfs::_memchan_handler {filename cmd chan args} {
+        upvar #0 ::vfs::_memchan(buf,$chan) buf
+        upvar #0 ::vfs::_memchan(pos,$chan) pos
+        upvar #0 ::vfs::_memchan(name,$chan) name
+        upvar #0 ::vfs::_memchan(timer) timer
+        switch -exact -- $cmd {
+            initialize {
+                foreach {mode} $args break
+                set buf ""
+                set pos 0
+                set watch {}
+                set name $filename
+                if {![info exists timer]} { set timer "" }
+                return {initialize finalize watch read write seek cget cgetall}
+            }
+            finalize {
+                unset buf pos name
+            }
+            seek {
+                foreach {offset base} $args break
+                switch -exact -- $base {
+                    current { incr offset $pos }
+                    end     { incr offset [string length $buf] }
+                }
+                if {$offset < 0} {
+                    return -code error "error during seek on \"$chan\":\
+                        invalid argument"
+                } elseif {$offset > [string length $buf]} {
+                    set extend [expr {$offset - [string length $buf]}]
+                    append buf [binary format @$extend]
+                }
+                return [set pos $offset]
+            }
+            read {
+                foreach {count} $args break
+                set r [string range $buf $pos [expr {$pos + $count - 1}]]
+                incr pos [string length $r]
+                return $r
+            }
+            write {
+                foreach {data} $args break
+               set count [string length $data]
+               if { $pos >= [string length $buf] } {
+                   append buf $data
+               } else {
+                   set last [expr { $pos + $count - 1 }]
+                   set buf [string replace $buf $pos $last $data]
+               }
+               incr pos $count
+               return $count
+            }
+            cget {
+                foreach {option} $args break
+                switch -exact -- $option {
+                    -length { return [string length $buf] }
+                    -allocated { return [string length $buf] }
+                    default {
+                        return -code error "bad option \"$option\":\
+                            should be one of -blocking, -buffering,\
+                            -buffersize, -encoding, -eofchar, -translation,\
+                            -length or -allocated" 
+                    }
+                }
+            }
+            cgetall {
+                return [list -length [string length $buf] \
+                            -allocated [string length $buf]]
+            }
+            watch {
+                foreach {eventspec} $args break
+                after cancel $timer
+                foreach event {read write} {
+                    upvar #0 ::vfs::_memchan(watch,$event) watch
+                    if {![info exists watch]} { set watch {} }
+                    set ndx [lsearch -exact $watch $chan]
+                    if {$event in $eventspec} {
+                        if {$ndx == -1} { lappend watch $chan }
+                    } else {
+                        if {$ndx != -1} {
+                            set watch [lreplace $watch $ndx $ndx]
+                        }
+                    }
+                }
+                set timer [after 10 [list ::vfs::_memchan_timer]]
+            }
+        }
+    }
+    # memchan channels are always writable and always readable
+    proc ::vfs::_memchan_timer {} {
+        set continue 0
+        foreach event {read write} {
+            upvar #0 ::vfs::_memchan(watch,$event) watch
+            incr continue [llength $watch]
+            foreach chan $watch { chan postevent $chan $event }
+        }
+        if {$continue > 0} {
+            set ::vfs::_memchan(timer) [after 10 [info level 0]]
+        }
+    }
+
+} elseif {[info command rechan] ne "" || ![catch {load "" rechan}]} {
+
+    proc vfs::memchan_handler {cmd fd args} {
+       upvar 1 ::vfs::_memchan_buf($fd) buf
+       upvar 1 ::vfs::_memchan_pos($fd) pos
+        upvar 1 ::vfs::_memchan_nam($fd) nam
+       set arg1 [lindex $args 0]
+
+       switch -- $cmd {
+           seek {
+               switch [lindex $args 1] {
+                   1 - current { incr arg1 $pos }
+                   2 - end { incr arg1 [string length $buf]}
+               }
+               return [set pos $arg1]
+           }
+           read {
+               set r [string range $buf $pos [expr { $pos + $arg1 - 1 }]]
+               incr pos [string length $r]
+               return $r
+           }
+           write {
+               set n [string length $arg1]
+               if { $pos >= [string length $buf] } {
+                   append buf $arg1
+               } else { # the following doesn't work yet :(
+                   set last [expr { $pos + $n - 1 }]
+                   set buf [string replace $buf $pos $last $arg1]
+                   error "vfs memchan: sorry no inline write yet"
+               }
+               incr pos $n
+               return $n
+           }
+           close {
+               unset buf pos nam
+           }
+           default { error "bad cmd in memchan_handler: $cmd" }
+       }
+    }
+
+    proc vfs::memchan {{filename {}}} {
+       set fd [rechan ::vfs::memchan_handler 6]
+       set ::vfs::_memchan_buf($fd) ""
+       set ::vfs::_memchan_pos($fd) 0
+        set ::vfs::_memchan_nam($fd) $filename
+       return $fd
+    }
+
+    proc vfs::zstream_handler {zcmd ifd clen ilen imode cmd fd {a1 ""} {a2 ""}} {
+       #puts stderr "z $zcmd $ifd $ilen $cmd $fd $a1 $a2"
+       upvar ::vfs::_zstream_pos($fd) pos
+
+       switch -- $cmd {
+           seek {
+               switch $a2 {
+                   1 - current { incr a1 $pos }
+                   2 - end { incr a1 $ilen }
+               }
+               # to seek back, rewind, i.e. start from scratch
+               if {$a1 < $pos} {
+                   rename $zcmd ""
+                   zlib $imode $zcmd
+                   seek $ifd 0
+                   set pos 0
+               }
+               # consume data while not yet at seek position
+               while {$pos < $a1} {
+                   set n [expr {$a1 - $pos}]
+                   if {$n > 4096} { set n 4096 }
+                   # 2003-02-09: read did not work (?), spell it out instead
+                   #read $fd $n
+                   zstream_handler $zcmd $ifd $clen $ilen $imode read $fd $n
+               }
+               return $pos
+           }
+           read {
+               set r ""
+               set n $a1
+               #puts stderr " want $n z $zcmd pos $pos ilen $ilen"
+               if {$n + $pos > $ilen} { set n [expr {$ilen - $pos}] }
+               while {$n > 0} {
+                   if {[$zcmd fill] == 0} {
+                       set c [expr {$clen - [tell $ifd]}]
+                       if {$c > 4096} { set c 4096 }
+                       set data [read $ifd $c]
+                       #puts "filled $c [string length $data]"
+                       $zcmd fill $data
+                   }
+                   set data [$zcmd drain $n]
+                   #puts stderr " read [string length $data]"
+                   if {$data eq ""} break
+                   append r $data
+                   incr pos [string length $data]
+                   incr n -[string length $data]
+               }
+               return $r
+           }
+           close {
+               rename $zcmd ""
+               close $ifd
+               unset pos
+           }
+           default { error "bad cmd in zstream_handler: $cmd" }
+       }
+    }
+
+    variable ::vfs::zseq 0     ;# used to generate temp zstream cmd names
+
+    # vfs::zstream -- 
+    #
+    #  Create a read-only seekable compressed channel using rechan and
+    #  the streaming mode of tclkit's zlib extension.
+    #
+    #    mode - compress or decompress
+    #    ifd  - input channel (should be binary)
+    #    clen - size of compressed data in bytes
+    #    ilen - size of decompressed data in bytes
+    #
+    proc vfs::zstream {mode ifd clen ilen} {
+        set cname _zstream_[incr ::vfs::zseq]
+        zlib s$mode $cname
+        fconfigure $ifd -translation binary
+        set cmd [list ::vfs::zstream_handler $cname $ifd $clen $ilen s$mode]
+        set fd [rechan $cmd 2]
+        set ::vfs::_zstream_pos($fd) 0
+        return $fd
+    }
+}
+
diff --git a/8.x/tclvfs/library/webdavvfs.tcl b/8.x/tclvfs/library/webdavvfs.tcl
new file mode 100644 (file)
index 0000000..d22d67a
--- /dev/null
@@ -0,0 +1,285 @@
+
+package provide vfs::webdav 0.1
+
+package require vfs 1.0
+package require http 2.6
+# part of tcllib
+package require base64
+
+# This works for very basic operations.
+# It has been put together, so far, largely by trial and error!
+# What it really needs is to be filled in with proper xml support,
+# using the tclxml package.
+
+namespace eval vfs::webdav {}
+
+proc vfs::webdav::Mount {dirurl local} {
+    ::vfs::log "http-vfs: attempt to mount $dirurl at $local"
+    if {[string index $dirurl end] != "/"} {
+       append dirurl "/"
+    }
+    if {[string range $dirurl 0 6] == "http://"} {
+       set rest [string range $dirurl 7 end]
+    } else {
+       set rest $dirurl
+       set dirurl "http://${dirurl}"
+    }
+    
+    if {![regexp {(([^:]*)(:([^@]*))?@)?([^/]*)(/(.*/)?([^/]*))?$} $rest \
+           junk junk user junk pass host junk path file]} {
+       return -code error "Sorry I didn't understand\
+         the url address \"$dirurl\""
+    }
+    
+    if {[string length $file]} {
+       return -code error "Can only mount directories, not\
+         files (perhaps you need a trailing '/' - I understood\
+         a path '$path' and file '$file')"
+    }
+    
+    if {![string length $user]} {
+       set user anonymous
+    }
+    
+    set dirurl "http://$host/$path"
+    
+    set extraHeadersList [list Authorization \
+           [list Basic [base64::encode ${user}:${pass}]]]
+
+    set token [::http::geturl $dirurl -headers $extraHeadersList -validate 1]
+    http::cleanup $token
+    
+    if {![catch {vfs::filesystem info $dirurl}]} {
+       # unmount old mount
+       ::vfs::log "ftp-vfs: unmounted old mount point at $dirurl"
+       vfs::unmount $dirurl
+    }
+    ::vfs::log "http $host, $path mounted at $local"
+    vfs::filesystem mount $local [list vfs::webdav::handler \
+           $dirurl $extraHeadersList $path]
+    # Register command to unmount
+    vfs::RegisterMount $local [list ::vfs::webdav::Unmount $dirurl]
+    return $dirurl
+}
+
+proc vfs::webdav::Unmount {dirurl local} {
+    vfs::filesystem unmount $local
+}
+
+proc vfs::webdav::handler {dirurl extraHeadersList path cmd root relative actualpath args} {
+    ::vfs::log "handler $dirurl $path $cmd"
+    if {$cmd == "matchindirectory"} {
+       eval [list $cmd $dirurl $extraHeadersList $relative $actualpath] $args
+    } else {
+       eval [list $cmd $dirurl $extraHeadersList $relative] $args
+    }
+}
+
+# If we implement the commands below, we will have a perfect
+# virtual file system for remote http sites.
+
+proc vfs::webdav::stat {dirurl extraHeadersList name} {
+    ::vfs::log "stat $name"
+    
+    # get information on the type of this file.  
+    if {$name == ""} {
+       set mtime 0
+       lappend res type directory
+       lappend res dev -1 uid -1 gid -1 nlink 1 depth 0 \
+         atime $mtime ctime $mtime mtime $mtime mode 0777
+       return $res
+    }
+    
+    # This is a bit of a hack.  We really want to do a 'PROPFIND'
+    # request with depth 0, I believe.  I don't think Tcl's http
+    # package supports that.
+    set token [::http::geturl $dirurl$name -method PROPFIND \
+      -headers [concat $extraHeadersList [list Depth 0]] -protocol 1.1]
+    upvar #0 $token state
+
+    if {![regexp " (OK|Multi\\-Status)$" $state(http)]} {
+       ::vfs::log "No good: $state(http)"
+       #parray state
+       ::http::cleanup $token
+       error "Not found"
+    }
+    
+    regexp {<D:prop>(.*)</D:prop>} [::http::data $token] -> properties
+    if {[regexp {<D:resourcetype><D:collection/>} $properties]} {
+       set type directory
+    } else {
+       set type file
+    }
+    
+    #parray state
+    set mtime 0
+
+    lappend res type $type
+    lappend res dev -1 uid -1 gid -1 nlink 1 depth 0 \
+      atime $mtime ctime $mtime mtime $mtime mode 0777 \
+      size $state(totalsize)
+
+    ::http::cleanup $token
+    return $res
+}
+
+proc vfs::webdav::access {dirurl extraHeadersList name mode} {
+    ::vfs::log "access $name $mode"
+    if {$name == ""} { return 1 }
+    set token [::http::geturl $dirurl$name -headers $extraHeadersList]
+    upvar #0 $token state
+    if {![regexp " (OK|Moved Permanently)$" $state(http)]} {
+       ::vfs::log "No good: $state(http)"
+       ::http::cleanup $token
+       error "Not found"
+    } else {
+       ::http::cleanup $token
+       return 1
+    }
+}
+
+# We've chosen to implement these channels by using a memchan.
+# The alternative would be to use temporary files.
+proc vfs::webdav::open {dirurl extraHeadersList name mode permissions} {
+    ::vfs::log "open $name $mode $permissions"
+    # return a list of two elements:
+    # 1. first element is the Tcl channel name which has been opened
+    # 2. second element (optional) is a command to evaluate when
+    #    the channel is closed.
+    switch -glob -- $mode {
+       "" -
+       "r" {
+           set token [::http::geturl $dirurl$name -headers $extraHeadersList]
+           upvar #0 $token state
+
+           set filed [vfs::memchan]
+            fconfigure $filed -encoding binary -translation binary
+           puts -nonewline $filed [::http::data $token]
+           seek $filed 0
+           ::http::cleanup $token
+           return [list $filed]
+       }
+       "a" -
+       "w*" {
+           error "Can't open $name for writing"
+       }
+       default {
+           return -code error "illegal access mode \"$mode\""
+       }
+    }
+}
+
+proc vfs::webdav::matchindirectory {dirurl extraHeadersList path actualpath pattern type} {
+    ::vfs::log "matchindirectory $dirurl $path $actualpath $pattern $type"
+    set res [list]
+
+    if {[string length $pattern]} {
+       # need to match all files in a given remote http site.
+       set token [::http::geturl $dirurl$path -method PROPFIND \
+         -headers [concat $extraHeadersList [list Depth 1]]]
+       upvar #0 $token state
+       #parray state
+
+       set body [::http::data $token]
+       ::http::cleanup $token
+       #::vfs::log $body
+       while {1} {
+           set start [string first "<D:response" $body]
+           set end [string first "</D:response" $body]
+           if {$start == -1 || $end == -1} { break }
+           set item [string range $body $start $end]
+           set body [string range $body [expr {$end + 12}] end]
+           if {![regexp "<D:href>(.*)</D:href>" $item -> name]} {
+               continue
+           }
+           # Get tail of name (don't use 'file tail' since it isn't a file).
+           vfs::log "checking: $name"
+           regexp {[^/]+/?$} $name name
+           if {$name == ""} { continue }
+           if {[string match $pattern $name]} {
+               vfs::log "check: $name"
+               if {$type == 0} {
+                   lappend res [file join $actualpath $name]
+               } else {
+                   eval lappend res [_matchtypes $item \
+                     [file join $actualpath $name] $type]
+               }
+           }
+           #vfs::log "got: $res"
+       }
+    } else {
+       # single file
+       set token [::http::geturl $dirurl$path -method PROPFIND \
+         -headers [concat $extraHeadersList [list Depth 0]]]
+       
+       upvar #0 $token state
+       if {![regexp " (OK|Multi\\-Status)$" $state(http)]} {
+           ::vfs::log "No good: $state(http)"
+           #parray state
+           ::http::cleanup $token
+           return ""
+       }
+       set body [::http::data $token]
+       ::http::cleanup $token
+       #::vfs::log $body
+       
+       eval lappend res [_matchtypes $body $actualpath $type]
+    }
+    
+    return $res
+}
+
+# Helper function
+proc vfs::webdav::_matchtypes {item actualpath type} {
+    #::vfs::log [list $item $actualpath $type]
+    if {[regexp {<D:resourcetype><D:collection/>} $item]} {
+       if {![::vfs::matchDirectories $type]} {
+           return ""
+       }
+    } else {
+       if {![::vfs::matchFiles $type]} {
+           return ""
+       }
+    }
+    return [list $actualpath]
+}
+
+proc vfs::webdav::createdirectory {dirurl extraHeadersList name} {
+    ::vfs::log "createdirectory $name"
+    error "write access not implemented"
+}
+
+proc vfs::webdav::removedirectory {dirurl extraHeadersList name recursive} {
+    ::vfs::log "removedirectory $name"
+    error "write access not implemented"
+}
+
+proc vfs::webdav::deletefile {dirurl extraHeadersList name} {
+    ::vfs::log "deletefile $name"
+    error "write access not implemented"
+}
+
+proc vfs::webdav::fileattributes {dirurl extraHeadersList path args} {
+    ::vfs::log "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+           return [list]
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+           error "write access not implemented"
+       }
+    }
+}
+
+proc vfs::webdav::utime {dirurl extraHeadersList path actime mtime} {
+    error "write access not implemented"
+}
+
diff --git a/8.x/tclvfs/library/zipvfs.tcl b/8.x/tclvfs/library/zipvfs.tcl
new file mode 100644 (file)
index 0000000..45cfbed
--- /dev/null
@@ -0,0 +1,602 @@
+# Removed provision of the backward compatible name. Moved to separate
+# file/package.
+package provide vfs::zip 1.0.3
+
+package require vfs
+
+# Using the vfs, memchan and Trf extensions, we ought to be able
+# to write a Tcl-only zip virtual filesystem.  What we have below
+# is basically that.
+
+namespace eval vfs::zip {}
+
+# Used to execute a zip archive.  This is rather like a jar file
+# but simpler.  We simply mount it and then source a toplevel
+# file called 'main.tcl'.
+proc vfs::zip::Execute {zipfile} {
+    Mount $zipfile $zipfile
+    source [file join $zipfile main.tcl]
+}
+
+proc vfs::zip::Mount {zipfile local} {
+    set fd [::zip::open [::file normalize $zipfile]]
+    vfs::filesystem mount $local [list ::vfs::zip::handler $fd]
+    # Register command to unmount
+    vfs::RegisterMount $local [list ::vfs::zip::Unmount $fd]
+    return $fd
+}
+
+proc vfs::zip::Unmount {fd local} {
+    vfs::filesystem unmount $local
+    ::zip::_close $fd
+}
+
+proc vfs::zip::handler {zipfd cmd root relative actualpath args} {
+    #::vfs::log [list $zipfd $cmd $root $relative $actualpath $args]
+    if {$cmd == "matchindirectory"} {
+       eval [list $cmd $zipfd $relative $actualpath] $args
+    } else {
+       eval [list $cmd $zipfd $relative] $args
+    }
+}
+
+proc vfs::zip::attributes {zipfd} { return [list "state"] }
+proc vfs::zip::state {zipfd args} {
+    vfs::attributeCantConfigure "state" "readonly" $args
+}
+
+# If we implement the commands below, we will have a perfect
+# virtual file system for zip files.
+
+proc vfs::zip::matchindirectory {zipfd path actualpath pattern type} {
+    #::vfs::log [list matchindirectory $path $actualpath $pattern $type]
+
+    # This call to zip::getdir handles empty patterns properly as asking
+    # for the existence of a single file $path only
+    set res [::zip::getdir $zipfd $path $pattern]
+    #::vfs::log "got $res"
+    if {![string length $pattern]} {
+       if {![::zip::exists $zipfd $path]} { return {} }
+       set res [list $actualpath]
+       set actualpath ""
+    }
+
+    set newres [list]
+    foreach p [::vfs::matchCorrectTypes $type $res $actualpath] {
+       lappend newres [file join $actualpath $p]
+    }
+    #::vfs::log "got $newres"
+    return $newres
+}
+
+proc vfs::zip::stat {zipfd name} {
+    #::vfs::log "stat $name"
+    ::zip::stat $zipfd $name sb
+    #::vfs::log [array get sb]
+    array get sb
+}
+
+proc vfs::zip::access {zipfd name mode} {
+    #::vfs::log "zip-access $name $mode"
+    if {$mode & 2} {
+       vfs::filesystem posixerror $::vfs::posix(EROFS)
+    }
+    # Readable, Exists and Executable are treated as 'exists'
+    # Could we get more information from the archive?
+    if {[::zip::exists $zipfd $name]} {
+       return 1
+    } else {
+       error "No such file"
+    }
+    
+}
+
+proc vfs::zip::open {zipfd name mode permissions} {
+    #::vfs::log "open $name $mode $permissions"
+    # return a list of two elements:
+    # 1. first element is the Tcl channel name which has been opened
+    # 2. second element (optional) is a command to evaluate when
+    #    the channel is closed.
+
+    switch -- $mode {
+       "" -
+       "r" {
+           if {![::zip::exists $zipfd $name]} {
+               vfs::filesystem posixerror $::vfs::posix(ENOENT)
+           }
+           
+           ::zip::stat $zipfd $name sb
+
+           set nfd [vfs::memchan]
+           fconfigure $nfd -translation binary
+
+           seek $zipfd $sb(ino) start
+           set data [zip::Data $zipfd sb 0]
+
+           puts -nonewline $nfd $data
+
+           fconfigure $nfd -translation auto
+           seek $nfd 0
+           return [list $nfd]
+       }
+       default {
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+    }
+}
+
+proc vfs::zip::createdirectory {zipfd name} {
+    #::vfs::log "createdirectory $name"
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
+
+proc vfs::zip::removedirectory {zipfd name recursive} {
+    #::vfs::log "removedirectory $name"
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
+
+proc vfs::zip::deletefile {zipfd name} {
+    #::vfs::log "deletefile $name"
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
+
+proc vfs::zip::fileattributes {zipfd name args} {
+    #::vfs::log "fileattributes $args"
+    switch -- [llength $args] {
+       0 {
+           # list strings
+           return [list]
+       }
+       1 {
+           # get value
+           set index [lindex $args 0]
+           return ""
+       }
+       2 {
+           # set value
+           set index [lindex $args 0]
+           set val [lindex $args 1]
+           vfs::filesystem posixerror $::vfs::posix(EROFS)
+       }
+    }
+}
+
+proc vfs::zip::utime {fd path actime mtime} {
+    vfs::filesystem posixerror $::vfs::posix(EROFS)
+}
+
+# Below copied from TclKit distribution
+
+#
+# ZIP decoder:
+#
+# See the ZIP file format specification:
+#   http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+#
+# Format of zip file:
+# [ Data ]* [ TOC ]* EndOfArchive
+#
+# Note: TOC is refered to in ZIP doc as "Central Archive"
+#
+# This means there are two ways of accessing:
+#
+# 1) from the begining as a stream - until the header
+#      is not "PK\03\04" - ideal for unzipping.
+#
+# 2) for table of contents without reading entire
+#      archive by first fetching EndOfArchive, then
+#      just loading the TOC
+#
+
+namespace eval zip {
+    array set methods {
+       0       {stored - The file is stored (no compression)}
+       1       {shrunk - The file is Shrunk}
+       2       {reduce1 - The file is Reduced with compression factor 1}
+       3       {reduce2 - The file is Reduced with compression factor 2}
+       4       {reduce3 - The file is Reduced with compression factor 3}
+       5       {reduce4 - The file is Reduced with compression factor 4}
+       6       {implode - The file is Imploded}
+       7       {reserved - Reserved for Tokenizing compression algorithm}
+       8       {deflate - The file is Deflated}
+       9       {reserved - Reserved for enhanced Deflating}
+       10      {pkimplode - PKWARE Date Compression Library Imploding}
+        11     {reserved - Reserved by PKWARE}
+        12     {bzip2 - The file is compressed using BZIP2 algorithm}
+        13     {reserved - Reserved by PKWARE}
+        14     {lzma - LZMA (EFS)}
+        15     {reserved - Reserved by PKWARE}
+    }
+    # Version types (high-order byte)
+    array set systems {
+       0       {dos}
+       1       {amiga}
+       2       {vms}
+       3       {unix}
+       4       {vm cms}
+       5       {atari}
+       6       {os/2}
+       7       {macos}
+       8       {z system 8}
+       9       {cp/m}
+       10      {tops20}
+       11      {windows}
+       12      {qdos}
+       13      {riscos}
+       14      {vfat}
+       15      {mvs}
+       16      {beos}
+       17      {tandem}
+       18      {theos}
+    }
+    # DOS File Attrs
+    array set dosattrs {
+       1       {readonly}
+       2       {hidden}
+       4       {system}
+       8       {unknown8}
+       16      {directory}
+       32      {archive}
+       64      {unknown64}
+       128     {normal}
+    }
+
+    proc u_short {n}  { return [expr { ($n+0x10000)%0x10000 }] }
+}
+
+proc zip::DosTime {date time} {
+    set time [u_short $time]
+    set date [u_short $date]
+
+    # time = fedcba9876543210
+    #        HHHHHmmmmmmSSSSS (sec/2 actually)
+
+    # data = fedcba9876543210
+    #        yyyyyyyMMMMddddd
+
+    set sec  [expr { ($time & 0x1F) * 2 }]
+    set min  [expr { ($time >> 5) & 0x3F }]
+    set hour [expr { ($time >> 11) & 0x1F }]
+
+    set mday [expr { $date & 0x1F }]
+    set mon  [expr { (($date >> 5) & 0xF) }]
+    set year [expr { (($date >> 9) & 0xFF) + 1980 }]
+
+    # Fix up bad date/time data, no need to fail
+    while {$sec  > 59} {incr sec  -60}
+    while {$min  > 59} {incr sec  -60}
+    while {$hour > 23} {incr hour -24}
+    if {$mday < 1}  {incr mday}
+    if {$mon  < 1}  {incr mon}
+    while {$mon > 12} {incr hour -12}
+
+    while {[catch {
+       set dt [format {%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d} \
+                   $year $mon $mday $hour $min $sec]
+       set res [clock scan $dt -gmt 1]
+    }]} {
+       # Only mday can be wrong, at end of month
+       incr mday -1
+    }
+    return $res
+}
+
+
+proc zip::Data {fd arr verify} {
+    upvar 1 $arr sb
+
+    # APPNOTE A: Local file header
+    set buf [read $fd 30]
+    set n [binary scan $buf A4sssssiiiss \
+               hdr sb(ver) sb(flags) sb(method) time date \
+               crc csize size namelen xtralen]
+
+    if { ![string equal "PK\03\04" $hdr] } {
+       binary scan $hdr H* x
+       return -code error "bad header: $x"
+    }
+    set sb(ver)           [expr {$sb(ver) & 0xffff}]
+    set sb(flags)  [expr {$sb(flags) & 0xffff}]
+    set sb(method) [expr {$sb(method) & 0xffff}]
+    set sb(mtime)  [DosTime $date $time]
+    if {!($sb(flags) & (1<<3))} {
+        set sb(crc)    [expr {$crc & 0xffffffff}]
+        set sb(csize)  [expr {$csize & 0xffffffff}]
+        set sb(size)   [expr {$size & 0xffffffff}]
+    }
+
+    set sb(name)   [read $fd [expr {$namelen & 0xffff}]]
+    set sb(extra)  [read $fd [expr {$xtralen & 0xffff}]]
+    if {$sb(flags) & (1 << 10)} {
+        set sb(name) [encoding convertfrom utf-8 $sb(name)]
+    }
+    set sb(name) [string trimleft $sb(name) "./"]
+
+    # APPNOTE B: File data
+    #   if bit 3 of flags is set the csize comes from the central directory
+    set data [read $fd $sb(csize)]
+
+    # APPNOTE C: Data descriptor
+    if { $sb(flags) & (1<<3) } {
+        binary scan [read $fd 4] i ddhdr
+        if {($ddhdr & 0xffffffff) == 0x08074b50} {
+            binary scan [read $fd 12] iii sb(crc) sb(csize) sb(size)
+        } else {
+            set sb(crc) $ddhdr
+            binary scan [read $fd 8] ii sb(csize) sb(size)
+        }
+        set sb(crc) [expr {$sb(crc) & 0xffffffff}]
+        set sb(csize) [expr {$sb(csize) & 0xffffffff}]
+        set sb(size) [expr {$sb(size) & 0xffffffff}]
+    }
+    
+    switch -exact -- $sb(method) {
+        0 {
+            # stored; no compression
+        }
+        8 {
+            # deflated
+            if {[catch {
+                set data [vfs::zip -mode decompress -nowrap 1 $data]
+            } err]} then {
+                return -code error "error inflating \"$sb(name)\": $err"
+            }
+        }
+        default {
+            set method $sb(method)
+            if {[info exists methods($method)]} {
+                set method $methods($method)
+            }
+            return -code error "unsupported compression method
+                \"$method\" used for \"$sb(name)\""
+        }
+    }
+
+    if { $verify && $sb(method) != 0} {
+       set ncrc [vfs::crc $data]
+       if { ($ncrc & 0xffffffff) != $sb(crc) } {
+           vfs::log [format {%s: crc mismatch: expected 0x%x, got 0x%x} \
+                          $sb(name) $sb(crc) $ncrc]
+       }
+    }
+    return $data
+}
+
+proc zip::EndOfArchive {fd arr} {
+    upvar 1 $arr cb
+
+    # [SF Tclvfs Bug 1003574]. Do not seek over beginning of file.
+    seek $fd 0 end
+
+    # Just looking in the last 512 bytes may be enough to handle zip
+    # archives without comments, however for archives which have
+    # comments the chunk may start at an arbitrary distance from the
+    # end of the file. So if we do not find the header immediately
+    # we have to extend the range of our search, possibly until we
+    # have a large part of the archive in memory. We can fail only
+    # after the whole file has been searched.
+
+    set sz  [tell $fd]
+    set len 512
+    set at  512
+    while {1} {
+       if {$sz < $at} {set n -$sz} else {set n -$at}
+
+       seek $fd $n end
+       set hdr [read $fd $len]
+
+       # We are using 'string last' as we are searching the first
+       # from the end, which is the last from the beginning. See [SF
+       # Bug 2256740]. A zip archive stored in a zip archive can
+       # confuse the unmodified code, triggering on the magic
+       # sequence for the inner, uncompressed archive.
+       set pos [string last "PK\05\06" $hdr]
+       if {$pos == -1} {
+           if {$at >= $sz} {
+               return -code error "no header found"
+           }
+           set len 540 ; # after 1st iteration we force overlap with last buffer
+           incr at 512 ; # to ensure that the pattern we look for is not split at
+           #           ; # a buffer boundary, nor the header itself
+       } else {
+           break
+       }
+    }
+
+    set hdr [string range $hdr [expr {$pos + 4}] [expr {$pos + 21}]]
+    set pos [expr {[tell $fd] + $pos - 512}]
+
+    binary scan $hdr ssssiis \
+       cb(ndisk) cb(cdisk) \
+       cb(nitems) cb(ntotal) \
+       cb(csize) cb(coff) \
+       cb(comment)
+
+    set cb(ndisk)      [u_short $cb(ndisk)]
+    set cb(nitems)     [u_short $cb(nitems)]
+    set cb(ntotal)     [u_short $cb(ntotal)]
+    set cb(comment)    [u_short $cb(comment)]
+
+    # Compute base for situations where ZIP file
+    # has been appended to another media (e.g. EXE)
+    set cb(base)       [expr { $pos - $cb(csize) - $cb(coff) }]
+}
+
+proc zip::TOC {fd arr} {
+    upvar 1 $arr sb
+
+    set buf [read $fd 46]
+
+    binary scan $buf A4ssssssiiisssssii hdr \
+      sb(vem) sb(ver) sb(flags) sb(method) time date \
+      sb(crc) sb(csize) sb(size) \
+      flen elen clen sb(disk) sb(attr) \
+      sb(atx) sb(ino)
+
+    if { ![string equal "PK\01\02" $hdr] } {
+       binary scan $hdr H* x
+       return -code error "bad central header: $x"
+    }
+
+    foreach v {vem ver flags method disk attr} {
+       set sb($v) [expr {$sb($v) & 0xffff}]
+    }
+    set sb(crc) [expr {$sb(crc) & 0xffffffff}]
+    set sb(csize) [expr {$sb(csize) & 0xffffffff}]
+    set sb(size) [expr {$sb(size) & 0xffffffff}]
+    set sb(mtime) [DosTime $date $time]
+    set sb(mode) [expr { ($sb(atx) >> 16) & 0xffff }]
+    if { ( $sb(atx) & 0xff ) & 16 } {
+       set sb(type) directory
+    } else {
+       set sb(type) file
+    }
+    set sb(name) [read $fd [u_short $flen]]
+    set sb(extra) [read $fd [u_short $elen]]
+    set sb(comment) [read $fd [u_short $clen]]
+    if {$sb(flags) & (1 << 10)} {
+        set sb(name) [encoding convertfrom utf-8 $sb(name)]
+        set sb(comment) [encoding convertfrom utf-8 $sb(comment)]
+    }
+    set sb(name) [string trimleft $sb(name) "./"]
+}
+
+proc zip::open {path} {
+    #vfs::log [list open $path]
+    set fd [::open $path]
+    
+    if {[catch {
+       upvar #0 zip::$fd cb
+       upvar #0 zip::$fd.toc toc
+
+       fconfigure $fd -translation binary ;#-buffering none
+       
+       zip::EndOfArchive $fd cb
+
+       seek $fd $cb(coff) start
+
+       set toc(_) 0; unset toc(_); #MakeArray
+       
+       for {set i 0} {$i < $cb(nitems)} {incr i} {
+           zip::TOC $fd sb
+           
+           set sb(depth) [llength [file split $sb(name)]]
+           
+           set name [string tolower $sb(name)]
+           set toc($name) [array get sb]
+           FAKEDIR toc [file dirname $name]
+       }
+    } err]} {
+       close $fd
+       return -code error $err
+    }
+
+    return $fd
+}
+
+proc zip::FAKEDIR {arr path} {
+    upvar 1 $arr toc
+
+    if { $path == "."} { return }
+
+
+    if { ![info exists toc($path)] } {
+       # Implicit directory
+       lappend toc($path) \
+               name $path \
+               type directory mtime 0 size 0 mode 0777 \
+               ino -1 depth [llength [file split $path]]
+    }
+    FAKEDIR toc [file dirname $path]
+}
+
+proc zip::exists {fd path} {
+    #::vfs::log "$fd $path"
+    if {$path == ""} {
+       return 1
+    } else {
+       upvar #0 zip::$fd.toc toc
+       info exists toc([string tolower $path])
+    }
+}
+
+proc zip::stat {fd path arr} {
+    upvar #0 zip::$fd.toc toc
+    upvar 1 $arr sb
+    #vfs::log [list stat $fd $path $arr [info level -1]]
+
+    set name [string tolower $path]
+    if { $name == "" || $name == "." } {
+       array set sb {
+           type directory mtime 0 size 0 mode 0777 
+           ino -1 depth 0 name ""
+       }
+    } elseif {![info exists toc($name)] } {
+       return -code error "could not read \"$path\": no such file or directory"
+    } else {
+       array set sb $toc($name)
+    }
+    set sb(dev) -1
+    set sb(uid)        -1
+    set sb(gid)        -1
+    set sb(nlink) 1
+    set sb(atime) $sb(mtime)
+    set sb(ctime) $sb(mtime)
+    return ""
+}
+
+# Treats empty pattern as asking for a particular file only
+proc zip::getdir {fd path {pat *}} {
+    #::vfs::log [list getdir $fd $path $pat]
+    upvar #0 zip::$fd.toc toc
+
+    if { $path == "." || $path == "" } {
+       set path [set tmp [string tolower $pat]]
+    } else {
+        set globmap [list "\[" "\\\[" "*" "\\*" "?" "\\?"]
+       set tmp [string tolower $path]
+        set path [string map $globmap $tmp]
+       if {$pat != ""} {
+           append tmp /[string tolower $pat]
+           append path /[string tolower $pat]
+       }
+    }
+    # file split can be confused by the glob quoting so split tmp string
+    set depth [llength [file split $tmp]]
+
+    #vfs::log "getdir $fd $path $depth $pat [array names toc $path]"
+    if {$depth} {
+       set ret {}
+       foreach key [array names toc $path] {
+           if {[string index $key end] == "/"} {
+               # Directories are listed twice: both with and without
+               # the trailing '/', so we ignore the one with
+               continue
+           }
+           array set sb $toc($key)
+
+           if { $sb(depth) == $depth } {
+               if {[info exists toc(${key}/)]} {
+                   array set sb $toc(${key}/)
+               }
+               lappend ret [file tail $sb(name)]
+           } else {
+               #::vfs::log "$sb(depth) vs $depth for $sb(name)"
+           }
+           unset sb
+       }
+       return $ret
+    } else {
+       # just the 'root' of the zip archive.  This obviously exists and
+       # is a directory.
+       return [list {}]
+    }
+}
+
+proc zip::_close {fd} {
+    variable $fd
+    variable $fd.toc
+    unset $fd
+    unset $fd.toc
+    ::close $fd
+}
diff --git a/8.x/tclvfs/license.terms b/8.x/tclvfs/license.terms
new file mode 100644 (file)
index 0000000..2aa12c3
--- /dev/null
@@ -0,0 +1,38 @@
+This software is copyrighted by the Vince Darley, and other
+parties.  The following terms apply to all files associated with the
+software unless explicitly disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+GOVERNMENT USE: If you are acquiring this software on behalf of the
+U.S. government, the Government shall have only "Restricted Rights"
+in the software and related documentation as defined in the Federal 
+Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
+are acquiring the software on behalf of the Department of Defense, the
+software shall be classified as "Commercial Computer Software" and the
+Government shall have only "Restricted Rights" as defined in Clause
+252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
+authors grant the U.S. Government and others acting in its behalf
+permission to use and distribute the software in accordance with the
+terms specified in this license. 
diff --git a/8.x/tclvfs/make55.tcl b/8.x/tclvfs/make55.tcl
new file mode 100644 (file)
index 0000000..621e554
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/sh
+# The next line is executed by /bin/sh, but not tcl \
+exec /usr/local/bin/tclsh8.4 $0 ${1+"$@"}
+
+
+proc platform {} {
+    global tcl_platform
+    set plat [lindex $tcl_platform(os) 0]
+    set mach $tcl_platform(machine)
+    switch -glob -- $mach {
+       sun4* { set mach sparc }
+       intel -
+       i*86* { set mach x86 }
+       "Power Macintosh" { set mach ppc }
+    }
+    return "$plat-$mach"
+}
+
+proc makepackagedirs {pkgname} {
+    file delete -force $pkgname
+    file mkdir $pkgname
+    file mkdir [file join $pkgname tcl]
+    file mkdir [file join $pkgname doc]
+    file mkdir [file join $pkgname examples]
+    file mkdir [file join $pkgname [platform]]
+    file mkdir [file join $pkgname tcl]
+}
+
+proc makepackage {pkgname} {
+    global files
+    makepackagedirs $pkgname
+
+    foreach type [array names files] {
+       foreach pat $files($type) {
+           foreach f [glob -nocomplain $pat] {
+               file copy $f [file join $pkgname $type]
+           }
+       }
+    }
+    file copy DESCRIPTION.txt $pkgname
+
+    if {![catch {package require installer}]} {
+       installer::mkIndex $pkgname
+    }
+} 
+
+
+array set files {
+    tcl         library/*.tcl
+    examples    examples/*.tcl
+    doc         {doc/*.n Readme.txt}
+}
+## how should files([platform]) be set?
+## the version number ought to be a param, needs to come fro
+## the config file: vfs_LIB_FILE
+
+if [catch {open config.status} config] {
+    error $config
+}
+
+while {[gets $config line] != -1} {
+    regexp -expanded {s(.)@vfs_LIB_FILE@\1(.*)\1} $line => sep files([platform])
+}
+close $config
+
+parray files
+
+
+makepackage vfs1.2.1
diff --git a/8.x/tclvfs/pkgIndex.tcl.in b/8.x/tclvfs/pkgIndex.tcl.in
new file mode 100644 (file)
index 0000000..0554ac6
--- /dev/null
@@ -0,0 +1,45 @@
+# -*- tcl -*-
+# Tcl package index file, version 1.1
+# This file was generated by hand.
+#
+# This will be autogenerated by configure to use the correct name
+# for the vfs dynamic library.
+
+# We don't really want to throw an error with older versions of
+# Tcl, they should just ignore us.
+if {[package provide Tcl] < 8.4} {
+    return
+}
+package require Tcl 8.4
+
+package ifneeded vfs @PACKAGE_VERSION@ [list source [file join $dir vfs.tcl]]
+
+package ifneeded starkit 1.3.3 [list source [file join $dir starkit.tcl]]
+
+# New, for the old, keep version numbers synchronized.
+package ifneeded vfs::mk4     1.10.1 [list source [file join $dir mk4vfs.tcl]]
+package ifneeded vfs::zip     1.0.3  [list source [file join $dir zipvfs.tcl]]
+
+# New
+package ifneeded vfs::ftp     1.0 [list source [file join $dir ftpvfs.tcl]]
+package ifneeded vfs::http    0.6 [list source [file join $dir httpvfs.tcl]]
+package ifneeded vfs::ns      0.5.1 [list source [file join $dir tclprocvfs.tcl]]
+package ifneeded vfs::tar     0.91 [list source [file join $dir tarvfs.tcl]]
+package ifneeded vfs::test    1.0 [list source [file join $dir testvfs.tcl]]
+package ifneeded vfs::urltype 1.0 [list source [file join $dir vfsUrl.tcl]]
+package ifneeded vfs::webdav  0.1 [list source [file join $dir webdavvfs.tcl]]
+package ifneeded vfs::tk      0.5 [list source [file join $dir tkvfs.tcl]]
+#
+# Virtual filesystems based on the template vfs:
+#
+if {[lsearch -exact $::auto_path [file join $dir template]] == -1} {
+    lappend ::auto_path [file join $dir template]
+}
+package ifneeded vfs::template 1.5.4 \
+    [list source [file join $dir template templatevfs.tcl]]
+#
+# Helpers
+#
+package ifneeded fileutil::globfind 1.5 \
+    [list source [file join $dir template globfind.tcl]]
+package ifneeded trsync 1.0 [list source [file join $dir template tdelta.tcl]]
diff --git a/8.x/tclvfs/tclconfig/README.txt b/8.x/tclvfs/tclconfig/README.txt
new file mode 100644 (file)
index 0000000..9055a58
--- /dev/null
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension.  For more information on TEA see:
+
+       http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+       http://tcl.sourceforge.net/
+
+This package is a freely available open source package.  You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt     This file
+
+install-sh     Program used for copying binaries and script files
+               to their install locations.
+
+tcl.m4         Collection of Tcl autoconf macros.  Included by a package's
+               aclocal.m4 to define SC_* macros.
diff --git a/8.x/tclvfs/tclconfig/install-sh b/8.x/tclvfs/tclconfig/install-sh
new file mode 100755 (executable)
index 0000000..0ff4b6a
--- /dev/null
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+       echo "install:  no destination specified"
+       exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+       dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/8.x/tclvfs/tclconfig/tcl.m4 b/8.x/tclvfs/tclconfig/tcl.m4
new file mode 100644 (file)
index 0000000..fc094c9
--- /dev/null
@@ -0,0 +1,4105 @@
+# tcl.m4 --
+#
+#      This file provides a set of autoconf macros to help TEA-enable
+#      a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: tcl.m4,v 1.22 2008/12/03 02:30:42 hobbs Exp $
+
+AC_PREREQ(2.57)
+
+dnl TEA extensions pass us the version of TEA they think they
+dnl are compatible with (must be set in TEA_INIT below)
+dnl TEA_VERSION="3.7"
+
+# Possible values for key variables defined:
+#
+# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
+# TEA_PLATFORM        - windows unix
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+#      Locate the tclConfig.sh file and perform a sanity check on
+#      the Tcl compile flags
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tcl=...
+#
+#      Defines the following vars:
+#              TCL_BIN_DIR     Full path to the directory containing
+#                              the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+       AC_ARG_WITH(tcl,
+           AC_HELP_STRING([--with-tcl],
+               [directory containing tcl configuration (tclConfig.sh)]),
+           with_tclconfig=${withval})
+       AC_MSG_CHECKING([for Tcl configuration])
+       AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # TEA specific: on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           AC_MSG_ERROR([Can't find Tcl configuration definitions])
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+#      Locate the tkConfig.sh file
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tk=...
+#
+#      Defines the following vars:
+#              TK_BIN_DIR      Full path to the directory containing
+#                              the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+    #
+    # Ok, lets find the tk configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tk
+    #
+
+    if test x"${no_tk}" = x ; then
+       # we reset no_tk in case something fails here
+       no_tk=true
+       AC_ARG_WITH(tk,
+           AC_HELP_STRING([--with-tk],
+               [directory containing tk configuration (tkConfig.sh)]),
+           with_tkconfig=${withval})
+       AC_MSG_CHECKING([for Tk configuration])
+       AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+           # First check to see if --with-tkconfig was specified.
+           if test x"${with_tkconfig}" != x ; then
+               case ${with_tkconfig} in
+                   */tkConfig.sh )
+                       if test -f ${with_tkconfig}; then
+                           AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+                           with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tkconfig}/tkConfig.sh" ; then
+                   ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tk library
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ../tk \
+                       `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tk \
+                       `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tk \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tk.framework/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # TEA specific: on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tk \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tkconfig}" = x ; then
+           TK_BIN_DIR="# no Tk configs found"
+           AC_MSG_ERROR([Can't find Tk configuration definitions])
+       else
+           no_tk=
+           TK_BIN_DIR=${ac_cv_c_tkconfig}
+           AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+#      Load the tclConfig.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              TCL_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              TCL_BIN_DIR
+#              TCL_SRC_DIR
+#              TCL_LIB_FILE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+    AC_SUBST(TCL_VERSION)
+    AC_SUBST(TCL_BIN_DIR)
+    AC_SUBST(TCL_SRC_DIR)
+
+    AC_SUBST(TCL_LIB_FILE)
+    AC_SUBST(TCL_LIB_FLAG)
+    AC_SUBST(TCL_LIB_SPEC)
+
+    AC_SUBST(TCL_STUB_LIB_FILE)
+    AC_SUBST(TCL_STUB_LIB_FLAG)
+    AC_SUBST(TCL_STUB_LIB_SPEC)
+
+    # TEA specific:
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(TCL_DEFS)
+    AC_SUBST(TCL_EXTRA_CFLAGS)
+    AC_SUBST(TCL_LD_FLAGS)
+    AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+#      Load the tkConfig.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              TK_BIN_DIR
+#
+# Results:
+#
+#      Sets the following vars that should be in tkConfig.sh:
+#              TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${TK_BIN_DIR}/tkConfig.sh"
+    else
+        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+    # If the TK_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TK_LIB_SPEC will be set to the value
+    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+    # instead of TK_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        TK_LIB_SPEC=${TK_BUILD_LIB_SPEC}
+        TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC}
+        TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tk was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tk.framework installed in an arbitary location.
+       case ${TK_DEFS} in
+           *TK_FRAMEWORK*)
+               if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+                   for i in "`cd ${TK_BIN_DIR}; pwd`" \
+                            "`cd ${TK_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+                           TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+                   TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}"
+                   TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+    # TEA specific: Ensure windowingsystem is defined
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       case ${TK_DEFS} in
+           *MAC_OSX_TK*)
+               AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+               TEA_WINDOWINGSYSTEM="aqua"
+               ;;
+           *)
+               TEA_WINDOWINGSYSTEM="x11"
+               ;;
+       esac
+    elif test "${TEA_PLATFORM}" = "windows" ; then
+       TEA_WINDOWINGSYSTEM="win32"
+    fi
+
+    AC_SUBST(TK_VERSION)
+    AC_SUBST(TK_BIN_DIR)
+    AC_SUBST(TK_SRC_DIR)
+
+    AC_SUBST(TK_LIB_FILE)
+    AC_SUBST(TK_LIB_FLAG)
+    AC_SUBST(TK_LIB_SPEC)
+
+    AC_SUBST(TK_STUB_LIB_FILE)
+    AC_SUBST(TK_STUB_LIB_FLAG)
+    AC_SUBST(TK_STUB_LIB_SPEC)
+
+    # TEA specific:
+    AC_SUBST(TK_LIBS)
+    AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+#      Determine the fully qualified path name of the tclsh executable
+#      in the Tcl build directory or the tclsh installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the tclsh executable even if tclsh has not yet been
+#      built in the build directory. The tclsh found is always
+#      associated with a tclConfig.sh file. This tclsh should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+    AC_MSG_CHECKING([for tclsh])
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+    fi
+    AC_MSG_RESULT([${TCLSH_PROG}])
+    AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+#      Determine the fully qualified path name of the wish executable
+#      in the Tk build directory or the wish installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the wish executable even if wish has not yet been
+#      built in the build directory. The wish found is always
+#      associated with a tkConfig.sh file. This wish should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+    AC_MSG_CHECKING([for wish])
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        # tkConfig.sh is in Tk build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="${TK_BIN_DIR}/wish"
+        fi
+    else
+        # tkConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+        fi
+        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${WISH_PROG}" ; then
+                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+    fi
+    AC_MSG_RESULT([${WISH_PROG}])
+    AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+#      Allows the building of shared libraries
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-shared=yes|no
+#
+#      Defines the following vars:
+#              STATIC_BUILD    Used for building import/export libraries
+#                              on Windows.
+#
+#      Sets the following vars:
+#              SHARED_BUILD    Value of 1 or 0
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SHARED], [
+    AC_MSG_CHECKING([how to build libraries])
+    AC_ARG_ENABLE(shared,
+       AC_HELP_STRING([--enable-shared],
+           [build and link with shared libraries (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       AC_MSG_RESULT([shared])
+       SHARED_BUILD=1
+    else
+       AC_MSG_RESULT([static])
+       SHARED_BUILD=0
+       AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
+    fi
+    AC_SUBST(SHARED_BUILD)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+#      Specify if thread support should be enabled.  If "yes" is specified
+#      as an arg (optional), threads are enabled by default, "no" means
+#      threads are disabled.  "yes" is the default.
+#
+#      TCL_THREADS is checked so that if you are compiling an extension
+#      against a threaded core, your extension must be compiled threaded
+#      as well.
+#
+#      Note that it is legal to have a thread enabled extension run in a
+#      threaded or non-threaded Tcl core, but a non-threaded extension may
+#      only run in a non-threaded Tcl core.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-threads
+#
+#      Sets the following vars:
+#              THREADS_LIBS    Thread library(s)
+#
+#      Defines the following vars:
+#              TCL_THREADS
+#              _REENTRANT
+#              _THREAD_SAFE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+    AC_ARG_ENABLE(threads,
+       AC_HELP_STRING([--enable-threads],
+           [build with threads]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+           AC_DEFINE(USE_THREAD_ALLOC, 1,
+               [Do we want to use the threaded memory allocator?])
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           if test "`uname -s`" = "SunOS" ; then
+               AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+                       [Do we really want to follow the standard? Yes we do!])
+           fi
+           AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+           AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               AC_CHECK_LIB(pthread, __pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               AC_CHECK_LIB(pthreads, pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   AC_CHECK_LIB(c, pthread_mutex_init,
+                       tcl_ok=yes, tcl_ok=no)
+                   if test "$tcl_ok" = "no"; then
+                       AC_CHECK_LIB(c_r, pthread_mutex_init,
+                           tcl_ok=yes, tcl_ok=no)
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    AC_MSG_CHECKING([for building with threads])
+    if test "${TCL_THREADS}" = 1; then
+       AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+       AC_MSG_RESULT([yes (default)])
+    else
+       AC_MSG_RESULT([no])
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               AC_MSG_WARN([
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads.])
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               AC_MSG_WARN([
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core.])
+           fi
+           ;;
+    esac
+    AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+#      Specify if debugging symbols should be used.
+#      Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+#      none
+#      
+#      TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+#      the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+#      Requires the following vars to be set in the Makefile:
+#              CFLAGS_DEFAULT
+#              LDFLAGS_DEFAULT
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-symbols
+#
+#      Defines the following vars:
+#              CFLAGS_DEFAULT  Sets to $(CFLAGS_DEBUG) if true
+#                              Sets to $(CFLAGS_OPTIMIZE) if false
+#              LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+#                              Sets to $(LDFLAGS_OPTIMIZE) if false
+#              DBGX            Formerly used as debug library extension;
+#                              always blank now.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_CONFIG_CFLAGS])
+    AC_MSG_CHECKING([for build with symbols])
+    AC_ARG_ENABLE(symbols,
+       AC_HELP_STRING([--enable-symbols],
+           [build with debugging symbols (default: off)]),
+       [tcl_ok=$enableval], [tcl_ok=no])
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       AC_MSG_RESULT([no])
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           AC_MSG_RESULT([yes (standard debugging)])
+       fi
+    fi
+    # TEA specific:
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+    AC_SUBST(CFLAGS_DEFAULT)
+    AC_SUBST(LDFLAGS_DEFAULT)
+    AC_SUBST(TCL_DBGX)
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+       AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           AC_MSG_RESULT([enabled symbols mem debugging])
+       else
+           AC_MSG_RESULT([enabled $tcl_ok debugging])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+#      Allows use of modern nl_langinfo check for better l10n.
+#      This is only relevant for Unix.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-langinfo=yes|no (default is yes)
+#
+#      Defines the following vars:
+#              HAVE_LANGINFO   Triggers use of nl_langinfo if defined.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+    AC_ARG_ENABLE(langinfo,
+       AC_HELP_STRING([--enable-langinfo],
+           [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+       [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+    HAVE_LANGINFO=0
+    if test "$langinfo_ok" = "yes"; then
+       AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+    fi
+    AC_MSG_CHECKING([whether to use nl_langinfo])
+    if test "$langinfo_ok" = "yes"; then
+       AC_CACHE_VAL(tcl_cv_langinfo_h, [
+           AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+                   [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+       AC_MSG_RESULT([$tcl_cv_langinfo_h])
+       if test $tcl_cv_langinfo_h = yes; then
+           AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+       fi
+    else 
+       AC_MSG_RESULT([$langinfo_ok])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+#      Determine what the system is (some things cannot be easily checked
+#      on a feature-driven basis, alas). This can usually be done via the
+#      "uname" command, but there are a few systems, like Next, where
+#      this doesn't work.
+#
+# Arguments:
+#      none
+#
+# Results:
+#      Defines the following var:
+#
+#      system -        System/platform/version identification code.
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+       # TEA specific:
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               AC_MSG_WARN([can't find uname command])
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+    ])
+    system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+#      Try to determine the proper flags to pass to the compiler
+#      for building shared libraries and other such nonsense.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substitutes the following vars:
+#
+#       DL_OBJS -       Name of the object file that implements dynamic
+#                       loading for Tcl on this system.
+#       DL_LIBS -       Library file(s) to include in tclsh and other base
+#                       applications in order for the "load" command to work.
+#       LDFLAGS -      Flags to pass to the compiler when linking object
+#                       files into an executable application binary such
+#                       as tclsh.
+#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
+#                       be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+#       CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile.
+#       SHLIB_CFLAGS -  Flags to pass to cc when compiling the components
+#                       of a shared library (may request position-independent
+#                       code, among other things).
+#       SHLIB_LD -      Base command to use for combining object files
+#                       into a shared library.
+#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+#                       creating shared libraries.  This symbol typically
+#                       goes at the end of the "ld" commands that build
+#                       shared libraries. The value of the symbol is
+#                       "${LIBS}" if all of the dependent libraries should
+#                       be specified when creating a shared library.  If
+#                       dependent libraries should not be specified (as on
+#                       SunOS 4.x, where they cause the link to fail, or in
+#                       general if Tcl and Tk aren't themselves shared
+#                       libraries), then this symbol has an empty string
+#                       as its value.
+#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
+#                       extensions.  An empty string means we don't know how
+#                       to use shared libraries on this platform.
+#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
+#                       in a static or shared library name, using the $VERSION variable
+#                       to put the version in the right place.  This is used
+#                       by platforms that need non-standard library names.
+#                       Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
+#                       to have a version after the .so, and ${VERSION}.a
+#                       on AIX, since a shared library needs to have
+#                       a .a extension whereas shared objects for loadable
+#                       extensions have a .so extension.  Defaults to
+#                       ${VERSION}${SHLIB_SUFFIX}.
+#       TCL_NEEDS_EXP_FILE -
+#                       1 means that an export file is needed to link to a
+#                       shared library.
+#       TCL_EXP_FILE -  The name of the installed export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#       TCL_BUILD_EXP_FILE -
+#                       The name of the built export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#      CFLAGS_DEBUG -
+#                      Flags used when running the compiler in debug mode
+#      CFLAGS_OPTIMIZE -
+#                      Flags used when running the compiler in optimize mode
+#      CFLAGS -        Additional CFLAGS added as necessary (usually 64-bit)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+
+    # Step 0.a: Enable 64 bit support?
+
+    AC_MSG_CHECKING([if 64bit support is requested])
+    AC_ARG_ENABLE(64bit,
+       AC_HELP_STRING([--enable-64bit],
+           [enable 64bit support (default: off)]),
+       [do64bit=$enableval], [do64bit=no])
+    AC_MSG_RESULT([$do64bit])
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+    AC_ARG_ENABLE(64bit-vis,
+       AC_HELP_STRING([--enable-64bit-vis],
+           [enable 64bit Sparc VIS support (default: off)]),
+       [do64bitVIS=$enableval], [do64bitVIS=no])
+    AC_MSG_RESULT([$do64bitVIS])
+    # Force 64bit on with VIS
+    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+    # Step 0.c: Check if visibility support is available. Do this here so
+    # that platform specific alternatives can be used below if this fails.
+
+    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+       tcl_cv_cc_visibility_hidden, [
+       hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+       AC_TRY_LINK([
+           extern __attribute__((__visibility__("hidden"))) void f(void);
+           void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+           tcl_cv_cc_visibility_hidden=no)
+       CFLAGS=$hold_cflags])
+    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+       AC_DEFINE(MODULE_SCOPE,
+           [extern __attribute__((__visibility__("hidden")))],
+           [Compiler support for module scope symbols])
+    ])
+
+    # Step 0.d: Disable -rpath support?
+
+    AC_MSG_CHECKING([if rpath support is requested])
+    AC_ARG_ENABLE(rpath,
+       AC_HELP_STRING([--disable-rpath],
+           [disable rpath support (default: on)]),
+       [doRpath=$enableval], [doRpath=yes])
+    AC_MSG_RESULT([$doRpath])
+
+    # TEA specific: Cross-compiling options for Windows/CE builds?
+
+    AS_IF([test "${TEA_PLATFORM}" = windows], [
+       AC_MSG_CHECKING([if Windows/CE build is requested])
+       AC_ARG_ENABLE(wince,
+           AC_HELP_STRING([--enable-wince],
+               [enable Win/CE support (where applicable)]),
+           [doWince=$enableval], [doWince=no])
+       AC_MSG_RESULT([$doWince])
+    ])
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+    TEA_CONFIG_SYSTEM
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
+
+    # Require ranlib early so we can override it in special cases below.
+
+    AC_REQUIRE([AC_PROG_RANLIB])
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    AS_IF([test "$GCC" = yes], [
+       # TEA specific:
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall -Wno-implicit-int"
+    ], [CFLAGS_WARNING=""])
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
+dnl AC_CHECK_TOOL(AR, ar)
+    AC_CHECK_PROG(AR, ar, ar)
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    case $system in
+       # TEA specific:
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+                   AC_MSG_WARN([Ensure latest Platform SDK is installed])
+                   do64bit="no"
+               else
+                   AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+               fi
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+               fi
+               TEA_PATH_CELIB
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+           if ([$]1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+           if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+           if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+                   TEA_ADD_LIBS([bufferoverflowU.lib])
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+                       AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+                   done
+                   AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+                   AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+                   AC_SUBST(CELIB_DIR)
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # and also
+               # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug -debugtype:cv"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r)
+                       # ok ...
+                       ;;
+                   *)
+                       CC=${CC}_r
+                       ;;
+               esac
+               AC_MSG_RESULT([Using $CC for compiling with threads])
+           ])
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           AS_IF([test "$do64bit" = yes -a "`uname -v`" -gt 3], [
+               AS_IF([test "$GCC" = yes], [
+                   AC_MSG_WARN([64bit mode not supported with GCC on $system])
+               ], [
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+               ])
+           ])
+
+           AS_IF([test "`uname -m`" = ia64], [
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               AS_IF([test "$GCC" = yes], [
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               ], [
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+               ])
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           ], [
+               AS_IF([test "$GCC" = yes], [SHLIB_LD='${CC} -shared'], [
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+               ])
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               # TEA specific: use PACKAGE_VERSION instead of VERSION
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+           ])
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           AS_IF([test "$system" = "AIX-4.1" -o "`uname -v`" -lt 4], [
+               AC_LIBOBJ([tclLoadAix])
+               DL_LIBS="-lld"
+           ])
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
+           AS_IF([test $libbsd = yes], [
+               MATH_LIBS="$MATH_LIBS -lbsd"
+               AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
+           ])
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -nostart'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD='${CC} -shared'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+           AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+           # TEA specific: Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           AS_IF([test "`uname -m`" = ia64], [
+               SHLIB_SUFFIX=".so"
+               # Use newer C++ library for C++ extensions
+               #if test "$GCC" != "yes" ; then
+               #   CPPFLAGS="-AA"
+               #fi
+           ], [
+               SHLIB_SUFFIX=".sl"
+           ])
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           AS_IF([test "$tcl_ok" = yes], [
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           ])
+           AS_IF([test "$GCC" = yes], [
+               SHLIB_LD='${CC} -shared'
+               SHLIB_LD_LIBS='${LIBS}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           ])
+
+           # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+           #CFLAGS="$CFLAGS +DAportable"
+
+           # Check to enable 64-bit flags for compiler/linker
+           AS_IF([test "$do64bit" = "yes"], [
+               AS_IF([test "$GCC" = yes], [
+                   case `${CC} -dumpmachine` in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD='${CC} -shared'
+                           SHLIB_LD_LIBS='${LIBS}'
+                           AS_IF([test $doRpath = yes], [
+                               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           AC_MSG_WARN([64bit mode not supported with GCC on $system])
+                           ;;
+                   esac
+               ], [
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+               ])
+           ]) ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           AS_IF([test "$tcl_ok" = yes], [
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           ]) ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           AS_IF([test "$GCC" = yes], [
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+           ], [
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+           ])
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           AS_IF([test "$do64bit" = yes], [
+               AS_IF([test "$GCC" = yes], [
+                   AC_MSG_WARN([64bit mode not supported by gcc])
+               ], [
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               ])
+           ])
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           # TEA specific:
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+           AS_IF([test $do64bit = yes], [
+               AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+                   CFLAGS=$hold_cflags])
+               AS_IF([test $tcl_cv_cc_m64 = yes], [
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+               ])
+          ])
+
+           # The combo of gcc + glibc has a bug related to inlining of
+           # functions like strtod(). The -fno-builtin flag should address
+           # this problem but it does not work. The -fno-inline flag is kind
+           # of overkill but it works. Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+
+           AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD='${CC} -shared'
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD='${CC} -shared'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-1.*|FreeBSD-[[1-2]].*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           AS_IF([test $tcl_cv_ld_elf = yes], [
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+           ], [
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           ])
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           AS_IF([test $tcl_cv_ld_elf = yes], [
+               LDFLAGS=-Wl,-export-dynamic
+           ], [LDFLAGS=""])
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       NetBSD-*|FreeBSD-*)
+           # FreeBSD 3.* and greater have ELF.
+           # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           AS_IF([test "${TCL_THREADS}" = "1"], [
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+           ])
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           # To avoid discrepancies between what headers configure sees during
+           # preprocessing tests and compiling tests, move any -isysroot and
+           # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+           CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
+           CFLAGS="`echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
+           AS_IF([test $do64bit = yes], [
+               case `arch` in
+                   ppc)
+                       AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+                               tcl_cv_cc_arch_ppc64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+                                   tcl_cv_cc_arch_ppc64=no)
+                           CFLAGS=$hold_cflags])
+                       AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+                       ]);;
+                   i386)
+                       AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+                               tcl_cv_cc_arch_x86_64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+                                   tcl_cv_cc_arch_x86_64=no)
+                           CFLAGS=$hold_cflags])
+                       AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+                       ]);;
+                   *)
+                       AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+               esac
+           ], [
+               # Check for combined 32-bit and 64-bit fat build
+               AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+                   && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+                   fat_32_64=yes])
+           ])
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+               LDFLAGS=$hold_ldflags])
+           AS_IF([test $tcl_cv_ld_single_module = yes], [
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+           ])
+           # TEA specific: link shlib with current and compatiblity version flags
+           vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+           SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+               "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+               LDFLAGS="$LDFLAGS -prebind"])
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+                   tcl_cv_ld_search_paths_first, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+                       tcl_cv_ld_search_paths_first=no)
+               LDFLAGS=$hold_ldflags])
+           AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+           ])
+           AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+               AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+                   [Compiler support for module scope symbols])
+           ])
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+           # TEA specific: for combined 32 & 64 bit fat builds of Tk
+           # extensions, verify that 64-bit build is possible.
+           AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+               AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+                   AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+                       done
+                       CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+                       LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+                       AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
+                           tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval $v'="$hold_'$v'"'
+                       done])
+               ])
+               # remove 64-bit arch flags from CFLAGS et al. if configuration
+               # does not support 64-bit.
+               AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua -o "$tcl_cv_lib_x11_64" = no], [
+                   AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
+                   for v in CFLAGS CPPFLAGS LDFLAGS; do
+                       eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+                   done])
+           ])
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD='${CC} -nostdlib -r'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+           AC_DEFINE(_OE_SOCKETS, 1,   # needed in sys/socket.h
+               [Should OS/390 do the right thing with sockets?])
+           ;;      
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export $@:'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           AS_IF([test "$SHARED_BUILD" = 1], [SHLIB_LD="ld -shared"], [
+               SHLIB_LD="ld -non_shared"
+           ])
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           AS_IF([test "$SHARED_BUILD" = 1], [
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+           ], [
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+           ])
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           AS_IF([test "${TCL_THREADS}" = 1], [
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               AS_IF([test "$GCC" = yes], [
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+               ], [
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+               ])
+           ])
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           AS_IF([test "$GCC" = yes], [
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+           ], [
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+           ])
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[[0-6]])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           AS_IF([test "$GCC" = yes], [
+               SHLIB_LD='${CC} -shared'
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           ], [
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           ])
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           AS_IF([test "$do64bit" = yes], [
+               arch=`isainfo`
+               AS_IF([test "$arch" = "sparcv9 sparc"], [
+                   AS_IF([test "$GCC" = yes], [
+                       AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+                           AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+                       ], [
+                           do64bit_ok=yes
+                           CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                           LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                           SHLIB_CFLAGS="-fPIC"
+                       ])
+                   ], [
+                       do64bit_ok=yes
+                       AS_IF([test "$do64bitVIS" = yes], [
+                           CFLAGS="$CFLAGS -xarch=v9a"
+                           LDFLAGS_ARCH="-xarch=v9a"
+                       ], [
+                           CFLAGS="$CFLAGS -xarch=v9"
+                           LDFLAGS_ARCH="-xarch=v9"
+                       ])
+                       # Solaris 64 uses this as well
+                       #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+                   ])
+               ], [AS_IF([test "$arch" = "amd64 i386"], [
+                   AS_IF([test "$GCC" = yes], [
+                       case $system in
+                           SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64"
+                               LDFLAGS="$LDFLAGS -m64";;
+                           *)
+                               AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+                       esac
+                   ], [
+                       do64bit_ok=yes
+                       case $system in
+                           SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+                               CFLAGS="$CFLAGS -m64"
+                               LDFLAGS="$LDFLAGS -m64";;
+                           *)
+                               CFLAGS="$CFLAGS -xarch=amd64"
+                               LDFLAGS="$LDFLAGS -xarch=amd64";;
+                       esac
+                   ])
+               ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+           ])
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           AS_IF([test "$GCC" = yes], [
+               SHLIB_LD='${CC} -shared'
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               AS_IF([test "$do64bit_ok" = yes], [
+                   AS_IF([test "$arch" = "sparcv9 sparc"], [
+                       # We need to specify -static-libgcc or we need to
+                       # add the path to the sparv9 libgcc.
+                       # JH: static-libgcc is necessary for core Tcl, but may
+                       # not be necessary for extensions.
+                       SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                       # for finding sparcv9 libgcc, get the regular libgcc
+                       # path, remove so name and append 'sparcv9'
+                       #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                       #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+                   ], [AS_IF([test "$arch" = "amd64 i386"], [
+                       # JH: static-libgcc is necessary for core Tcl, but may
+                       # not be necessary for extensions.
+                       SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+                   ])])
+               ])
+           ], [
+               case $system in
+                   SunOS-5.[[1-9]][[0-9]]*)
+                       SHLIB_LD='${CC} -G -z text ${LDFLAGS}';;
+                   *)
+                       SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+               esac
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           ])
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+               LDFLAGS=$hold_ldflags])
+           AS_IF([test $tcl_cv_ld_Bexport = yes], [
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           ])
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+       AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+    ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    AC_ARG_ENABLE(load,
+       AC_HELP_STRING([--enable-load],
+           [allow dynamic loading and "load" command (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+    AS_IF([test "$tcl_ok" = no], [DL_OBJS=""])
+
+    AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [
+       AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.])
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+    ])
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
+       case $system in
+           AIX-*) ;;
+           BSD/OS*) ;;
+           IRIX*) ;;
+           NetBSD-*|FreeBSD-*) ;;
+           Darwin-*) ;;
+           SCO_SV-3.2*) ;;
+           *) SHLIB_CFLAGS="-fPIC" ;;
+       esac])
+
+    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+       # TEA specific: use PACKAGE_VERSION instead of VERSION
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
+    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+       # TEA specific: use PACKAGE_VERSION instead of VERSION
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
+
+    AC_SUBST(DL_LIBS)
+
+    AC_SUBST(CFLAGS_DEBUG)
+    AC_SUBST(CFLAGS_OPTIMIZE)
+    AC_SUBST(CFLAGS_WARNING)
+
+    AC_SUBST(STLIB_LD)
+    AC_SUBST(SHLIB_LD)
+
+    AC_SUBST(SHLIB_LD_LIBS)
+    AC_SUBST(SHLIB_CFLAGS)
+
+    AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+    TEA_TCL_EARLY_FLAGS
+    TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+#      Determine which interface to use to talk to the serial port.
+#      Note that #include lines must begin in leftmost column for
+#      some compilers to recognize them as preprocessor directives,
+#      and some build environments have stdin not pointing at a
+#      pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines only one of the following vars:
+#              HAVE_SYS_MODEM_H
+#              USE_TERMIOS
+#              USE_TERMIO
+#              USE_SGTTY
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+    AC_CHECK_HEADERS(sys/modem.h)
+    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+    AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+    }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+    fi])
+    case $tcl_cv_api_serial in
+       termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+       termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+       sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_MISSING_POSIX_HEADERS
+#
+#      Supply substitutes for missing POSIX header files.  Special
+#      notes:
+#          - stdlib.h doesn't define strtol, strtoul, or
+#            strtod insome versions of SunOS
+#          - some versions of string.h don't declare procedures such
+#            as strstr
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              NO_DIRENT_H
+#              NO_ERRNO_H
+#              NO_VALUES_H
+#              HAVE_LIMITS_H or NO_LIMITS_H
+#              NO_STDLIB_H
+#              NO_STRING_H
+#              NO_SYS_WAIT_H
+#              NO_DLFCN_H
+#              HAVE_SYS_PARAM_H
+#
+#              HAVE_STRING_H ?
+#
+# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+# CHECK on limits.h
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
+    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
+    AC_TRY_LINK([#include <sys/types.h>
+#include <dirent.h>], [
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
+
+    if test $tcl_cv_dirent_h = no; then
+       AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
+    fi
+
+    # TEA specific:
+    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
+    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
+    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
+    AC_CHECK_HEADER(limits.h,
+       [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
+       [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
+    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
+    fi
+    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
+    fi
+
+    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
+    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+    AC_HAVE_HEADERS(sys/param.h)
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+#      Locate the X11 header files and the X11 library archive.  Try
+#      the ac_path_x macro first, but if it doesn't find the X stuff
+#      (e.g. because there's no xmkmf program) then check through
+#      a list of possible directories.  Under some conditions the
+#      autoconf macro will return an include directory that contains
+#      no include files, so double-check its result just to be safe.
+#
+#      This should be called after TEA_CONFIG_CFLAGS as setting the
+#      LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Sets the following vars:
+#              XINCLUDES
+#              XLIBSW
+#              PKG_LIBS (appends to)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+       TEA_PATH_UNIX_X
+    fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+    AC_PATH_X
+    not_really_there=""
+    if test "$no_x" = ""; then
+       if test "$x_includes" = ""; then
+           AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
+       else
+           if test ! -r $x_includes/X11/Intrinsic.h; then
+               not_really_there="yes"
+           fi
+       fi
+    fi
+    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+       AC_MSG_CHECKING([for X11 header files])
+       found_xincludes="no"
+       AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
+       if test "$found_xincludes" = "no"; then
+           dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+           for i in $dirs ; do
+               if test -r $i/X11/Intrinsic.h; then
+                   AC_MSG_RESULT([$i])
+                   XINCLUDES=" -I$i"
+                   found_xincludes="yes"
+                   break
+               fi
+           done
+       fi
+    else
+       if test "$x_includes" != ""; then
+           XINCLUDES="-I$x_includes"
+           found_xincludes="yes"
+       fi
+    fi
+    if test found_xincludes = "no"; then
+       AC_MSG_RESULT([couldn't find any!])
+    fi
+
+    if test "$no_x" = yes; then
+       AC_MSG_CHECKING([for X11 libraries])
+       XLIBSW=nope
+       dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+       for i in $dirs ; do
+           if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+               AC_MSG_RESULT([$i])
+               XLIBSW="-L$i -lX11"
+               x_libraries="$i"
+               break
+           fi
+       done
+    else
+       if test "$x_libraries" = ""; then
+           XLIBSW=-lX11
+       else
+           XLIBSW="-L$x_libraries -lX11"
+       fi
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_MSG_RESULT([could not find any!  Using -lX11.])
+       XLIBSW=-lX11
+    fi
+    # TEA specific:
+    if test x"${XLIBSW}" != x ; then
+       PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+#      The statements below check for systems where POSIX-style
+#      non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
+#      On these systems (mostly older ones), use the old BSD-style
+#      FIONBIO approach instead.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              HAVE_SYS_IOCTL_H
+#              HAVE_SYS_FILIO_H
+#              USE_FIONBIO
+#              O_NONBLOCK
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+    AC_CHECK_HEADERS(sys/ioctl.h)
+    AC_CHECK_HEADERS(sys/filio.h)
+    TEA_CONFIG_SYSTEM
+    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+    case $system in
+       # There used to be code here to use FIONBIO under AIX.  However, it
+       # was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
+       # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
+       # code (JO, 5/31/97).
+
+       OSF*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       SunOS-4*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       *)
+           AC_MSG_RESULT([O_NONBLOCK])
+           ;;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANLDER
+#
+#      Checks how the system deals with time.h, what time structures
+#      are used on the system, and what fields the structures have.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              USE_DELTA_FOR_TZ
+#              HAVE_TM_GMTOFF
+#              HAVE_TM_TZADJ
+#              HAVE_TIMEZONE_VAR
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+    AC_CHECK_HEADERS(sys/time.h)
+    AC_HEADER_TIME
+    AC_STRUCT_TIMEZONE
+
+    AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+           tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+    if test $tcl_cv_member_tm_tzadj = yes ; then
+       AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+    fi
+
+    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+           tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+    if test $tcl_cv_member_tm_gmtoff = yes ; then
+       AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+    fi
+
+    #
+    # Its important to include time.h in this check, as some systems
+    # (like convex) have timezone functions, etc.
+    #
+    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+       AC_TRY_COMPILE([#include <time.h>],
+           [extern long timezone;
+           timezone += 1;
+           exit (0);],
+           tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+    if test $tcl_cv_timezone_long = yes ; then
+       AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+    else
+       #
+       # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+       #
+       AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+           AC_TRY_COMPILE([#include <time.h>],
+               [extern time_t timezone;
+               timezone += 1;
+               exit (0);],
+               tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+       if test $tcl_cv_timezone_time = yes ; then
+           AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+#      Under Solaris 2.4, strtod returns the wrong value for the
+#      terminating character under some conditions.  Check for this
+#      and if the problem exists use a substitute procedure
+#      "fixstrtod" (provided by Tcl) that corrects the error.
+#      Also, on Compaq's Tru64 Unix 5.0,
+#      strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Might defines some of the following vars:
+#              strtod (=fixstrtod)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+    if test "$tcl_strtod" = 1; then
+       AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+           AC_TRY_RUN([
+               extern double strtod();
+               int main() {
+                   char *infString="Inf", *nanString="NaN", *spaceString=" ";
+                   char *term;
+                   double value;
+                   value = strtod(infString, &term);
+                   if ((term != infString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(nanString, &term);
+                   if ((term != nanString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(spaceString, &term);
+                   if (term == (spaceString+1)) {
+                       exit(1);
+                   }
+                   exit(0);
+               }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+                   tcl_cv_strtod_buggy=buggy)])
+       if test "$tcl_cv_strtod_buggy" = buggy; then
+           AC_LIBOBJ([fixstrtod])
+           USE_COMPAT=1
+           AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_LINK_LIBS
+#
+#      Search for the libraries needed to link the Tcl shell.
+#      Things like the math library (-lm) and socket stuff (-lsocket vs.
+#      -lnsl) are dealt with here.
+#
+# Arguments:
+#      Requires the following vars to be set in the Makefile:
+#              DL_LIBS
+#              LIBS
+#              MATH_LIBS
+#      
+# Results:
+#
+#      Subst's the following var:
+#              TCL_LIBS
+#              MATH_LIBS
+#
+#      Might append to the following vars:
+#              LIBS
+#
+#      Might define the following vars:
+#              HAVE_NET_ERRNO_H
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_LINK_LIBS], [
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+    AC_CHECK_HEADER(net/errno.h, [
+       AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+    if test "$tcl_checkSocket" = 1; then
+       AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
+           LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
+    fi
+    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
+           [LIBS="$LIBS -lnsl"])])
+
+    # TEA specific: Don't perform the eval of the libraries here because
+    # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(MATH_LIBS)
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+#      Check for what flags are needed to be passed so the correct OS
+#      features are available.
+#
+# Arguments:
+#      None
+#      
+# Results:
+#
+#      Might define the following vars:
+#              _ISOC99_SOURCE
+#              _LARGEFILE64_SOURCE
+#              _LARGEFILE_SOURCE64
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+       AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+           AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+       AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+       tcl_flags="$tcl_flags $1"
+    fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+    AC_MSG_CHECKING([for required early compiler flags])
+    tcl_flags=""
+    TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+       [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+       [struct stat64 buf; int i = stat64("/", &buf);])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+       [char *p = (char *)open64;])
+    if test "x${tcl_flags}" = "x" ; then
+       AC_MSG_RESULT([none])
+    else
+       AC_MSG_RESULT([${tcl_flags}])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+#      Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+#      None
+#      
+# Results:
+#
+#      Might define the following vars:
+#              TCL_WIDE_INT_IS_LONG
+#              TCL_WIDE_INT_TYPE
+#              HAVE_STRUCT_DIRENT64
+#              HAVE_STRUCT_STAT64
+#              HAVE_TYPE_OFF64_T
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+    AC_MSG_CHECKING([for 64-bit integer type])
+    AC_CACHE_VAL(tcl_cv_type_64bit,[
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+           tcl_type_64bit=__int64, tcl_type_64bit="long long")
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        AC_TRY_COMPILE(,[switch (0) { 
+            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; 
+        }],tcl_cv_type_64bit=${tcl_type_64bit})])
+    if test "${tcl_cv_type_64bit}" = none ; then
+       AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+       AC_MSG_RESULT([using long])
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # TEA specific: We actually want to use the default tcl.h checks in
+       # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       AC_MSG_RESULT([using Tcl header defaults])
+    else
+       AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+           [What type should be used to define wide integers?])
+       AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+       # Now check for auxiliary declarations
+       AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+           AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/dirent.h>],[struct dirent64 p;],
+               tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+       fi
+
+       AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+           AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+               tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+       fi
+
+       AC_CHECK_FUNCS(open64 lseek64)
+       AC_MSG_CHECKING([for off64_t])
+       AC_CACHE_VAL(tcl_cv_type_off64_t,[
+           AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+               tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+       dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+       dnl functions lseek64 and open64 are defined.
+       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+           AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+           AC_MSG_RESULT([yes])
+       else
+           AC_MSG_RESULT([no])
+       fi
+    fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+#      Init various Tcl Extension Architecture (TEA) variables.
+#      This should be the first called TEA_* macro.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              CYGPATH
+#              EXEEXT
+#      Defines only:
+#              TEA_VERSION
+#              TEA_INITED
+#              TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+#      Select the executable extension based on the host type.  This
+#      is a lightweight replacement for AC_EXEEXT that doesn't require
+#      a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.7"
+
+    AC_MSG_CHECKING([for correct TEA configuration])
+    if test x"${PACKAGE_NAME}" = x ; then
+       AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.in])
+    fi
+    if test x"$1" = x ; then
+       AC_MSG_ERROR([
+TEA version not specified.])
+    elif test "$1" != "${TEA_VERSION}" ; then
+       AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
+    else
+       AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+           AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+    AC_SUBST(EXEEXT)
+    AC_SUBST(CYGPATH)
+
+    # This package name must be replaced statically for AC_SUBST to work
+    AC_SUBST(PKG_LIB_FILE)
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+    AC_SUBST(PKG_STUB_LIB_FILE)
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+    AC_SUBST(PKG_TCL_SOURCES)
+    AC_SUBST(PKG_HEADERS)
+    AC_SUBST(PKG_INCLUDES)
+    AC_SUBST(PKG_LIBS)
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_SOURCES
+#              PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       case $i in
+           [\$]*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               # To add more dirs here (like 'src'), you have to update VPATH
+               # in Makefile.in as well
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   AC_MSG_ERROR([could not find source file '$i'])
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+    AC_SUBST(PKG_SOURCES)
+    AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_STUB_SOURCES
+#              PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           AC_MSG_ERROR([could not find stub source file '$i'])
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+#      Specify one or more Tcl source files.  These should be platform
+#      independent runtime files.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+    AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+#      Specify one or more source headers.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+    AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+#      Specify one or more include dirs.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+    vars="$@"
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+    AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+#      Specify one or more libraries.  Users should check for
+#      the right platform before adding to their list.  For Windows,
+#      libraries provided in "foo.lib" format will be converted to
+#      "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+    vars="$@"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+    AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+#      Specify one or more CFLAGS.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+    PKG_CFLAGS="$PKG_CFLAGS $@"
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+#      Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      If --prefix or --exec-prefix was not specified, $prefix and
+#      $exec_prefix will be set to the values given to Tcl when it was
+#      configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+           prefix=${TCL_PREFIX}
+       else
+           AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+           exec_prefix=$prefix
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+#      Do compiler checks the way we want.  This is just a replacement
+#      for AC_PROG_CC in TEA configure.in files to make them cleaner.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    AC_PROG_CC
+    AC_PROG_CPP
+
+    AC_PROG_INSTALL
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    AC_PROG_MAKE_SET
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    AC_PROG_RANLIB
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+    AC_OBJEXT
+    AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+#      Do compiler checks that use the compiler.  This must go after
+#      TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+    AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       AC_CACHE_CHECK([if the compiler understands -pipe],
+           tcl_cv_cc_pipe, [
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+           CFLAGS=$hold_cflags])
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    AC_C_BIGENDIAN
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       TEA_TCL_LINK_LIBS
+       TEA_MISSING_POSIX_HEADERS
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+#      Generate a line that can be used to build a shared/unshared library
+#      in a platform independent manner.
+#
+# Arguments:
+#      none
+#
+#      Requires:
+#
+# Results:
+#
+#      Defines the following vars:
+#      CFLAGS -        Done late here to note disturb other AC macros
+#       MAKE_LIB -      Command to execute to build the Tcl library;
+#                       differs depending on whether or not Tcl is being
+#                       compiled as a shared library.
+#      MAKE_SHARED_LIB Makefile rule for building a shared library
+#      MAKE_STATIC_LIB Makefile rule for building a static library
+#      MAKE_STUB_LIB   Makefile rule for building a stub library
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+    AC_SUBST(MAKE_LIB)
+    AC_SUBST(MAKE_SHARED_LIB)
+    AC_SUBST(MAKE_STATIC_LIB)
+    AC_SUBST(MAKE_STUB_LIB)
+    AC_SUBST(RANLIB_STUB)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+#      Compute the name of an existing object library located in libdir
+#      from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+#      basename        The base name of the library without version
+#                      numbers, extensions, or "lib" prefixes.
+#      extra_dir       Extra directory in which to search for the
+#                      library.  This location is used first, then
+#                      $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+#      TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+#      Defines the following vars:
+#              ${basename}_LIB_NAME    The computed library name.
+#              ${basename}_LIB_SPEC    The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+    AC_MSG_CHECKING([for $1 library])
+
+    # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+    tea_lib_name_dir="${exec_prefix}/lib"
+
+    # Or in a user-specified location.
+
+    if test x"$2" != x ; then
+       tea_extra_lib_dir=$2
+    else
+       tea_extra_lib_dir=NONE
+    fi
+
+    for i in \
+           `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+       if test -f "$i" ; then
+           tea_lib_name_dir=`dirname $i`
+           $1_LIB_NAME=`basename $i`
+           $1_LIB_PATH_NAME=$i
+           break
+       fi
+    done
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+    else
+       # Strip off the leading "lib" and trailing ".a" or ".so"
+
+       tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+       $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+    fi
+
+    if test "x${$1_LIB_NAME}" = x ; then
+       AC_MSG_ERROR([not found])
+    else
+       AC_MSG_RESULT([${$1_LIB_SPEC}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+#      Locate the private Tcl include files
+#
+# Arguments:
+#
+#      Requires:
+#              TCL_SRC_DIR     Assumes that TEA_LOAD_TCLCONFIG has
+#                              already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TCL_TOP_DIR_NATIVE
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+    # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+    AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+    AC_MSG_CHECKING([for Tcl private include files])
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+    # Check to see if tcl<Plat>Port.h isn't already with the public headers
+    # Don't look for tclInt.h because that resides with tcl.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+       -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+       result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+       -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+       result="private headers found with public headers"
+    else
+       TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+       if test "${TEA_PLATFORM}" = "windows"; then
+           TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+       else
+           TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+       fi
+       # Overwrite the previous TCL_INCLUDES as this should capture both
+       # public and private headers in the same set.
+       # We want to ensure these are substituted so as not to require
+       # any *_NATIVE vars be defined in the Makefile
+       TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+       if test "`uname -s`" = "Darwin"; then
+            # If Tcl was built as a framework, attempt to use
+            # the framework's Headers and PrivateHeaders directories
+            case ${TCL_DEFS} in
+               *TCL_FRAMEWORK*)
+                   if test -d "${TCL_BIN_DIR}/Headers" -a \
+                           -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+                       TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+                   else
+                       TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+                   fi
+                   ;;
+           esac
+           result="Using ${TCL_INCLUDES}"
+       else
+           if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+               AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+           fi
+           result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+       fi
+    fi
+
+    AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+    AC_SUBST(TCL_INCLUDES)
+    AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+#      Locate the installed public Tcl header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tclinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl public headers])
+
+    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tclh, [
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       AC_MSG_ERROR([tcl.h not found.  Please specify its location with --with-tclinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tclh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+#      Locate the private Tk include files
+#
+# Arguments:
+#
+#      Requires:
+#              TK_SRC_DIR      Assumes that TEA_LOAD_TKCONFIG has
+#                               already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+    # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+    AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+    AC_MSG_CHECKING([for Tk private include files])
+
+    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+    # Check to see if tk<Plat>Port.h isn't already with the public headers
+    # Don't look for tkInt.h because that resides with tk.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+       -f "${ac_cv_c_tkh}/tkWinPort.h"; then
+       result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+       -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+       result="private headers found with public headers"
+    else
+       TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+       TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+       if test "${TEA_PLATFORM}" = "windows"; then
+           TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+       else
+           TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+       fi
+       # Overwrite the previous TK_INCLUDES as this should capture both
+       # public and private headers in the same set.
+       # We want to ensure these are substituted so as not to require
+       # any *_NATIVE vars be defined in the Makefile
+       TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+       # Detect and add ttk subdir
+       if test -d "${TK_SRC_DIR}/generic/ttk"; then
+          TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+       fi
+       if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+          TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+       fi
+       if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+          TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+       fi
+       if test "`uname -s`" = "Darwin"; then
+           # If Tk was built as a framework, attempt to use
+           # the framework's Headers and PrivateHeaders directories
+           case ${TK_DEFS} in
+               *TK_FRAMEWORK*)
+                       if test -d "${TK_BIN_DIR}/Headers" -a \
+                               -d "${TK_BIN_DIR}/PrivateHeaders"; then
+                           TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+                       else
+                           TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+                       fi
+                       ;;
+           esac
+           result="Using ${TK_INCLUDES}"
+       else
+           if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+              AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+           fi
+           result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+       fi
+    fi
+
+    AC_SUBST(TK_TOP_DIR_NATIVE)
+    AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+    AC_SUBST(TK_INCLUDES)
+    AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+#      Locate the installed public Tk header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tkinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk public headers])
+
+    AC_ARG_WITH(tkinclude, [  --with-tkinclude        directory containing the public Tk header files], with_tkinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tkh, [
+       # Use the value from --with-tkinclude, if it was given
+
+       if test x"${with_tkinclude}" != x ; then
+           if test -f "${with_tkinclude}/tk.h" ; then
+               ac_cv_c_tkh=${with_tkinclude}
+           else
+               AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tk was built as a framework, attempt to use
+               # the framework's Headers directory.
+               case ${TK_DEFS} in
+                   *TK_FRAMEWORK*)
+                       list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tk is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TK_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tk's --prefix location,
+           # relative to directory of tkConfig.sh, Tcl's --prefix location, 
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TK_PREFIX}/include      2>/dev/null` \
+               `ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+           fi
+           for i in $list ; do
+               if test -f "$i/tk.h" ; then
+                   ac_cv_c_tkh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tkh}" = x ; then
+       AC_MSG_ERROR([tk.h not found.  Please specify its location with --with-tkinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tkh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TK_INCLUDES)
+
+    if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+       # On Windows and Aqua, we need the X compat headers
+       AC_MSG_CHECKING([for X11 header files])
+       if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+           INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+           TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+           AC_SUBST(TK_XINCLUDES)
+       fi
+       AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+#      Locate the ${1}Config.sh file and perform a sanity check on
+#      the ${1} compile flags.  These are used by packages like
+#      [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-$1=...
+#
+#      Defines the following vars:
+#              $1_BIN_DIR      Full path to the directory containing
+#                              the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+    #
+    # Ok, lets find the $1 configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-$1
+    #
+
+    if test x"${no_$1}" = x ; then
+       # we reset no_$1 in case something fails here
+       no_$1=true
+       AC_ARG_WITH($1, [  --with-$1              directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+       AC_MSG_CHECKING([for $1 configuration])
+       AC_CACHE_VAL(ac_cv_c_$1config,[
+
+           # First check to see if --with-$1 was specified.
+           if test x"${with_$1config}" != x ; then
+               case ${with_$1config} in
+                   */$1Config.sh )
+                       if test -f ${with_$1config}; then
+                           AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+                           with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+                       fi;;
+               esac
+               if test -f "${with_$1config}/$1Config.sh" ; then
+                   ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+               fi
+           fi
+
+           # then check for a private $1 installation
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in \
+                       ../$1 \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../$1 \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../$1 \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../$1 \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+                   if test -f "$i/unix/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_$1config}" = x ; then
+           $1_BIN_DIR="# no $1 configs found"
+           AC_MSG_WARN([Cannot find $1 configuration definitions])
+           exit 0
+       else
+           no_$1=
+           $1_BIN_DIR=${ac_cv_c_$1config}
+           AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+#      Load the $1Config.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              $1_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              $1_SRC_DIR
+#              $1_LIB_FILE
+#              $1_LIB_SPEC
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${$1_BIN_DIR}/$1Config.sh"
+    else
+        AC_MSG_RESULT([file not found])
+    fi
+
+    #
+    # If the $1_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable $1_LIB_SPEC will be set to the value
+    # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+    # instead of $1_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    #
+
+    if test -f "${$1_BIN_DIR}/Makefile" ; then
+       AC_MSG_WARN([Found Makefile - using build library specs for $1])
+        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+    fi
+
+    AC_SUBST($1_VERSION)
+    AC_SUBST($1_BIN_DIR)
+    AC_SUBST($1_SRC_DIR)
+
+    AC_SUBST($1_LIB_FILE)
+    AC_SUBST($1_LIB_SPEC)
+
+    AC_SUBST($1_STUB_LIB_FILE)
+    AC_SUBST($1_STUB_LIB_SPEC)
+    AC_SUBST($1_STUB_LIB_PATH)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+#      Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-celib=...
+#
+#      Defines the following vars:
+#              CELIB_DIR       Full path to the directory containing
+#                              the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+       AC_ARG_WITH(celib,[  --with-celib=DIR        use Windows/CE support library from DIR], with_celibconfig=${withval})
+       AC_MSG_CHECKING([for Windows/CE celib directory])
+       AC_CACHE_VAL(ac_cv_c_celibconfig,[
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           AC_MSG_ERROR([Cannot find celib support library directory])
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           AC_MSG_RESULT([found $CELIB_DIR])
+       fi
+    fi
+])
+
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/8.x/tclvfs/tests/all.tcl b/8.x/tclvfs/tests/all.tcl
new file mode 100644 (file)
index 0000000..f44762c
--- /dev/null
@@ -0,0 +1,71 @@
+# all.tcl --
+#
+# This file contains a top-level script to run all of the Tcl
+# tests.  Execute it by invoking "source all.test" when running tcltest
+# in this directory.
+#
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+# All rights reserved.
+# 
+# RCS: @(#) $Id: all.tcl,v 1.3 2008/12/03 02:20:45 hobbs Exp $
+
+set tcltestVersion [package require tcltest]
+namespace import -force tcltest::*
+
+#tcltest::testsDirectory [file dir [info script]]
+#tcltest::runAllTests
+
+set ::tcltest::testSingleFile false
+set ::tcltest::testsDirectory [file dir [info script]]
+
+proc vfsCreateInterp {name} {
+    # Use the same setup to access vfs as the master
+    if {[catch {
+       interp create $name
+       $name eval [list set ::auto_path $::auto_path]
+       $name eval {package require vfs}
+    } err]} {
+       puts "$err ; $::errorInfo"
+    }
+}
+
+# We need to ensure that the testsDirectory is absolute
+::tcltest::normalizePath ::tcltest::testsDirectory
+
+package require vfs 1.4
+
+puts stdout "Tests running in interp:  [info nameofexecutable]"
+puts stdout "Tests running in working dir:  $::tcltest::testsDirectory"
+if {[llength $::tcltest::skip] > 0} {
+    puts stdout "Skipping tests that match:  $::tcltest::skip"
+}
+if {[llength $::tcltest::match] > 0} {
+    puts stdout "Only running tests that match:  $::tcltest::match"
+}
+
+if {[llength $::tcltest::skipFiles] > 0} {
+    puts stdout "Skipping test files that match:  $::tcltest::skipFiles"
+}
+if {[llength $::tcltest::matchFiles] > 0} {
+    puts stdout "Only sourcing test files that match:  $::tcltest::matchFiles"
+}
+
+tcltest::testConstraint fsIsWritable [expr {1 - [catch {file mkdir isreadonly ; file delete isreadonly}]}]
+
+set timeCmd {clock format [clock seconds]}
+puts stdout "Tests began at [eval $timeCmd]"
+
+# source each of the specified tests
+foreach file [lsort [::tcltest::getMatchingFiles]] {
+    set tail [file tail $file]
+    puts stdout $tail
+    if {[catch {source $file} msg]} {
+       puts stdout $msg
+    }
+}
+
+# cleanup
+puts stdout "\nTests ended at [eval $timeCmd]"
+::tcltest::cleanupTests 1
+return
+
diff --git a/8.x/tclvfs/tests/vfs.test b/8.x/tclvfs/tests/vfs.test
new file mode 100644 (file)
index 0000000..7cbc1aa
--- /dev/null
@@ -0,0 +1,210 @@
+# Commands covered:  vfs::filesystem
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2001-2002 by Vince Darley.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import ::tcltest::*
+}
+
+package require vfs
+
+proc filelistrelative {filelist {remove ""}} {
+    if {[llength $remove]} {
+       set newlist {}
+       foreach f $filelist {
+           if {[lsearch -exact $remove $f] == -1} {
+               lappend newlist $f
+           }
+       }
+       set filelist $newlist
+    }
+    set dir [file normalize [pwd]]
+    set len [string length $dir]
+    incr len
+    set res {}
+    foreach d $filelist {
+       if {[string first $dir $d] == 0} {
+          lappend res [string range $d $len end]
+       } else {
+          lappend res $d
+       }
+    }
+    set res
+}
+
+test vfs-1.1 {mount unmount} {
+    catch {unset res}
+    vfs::filesystem mount foo bar
+    set res [list [catch {vfs::filesystem unmount foo bar} err]]
+    lappend res $err
+    vfs::filesystem unmount foo
+    unset err
+    set res
+} {1 {wrong # args: should be "vfs::filesystem unmount path"}}
+
+
+# Test 2.x sub-interps
+
+test vfs-2.1 {mount unmount in sub interp} {
+    catch {interp delete a}
+    catch {unset res}
+    set remove [vfs::filesystem info]
+    vfs::filesystem mount foo bar
+    vfsCreateInterp a
+    a eval {package require vfs}
+    a eval {vfs::filesystem mount foo2 bar2}
+    set res {}
+    eval lappend res [vfs::filesystem info]
+    a eval {vfs::filesystem unmount foo2}
+    interp delete a
+    eval lappend res [vfs::filesystem info]
+    vfs::filesystem unmount foo
+    filelistrelative $res $remove
+} {foo2 foo foo}
+
+test vfs-2.2 {mount, delete sub interp} {
+    catch {interp delete a}
+    catch {unset res}
+    set remove [vfs::filesystem info]
+    vfs::filesystem mount foo bar
+    vfsCreateInterp a
+    a eval {package require vfs}
+    a eval {vfs::filesystem mount foo2 bar2}
+    set res {}
+    eval lappend res [vfs::filesystem info]
+    interp delete a
+    eval lappend res [vfs::filesystem info]
+    vfs::filesystem unmount foo
+    filelistrelative $res $remove
+} {foo2 foo foo}
+
+test vfs-2.3 {mount where command doesn't exist} {
+    # This is failing in 8.4.0-19, ok in 8.5, but changed message in 8.5.6
+    # and causes the 'error reading package index' in other tests for 8.4
+    vfs::filesystem mount foo bar
+    set code [catch {glob foo/pkgIndex.tcl} msg]
+    vfs::filesystem unmount foo
+    list $code $msg
+} {1 {invalid command name "bar"}}
+
+test vfs-2.4 {mount where command doesn't exist} {
+    # Building on vfs-2.3, but -nocomplain changed in 8.5 to still complain
+    # on real underlying issues (just not on empty result)
+    vfs::filesystem mount foo bar
+    set code [catch {glob -nocomplain foo/pkgIndex.tcl} msg]
+    vfs::filesystem unmount foo
+    if {![package vsatisfies [package require Tcl] 8.5]} {
+       if {$code == 0} {
+           set code 1 ; set msg {invalid command name "bar"}
+       }
+    }
+    list $code $msg
+} {1 {invalid command name "bar"}}
+
+test vfs-3.1 {vfs helpers: in memory channels} {
+    close [::vfs::memchan]
+    # If we get here, it's ok.  If this test fails,
+    # probably many other tests will fail too.  In particular
+    # any use of 'open', 'source', 'load', and usually also
+    # 'file copy', 'file rename' in a vfs will fail.
+    # 
+    # What this means is that tclvfs can't find some other
+    # extension/code it requires -- you may need to install
+    # the Memchan or Rchan extension for example.
+} {}
+
+test vfs-3.2 {vfs helpers: crc} {
+    # If this test fails, probably many other tests will fail too (at
+    # least anything to do with 'zip' vfs).
+    # 
+    # What this means is that tclvfs can't find some other
+    # extension/code it requires -- you may need to install
+    # the Trf extension for example.
+    format %08x [::vfs::crc abcd]
+} {ed82cd11}
+
+test vfs-3.3 {vfs helpers: zip} {
+    # If this test fails, probably many other tests will fail too (at
+    # least anything to do with 'zip' vfs).
+    # 
+    # What this means is that tclvfs can't find some other
+    # extension/code it requires -- you may need to install
+    # the Try extension for example.
+    ::vfs::zip -mode compress 1234567890
+} "\x78\x9c\x33\x34\x32\x36\x31\x35\x33\xb7\xb0\x34\x0\x0\xb\x2c\x2\xe"
+
+test vfs-3.4 {vfs helpers: zip} {
+    # If this test fails, probably many other tests will fail too (at
+    # least anything to do with 'zip' vfs).
+    # 
+    # What this means is that tclvfs can't find some other
+    # extension/code it requires -- you may need to install
+    # the Try extension for example.
+    ::vfs::zip -mode decompress "\x78\x9c\x33\x34\x32\x36\x31\x35\x33\xb7\xb0\x34\x0\x0\xb\x2c\x2\xe"
+} {1234567890}
+
+test vfs-4.1 {vfs glob with .. [Bug 2378350]} -setup {
+    package require vfs::ns 0.5.1
+} -body {
+    namespace eval ::test {}
+    namespace eval ::test::bar {}
+    namespace eval ::test::baz {}
+    proc ::test::waz {args} { blah blah}
+    proc ::test::bar::lol {args} { body body }
+    proc ::test::baz::noz {args} { moo moo }
+    vfs::ns::Mount :: nstest
+    set res [list]
+    lappend res [catch {lsort [glob nstest/test/*]} msg] $msg \
+       [catch {lsort [glob nstest/test/baz/*]} msg] $msg \
+       [catch {lsort [glob nstest/test/bar/../baz/*]} msg] $msg
+} -cleanup {
+    catch {vfs::unmount nstest}
+    catch {namespace delete ::test}
+} -result [list \
+              0 {nstest/test/bar nstest/test/baz nstest/test/waz} \
+              0 {nstest/test/baz/noz} \
+              0 {nstest/test/bar/../baz/noz} \
+              ]
+
+test vfs-4.2 {Test MatchInDirectory fix} -setup {
+    package require vfs::ns 0.5.1
+} -body {
+    namespace eval ::test {}
+    namespace eval ::test::quux {}
+    proc ::test::waz {args} { blah blah}
+    vfs::ns::Mount :: nstest
+    set res [list]
+    lappend res \
+           [catch {lsort [glob nstest/test/*]} msg] $msg \
+           [catch {lsort [glob nstest/test/quux/*]} msg] $msg \
+           [catch {lsort [glob -nocomplain nstest/test/quux/*]} msg] $msg \
+           [catch {lsort [glob nstest/test/quux/nothingthere/*]} msg] $msg \
+           [catch {lsort [glob -nocomplain nstest/test/quux/nothingthere/*]} msg] $msg \
+} -cleanup {
+    catch {vfs::unmount nstest}
+    catch {namespace delete ::test}
+} -result [list \
+              0 {nstest/test/quux nstest/test/waz} \
+               1 {no files matched glob pattern "nstest/test/quux/*"} \
+               0 {} \
+               1 {no files matched glob pattern "nstest/test/quux/nothingthere/*"} \
+               0 {} \
+              ]
+
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local variables:
+# mode: tcl
+# End:
\ No newline at end of file
diff --git a/8.x/tclvfs/tests/vfsArchive.test b/8.x/tclvfs/tests/vfsArchive.test
new file mode 100644 (file)
index 0000000..a135d78
--- /dev/null
@@ -0,0 +1,129 @@
+# vfsArchive.test                                               -*- tcl -*-
+#
+#      Commands covered: running our tests from inside a 'zip' vfs.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2001-2002 by Vince Darley.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import ::tcltest::*
+}
+
+# -------------------------------------------------------------------------
+# This file really buggers up the normal test suite run.
+# Comment this return if you really want to run this.
+#
+return
+#
+# -------------------------------------------------------------------------
+
+tcltest::testConstraint nativefs \
+  [string equal [lindex [file system [info script]] 0] "native"]
+
+proc makeAndMountZipArchive {} {
+    puts stdout "Zipping tests" ; update
+    cd [file dirname [file dirname [file normalize [info script]]]]
+    set filelist [concat [glob -dir [pwd] -join -tails tests *.test] \
+      [glob -dir [pwd] -join -tails tests *.tcl]]
+    catch {file delete [file join tests tests.zip]}
+    eval [list exec zip -q -9 [file join tests tests.zip]] $filelist
+    puts stdout "Done zipping"
+    cd [file dirname [info script]]
+    
+    package require vfs::zip
+    set mount [vfs::zip::Mount tests.zip tests.zip]
+    #puts "[pwd] ; $::auto_path, [glob *]"
+    pwd
+    cd tests.zip
+    return [list vfs::zip::Unmount $mount tests.zip]
+}
+
+proc makeAndMountMk4Archive {} {
+    puts stdout "Making mk4 archive of tests" ; update
+    cd [file dirname [file dirname [file normalize [info script]]]]
+    catch {file delete [file join tests tests.bin]}
+    exec sdx fs2sd tests
+    puts stdout "Done making mk4 archive"
+    cd [file dirname [info script]]
+    
+    package require vfs::mk4
+    set mount [vfs::mk4::Mount tests.bin tests.bin]
+    cd tests.bin
+    return [list vfs::mk4::Unmount $mount tests.bin]
+}
+
+# This actually calls the test suite recursively, which probably
+# causes some problems, although it shouldn't really!
+test vfsArchive-1.0 {package require vfs} {
+    if {![catch {package require vfs} res]} {
+       set res "ok"
+    }
+    set res
+} {ok}
+
+# This actually calls the test suite recursively, which probably
+# causes some problems, although it shouldn't really!
+test vfsArchive-1.1 {run tests in zip archive} {nativefs} {
+    # If this test fails, you probably don't have 'zip' installed.
+    set testdir [pwd]
+    package require vfs
+    if {[catch {makeAndMountZipArchive} unmount]} {
+       set res "Couldn't make and mount zip archive to test with: $unmount"
+       puts $::errorInfo
+       puts stderr $::auto_path
+    } else {
+       puts stdout "=== Running tests in zip archive ==="
+       if {![catch {
+           cd tests
+           source all.tcl
+           cd ..
+           cd ..
+           puts [pwd]
+           eval $unmount
+       } res]} {
+           set res "ok"
+       }
+       puts stdout "=== End of embedded zip tests ==="
+    }
+    cd $testdir
+    set res
+} {ok}
+
+
+# This actually calls the test suite recursively, which probably
+# causes some problems, although it shouldn't really!
+test vfsArchive-1.2 {run tests in mk4 archive} {nativefs} {
+    # If this test fails, you probably don't have tclkit and 'sdx'
+    # installed.  That's not a big deal.
+    set testdir [pwd]
+    puts stderr $testdir
+    package require vfs
+    if {[catch {makeAndMountMk4Archive} unmount]} {
+       set res "Couldn't make and mount mk4 archive to test with: $unmount"
+       puts stderr $::auto_path
+    } else {
+       puts stdout "=== Running tests in mk4 archive ==="
+       cd tests
+       source all.tcl
+       cd ..
+       cd ..
+       puts [pwd]
+       eval $unmount
+       set res "ok"
+       puts stdout "=== End of embedded mk4 tests ==="
+    }
+    cd $testdir
+    set res
+} {ok}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/8.x/tclvfs/tests/vfsFtp.test b/8.x/tclvfs/tests/vfsFtp.test
new file mode 100644 (file)
index 0000000..27cba12
--- /dev/null
@@ -0,0 +1,61 @@
+# vfsFtp.test                                                   -*- tcl -*-
+#
+#      Commands covered:  vfs::ftp::Mount and friends.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2001 by Vince Darley.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import ::tcltest::*
+}
+
+testConstraint ftp [expr {![catch {package require vfs::ftp}]}]
+
+if {[testConstraint ftp]} {
+    puts stdout "These tests require an internet connection, and might"
+    puts stdout "take a long time to complete."
+}
+
+test vfsFtp-1.1 {mount and cd} -constraints {ftp} -setup {
+    set cwd [pwd]
+} -body {
+    vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ local
+    cd local
+    cd tcl
+    set result [file tail [pwd]]
+    vfs::unmount local
+    set result
+} -cleanup {
+    cd $pwd
+} -result {tcl}
+
+test vfsFtp-1.2 {mount and glob} -constraints {ftp} -setup {
+    vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ local
+} -body {
+    glob -nocomplain -directory local/tcl vfsTest.tcl
+} -cleanup {
+    vfs::unmount local
+} -result {vfsTest.tcl}
+
+test vfsFtp-1.3 {mount and source} -constraints {ftp} -setup {
+    vfs::ftp::Mount ftp://ftp.ucsd.edu/pub/alpha/ local
+} -body {
+    set f [open local/tcl/vfsTest.tcl r]
+    set data [read $f]
+    close $f
+    set data
+} -cleanup {
+    vfs::unmount local
+} -result {This was returned from a remote file}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/8.x/tclvfs/tests/vfsTar.test b/8.x/tclvfs/tests/vfsTar.test
new file mode 100644 (file)
index 0000000..bf74703
Binary files /dev/null and b/8.x/tclvfs/tests/vfsTar.test differ
diff --git a/8.x/tclvfs/tests/vfsUrl.test b/8.x/tclvfs/tests/vfsUrl.test
new file mode 100644 (file)
index 0000000..3716ae5
--- /dev/null
@@ -0,0 +1,101 @@
+# vfsZip.test                                                   -*- tcl -*-
+#
+#      Commands covered:  vfs::urltype::Mount and friends.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2001 by Vince Darley.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import ::tcltest::*
+}
+
+package require vfs::urltype
+
+puts stdout "These tests require an internet connection, and might"
+puts stdout "take a long time to complete."
+
+set vfsTestDir [pwd]
+if {![file writable $vfsTestDir]} {
+    if {[info exists env(TEMP)] && [file writable $env(TEMP)]} {
+       set vfsTestDir $env(TEMP)
+       tcltest::testConstraint vfsWritable 1
+       puts stdout "Using temporary directory for some files\
+         (since [pwd] is not writable)"
+    } else {
+       tcltest::testConstraint vfsWritable 0
+    }
+} else {
+    tcltest::testConstraint vfsWritable 1
+}
+
+test vfsUrl-1.1 {mount} {
+    vfs::urltype::Mount ftp
+} {Mounted at "ftp://"}
+
+test vfsUrl-1.2 {mount} {
+    file exists ftp://ftp.tcl.tk
+} {1}
+
+test vfsUrl-1.3 {mounted volumes} {
+    set idx [lsearch -exact [file volumes] ftp://]
+    if {$idx < 0} {
+       set res "No ftp:// volume!"
+    } else {
+       set res "New volume 'ftp://' mounted"
+    }
+    set res
+} {New volume 'ftp://' mounted}
+
+test vfsUrl-2.1 {auto-mount ftp and copy file} {vfsWritable} {
+    file delete -force README.tclversions
+    file copy ftp://ftp.tcl.tk/pub/tcl/README.tclversions $vfsTestDir
+    set to [file join $vfsTestDir README.tclversions]
+    if {[file exists $to]} {
+       if {[file size $to] < 800} {
+           set res "file too short"
+       } else {
+           set res "ok"
+       }
+    } else {
+       set res "file doesn't exist"
+    }
+    file delete $to
+    set res
+} {ok}
+
+test vfsUrl-2.2 {auto-mount bad ftp} {
+    catch {file copy ftp://invalid.name.dom/pub/tcl/README.tclversions $vfsTestDir}
+    set to [file join $vfsTestDir README.tclversions]
+    if {[file exists $to]} {
+       set res "file shouldn't exist!"
+       file delete -force $to
+    } else {
+       set res "file doesn't exist"
+    }
+    set res
+} {file doesn't exist}
+
+test vfsUrl-3.1 {mount http} {
+    vfs::urltype::Mount http
+} {Mounted at "http://"}
+
+# cleanup
+catch {
+    # Unmount all successfully mounted volumes.
+    foreach vol [file volumes] {
+       if {[regexp {^([a-zA-Z]+):/?//$} $vol "" type]} {
+           catch {vfs::urltype::Unmount $type}
+       }
+    }
+}
+
+::tcltest::cleanupTests
+return
diff --git a/8.x/tclvfs/tests/vfsZip.test b/8.x/tclvfs/tests/vfsZip.test
new file mode 100644 (file)
index 0000000..383fda2
--- /dev/null
@@ -0,0 +1,356 @@
+# vfsZip.test                                                   -*- tcl -*-
+#
+#      Commands covered:  the 'zip' vfs.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2001-2002 by Vince Darley.
+# Copyright (c) 2009 by Pat Thoyts <patthoyts@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import ::tcltest::*
+}
+
+testConstraint zipfs [expr {![catch {package require vfs::zip}]}]
+
+# To test this properly we require a zip file. If a zip
+# executable can be found then we will create one.
+#
+testConstraint zipexe [expr {[auto_execok zip] ne ""}]
+if {[testConstraint zipfs] && [testConstraint zipexe]} {
+    file mkdir zipfs.test
+    makeFile {File one} zipfs.test/One.txt
+    makeFile {File two} zipfs.test/Two.txt
+    file mkdir zipfs.test/Aleph
+    makeFile {File aleph one} zipfs.test/Aleph/One.txt
+    makeFile {File aleph two} zipfs.test/Aleph/Two.txt
+    eval exec [auto_execok zip] [list -r zipfs.zip zipfs.test]
+    eval exec [auto_execok zip] [list zipnest.zip zipfs.zip]
+
+    file mkdir zipglob.test
+    makeFile {Glob one} "zipglob.test/one\[1\].txt"
+    makeFile {Glob two} "zipglob.test/two \[2\].txt"
+    file mkdir zipglob.test/a\[0\]
+    makeFile {Glob three} "zipglob.test/a\[0\]/three.txt"
+    eval exec [auto_execok zip] [list -r zipglob.zip zipglob.test]
+
+    testConstraint zipcat [expr {![catch {
+        makeFile {} zipcat.zip
+        set f [open zipcat.zip w] ; fconfigure $f -translation binary
+        set fin [open zipfs.zip r] ; fconfigure $fin -translation binary
+        puts -nonewline $f "[string repeat # 4095]\xff"
+        fcopy $fin $f
+        close $fin ; close $f
+        eval exec [auto_execok zip] [list -A zipcat.zip]
+    }]}]
+}
+
+test vfsZip-1.1 "mount non-existent zip file" -constraints {zipfs} -setup {
+    set file [makeFile {} vfszip.zip]
+} -body {
+    set mnt [vfs::zip::Mount $file localmount]
+} -cleanup {
+    removeFile $file
+} -returnCodes {error} -result {no header found}
+
+test vfsZip-1.2 "mount invalid zip file"  -constraints {zipfs} -setup {
+    set file [makeFile {random text} vfszip.zip]
+} -body {
+    set mnt [vfs::zip::Mount $file localmount]
+} -cleanup {
+    removeFile $file
+} -returnCodes {error} -result {no header found}
+
+test vfsZip-1.3 "mount zipfile" -constraints {zipfs zipexe} -body {
+    vfs::zip::Mount zipfs.zip local
+    vfs::unmount local
+} -result {}
+
+test vfsZip-1.4 "glob" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    glob -directory local *
+} -cleanup {
+    vfs::unmount local
+} -result {local/zipfs.test}
+
+test vfsZip-1.5 "glob files" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    lsort [glob -directory local/zipfs.test -tails *]
+} -cleanup {
+    vfs::unmount local
+} -result {Aleph One.txt Two.txt}
+
+test vfsZip-1.6 "glob non-present files" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    lsort [glob -directory local/zipfs.test -tails ridikulus.txt]
+} -cleanup {
+    vfs::unmount local
+} -returnCodes {error} -result {no files matched glob pattern "ridikulus.txt"}
+
+test vfsZip-1.7 "glob non-present directory" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    lsort [glob -directory local/zipfs.test/ridikulus -tails *]
+} -cleanup {
+    vfs::unmount local
+} -returnCodes {error} -result {no files matched glob pattern "*"}
+
+test vfsZip-1.8 "read file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    set f [open local/zipfs.test/One.txt r]
+    set data [string trim [read $f]]
+    close $f
+    set data
+} -cleanup {
+    vfs::unmount local
+} -result {File one}
+
+test vfsZip-1.9 "stat file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat local/zipfs.test/One.txt stat
+    lappend result type $stat(type) size [expr {$stat(size) > 8}]
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount local
+} -result {type file size 1}
+
+test vfsZip-1.10 "stat directory" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat local/zipfs.test/Aleph stat
+    lappend result type $stat(type) size $stat(size)
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount local
+} -result {type directory size 0}
+
+test vfsZip-1.11 "cd directory" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+    set cwd [pwd]
+} -body {
+    cd local/zipfs.test/Aleph
+    lsort [glob *]
+} -cleanup {
+    cd $cwd
+    vfs::unmount local
+} -result {One.txt Two.txt}
+
+test vfsZip-1.12 "globby filenames" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipglob.zip local
+} -body {
+    glob -type f -tail -directory local/zipglob.test *
+} -cleanup {
+    vfs::unmount local
+} -result [list "one\[1\].txt" "two \[2\].txt"]
+
+test vfsZip-1.13 "globby filenames" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipglob.zip local
+} -body {
+    set result {}
+    foreach file [glob -type f -directory local/zipglob.test *] {
+        set f [open $file r]
+        lappend result [string trim [read $f]]
+    }
+    set result
+} -cleanup {
+    vfs::unmount local
+} -result [list "Glob one" "Glob two"]
+
+test vfsZip-1.14 "globby subdir" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipglob.zip local
+} -body {
+    glob -type d -tail -directory local/zipglob.test *
+} -cleanup {
+    vfs::unmount local
+} -result [list "a\[0\]"]
+
+test vfsZip-1.15 "globby subdir" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipglob.zip local
+} -body {
+    set result {}
+    foreach dir [glob -type d -directory local/zipglob.test *] {
+        lappend result [glob -nocomplain -tail -directory $dir *]
+    }
+    set result
+} -cleanup {
+    vfs::unmount local
+} -returnCodes {ok error} -result {three.txt}
+
+test vfsZip-2.0 "nested stat file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat local/zipfs.zip stat
+    lappend result type $stat(type) size [expr {$stat(size) != 0}]
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount local
+} -result {type file size 1}
+
+test vfsZip-2.1 "nested mount" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+} -body {
+    vfs::zip::Mount local/zipfs.zip nested
+    vfs::unmount nested
+} -cleanup {
+    vfs::unmount local
+} -result {}
+
+test vfsZip-2.2 "stat mountpoint" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+    vfs::zip::Mount local/zipfs.zip nested
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat nested stat
+    lappend result type $stat(type) size $stat(size)
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount nested
+    vfs::unmount local
+} -result {type directory size 0}
+
+test vfsZip-2.3 "stat nested file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+    vfs::zip::Mount local/zipfs.zip nested
+    unset -nocomplain stat
+    set result ""
+} -body {
+    file stat nested/zipfs.test/One.txt stat
+    lappend result type $stat(type) size [expr {$stat(size) > 0}]
+} -cleanup {
+    unset -nocomplain stat
+    vfs::unmount nested
+    vfs::unmount local
+} -result {type file size 1}
+
+test vfsZip-2.4 "nested self-mount" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip local
+} -body {
+    vfs::zip::Mount local/zipfs.zip local/zipfs.zip
+    set r [file isdirectory local/zipfs.zip]
+    vfs::unmount local/zipfs.zip
+    set r
+} -cleanup {
+    vfs::unmount local
+} -result {1}
+
+test vfsZip-2.5 "nested cwd" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip vfszip25
+    vfs::zip::Mount vfszip25/zipfs.zip vfszip25/zipfs.zip
+    set cwd [pwd]
+} -body {
+    cd vfszip25/zipfs.zip/zipfs.test/Aleph
+    lsort [glob *]
+} -cleanup {
+    cd $cwd
+    vfs::unmount vfszip25/zipfs.zip
+    vfs::unmount vfszip25
+} -result {One.txt Two.txt}
+
+# NOTE: this test issues an error, it should probably be a nicer error though if
+#       someone unmounts while using the vfs. At the moment the message is garbage.
+#
+test vfsZip-2.6 "nested cwd, umount in use" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipnest.zip vfszip26
+    set cwd [pwd]
+} -body {
+    vfs::zip::Mount vfszip26/zipfs.zip vfszip26/zipfs.zip
+    cd vfszip26/zipfs.zip/zipfs.test/Aleph
+    vfs::unmount vfszip26/zipfs.zip
+    pwd
+} -cleanup {
+    cd $cwd
+    vfs::unmount vfszip26/zipfs.zip
+    vfs::unmount vfszip26
+} -returnCodes {error} -match glob -result {*}
+
+
+test vfsZip-2.7 "nested mount mis-ordered unmounts" -constraints {zipfs zipexe} -setup {
+} -body {
+    vfs::zip::Mount zipnest.zip vfszip27
+    vfs::zip::Mount vfszip27/zipfs.zip vfszip27/zipfs.zip
+    set r [file isdirectory vfszip27/zipfs.zip]
+    vfs::unmount vfszip27
+    vfs::unmount vfszip27/zipfs.zip
+    set r
+} -cleanup {
+} -result {1}
+
+testConstraint bug1533748 [file exists [file join [testsDirectory] bug1533748.zip]]
+
+test vfsZip-3.0 "bug #: ./ prefixed filenames" -constraints {zipfs zipexe bug1533748} -setup {
+    vfs::zip::Mount [file join [testsDirectory] bug1533748.zip] vfszip30
+} -body {
+    list [glob -nocomplain -directory vfszip30 -tails *] \
+        [glob -nocomplain -directory vfszip30/articles -tails *] \
+} -cleanup {
+    vfs::unmount vfszip30
+} -result {articles c_5498.xml}
+
+test vfsZip-3.1 "bug #: ./ prefixed filenames" -constraints {zipfs zipexe bug1533748} -setup {
+    vfs::zip::Mount [file join [testsDirectory] bug1533748.zip] vfszip31
+} -body {
+    set f [open vfszip31/articles/c_5498.xml r]
+    fconfigure $f -translation binary
+    set data [read $f]
+    close $f
+    expr {[string length $data] == [file size vfszip31/articles/c_5498.xml]}
+} -cleanup {
+    vfs::unmount vfszip31
+} -result {1}
+
+test vfsZip-4.0 "zip with preface code" -constraints {zipfs zipcat} -body {
+    vfs::zip::Mount zipcat.zip local
+    set r [glob -nocomplain -directory local -tails *]
+    vfs::unmount local
+    set r
+} -result {zipfs.test}
+
+test vfsZip-4.1 "zip with preface code" -constraints {zipfs zipcat} -setup {
+    vfs::zip::Mount zipcat.zip local
+} -body {
+    set f [open local/zipfs.test/Aleph/One.txt r]
+    set r [string trim [read $f]]
+    close $f
+    set r
+} -cleanup {
+    vfs::unmount local
+} -result {File aleph one}
+
+test vfsZip-9.0 "attempt to delete mounted file" -constraints {zipfs zipexe} -setup {
+    vfs::zip::Mount zipfs.zip local
+} -body {
+    file delete zipfs.zip
+} -cleanup {
+    vfs::unmount local
+} -returnCodes {error} -result {error deleting "zipfs.zip": permission denied}
+
+
+# cleanup
+if {[testConstraint zipfs] && [testConstraint zipexe]} {
+    file delete -force zipfs.test
+    file delete -force zipglob.test
+    file delete zipfs.zip
+    file delete zipnest.zip
+    file delete zipglob.zip
+}
+tcltest::cleanupTests
+return
diff --git a/8.x/tclvfs/win/makefile.vc b/8.x/tclvfs/win/makefile.vc
new file mode 100644 (file)
index 0000000..3299755
--- /dev/null
@@ -0,0 +1,512 @@
+# makefile.vc --                                               -*- Makefile -*-
+#
+# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
+#
+# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
+# make it suitable as a general package makefile. Look for the word EDIT
+# which marks sections that may need modification. As a minumum you will
+# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
+# relevant to your package.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+# Copyright (c) 2001 ActiveState Corporation.
+# Copyright (c) 2001-2002 David Gravereaux.
+# Copyright (c) 2003-2008 Pat Thoyts
+#
+#-------------------------------------------------------------------------
+# RCS: @(#)$Id: makefile.vc,v 1.32 2009/05/30 17:00:52 patthoyts Exp $
+#-------------------------------------------------------------------------
+
+# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
+# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
+# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
+MSG = ^
+You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
+Platform SDK first to setup the environment.  Jump to this line to read^
+the build instructions.
+!error $(MSG)
+!endif
+
+#------------------------------------------------------------------------------
+# HOW TO USE this makefile:
+#
+# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
+#     used  as a check to see if vcvars32.bat had been run prior to running
+#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
+#     been set globally and the PATH adjusted.  Either way is valid.
+#
+#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
+#     directory to setup the proper environment, if needed, for your current
+#     setup.  This is a needed bootstrap requirement and allows the swapping of
+#     different environments to be easier.
+#
+# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
+#     vcvars32.bat according to the instructions for it.  This can also turn on
+#     the 64-bit compiler, if your SDK has it.
+#
+# 3)  Targets are:
+#      all       -- Builds everything.
+#       <project> -- Builds the project (eg: nmake sample)
+#      test      -- Builds and runs the test suite.
+#      install   -- Installs the built binaries and libraries to $(INSTALLDIR)
+#                   in an appropriate subdirectory.
+#      clean/realclean/distclean -- varying levels of cleaning.
+#
+# 4)  Macros usable on the commandline:
+#      INSTALLDIR=<path>
+#              Sets where to install Tcl from the built binaries.
+#              C:\Progra~1\Tcl is assumed when not specified.
+#
+#      OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
+#              Sets special options for the core.  The default is for none.
+#              Any combination of the above may be used (comma separated).
+#              'none' will over-ride everything to nothing.
+#
+#              static  =  Builds a static library of the core instead of a
+#                         dll.  The shell will be static (and large), as well.
+#              msvcrt  =  Effects the static option only to switch it from
+#                         using libcmt(d) as the C runtime [by default] to
+#                         msvcrt(d). This is useful for static embedding
+#                         support.
+#              staticpkg = Effects the static option only to switch
+#                         tclshXX.exe to have the dde and reg extension linked
+#                         inside it.
+#              nothreads = Turns off multithreading support (not recommended)
+#              thrdalloc = Use the thread allocator (shared global free pool).
+#              symbols =  Adds symbols for step debugging.
+#              profile =  Adds profiling hooks.  Map file is assumed.
+#              loimpact =  Adds a flag for how NT treats the heap to keep memory
+#                         in use, low.  This is said to impact alloc performance.
+#
+#      STATS=memdbg,compdbg,none
+#              Sets optional memory and bytecode compiler debugging code added
+#              to the core.  The default is for none.  Any combination of the
+#              above may be used (comma separated).  'none' will over-ride
+#              everything to nothing.
+#
+#              memdbg   = Enables the debugging memory allocator.
+#              compdbg  = Enables byte compilation logging.
+#
+#      MACHINE=(IX86|IA64|ALPHA|AMD64)
+#              Set the machine type used for the compiler, linker, and
+#              resource compiler.  This hook is needed to tell the tools
+#              when alternate platforms are requested.  IX86 is the default
+#              when not specified. If the CPU environment variable has been
+#              set (ie: recent Platform SDK) then MACHINE is set from CPU.
+#
+#      TMP_DIR=<path>
+#      OUT_DIR=<path>
+#              Hooks to allow the intermediate and output directories to be
+#              changed.  $(OUT_DIR) is assumed to be 
+#              $(BINROOT)\(Release|Debug) based on if symbols are requested.
+#              $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
+#
+#      TESTPAT=<file>
+#              Reads the tests requested to be run from this file.
+#
+#      CFG_ENCODING=encoding
+#              name of encoding for configuration information. Defaults
+#              to cp1252
+#
+# 5)  Examples:
+#
+#      Basic syntax of calling nmake looks like this:
+#      nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
+#
+#                        Standard (no frills)
+#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+#       Setting environment for using Microsoft Visual C++ tools.
+#       c:\tcl_src\win\>nmake -f makefile.vc all
+#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
+#
+#                         Building for Win64
+#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+#       Setting environment for using Microsoft Visual C++ tools.
+#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
+#       Targeting Windows pre64 RETAIL
+#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
+#
+#------------------------------------------------------------------------------
+#==============================================================================
+###############################################################################
+#------------------------------------------------------------------------------
+
+!if !exist("makefile.vc")
+MSG = ^
+You must run this makefile only from the directory it is in.^
+Please `cd` to its location first.
+!error $(MSG)
+!endif
+
+#-------------------------------------------------------------------------
+# Project specific information (EDIT)
+#
+# You should edit this with the name and version of your project. This
+# information is used to generate the name of the package library and
+# it's install location.
+#
+# For example, the sample extension is  going to build sample04.dll and
+# would install it into $(INSTALLDIR)\lib\sample04
+#
+# You need to specify the object files that need to be linked into your
+# binary here.
+#
+#-------------------------------------------------------------------------
+
+PROJECT = vfs
+
+# Uncomment the following line if this is a Tk extension.
+#PROJECT_REQUIRES_TK=1
+!include "rules.vc"
+
+DOTVERSION      = 1.4
+VERSION         = $(DOTVERSION:.=)
+STUBPREFIX      = $(PROJECT)stub
+
+DLLOBJS = \
+       $(TMP_DIR)\vfs.obj \
+       $(TMP_DIR)\tclvfs.res
+
+TCL_FILES = \
+       ftpvfs.tcl \
+       httpvfs.tcl \
+       mk4vfs.tcl \
+       starkit.tcl \
+       tarvfs.tcl \
+       tclprocvfs.tcl \
+       testvfs.tcl \
+       vfsUrl.tcl \
+       vfsUtils.cl \
+       vfslib.tcl \
+       webdavvfs.tcl \
+       zipvfs.tcl \
+       tkvfs.tcl
+
+TEMPLATEVFS = \
+       collatevfs.tcl \
+       deltavfs.tcl \
+       fishvfs.tcl \
+       globfind.tcl \
+       quotavfs.tcl \
+       tdelta.tcl \
+       templatevfs.tcl \
+       versionvfs.tcl \
+       chrootvfs.tcl
+
+#-------------------------------------------------------------------------
+# Target names and paths ( shouldn't need changing )
+#-------------------------------------------------------------------------
+
+BINROOT                = .
+ROOT            = ..
+
+PRJIMPLIB      = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME     = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+PRJLIB         = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB     = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+### Make sure we use backslash only.
+PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR     = $(PRJ_INSTALL_DIR)
+INCLUDE_INSTALL_DIR    = $(_TCLDIR)\include
+
+### The following paths CANNOT have spaces in them.
+GENERICDIR     = $(ROOT)\generic
+WINDIR         = $(ROOT)\win
+LIBDIR          = $(ROOT)\library
+DOCDIR         = $(ROOT)\doc
+TOOLSDIR       = $(ROOT)\tools
+COMPATDIR      = $(ROOT)\compat
+
+#---------------------------------------------------------------------
+# Compile flags
+#---------------------------------------------------------------------
+
+!if !$(DEBUG)
+!if $(OPTIMIZING)
+### This cranks the optimization level to maximize speed
+cdebug = $(OPTIMIZATIONS)
+!else
+cdebug =
+!endif
+!else if "$(MACHINE)" == "IA64" #|| "$(MACHINE)" == "AMD64"
+### Warnings are too many, can't support warnings into errors.
+cdebug = -Zi -Od $(DEBUGFLAGS)
+!else
+cdebug = -Zi -WX $(DEBUGFLAGS)
+!endif
+
+### Declarations common to all compiler options
+cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
+cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
+
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+!if !$(STATIC_BUILD)
+cflags = $(cflags) -DUSE_TCL_STUBS
+!if defined(TKSTUBLIB)
+cflags = $(cflags) -DUSE_TK_STUBS
+!endif
+!endif
+
+INCLUDES       = $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)"
+BASE_CFLAGS    = $(cflags) $(cdebug) $(crt) $(INCLUDES)
+CON_CFLAGS     = $(cflags) $(cdebug) $(crt) -DCONSOLE
+TCL_CFLAGS     = -DPACKAGE_NAME="\"$(PROJECT)\"" \
+                 -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+                  -DBUILD_$(PROJECT) $(BASE_CFLAGS) $(OPTDEFINES)
+
+### Stubs files should not be compiled with -GL
+STUB_CFLAGS     = $(cflags) $(cdebug:-GL=) #$(TK_DEFINES)
+
+#---------------------------------------------------------------------
+# Link flags
+#---------------------------------------------------------------------
+
+!if $(DEBUG)
+ldebug = -debug
+!if $(MSVCRT)
+ldebug = $(ldebug) -nodefaultlib:msvcrt
+!endif
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!endif
+
+### Declarations common to all linker options
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(PROFILE)
+lflags = $(lflags) -profile
+!endif
+
+!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
+### Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
+### Align sections for speed in loading by choosing the virtual page size.
+lflags = $(lflags) -align:4096
+!endif
+
+!if $(LOIMPACT)
+lflags = $(lflags) -ws:aggressive
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+!if !$(STATIC_BUILD)
+baselibs  = $(TCLSTUBLIB)
+!if defined(TKSTUBLIB)
+baselibs  = $(baselibs) $(TKSTUBLIB)
+!endif
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) >= 1400 && $(VCVERSION) < 1500
+baselibs   = $(baselibs) bufferoverflowU.lib
+!endif
+!endif
+
+!if exist("$(TCLDIR)\win\coffbase.txt")
+#dllbase       = -base:@$(TCLDIR)\win\coffbase.txt,tclvfs
+dllbase = -base:0x10A70000
+!else
+dllbase = -base:0x10A70000
+!endif
+
+#---------------------------------------------------------------------
+# TclTest flags
+#---------------------------------------------------------------------
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+#---------------------------------------------------------------------
+# Project specific targets (EDIT)
+#---------------------------------------------------------------------
+
+all:       setup $(PROJECT)
+$(PROJECT): setup $(PRJLIB) pkgIndex
+install:    install-binaries install-libraries install-docs
+pkgIndex:   setup $(OUT_DIR)\pkgIndex.tcl $(OUT_DIR)\vfs.tcl
+
+test: setup $(PROJECT)
+       @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+       @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+       $(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+       @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+       @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
+       $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS)
+!else
+       @echo Please wait while the tests are collected...
+       $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) > tests.log
+       type tests.log | more
+!endif
+
+shell: setup $(PROJECT)
+       @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+        @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+       @set VFS_LIBRARY=$(LIBDIR:\=/)
+!if $(TCLINSTALL)
+       @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+       @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
+       $(DEBUGGER) $(TCLSH)
+!else
+       @echo Please wait while the tests are collected...
+       $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) > tests.log
+       type tests.log | more
+!endif
+
+setup:
+       @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+       @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+$(PRJLIB): $(DLLOBJS)
+!if $(STATIC_BUILD)
+       $(lib32) -nologo -out:$@ @<<
+$**
+<<
+!else
+       $(link32) $(dlllflags) $(dllbase) -out:$@ $(baselibs) @<<
+$**
+<<
+       $(_VC_MANIFEST_EMBED_DLL)
+       -@del $*.exp
+!endif
+
+$(PRJSTUBLIB): $(PRJSTUBOBJS)
+       $(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
+
+#---------------------------------------------------------------------
+# Implicit rules
+#---------------------------------------------------------------------
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+       $(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
+               -DCOMMAVERSION=$(DOTVERSION:.=,),0,0 \
+               -DDOTVERSION=\"$(DOTVERSION)\" \
+               -DVERSION=\"$(VERSION)$(SUFX)\" \
+!if $(DEBUG)
+       -d DEBUG \
+!endif
+!if $(TCL_THREADS)
+       -d TCL_THREADS \
+!endif
+!if $(STATIC_BUILD)
+       -d STATIC_BUILD \
+!endif
+       $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+#-------------------------------------------------------------------------
+# Explicit dependency rules
+#
+#-------------------------------------------------------------------------
+
+.PHONY: $(OUT_DIR)\pkgIndex.tcl $(OUT_DIR)\vfs.tcl
+
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+       nmakehlp -s << $** > $@
+@PACKAGE_NAME@     $(PROJECT)
+@PACKAGE_VERSION@  $(DOTVERSION)
+@PKG_LIB_FILE@     $(PRJLIBNAME)
+<<
+
+$(OUT_DIR)\vfs.tcl: $(ROOT)\library\vfs.tcl.in
+       nmakehlp -s << $** > $@
+@PACKAGE_NAME@     $(PROJECT)
+@PACKAGE_VERSION@  $(DOTVERSION)
+@PKG_LIB_FILE@     $(PRJLIBNAME)
+<<
+
+#---------------------------------------------------------------------
+# Installation. (EDIT)
+#
+# You may need to modify this section to reflect the final distribution
+# of your files and possibly to generate documentation.
+#
+#---------------------------------------------------------------------
+
+install-binaries:
+       @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+       @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+       @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+install-libraries: pkgIndex
+        @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+        @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+        @echo Installing package entrypoint in '$(SCRIPT_INSTALL_DIR)'
+       @$(CPY) $(OUT_DIR)\vfs.tcl "$(SCRIPT_INSTALL_DIR)"
+        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+       @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)"
+
+install-docs:
+       @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+       @if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"
+
+#---------------------------------------------------------------------
+# Clean up
+#---------------------------------------------------------------------
+
+clean:
+       @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+       @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+       @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+       @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+       @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+
+realclean: clean
+       @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+distclean: realclean
+       @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+       @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
diff --git a/8.x/tclvfs/win/nmakehlp.c b/8.x/tclvfs/win/nmakehlp.c
new file mode 100644 (file)
index 0000000..a13b6d7
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ * ----------------------------------------------------------------------------
+ * nmakehlp.c --
+ *
+ *     This is used to fix limitations within nmake and the environment.
+ *
+ * Copyright (c) 2002 by David Gravereaux.
+ * Copyright (c) 2006 by Pat Thoyts
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * ----------------------------------------------------------------------------
+ * RCS: @(#) $Id: nmakehlp.c,v 1.2 2009/01/22 14:36:58 patthoyts Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#define _CRT_SECURE_NO_DEPRECATE
+#include <windows.h>
+#define NO_SHLWAPI_GDI
+#define NO_SHLWAPI_STREAM
+#define NO_SHLWAPI_REG
+#include <shlwapi.h>
+#pragma comment (lib, "user32.lib")
+#pragma comment (lib, "kernel32.lib")
+#pragma comment (lib, "shlwapi.lib")
+#include <stdio.h>
+#include <math.h>
+
+/*
+ * This library is required for x64 builds with _some_ versions of MSVC
+ */
+#if defined(_M_IA64) || defined(_M_AMD64)
+#if _MSC_VER >= 1400 && _MSC_VER < 1500
+#pragma comment(lib, "bufferoverflowU")
+#endif
+#endif
+
+/* ISO hack for dumb VC++ */
+#ifdef _MSC_VER
+#define   snprintf     _snprintf
+#endif
+
+
+
+/* protos */
+
+int            CheckForCompilerFeature(const char *option);
+int            CheckForLinkerFeature(const char *option);
+int            IsIn(const char *string, const char *substring);
+int            GrepForDefine(const char *file, const char *string);
+int            SubstituteFile(const char *substs, const char *filename);
+int            QualifyPath(const char *path);
+const char *    GetVersionFromFile(const char *filename, const char *match);
+DWORD WINAPI   ReadFromPipe(LPVOID args);
+
+/* globals */
+
+#define CHUNK  25
+#define STATICBUFFERSIZE    1000
+typedef struct {
+    HANDLE pipe;
+    char buffer[STATICBUFFERSIZE];
+} pipeinfo;
+
+pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
+pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
+\f
+/*
+ * exitcodes: 0 == no, 1 == yes, 2 == error
+ */
+
+int
+main(
+    int argc,
+    char *argv[])
+{
+    char msg[300];
+    DWORD dwWritten;
+    int chars;
+
+    /*
+     * Make sure children (cl.exe and link.exe) are kept quiet.
+     */
+
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+
+    /*
+     * Make sure the compiler and linker aren't effected by the outside world.
+     */
+
+    SetEnvironmentVariable("CL", "");
+    SetEnvironmentVariable("LINK", "");
+
+    if (argc > 1 && *argv[1] == '-') {
+       switch (*(argv[1]+1)) {
+       case 'c':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -c <compiler option>\n"
+                       "Tests for whether cl.exe supports an option\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return CheckForCompilerFeature(argv[2]);
+       case 'l':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -l <linker option>\n"
+                       "Tests for whether link.exe supports an option\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return CheckForLinkerFeature(argv[2]);
+       case 'f':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -f <string> <substring>\n"
+                       "Find a substring within another\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           } else if (argc == 3) {
+               /*
+                * If the string is blank, there is no match.
+                */
+
+               return 0;
+           } else {
+               return IsIn(argv[2], argv[3]);
+           }
+       case 'g':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -g <file> <string>\n"
+                       "grep for a #define\n"
+                       "exitcodes: integer of the found string (no decimals)\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return GrepForDefine(argv[2], argv[3]);
+       case 's':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -s <substitutions file> <file>\n"
+                       "Perform a set of string map type substutitions on a file\n"
+                       "exitcodes: 0\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return SubstituteFile(argv[2], argv[3]);
+       case 'V':
+           if (argc != 4) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                   "usage: %s -V filename matchstring\n"
+                   "Extract a version from a file:\n"
+                   "eg: pkgIndex.tcl \"package ifneeded http\"",
+                   argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                   &dwWritten, NULL);
+               return 0;
+           }
+           printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
+           return 0;
+       case 'Q':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                   "usage: %s -q path\n"
+                   "Emit the fully qualified path\n"
+                   "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                   &dwWritten, NULL);
+               return 2;
+           }
+           return QualifyPath(argv[2]);
+       }
+    }
+    chars = snprintf(msg, sizeof(msg) - 1,
+           "usage: %s -c|-l|-f|-g|-V|-s|-Q ...\n"
+           "This is a little helper app to equalize shell differences between WinNT and\n"
+           "Win9x and get nmake.exe to accomplish its job.\n",
+           argv[0]);
+    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
+    return 2;
+}
+\f
+int
+CheckForCompilerFeature(
+    const char *option)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    SECURITY_ATTRIBUTES sa;
+    DWORD threadID;
+    char msg[300];
+    BOOL ok;
+    HANDLE hProcess, h, pipeThreads[2];
+    char cmdline[100];
+
+    hProcess = GetCurrentProcess();
+
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO);
+    si.dwFlags   = STARTF_USESTDHANDLES;
+    si.hStdInput = INVALID_HANDLE_VALUE;
+
+    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = FALSE;
+
+    /*
+     * Create a non-inheritible pipe.
+     */
+
+    CreatePipe(&Out.pipe, &h, &sa, 0);
+
+    /*
+     * Dupe the write side, make it inheritible, and close the original.
+     */
+
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Same as above, but for the error side.
+     */
+
+    CreatePipe(&Err.pipe, &h, &sa, 0);
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Base command line.
+     */
+
+    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
+
+    /*
+     * Append our option for testing
+     */
+
+    lstrcat(cmdline, option);
+
+    /*
+     * Filename to compile, which exists, but is nothing and empty.
+     */
+
+    lstrcat(cmdline, " .\\nul");
+
+    ok = CreateProcess(
+           NULL,           /* Module name. */
+           cmdline,        /* Command line. */
+           NULL,           /* Process handle not inheritable. */
+           NULL,           /* Thread handle not inheritable. */
+           TRUE,           /* yes, inherit handles. */
+           DETACHED_PROCESS, /* No console for you. */
+           NULL,           /* Use parent's environment block. */
+           NULL,           /* Use parent's starting directory. */
+           &si,            /* Pointer to STARTUPINFO structure. */
+           &pi);           /* Pointer to PROCESS_INFORMATION structure. */
+
+    if (!ok) {
+       DWORD err = GetLastError();
+       int chars = snprintf(msg, sizeof(msg) - 1,
+               "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
+               FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
+               (300-chars), 0);
+       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+       return 2;
+    }
+
+    /*
+     * Close our references to the write handles that have now been inherited.
+     */
+
+    CloseHandle(si.hStdOutput);
+    CloseHandle(si.hStdError);
+
+    WaitForInputIdle(pi.hProcess, 5000);
+    CloseHandle(pi.hThread);
+
+    /*
+     * Start the pipe reader threads.
+     */
+
+    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
+    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
+
+    /*
+     * Block waiting for the process to end.
+     */
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    CloseHandle(pi.hProcess);
+
+    /*
+     * Wait for our pipe to get done reading, should it be a little slow.
+     */
+
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
+    CloseHandle(pipeThreads[0]);
+    CloseHandle(pipeThreads[1]);
+
+    /*
+     * Look for the commandline warning code in both streams.
+     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
+     */
+
+    return !(strstr(Out.buffer, "D4002") != NULL
+             || strstr(Err.buffer, "D4002") != NULL
+             || strstr(Out.buffer, "D9002") != NULL
+             || strstr(Err.buffer, "D9002") != NULL
+             || strstr(Out.buffer, "D2021") != NULL
+             || strstr(Err.buffer, "D2021") != NULL);
+}
+\f
+int
+CheckForLinkerFeature(
+    const char *option)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    SECURITY_ATTRIBUTES sa;
+    DWORD threadID;
+    char msg[300];
+    BOOL ok;
+    HANDLE hProcess, h, pipeThreads[2];
+    char cmdline[100];
+
+    hProcess = GetCurrentProcess();
+
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO);
+    si.dwFlags   = STARTF_USESTDHANDLES;
+    si.hStdInput = INVALID_HANDLE_VALUE;
+
+    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = TRUE;
+
+    /*
+     * Create a non-inheritible pipe.
+     */
+
+    CreatePipe(&Out.pipe, &h, &sa, 0);
+
+    /*
+     * Dupe the write side, make it inheritible, and close the original.
+     */
+
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Same as above, but for the error side.
+     */
+
+    CreatePipe(&Err.pipe, &h, &sa, 0);
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Base command line.
+     */
+
+    lstrcpy(cmdline, "link.exe -nologo ");
+
+    /*
+     * Append our option for testing.
+     */
+
+    lstrcat(cmdline, option);
+
+    ok = CreateProcess(
+           NULL,           /* Module name. */
+           cmdline,        /* Command line. */
+           NULL,           /* Process handle not inheritable. */
+           NULL,           /* Thread handle not inheritable. */
+           TRUE,           /* yes, inherit handles. */
+           DETACHED_PROCESS, /* No console for you. */
+           NULL,           /* Use parent's environment block. */
+           NULL,           /* Use parent's starting directory. */
+           &si,            /* Pointer to STARTUPINFO structure. */
+           &pi);           /* Pointer to PROCESS_INFORMATION structure. */
+
+    if (!ok) {
+       DWORD err = GetLastError();
+       int chars = snprintf(msg, sizeof(msg) - 1,
+               "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
+               FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
+               (300-chars), 0);
+       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+       return 2;
+    }
+
+    /*
+     * Close our references to the write handles that have now been inherited.
+     */
+
+    CloseHandle(si.hStdOutput);
+    CloseHandle(si.hStdError);
+
+    WaitForInputIdle(pi.hProcess, 5000);
+    CloseHandle(pi.hThread);
+
+    /*
+     * Start the pipe reader threads.
+     */
+
+    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
+    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
+
+    /*
+     * Block waiting for the process to end.
+     */
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    CloseHandle(pi.hProcess);
+
+    /*
+     * Wait for our pipe to get done reading, should it be a little slow.
+     */
+
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
+    CloseHandle(pipeThreads[0]);
+    CloseHandle(pipeThreads[1]);
+
+    /*
+     * Look for the commandline warning code in the stderr stream.
+     */
+
+    return !(strstr(Out.buffer, "LNK1117") != NULL ||
+           strstr(Err.buffer, "LNK1117") != NULL ||
+           strstr(Out.buffer, "LNK4044") != NULL ||
+           strstr(Err.buffer, "LNK4044") != NULL);
+}
+\f
+DWORD WINAPI
+ReadFromPipe(
+    LPVOID args)
+{
+    pipeinfo *pi = (pipeinfo *) args;
+    char *lastBuf = pi->buffer;
+    DWORD dwRead;
+    BOOL ok;
+
+  again:
+    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
+       CloseHandle(pi->pipe);
+       return (DWORD)-1;
+    }
+    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
+    if (!ok || dwRead == 0) {
+       CloseHandle(pi->pipe);
+       return 0;
+    }
+    lastBuf += dwRead;
+    goto again;
+
+    return 0;  /* makes the compiler happy */
+}
+\f
+int
+IsIn(
+    const char *string,
+    const char *substring)
+{
+    return (strstr(string, substring) != NULL);
+}
+\f
+/*
+ * Find a specified #define by name.
+ *
+ * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
+ */
+
+int
+GrepForDefine(
+    const char *file,
+    const char *string)
+{
+    char s1[51], s2[51], s3[51];
+    FILE *f = fopen(file, "rt");
+
+    if (f == NULL) {
+       return 0;
+    }
+
+    do {
+       int r = fscanf(f, "%50s", s1);
+
+       if (r == 1 && !strcmp(s1, "#define")) {
+           /*
+            * Get next two words.
+            */
+
+           r = fscanf(f, "%50s %50s", s2, s3);
+           if (r != 2) {
+               continue;
+           }
+
+           /*
+            * Is the first word what we're looking for?
+            */
+
+           if (!strcmp(s2, string)) {
+               double d1;
+
+               fclose(f);
+
+               /*
+                * Add 1 past first double quote char. "8.5"
+                */
+
+               d1 = atof(s3 + 1);                /*    8.5  */
+               while (floor(d1) != d1) {
+                   d1 *= 10.0;
+               }
+               return ((int) d1);                /*    85   */
+           }
+       }
+    } while (!feof(f));
+
+    fclose(f);
+    return 0;
+}
+\f
+/*
+ * GetVersionFromFile --
+ *     Looks for a match string in a file and then returns the version
+ *     following the match where a version is anything acceptable to
+ *     package provide or package ifneeded.
+ */
+
+const char *
+GetVersionFromFile(
+    const char *filename,
+    const char *match)
+{
+    size_t cbBuffer = 100;
+    static char szBuffer[100];
+    char *szResult = NULL;
+    FILE *fp = fopen(filename, "rt");
+
+    if (fp != NULL) {
+       /*
+        * Read data until we see our match string.
+        */
+
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           LPSTR p, q;
+
+           p = strstr(szBuffer, match);
+           if (p != NULL) {
+               /*
+                * Skip to first digit.
+                */
+
+               while (*p && !isdigit(*p)) {
+                   ++p;
+               }
+
+               /*
+                * Find ending whitespace.
+                */
+
+               q = p;
+               while (*q && (isalnum(*q) || *q == '.')) {
+                   ++q;
+               }
+
+               memcpy(szBuffer, p, q - p);
+               szBuffer[q-p] = 0;
+               szResult = szBuffer;
+               break;
+           }
+       }
+       fclose(fp);
+    }
+    return szResult;
+}
+\f
+/*
+ * List helpers for the SubstituteFile function
+ */
+
+typedef struct list_item_t {
+    struct list_item_t *nextPtr;
+    char * key;
+    char * value;
+} list_item_t;
+
+/* insert a list item into the list (list may be null) */
+static list_item_t *
+list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
+{
+    list_item_t *itemPtr = malloc(sizeof(list_item_t));
+    if (itemPtr) {
+       itemPtr->key = strdup(key);
+       itemPtr->value = strdup(value);
+       itemPtr->nextPtr = NULL;
+
+       while(*listPtrPtr) {
+           listPtrPtr = &(*listPtrPtr)->nextPtr;
+       }
+       *listPtrPtr = itemPtr;
+    }
+    return itemPtr;
+}
+
+static void
+list_free(list_item_t **listPtrPtr)
+{
+    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
+    while (listPtr) {
+       tmpPtr = listPtr;
+       listPtr = listPtr->nextPtr;
+       free(tmpPtr->key);
+       free(tmpPtr->value);
+       free(tmpPtr);
+    }
+}
+\f
+/*
+ * SubstituteFile --
+ *     As windows doesn't provide anything useful like sed and it's unreliable
+ *     to use the tclsh you are building against (consider x-platform builds -
+ *     eg compiling AMD64 target from IX86) we provide a simple substitution
+ *     option here to handle autoconf style substitutions.
+ *     The substitution file is whitespace and line delimited. The file should
+ *     consist of lines matching the regular expression:
+ *       \s*\S+\s+\S*$
+ *
+ *     Usage is something like:
+ *       nmakehlp -S << $** > $@
+ *        @PACKAGE_NAME@ $(PACKAGE_NAME)
+ *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
+ *        <<
+ */
+
+int
+SubstituteFile(
+    const char *substitutions,
+    const char *filename)
+{
+    size_t cbBuffer = 1024;
+    static char szBuffer[1024], szCopy[1024];
+    char *szResult = NULL;
+    list_item_t *substPtr = NULL;
+    FILE *fp, *sp;
+
+    fp = fopen(filename, "rt");
+    if (fp != NULL) {
+
+       /*
+        * Build a list of substutitions from the first filename
+        */
+
+       sp = fopen(substitutions, "rt");
+       if (sp != NULL) {
+           while (fgets(szBuffer, cbBuffer, sp) != NULL) {
+               char *ks, *ke, *vs, *ve;
+               ks = szBuffer;
+               while (ks && *ks && isspace(*ks)) ++ks;
+               ke = ks;
+               while (ke && *ke && !isspace(*ke)) ++ke;
+               vs = ke;
+               while (vs && *vs && isspace(*vs)) ++vs;
+               ve = vs;
+               while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
+               *ke = 0, *ve = 0;
+               list_insert(&substPtr, ks, vs);
+           }
+           fclose(sp);
+       }
+
+       /* debug: dump the list */
+#ifdef _DEBUG
+       {
+           int n = 0;
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
+               fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
+           }
+       }
+#endif
+       
+       /*
+        * Run the substitutions over each line of the input
+        */
+       
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr) {
+               char *m = strstr(szBuffer, p->key);
+               if (m) {
+                   char *cp, *op, *sp;
+                   cp = szCopy;
+                   op = szBuffer;
+                   while (op != m) *cp++ = *op++;
+                   sp = p->value;
+                   while (sp && *sp) *cp++ = *sp++;
+                   op += strlen(p->key);
+                   while (*op) *cp++ = *op++;
+                   *cp = 0;
+                   memcpy(szBuffer, szCopy, sizeof(szCopy));
+               }
+           }
+           printf(szBuffer);
+       }
+       
+       list_free(&substPtr);
+    }
+    fclose(fp);
+    return 0;
+}
+\f
+/*
+ * QualifyPath --
+ *
+ *     This composes the current working directory with a provided path
+ *     and returns the fully qualified and normalized path.
+ *     Mostly needed to setup paths for testing.
+ */
+
+int
+QualifyPath(
+    const char *szPath)
+{
+    char szCwd[MAX_PATH + 1];
+    char szTmp[MAX_PATH + 1];
+    char *p;
+    GetCurrentDirectory(MAX_PATH, szCwd);
+    while ((p = strchr(szPath, '/')) && *p)
+       *p = '\\';
+    PathCombine(szTmp, szCwd, szPath);
+    PathCanonicalize(szCwd, szTmp);
+    printf("%s\n", szCwd);
+    return 0;
+}
+
+/*
+ * Local variables:
+ *   mode: c
+ *   c-basic-offset: 4
+ *   fill-column: 78
+ *   indent-tabs-mode: t
+ *   tab-width: 8
+ * End:
+ */
diff --git a/8.x/tclvfs/win/rules.vc b/8.x/tclvfs/win/rules.vc
new file mode 100644 (file)
index 0000000..48e21d5
--- /dev/null
@@ -0,0 +1,694 @@
+#------------------------------------------------------------- -*- Makefile -*-
+# rules.vc --
+#
+#      Microsoft Visual C++ makefile include for decoding the commandline
+#      macros.  This file does not need editing to build Tcl.
+#
+#      This version is modified from the Tcl source version to support
+#      building extensions using nmake.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# Copyright (c) 2001-2002 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+#
+#------------------------------------------------------------------------------
+# RCS: @(#) $Id: rules.vc,v 1.2 2009/01/22 14:36:58 patthoyts Exp $
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+cc32           = $(CC)   # built-in default.
+link32         = link
+lib32          = lib
+rc32           = $(RC)   # built-in default.
+
+!ifndef INSTALLDIR
+### Assume the normal default.
+_INSTALLDIR    = C:\Program Files\Tcl
+!else
+### Fix the path separators.
+_INSTALLDIR    = $(INSTALLDIR:/=\)
+!endif
+
+!ifndef MACHINE
+!if "$(CPU)" == "" || "$(CPU)" == "i386"
+MACHINE                = IX86
+!else
+MACHINE         = $(CPU)
+!endif
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING   = \"cp1252\"
+!endif
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+!if "$(OS)" == "Windows_NT"
+RMDIR  = rmdir /S /Q
+ERRNULL  = 2>NUL
+!if ![ver | find "4.0" > nul]
+CPY    = echo y | xcopy /i >NUL
+COPY   = copy >NUL
+!else
+CPY    = xcopy /i /y >NUL
+COPY   = copy /y >NUL
+!endif
+!else # "$(OS)" != "Windows_NT"
+CPY    = xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
+COPY   = copy >_JUNK.OUT # On Win98 NUL does not work here.
+RMDIR  = deltree /Y
+NULL    = \NUL # Used in testing directory existence
+ERRNULL = >NUL # Win9x shell cannot redirect stderr
+!endif
+MKDIR   = mkdir
+
+!message ===============================================================================
+
+#----------------------------------------------------------
+# build the helper app we need to overcome nmake's limiting
+# environment.
+#----------------------------------------------------------
+
+!if !exist(nmakehlp.exe)
+!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
+!endif
+!endif
+
+#----------------------------------------------------------
+# Test for compiler features
+#----------------------------------------------------------
+
+### test for optimizations
+!if [nmakehlp -c -Ot]
+!message *** Compiler has 'Optimizations'
+OPTIMIZING     = 1
+!else
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING     = 0
+!endif
+
+OPTIMIZATIONS   =
+
+!if [nmakehlp -c -Ot]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
+!endif
+
+!if [nmakehlp -c -Oi]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
+!endif
+
+!if [nmakehlp -c -Op]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
+!endif
+
+!if [nmakehlp -c -fp:strict]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
+!endif
+
+!if [nmakehlp -c -Gs]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
+!endif
+
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
+!endif
+
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
+!endif
+
+DEBUGFLAGS     =
+
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
+!endif
+
+COMPILERFLAGS  =-W3
+
+# In v13 -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+!if ![nmakehlp -c -GL]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
+!endif
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+COMPILERFLAGS  = $(COMPILERFLAGSS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+!if "$(MACHINE)" == "IA64"
+### test for Itanium errata
+!if [nmakehlp -c -QIA64_Bx]
+!message *** Compiler has 'B-stepping errata workarounds'
+COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
+!else
+!message *** Compiler does not have 'B-stepping errata workarounds'
+!endif
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for -align:4096, when align:512 will do.
+!if [nmakehlp -l -opt:nowin98]
+!message *** Linker has 'Win98 alignment problem'
+ALIGN98_HACK   = 1
+!else
+!message *** Linker does not have 'Win98 alignment problem'
+ALIGN98_HACK   = 0
+!endif
+!else
+ALIGN98_HACK   = 0
+!endif
+
+LINKERFLAGS     =
+
+!if [nmakehlp -l -ltcg]
+LINKERFLAGS     =-ltcg
+!endif
+
+#----------------------------------------------------------
+# MSVC8 (ships with Visual Studio 2005) generates a manifest
+# file that we should link into the binaries. This is how.
+#----------------------------------------------------------
+
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
+!include vercl.i
+!if ![del /q vercl.x vercl.i $(ERRNULL)]
+!endif
+!if $(VCVERSION) >= 1500
+VCVER=9
+!elseif $(VCVERSION) >= 1400
+VCVER=8
+!elseif $(VCVERSION) >= 1300
+VCVER=7
+!elseif $(VCVERSION) >= 1200
+VCVER=6
+!endif
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+#----------------------------------------------------------
+# Decode the options requested.
+#----------------------------------------------------------
+
+!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
+STATIC_BUILD   = 0
+TCL_THREADS    = 1
+DEBUG          = 0
+PROFILE                = 0
+MSVCRT         = 0
+LOIMPACT       = 0
+TCL_USE_STATIC_PACKAGES        = 0
+USE_THREAD_ALLOC = 1
+USE_THREAD_STORAGE = 1
+UNCHECKED       = 0
+!else
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD   = 1
+!else
+STATIC_BUILD   = 0
+!endif
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT         = 1
+!else
+MSVCRT         = 0
+!endif
+!if [nmakehlp -f $(OPTS) "staticpkg"]
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES        = 1
+!else
+TCL_USE_STATIC_PACKAGES        = 0
+!endif
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS    = 0
+!else
+TCL_THREADS     = 1
+!endif
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG          = 1
+!else
+DEBUG          = 0
+!endif
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE                = 1
+!else
+PROFILE                = 0
+!endif
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Doing loimpact
+LOIMPACT       = 1
+!else
+LOIMPACT       = 0
+!endif
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!else
+USE_THREAD_ALLOC = 0
+!endif
+!if [nmakehlp -f $(OPTS) "thrdstorage"]
+!message *** Doing thrdstorage
+USE_THREAD_STORAGE = 1
+!else
+USE_THREAD_STORAGE = 0
+!endif
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+!endif
+
+
+!if !$(STATIC_BUILD)
+# Make sure we don't build overly fat DLLs.
+MSVCRT         = 1
+# We shouldn't statically put the extensions inside the shell when dynamic.
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+
+#----------------------------------------------------------
+# Figure-out how to name our intermediate and output directories.
+# We wouldn't want different builds to use the same .obj files
+# by accident.
+#----------------------------------------------------------
+
+#----------------------------------------
+# Naming convention:
+#   t = full thread support.
+#   s = static library (as opposed to an
+#      import library)
+#   g = linked to the debug enabled C
+#      run-time.
+#   x = special static build when it
+#      links to the dynamic C run-time.
+#----------------------------------------
+SUFX       = sgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX       = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX       = $(SUFX:s=)
+EXT        = dll
+!if $(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX       = $(SUFX:x=)
+!endif
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT        = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX       = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX       = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR            = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR            = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR            = $(TMP_DIR)
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Decode the statistics requested.
+#----------------------------------------------------------
+
+!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
+TCL_MEM_DEBUG      = 0
+TCL_COMPILE_DEBUG   = 0
+!else
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG      = 1
+!else
+TCL_MEM_DEBUG      = 0
+!endif
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG   = 1
+!else
+TCL_COMPILE_DEBUG   = 0
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Decode the checks requested.
+#----------------------------------------------------------
+
+!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
+TCL_NO_DEPRECATED          = 0
+WARNINGS                   = -W3
+!else
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED          = 1
+!else
+TCL_NO_DEPRECATED          = 0
+!endif
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS                   = -W4
+!if [nmakehlp -l -warn:3]
+LINKERFLAGS                = $(LINKERFLAGS) -warn:3
+!endif
+!else
+WARNINGS                   = -W3
+!endif
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS                   = $(WARNINGS) -Wp64
+!endif
+!endif
+
+#----------------------------------------------------------
+# Set our defines now armed with our options.
+#----------------------------------------------------------
+
+OPTDEFINES     = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES     = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!if $(USE_THREAD_STORAGE)
+OPTDEFINES     = $(OPTDEFINES) -DUSE_THREAD_STORAGE=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES     = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_DEBUG
+!elseif $(OPTIMIZING)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!if $(PROFILE)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+
+
+#----------------------------------------------------------
+# Locate the Tcl headers to build against
+#----------------------------------------------------------
+
+!if "$(PROJECT)" == "tcl"
+
+_TCL_H          = ..\generic\tcl.h
+
+!else
+
+# If INSTALLDIR set to tcl root dir then reset to the lib dir.
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+!if !defined(TCLDIR)
+!if exist("$(_INSTALLDIR)\..\include\tcl.h")
+TCLINSTALL     = 1
+_TCLDIR                = $(_INSTALLDIR)\..
+_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h
+TCLDIR          = $(_INSTALLDIR)\..
+!else
+MSG=^
+Failed to find tcl.h.  Set the TCLDIR macro.
+!error $(MSG)
+!endif
+!else
+_TCLDIR        = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h")
+TCLINSTALL     = 1
+_TCL_H          = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h")
+TCLINSTALL     = 0
+_TCL_H          = $(_TCLDIR)\generic\tcl.h
+!else
+MSG =^
+Failed to find tcl.h.  The TCLDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+!endif
+
+#--------------------------------------------------------------
+# Extract various version numbers from tcl headers
+# The generated file is then included in the makefile.
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+# If building the tcl core then we need additional package versions
+!if "$(PROJECT)" == "tcl"
+!if [echo PKG_HTTP_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc]
+!endif
+!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
+!endif
+!if [echo PKG_MSGCAT_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]
+!endif
+!if [echo PKG_PLATFORM_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
+!endif
+!if [echo PKG_SHELL_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]
+!endif
+!endif
+
+!include versions.vc
+
+#--------------------------------------------------------------
+# Setup tcl version dependent stuff headers
+#--------------------------------------------------------------
+
+!if "$(PROJECT)" != "tcl"
+
+TCL_VERSION    = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+
+!if $(TCL_VERSION) < 81
+TCL_DOES_STUBS = 0
+!else
+TCL_DOES_STUBS = 1
+!endif
+
+!if $(TCLINSTALL)
+_TCLBINDIR      = "$(_TCLDIR)\bin"
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH           = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TCLSTUBLIB     = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB      = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
+TCL_LIBRARY    = $(_TCLDIR)\lib
+TCLREGLIB      = "$(_TCLDIR)\lib\tclreg11$(SUFX:t=).lib"
+TCLDDELIB      = "$(_TCLDIR)\lib\tcldde12$(SUFX:t=).lib"
+COFFBASE       = \must\have\tcl\sources\to\build\this\target
+TCLTOOLSDIR    = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES    = -I"$(_TCLDIR)\include"
+!else
+_TCLBINDIR      = $(_TCLDIR)\win\$(BUILDDIRTOP)
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TCLSTUBLIB     = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
+TCL_LIBRARY    = $(_TCLDIR)\library
+TCLREGLIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg11$(SUFX:t=).lib"
+TCLDDELIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde12$(SUFX:t=).lib"
+COFFBASE       = "$(_TCLDIR)\win\coffbase.txt"
+TCLTOOLSDIR    = $(_TCLDIR)\tools
+TCL_INCLUDES   = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+!endif
+
+!endif
+
+#-------------------------------------------------------------------------
+# Locate the Tk headers to build against
+#-------------------------------------------------------------------------
+
+!if "$(PROJECT)" == "tk"
+_TK_H          = ..\generic\tk.h
+!endif
+
+!ifdef PROJECT_REQUIRES_TK
+!if !defined(TKDIR)
+!if exist("$(_INSTALLDIR)\..\include\tk.h")
+TKINSTALL      = 1
+_TKDIR         = $(_INSTALLDIR)\..
+_TK_H          = $(_TKDIR)\include\tk.h
+TKDIR          = $(_TKDIR)
+!elseif exist("$(_TCLDIR)\include\tk.h")
+TKINSTALL      = 1
+_TKDIR         = $(_TCLDIR)
+_TK_H          = $(_TKDIR)\include\tk.h
+TKDIR          = $(_TKDIR)
+!endif
+!else
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL      = 1
+_TK_H          = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL      = 0
+_TK_H          = $(_TKDIR)\generic\tk.h
+!else
+MSG =^
+Failed to find tk.h. The TKDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+!endif
+
+#-------------------------------------------------------------------------
+# Extract Tk version numbers
+#-------------------------------------------------------------------------
+
+!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+
+!include versions.vc
+
+TK_DOTVERSION  = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+TK_VERSION     = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+
+!if "$(PROJECT)" != "tk"
+!if $(TKINSTALL)
+_TKBINDIR       = $(_TKDIR)\bin
+WISH           = "$(_TKBINDIR)\wish$(TK_VERSION)$(SUFX).exe"
+!if !exist($(WISH)) && $(TCL_THREADS)
+WISH           = "$(_TKBINDIR)\wish$(TK_VERSION)t$(SUFX).exe"
+!endif
+TKSTUBLIB      = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
+TK_LIBRARY     = $(_TKDIR)\lib
+TKIMPLIB       = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
+TK_INCLUDES     = -I"$(_TKDIR)\include"
+!else
+_TKBINDIR       = $(_TKDIR)\win\$(BUILDDIRTOP)
+WISH           = "$(_TKBINDIR)\wish$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(WISH)) && $(TCL_THREADS)
+WISH           = "$(_TKBINDIR)\wish$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TKSTUBLIB      = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
+TKIMPLIB       = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
+TK_LIBRARY     = $(_TKDIR)\library
+TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif
+!endif
+
+!endif
+
+#----------------------------------------------------------
+# Setup the fully qualified OUT_DIR path as OUT_DIR_PATH
+#----------------------------------------------------------
+!if [echo OUT_DIR_PATH = \>> versions.vc] \
+    && [nmakehlp -Q "$(OUT_DIR)" >> versions.vc]
+!endif
+!include versions.vc
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Optional defines are '$(OPTDEFINES)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
+!message *** Link options '$(LINKERFLAGS)'
+
+!endif
diff --git a/8.x/tclvfs/win/tclvfs.rc b/8.x/tclvfs/win/tclvfs.rc
new file mode 100644 (file)
index 0000000..fc6f342
--- /dev/null
@@ -0,0 +1,40 @@
+// tclvfs.rc - Copyright (C) 2008 Pat Thoyts <patthoyts@users.sf.net>
+//
+// Note: the version numbers in here are all provided from the makefile.
+//       No editing required.
+//
+// $Id: tclvfs.rc,v 1.1 2008/04/30 15:18:56 patthoyts Exp $
+
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION   COMMAVERSION
+ PRODUCTVERSION        COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS     VS_FF_DEBUG
+#else
+ FILEFLAGS     0x0L
+#endif
+ FILEOS                VOS__WINDOWS32
+ FILETYPE      VFT_DLL
+ FILESUBTYPE   0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"   /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
+        BEGIN
+            VALUE "FileDescription",  "Tcl virtual filesystem support\0"
+            VALUE "OriginalFilename", "vfs" VERSION ".dll\0"
+            VALUE "FileVersion",      DOTVERSION "\0"
+            VALUE "LegalCopyright",   "Copyright \251 2001 Vince Darley et al.\0"
+            VALUE "ProductName",      "TclVfs " DOTVERSION " for Windows\0"
+            VALUE "ProductVersion",   DOTVERSION "\0"
+            VALUE "Comments",         "http://sourceforge.net/projects/tclvfs\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
diff --git a/8.x/thread/.cvsignore b/8.x/thread/.cvsignore
new file mode 100644 (file)
index 0000000..87177f0
--- /dev/null
@@ -0,0 +1,6 @@
+config.status
+Makefile
+pkgIndex.tcl
+*.dll
+*.so
+autom4te.cache
diff --git a/8.x/thread/ChangeLog b/8.x/thread/ChangeLog
new file mode 100644 (file)
index 0000000..3e3c664
--- /dev/null
@@ -0,0 +1,1604 @@
+2010-05-31  Andreas Kupries  <andreask@activestate.com>
+
+       * pkgIndex.tcl.in: Fixed procedure collisions for Thread package
+       by inlining the load command into the ifneeded script, as is
+       standard for most binary packages. Tweaked the procedure for
+       Ttrace a bit, as the result of [info commands] is a list, and
+       using ::apply when possible. A named procedure is only a fallback.
+
+2010-05-27  Andreas Kupries  <andreask@activestate.com>
+
+       * lib/ttrace.tcl: Resynchronized version number with Thread.
+
+2010-05-26  Andreas Kupries  <andreask@activestate.com>
+
+       * generic/threadSpCmd.c (ThreadMutexObjCmd, ThreadRWMutexObjCmd):
+       [Bug 3007426]: Dropped trailing commas in enum definitions which
+       choked the strictly C89 AIX compiler.
+
+2010-04-01 Zoran Vasiljevic <zv@archiware.com>
+
+        * generic/tclXkeylist.c: Removed declaration of
+       global TclX keylist commands.
+
+2010-03-30 Zoran Vasiljevic <zv@archiware.com>
+
+       *** 2.6.6 TAGGED FOR RELEASE (thread-2-6-6) ***
+
+       * configure               Redo for TEA 3.7
+       * configure.in
+
+       * generic/tclThread.h     Cosmetic changes for the inclusion
+       * generic/threadCmd.c     in standard Tcl distribution.
+       * generic/threadPoolCmd.c
+       * generic/threadSpCmd.c
+       * generic/threadSvCmd.c
+       * generic/threadSvCmd.h
+
+2010-03-19   Jan Nijtmans <nijtmans@users.sourceforge.net>
+       
+        * generic/threadSpCmd.c    Silence gcc warning: dereferencing type-punned
+        * .cvsignore               pointer will break strict-aliasing rules
+        * configure                Regenerated using latest TEA
+
+2009-08-19 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: Implemented [tpool::suspend]
+       * doc/tpool.man:           and [tpool::resume] commands
+                                  as per RFE #2835615.
+                                  Also fixed Bug #2833864.
+2009-07-22   Jan Nijtmans <nijtmans@users.sourceforge.net>
+       
+       * generic/tclThread.h:   Remove unnecessary ';'s
+       * generic/tclXkeylist.c: Constify remaining of thread extension,
+       * generic/tclXkeylist.h: bringing it at the same level as Tcl 8.6
+       * generic/threadCmd.c
+       * generic/threadPoolCmd.c
+       * generic/threadSpCmd.c
+       * generic/threadSvCmd.c
+       * generic/threadSvCmd.h
+       * generic/threadSvKeylistCmd.c
+       * generic/threadSvKeylistCmd.h
+       * generic/threadSvListCmd.c
+       
+2009-07-16   Alexandre Ferrieux <ferrieux@sourceforge.net>
+       
+       * generic/tclXkeylist.c: Constify Tcl_ObjGetType return values to
+       * generic/threadSvCmd.c: get rid of const warnings; #if 0 of
+       * generic/threadSvCmd.h: SvFinalize which is unused.
+       
+2009-05-04  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * win/vc/makefile.vc: Updated the MSVC build to work with MSCV 8
+       * win/vc/rules.vc:    and 9 on both intel and amd64 targets.
+       * win/vc/nmakehlp.c:
+
+2009-05-03  Alexandre Ferrieux <ferrieux@sourceforge.net>
+       * generic/threadSpCmd.c: Reorder things in RemoveMutex and
+       RemoveCondv [Bugs 2511424,2511408]; fix a Put* leak in an error
+       path of rwmutexes [Bug 2511420].
+
+2008-12-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * generic/threadSvCmd.c: Handle TIP#336 addition of API to access
+       * generic/threadSpCmd.c: interp->errorLine
+
+2008-11-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * generic/threadSvCmd.c (SvObjObjCmd): safely set interp result obj
+
+       * generic/threadCmd.c (ThreadCutChannel): fix const warning
+       (ThreadSend): safely set interp result object [Bug #1988779]
+
+2009-10-22 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPool.c: fixed race condition when
+       creating minworkers worker thread upfront.
+       Failure to create one results in partial pool teardown.
+       Fix for Bug # 2005794.
+
+2008-05-22 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSpCmd.h: Added one cond variable per
+       sync bucket to wait for item deletion.
+
+       * generic/threadSpCmd.c: Threads that want to delete
+       any sync primitive now wait properly until the last
+       thread that references the primitive detaches.
+
+       Fixed (broken) reference counting of items.
+
+       Fixed wrong release of an condition variable that is
+       about to be time-waited.
+
+2008-05-18 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: Corrected potential race condition
+       in TpoolWorker().
+
+2007-06-30 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: Fixed signedness compiler warning
+       on jobId in TpoolWaitObjCmd().
+
+2007-06-30 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvKeylistCmd.c: Fixed off-by-1 error in argument
+       parsing for SvKeylkeysObjCmd(). See Tcl Bug #1575342.
+
+       * generic/threadPoolCmd.c: Fixed Tcl Bug #1512225 (tpool::wait and
+       tpool::cancel setting wrong values to passed variables)
+
+2007-05-26 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: Fixed [tpool::post -nowait] to start
+         one new worker thread only if there are none started. 
+
+2007-05-03  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+       * win/vc/rules.vc:     Updated the nmake build system to match
+       * win/vc/nmakehlp.c:   current 8.5. (support for non-intel build
+       * win/vc/makefile.vc:  and recent versions of msvc compiler)
+       * win/thread.rc:       Fixed line endings.
+
+2006-12-26 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: Fixed race condition for
+       creating preserved threads.
+
+       * generic/threadSv.c: Removed memory leak.
+
+2006-10-07 Zoran Vasiljevic <zv@archiware.com>
+
+       *** 2.6.5 TAGGED FOR RELEASE (thread-2-6-5) ***
+
+       Main changes since the last release:
+       ------------------------------------
+
+       Set versioning of (embedded) Ttrace package to
+       the same revision level as the main Thread package.
+
+       The Ttrace must now explicitly be loaded in every
+       new thread created by [thread::create] command.
+       
+       The [package require Ttrace] automatically loads 
+       Thread package as well.
+
+       NOTE: be sure to configure/make/make install
+       because the pkgIndex.tcl loader file is modified.
+
+
+2006-10-06 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPool.c:
+       * generic/threadCmd.c: Removed Tcl_PkgRequire 
+       from the new thread initialization and just 
+       initialize the C-aspect of the extension by 
+       calling Therad_Init. This basically discards 
+       the last checkin, which was in a sense bad
+       as it made thread creation very expensive
+       operation.
+
+       * pkgIndex.tcl.in: Added separate handling for
+       Ttrace loading. Now, users needing Ttrace caps
+       must "package require Ttrace" which in turn
+       automatically calls "package require Thread".
+       Also, each new thread created by [thread::create]
+       must be initialized for Ttrace by calling the
+       [package require Ttrace].
+       On the other hand, the "package require Thread"
+       is only necessary to first-load the package in
+       the startup thread. It is not necessary to call
+       this explicitly in every thread created by the
+       [thread::create] command as the C-code will
+       do that automatically as the first thing.
+
+       * doc/ttrace.man: Updated example usage to reflect
+       above changes.
+       
+       * lib/ttrace.tcl: Spliced version numbering of the
+       Ttrace package to the version of the Thread package
+       because of the weirdness of the Tcl package loading
+       mechanism. Also, the broadcast script used within
+       the ttrace::eval now explicitly loads Ttrace package
+       in every broadcasted thread.
+
+2006-10-05 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPool.c:
+       * generic/threadCmd.c: Call Tcl_PkgRequire() in the 
+       NewThread() to properly initialize the extension
+       in any new thread.
+
+       * doc/ttrace.man: Add small example of ttrace usage.
+
+       * lib/ttrace.tcl: Fixed [ttrace:eval] to not to call
+       [package require Ttrace] in the broadcast script as
+       this is now done implicitly for all new threads.
+       
+2006-08-06 Zoran Vasiljevic <zv@archiware.com>
+
+       *** 2.6.4 TAGGED FOR RELEASE (thread-2-6-4) ***
+
+       * generic/tclXkeylist.c: Silenced various 
+       * generic/threadCmd.c    compiler warnings.
+       * generic/threadSvCmd.c: 
+
+       * README: Removed version information.
+       * configure.in: Bumped to 2.6.4 version.
+       * confiigure: Regenerated.
+
+2006-06-04 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvCmd.c: SvIncrObjCmd() now implicitly creates
+       shared array and/or element and initializes it to zero if the
+       array and/or the element were not found.
+
+       * generic/tclThread.h: Removed some unusded debugging defs
+
+2006-04-05  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * win/vc/pkg.vc (PACKAGE_VERSION): correct to 2.6.3 for MSVC make.
+
+2006-03-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * generic/threadPoolCmd.c (AppExitHandler): fix teardown to
+       destruct pool list correctly. [Bug 1427570]
+
+2006-03-16 Zoran Vasiljevic <zv@archiware.com>
+
+       *** 2.6.3 TAGGED FOR RELEASE (thread-2-6-3) ***
+
+       * README: Bumped to 2.6.3
+
+2006-03-15 Zoran Vasiljevic <zv@archiware.com>
+
+
+       * configure.in: Changed BUILD_sample to
+       BUILD_thread for Windows compile under MinGW.
+
+       + configure: regen
+
+2006-03-14 Zoran Vasiljevic <zv@archiware.com>
+
+       * configure.in: Moved to 2.6.3 release
+       * configure: regen
+
+2006-02-09 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSpCmd.c: fixed race condition when testing
+       constraints (mutex being locked by the caller thread) when
+       waiting on the condition variable. Also, fixed exclusive
+       mutex ownership and usage counting.
+       * configure.in: uses TEA 3.5 
+       * tclconfig: updated to TEA3.5
+
+2006-01-28 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSpCmd.c: Revamped handling because of the deep 
+       * generic/threadSpCmd.h: race condition which resulted in
+       * tests/thread.test:     deadlocks when using exclusive mutexes.
+
+200i-10-15 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: channel transfer code cleans
+         ready-to-fire events from the thread event queue
+         prior to cutting the channel out of the interp.
+
+       * tests/thread.test: allows channel transfer tests
+         for all Unices and Windows using Tcl 8.4.10+ core.
+
+2005-09-23 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: ThreadDetach() sets the both
+         source and target thread ID's for the detached
+         channel to zero, thus signalizing the cleanup code
+         to leave the channel in the cleanup-list when the
+         thread who detached it exits.
+
+2005-08-24 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/tclXkeylist.c: made some calls static
+         so they do not interfere for static linking with
+          certain extensions.
+2005-08-08 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvCmd.c: fixed traversing the list
+         of registered object types in Sv_DuplicateObj()
+         (thx to eric.melbardis@netkitsolutions.com)
+
+2005-07-27 Zoran Vasiljevic <zv@archiware.com>
+
+       *** 2.6.2 TAGGED FOR RELEASE (thread-2-6-2) ***
+
+       * configure: regen
+       * unix/README: added some clarifications about usage
+         of --with-gdbm switch
+       * README: 
+       * configure.in: bumped version to 2.6.2
+       * aclocal.m4: fixed for alternate gdbm lib location 
+         as per patch request #1245204
+       * generic/tclThread.c: removed Thread_Unload and
+         Thread_SafeUnload because we can't really be unloaded.
+       * html/thread.html: regen
+       * html/tpool.html: regen
+       * html/tsv.html: regen
+       * html/ttrace.html: regen
+       * man/thread.n: regen
+       * man/tpool.n: regen
+       * man/tsv.n: regen
+       * man/ttrace.n: regen
+
+2005-07-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+       * Makefile.in: Remove SYSTEM_TCLSH and any
+       code that tries to run tclsh at build time
+       aside from running the test cases.
+       * configure: Regen.
+       * configure.in: Remove calls to TEA_BUILD_TCLSH
+       and TEA_BUILD_WISH since these were removed
+       from tcl.m4. This fixes up the build when
+       --with-tcl indicates either a build dir or
+       and install dir.
+
+2005-07-25 Zoran Vasiljevic <zv@archiware.com>
+
+       * pkgIndex.tcl.in: simplified by introducing a
+       helper procedure, thus avoiding too much quoting.
+
+2005-07-24  Mo DeJong  <mdejong@users.sourceforge.net>
+
+       * Makefile.in: Subst TCLSH_PROG as SYSTEM_TCLSH
+       and subst BUILD_TCLSH and BUILD_TCLSH_PROG.
+       * configure: Regen.
+       * configure.in: Invoke TEA_BUILD_TCLSH from
+       tcl.m4 to correctly determine BUILD_TCLSH.
+
+2005-04-12 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/tclThread.h:
+       * generic/threadCmd.c: reverted some changes by the
+       last checkin which slipped in by mistake
+
+2005-04-09 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/tclThread.h: 
+       * generic/threadCmd.c: added Thread_Unload and
+       Thread_SafeUnload to be able to load into the
+       8.5 shell. Both calls are still no-ops.
+
+2005-03-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in (AR): use @AR@
+       (TCLSH_ENV): add TCL_THREAD_LIBRARY var
+       * pkgIndex.tcl.in: grok TCL_THREAD_LIBRARY var
+
+       * configure, configure.in: update to TEA 3.2
+
+2005-03-15 Zoran Vasiljevic <zv@archiware.com>
+
+       * pkgIndex.tcl.in: Applied patch for Bug #1163357.
+       Also, fixed the case when directory path contains blanks.
+
+2005-03-05 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvCmd.c: fixed potential access
+       to the unlocked (and thus eventually freed) container
+
+       * lib/ttrace.tcl: the overloaded [info] command now
+       does the right thing when applied to non-existing 
+       procedures. We now transparently resolve them and
+       then allow the [info] to operate on them.
+
+       The ttrace::enable can now be called recursively.
+
+       Also, fixed stript generation issues for namespaced
+       variables containing wild escape sequences.
+
+2005-01-03 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: fixed Tcl Bug #1095370.
+       We were wrongly tearing down workers on idle timer
+       expiry *below* the number of workers set by the
+       "-minworkers" option.
+
+       * lib/ttrace.tcl: added [ttrace::config] to control
+       some runtime options. The only option it allows now
+       is "-doepochs". This is a boolean flag turning the
+        epoch generation off/on.
+       Also, improved handling of XOTcl introspections in
+       regard to namespaced objects/classes.
+
+2005-01-03 Zoran Vasiljevic <zv@archiware.com>
+
+       * lib/ttrace.tcl: added [ttrace::isenabled] and modified
+       the [ttrace::addtrace] to dynamically activate the tracer
+       if the tracing is already enabled. This way we can dynamically
+       load tracer scripts.
+       
+2005-01-03 Zoran Vasiljevic <zv@archiware.com>
+
+        **** RELEASE: 2.6.1 Tagged ****
+
+       * aolserver.m4:
+       * configure.in:
+       * configure: rebuild and include conditional compilation
+       for AOLserver which was wrongly ommited since the switch
+       to the TEA3 build system.
+       Also, we will now revert to <major>.<minor>.<patch>
+       version numbers for all releases.
+
+       * generic/threadCmd.c: added new option "-head" to the
+       [thread::send] command so scripts can be placed on the
+       head of the thread event queue instead of the tail only. 
+
+       * doc: rebuild html/nroff files from doctools sources
+
+       * generic/threadPoolCmd.c:
+       * generic/threadSvCmd.h:
+       * generic/tclThread.h: removed compat macros for 8.3 core
+
+       * test/thread.test: added case for [thread::send -head]
+
+2004-12-23 Zoran Vasiljevic <zv@archiware.com>
+
+        **** RELEASE: 2.6 Tagged ****
+
+       * tcl/cmdsrv/cmdsrv.tcl: example command server listens on
+       loopback interface (127.0.0.1) only
+
+       * README: removed stuff about (now unsupported) Tcl8.3 core
+       * unix/README: clarified usage of the CONFIG file
+       * win/vc: adjusted MSVC files for changes introduced by TEA3
+
+2004-12-18 Zoran Vasiljevic <zv@archiware.com>
+
+       **** COMPATIBILITY: Dropped support for Tcl8.3 ****
+       
+       * aclocal.m4: Adjusted for TEA3
+       * Makefile.in:
+       * configure.in:
+       * pkgIndex.tcl.in:
+
+       * configure: Rebuild with autoconf 2.59
+
+       * tests/all.tcl:    Removed extra handling for Tcl 8.3
+       * tests/thread.tcl: since we do not support 8.3 any more
+       * generic/psGdbm.c:
+       * generic/threadCmd.c:
+       * generic/threadSvCmd.c:
+
+       * doc/thread.man: Updated docs for the 2.6 release
+       * doc/tpool.man:
+       * doc/tsv.man:
+       * doc/ttrace.man:
+
+2004-11-27 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: Fixed race condition which resulted 
+       in blocking at pool creation with high -minworkers threads.
+       This fixes the Tcl Bug #933975.
+
+2004-11-25 Zoran Vasiljevic <zv@archiware.com>
+
+       * tests/thread.tcl: Disabled all tests handling channel transfer
+       for Windows ports until core is capable of handling this correctly.
+
+        * generic/threadSpCmd.c: Fixed segmentation problems observed on
+       Windows ports and related to notification of an uninitialized
+       condition variable(s). This closes Bug #1051068 (wrongly posted
+       under Tcl Patches at SF).
+
+       * doc/thread.man: Fixed mutex/condvar code example. Thanks to
+       Gustaf Neumann of XOTcl for the tip.
+
+2004-10-21  Andreas Kupries <andreask@activestate.com>
+
+       * tests/thread.test: Added two tests checking the working of
+       fileevents after a pipe channel has been transfered. The second
+       has to fail for any core where TIP #218 is not applied, because
+       the incoming alert is directed to the wrong thread for event
+       processing.
+
+2004-10-20 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c (ThreadSetResult): adjusted handling of
+       interp result to accomodate for recent changes in Tcl core.
+       This closes Tcl Bug# 1050490.
+2004-10-19  Andreas Kupries <andreask@activestate.com>
+
+       * generic/threadSvCmd.c: Added a prototype for
+       SvObjDispatchObjCmd. Prevented compilation of debug variant on
+       Windows due to warning as error.
+
+       * tests/thread.test: Added more tests transfering channels between
+       threads for in-core drivers.
+
+2004-10-18  Andreas Kupries <andreask@activestate.com>
+
+       * generic/threadCmd.c (ThreadErrorProc): Added code to explicitly
+       initialize the field 'interp' in ThreadSendData. This was ok
+       (NULL) for a regular build, but when build with symbols the
+       guard pattern forced a crash in test thread-16.2.
+
+       * tests/thread.test: Duplicate test id thread-16.1 renamed to
+       thread-16.2.
+
+2004-08-14 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: fixed broken parsing of 
+       pool handles. Pool handles are now generated in the
+       same format as thread handles.
+
+       * generic/threadCmd.c: thread handles are now cased to
+       (void*) and sprint/sscanf calls are used to generate thread
+       handles. This concludes the effort of correcting broken
+       handles on 64-bit machines since the problem was actually
+       in Tcl itself, rather than here.
+
+2004-07-21 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/tclThread.h: corrected namespace prefix for
+       AOLserver 4.x or higher, since namespaced commands are
+       now supported.
+
+       * generic/threadCmd.c: allows for re-initializing of package
+       commands for AOLserver 4.x (or higheri) interpreters. This way
+       we assure to have correct set of commands even if nobody
+       loaded the package on server startup.
+       Also, thread handles returned by the package now have the form:
+       "tid<number>" in (yet another) attempt to rectify problems found
+       on Cray computers.
+
+       * generic/threadPoolCmd.c: adjusted handles of the pools to
+       match ones of threads (see above).
+
+2004-07-21 Zoran Vasiljevic <zv@archiware.com>
+
+       * doc/*: reformatted docs and added some clarifications 
+       about mutex handling.
+
+       * generic/threadCmd.c: rewritten handling of thread handles
+       as passed to Tcl. Instead of casting Tcl_ThreadId to unsigned int
+       which brought some problems on Cray machines, we're now generating
+       opaque handles and match them to Tcl_ThreadId internally.
+
+       NOTE: this is not supposed to be a compatibility issue since
+       thread-handles should have been treated as opaque anyways.
+
+       * generic/threadSpCmd.*: improved behaviour when destroying locked
+       mutexes and locking the same mutex twice from the same thread.
+       In both cases we throw Tcl error instead of coring  the process
+       or deadlocking the (naive) application.
+
+       * generic/threadSvCmd.*: number of tsv buckets is now compile
+       time constant.
+
+       * lib/ttrace.tcl: Fixed error in unknown wrapper when the passed
+       command was empty string.
+
+       * tests/all.tcl
+       * tests/thread.test: rewritten from scratch.
+
+       * tests/tpool.test:
+       * tests/ttrace.test:
+       * tests/tsv.test: new files, currently no-ops.
+
+2004-01-31 Zoran Vasiljevic <zv@archiware.com>
+
+       * lib/ttrace.tcl: added unconditional "package require"
+       call to ttrace::eval so we need not explicitly load the
+       Ttrace package in each and every thread. Also, fixed some
+       issues with errorInfo/errorCode handling.
+
+       * pkgIndex.tcl.in: fixed Tcl Bug #918137
+       * doc/format.tcl: fixed inclusion of man.macros in
+       every *.n doc file
+
+2004-01-31 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed incorrect handling of return
+        codes from the scripts passed to threads. We were wrongly
+        triggering error for non-error return codes such as TCL_RETURN,
+       TCL_BREAK, TCL_CONTINUE etc. Now we trigger error only for
+       TCL_ERROR and return other codes (as-is) to the caller.
+       This also fixes the Tcl Bug #884549.
+
+2003-12-22 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSpCmd.c: added recursive and reader/writer locks
+       and associated commands
+
+       * generic/threadSpCmd.h: added new file
+
+       * generic/lib/ttrace.tcl: added Ttrace package implementation
+
+       * doc: added documentation for Ttrace package and synced other
+       doc files to match the release 2.6 state.
+
+
+2003-12-01 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: removed the concept of foreign
+       thread since it broke our async message bouncing. We
+       still have to find the way how we should avoid broadcasting
+       non-package threads (like for aolserver).
+
+2003-11-27 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed mutex release in ThreadSend
+       when refusing to send message to foreign thread.
+       Also, clear the result of the thread::broadcast since it
+       should not return anything to the caller, no matter the
+       outcome of the command.
+
+2003-11-27 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: mark threads created by the package
+       to distinguish them from "foreign" threads. We will forbid
+       sending messages to those since they will probably never listen.
+
+       * generic/threadSvCmd.c: corrected some typos
+
+       * generic/threadSvListCmd.c: added implementation for the
+       "tsv::lset" command
+
+       * generic/threadPoolCmd.c: added optional varname argument
+       (last arg) to the tpool::cancel
+
+2003-11-25 Zoran Vasiljevic <zv@archiware.com>
+
+       * doc/format.tcl: new file with a simple poor man's
+       documentation formatter.
+
+       * doc/thread.man
+       * doc/tpool.man
+       * doc/tsv.man: new doctools source files for building
+       the package documentation.
+
+       * Makefile.in: added support for building nroff and html
+       files out of doctools sources found in doc directory.
+
+2003-11-18 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: added implementation of the 
+       thread::broadcast command. This one asynchronously 
+       sends a script to all known threads, except the caller.
+
+2003-09-03 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/tclXkeylist.(c|h): added keyed-list datatype
+       implementation borrowed from the TclX package. This is
+       now part of the shared variable command set.
+
+       * generic/threadSvCmd.(c|h): modified to support persistent
+       shared variables with plugin-architecture for different
+       persistent store implementations.
+
+       * generic/threadSvlistCmd.(c|h): modified to reflect added 
+       support for persistent shared variables.
+
+       * generic/psGdbm.(c|h): added persistent store wrapper
+       for the GNU gdbm package.
+
+       * configure et al: regenerated with autoconf because of
+       added optional comilation with GNU gdbm. Updated makefiles
+       to process newly added files for keyed lists and persistent
+       stores.
+
+2003-08-27 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: after expiration of the idle
+       timer, all idle workers exit unconditionaly. Before the
+       change, idle threads exited after getting the first job
+       posted. This way we were loosing work.
+
+2003-08-26 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: fixed result list corruption
+       in TpoolCancelObjCmd. 
+
+2003-07-27 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: added "-nowait" option
+       to the "tpool::post" commandi. This allows the 
+       caller to post jobs to the threadpool queue without
+       waiting for an idle thread. The implementation will
+       start at least one worker thread if there is none 
+       available to satisfy the first request.
+       Added "tpool::cancel" command. See docs for info.
+
+2003-05-31 Zoran Vasiljevic <zv@archiware.com>
+       
+       * generic/threadCmd.c: fixed ListRemoveInner for
+       the Tcl Bug #746352
+
+       * generic/threadSpCmd.c: modified Sp_Init to 
+       return a proper value for Tcl Bug #746352
+
+2003-05-17 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: sets the name of the new thread
+       to "-tclthread-" when compiled for AOLserver
+
+2003-04-29 Zoran Vasiljevic <zv@archiware.com>
+
+        Tagged interim 2.5.2 release.
+
+       * configure.in
+       * configure: Added quick fix for autoconf issues
+        related to $srcdir and building of the package
+        from the top-level dir instead of unix/win subdir.
+        Thanks to Mo DeJong for the fix.
+
+2003-04-10 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: removed checking of stopped flag
+       during walk of the list of active threads. This
+       solves some subtle thread reservation problems
+       with threads marked to unwind on error.
+       Also, added new "-errorstate" configuration option
+       to set/get error state of reserved unwinding thread.
+       
+2003-04-02 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c:
+       * generic/threadPoolCmd.c:
+       * generic/threadSpCmd.c:
+       * generic/threadSvCmd.c: always call registered exit callbacks
+       with non-NULL clientData, otherwise Tcl won't invoke
+       the registered  callback. 
+
+2003-03-28 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvList.c
+       * generic/threadSvCmd.c: fixed some rare cases
+       where we incorrectly deep-copied the list object
+       having zero elements.
+
+       * generic/threadCmd.c: fixed broken AOLserver 3.x
+       compatibility mode introduced by last 4.x changes.
+
+2003-03-17 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvCmd.c: fixed incompatibility 
+       with Tcl 8.4.2 filepath object
+
+       * generic/threadCmd.c:
+       * aolstub.cpp: adjusted for AOLserver 4.0
+2003-02-24 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed ThreadSetResult
+       to correctly initialize all elements of the 
+       result structure.
+
+2003-02-08 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed ListRemoveInner
+       to correctly update global threadList ptr when 
+       the last referenced thread exits. This was not
+       the case before and we were trashing memory
+       leading to process exitus.      
+
+2003-01-25  Mo DeJong  <mdejong@users.sourceforge.net>
+
+       * generic/threadCmd.c (ThreadSendObjCmd):
+       The thread::send command was not working
+       under Win32 because threads that had an id
+       that was a negative number were generating
+       a usage error in the thread::send command.
+       * tests/thread.test: Add test for negative
+       number as thread id.
+
+2003-01-22 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed reference to errorInfo
+       when reporting error from the passed script.
+
+2003-01-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+       * configure: Regenerate to include recent fixes
+       for mingw build support in tclconfig module.
+
+2002-12-18 Zoran Vasiljevic <zv@archiware.com>
+
+       * README: added some AOLserver info
+       * tcl/tpool/tpool.tcl: added missing tpool::names command
+
+2002-12-14 Zoran Vasiljevic <zv@archiware.com>
+
+       * doc/*: finished docs for the 2.5 release
+
+2002-12-09 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolCmd.c: added tpool::names command
+       added -exitscript for tpool::create
+
+       * doc/tpool.tmml
+       * doc/man/tpool.n
+       * doc/html/tpool.html: added files. This is still the
+       work in progress.
+
+2002-12-06 Zoran Vasiljevic <zv@archiware.com>
+
+       * configure.in
+       * configure
+       * Makefile.in
+       * aolserver.m4: added support for compilation under
+       AOLserver as loadable module.
+
+2002-12-06 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvCmd.c: the tsv::lock now allows
+       for unsetting the shared array within the script argument.
+
+       * generic/threadPoolCmd.c: fixed one missing mutex unlock
+       in the ThreadRelease.
+
+        * tcl/tpool/tpool.tcl: implemented missing API calls found
+       in the C-level implementation.
+
+       * tcl/phttpd/phttpd.tcl: simplified switching to Tcl-level
+       threadpool implementation.      
+
+2002-12-04 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadPoolcmd.c: rewritten to use
+       worker threads sitting on the cond var instead of 
+       in the event loop. The poster thread still respects
+       i.e. does not block the event loop while posting jobs.
+
+2002-12-03 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/tclthread.h: added SpliceIn/SpliceOut macros.
+       Fixed to include exports from threadPoolCmd.c
+
+       * generic/threadSpCmd.c: does regular namespace handling
+       over the NS variable instead of hard-coding the "thread"
+       prefix for mutex/cond commands.
+
+       * generic/threadCmd.c: rewritten to use SpliceIn/SpliceOut
+        macros instead of hand-fiddling with linked lists.
+
+       * generic/threadPoolCmd.c: new file
+
+       * Makefile.in: added threadPoolCmd.c to list of source files.
+
+2002-11-25 Zoran Vasiljevic <zv@archiware.com>
+
+       * tcl/phttpd/phttpd.tcl: added raw file; no thread support
+       * tcl/cmdsrv/cmdsrv.tcl: first working version
+
+2002-11-24 Zoran Vasiljevic <zv@archiware.com>
+
+       * tcl/tpool/tpool.tcl: added threadpool implementation in Tcl
+       * tcl/phttpd: added directory for later mt-enabled pico-httpd 
+       * tcl/cmdsrv: added directory for later socket command server
+       * doc/man/thread.n
+       * doc/thread.tmml
+       * doc/html/thread.html: new tsv::eval, thread::attach, thread::detach
+
+       * generic/threadSvCmd.h
+       * generic/threadSvCmd.c: added tsv::eval command
+
+       * generic/threadCmd.c: added thread::attach, thread::detach
+       Also, fixed thread::preserve and thread::release to accept
+       the thread id as the optional paramter.
+       
+2002-11-23 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed ListRemoveInner() to recognize
+       and ignore already removed tsd thread structures. 
+       Fixed some invalid TCL_OK returns which masked serious errors.
+       
+2002-11-07 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixes problem when trying to report
+       the error from an async callback when the stderr channel is
+       not available (wish/tclkit on windows). Thanks to 
+       Wojciech Kocjan <wojciech@kocjan.org> for the correction.
+
+2002-10-23 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: added handling of background errors
+       while doing an async callback. 
+
+2002-10-20 Zoran Vasiljevic <zv@archiware.com>
+
+       * doc/html/thread.html
+       * doc/man/thread.n
+       * doc/thread.tmml: fixed "thread::send" command summary.
+       It was showing the wrong position of the "-async" argument.
+
+       * generic/threadSpCmd.c: adjusted mutex/cond handles to
+       use the same format and handling as AOLserver counterparts
+       when compiled for AOLserver support. This way one can mix
+       and match primitives declared with ns_mutex and thread::mutex
+       and/or ns_event and thread::cond commands.
+       Added thread::eval command. See documentation for syntax and usage.
+
+2002-10-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure:
+       * configure.in: move the CFLAGS definition into TEA_ENABLE_SHARED
+       and make it pick up the env CFLAGS at configure time.
+
+2002-08-23 Zoran Vasiljevic <zv@archiware.com>
+
+       * threadCmd.c: fixed potential memory corruption
+       when releasing preserved interpreter.
+       [Tcl bug 599290]
+
+2002-08-19 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvCmd.c: we now properly invalidate
+       duped object string rep if the internal rep has been
+       regenerated.
+
+2002-08-18 Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: updated some comments
+       * generic/threadSvCmd.c:
+       * generic/threadSvListCmd.c: fixed silly mem leak
+       where we were registering commands and object types
+       for each new thread, resulting in unnecessary table
+       grow. Not a memory leak per-se, therefore not found
+       by Purify, but shows itself by observing the size
+       of the process using the top utility. Gosh!
+
+2002-08-03  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvListCmd.c: corrected "tsv::lpush"
+       to correctly make a copy of the object pushed into
+       the list in shared array element.
+
+2002-07-22  Mo DeJong  <mdejong@users.sourceforge.net>
+
+       * README: Fix typo.
+       * doc/man/thread.n: Note that thread::join and
+       thread::transfer are only available with Tcl 8.4.
+
+2002-07-20  Mo DeJong  <mdejong@users.sourceforge.net>
+
+        * generic/threadSvCmd.c (Sv_tclEmptyStringRep, Sv_Init):
+        Avoid linking to the tclEmptyStringRep variable defined
+        in Tcl since this makes it very difficult to load
+        the Thread package into an executable that has
+        also loaded Tcl. The previous approach used a hack
+        under Windows, we now use this same hack on all systems.
+       [Tcl patch 584123]
+
+2002-07-19  Zoran Vasiljevic <zv@archiware.com>  
+
+       * threadCmd.c: added some macros to simplify
+       adding and removing result structure in and  
+       out of the corresponding lists
+
+2002-07-18  Zoran Vasiljevic <zv@archiware.com>  
+
+       * threadCmd.c: modified thread::release to allow
+       for optional "-wait" argument. This will result in 
+       the thread waiting until the target thread has really
+       exited. Otherwise, the command exits immediately and 
+       target thread may exit asynchronously some time later.
+       This is not techically needed since one can always join
+       the exiting thread, but the join command is not 
+       available for some older Tcl versions. 
+
+2002-07-13  Zoran Vasiljevic <zv@archiware.com>  
+
+       * doc/man:
+       * doc/html: added two directories with TMML generated files
+       * doc/thread.tmml: fixed for the final 2.4 release
+       * Makefile.in: updated install-doc target to look for man files
+       under doc/man instead only under doc directory
+
+2002-07-12  Zoran Vasiljevic <zv@archiware.com>  
+
+       * generic/threadSvCmd.s: fixed handling of string rep
+       in shared var object duplicator
+
+2002-07-09  Zoran Vasiljevic <zv@archiware.com>  
+       * README: added this file
+       * license.terms: added this file
+
+2002-07-05  Zoran Vasiljevic <zv@archiware.com>  
+
+        * tclconfig/tcl.m4: fixed reference to MINGW so we can
+       compile w/o MSVC under windows. 
+
+2002-07-03  Zoran Vasiljevic <zv@archiware.com>  
+
+       * generic/threadSvCmd.c: simplified object duplicator
+
+2002-06-17  Zoran Vasiljevic <zv@archiware.com>  
+
+       * generic/threadCmd.c: cleanup of some unused variables
+       * generic/threadSvCmd.c:
+       * generic/ThreadSpCmd.c:
+       * generic/threadSvList.c: added CONST qualifiers to avoid warnings
+       when compiling against 8.4 core. 
+
+2002-05-25  Zoran Vasiljevic <zv@archiware.com>  
+       * generic/threadCmd.c: added some typecasts to satisfy Windows 
+       * generic/threadSvCmd.h: added some typecasts to satisfy Windows 
+
+2002-05-04  Zoran Vasiljevic <zv@archiware.com>  
+       * generic/threadSvCmd.c: removed errant reference to (still not)
+       supported shared dictionary and shared keylist datatypes.
+
+2002-04-27  Zoran Vasiljevic <zv@archiware.com>  
+
+       * generic/threadCmd.c: fixed processing of -eventmark. We now
+       properly wait for target thread to catch up with processing events.
+
+2002-04-07  Zoran Vasiljevic <zv@archiware.com>  
+
+       * generic/threadCmd.c: added call to Ns_TclMarkForDelete(interp)
+       when compiled for AOLserver support, otherwise we were leaking std
+       channels on thread exit.
+
+2002-04-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in: improved use of DESTDIR in install targets.
+       Removed need for installdirs target.
+       Broke TCLSH_PROG into TCLSH_ENV and TCLSH_PROG with TCLSH var and
+       added comments about TCLSH_ENV.
+       Added default shell and gdb targets.
+
+       * configure: 
+       * configure.in: updated to new TEA base that: prefixes all macros
+       with TEA_* instead of SC_*; adds TEA_PREFIX, which defaults the
+       prefix and exec_prefix values to what Tcl used; adds
+       TEA_SETUP_COMPILER, which handles basic compiler / support program
+       checks and simplifies the configure.in.  Turn on --enable-threads
+       by default and do sanity checking as well.
+
+2002-04-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in (install-lib-binaries): ensure that binary files are
+       installed with executable bit set (use INSTALL_PROGRAM)
+
+2002-03-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure:
+       * configure.in: BUILD_${PACKAGE} had to be static BUILD_thread in
+       AC_DEFINE because autoconf wasn't substituting ${PACKAGE}.
+
+2002-03-27  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in (TCLSH_PROG): moved and updated env var definitions
+       to have tclsh work from build dir.  Removed TCL_EXTRA_CFLAGS,
+       TCL_LD_FLAGS, TCL_SHLIB_LD_LIBS, TCL_DBGX, TCL_STUB_LIB_FILE,
+       TCL_STUB_LIB_SPEC as they aren't needed (configure acquires all
+       that info for us).  TCL_LIBS is also not needed, but left in as a
+       reference to the libs Tcl used.
+
+       * configure: regen based on updated tclconfig/tcl.m4
+       * configure.in: moved the SHLIB_LD_LIBS magic into
+       tclconfig/tcl.m4 and noted where users can modify (SHLIB_LD_)LIBS.
+
+2002-03-19  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * generic/tclThread.h: 
+       * generic/threadCmd.c: added stub voodoo magic to allow building
+       against Tcl 8.3 and still get all the 8.4+ functionality when later
+       loaded into an 8.4+ interp.
+
+       * pkgIndex.tcl.in: simplified auto-generated pkgIndex.tcl file.
+
+       * tests/all.tcl:
+       * tests/thread.test: improved to detect 8.3/8.4 pkg differences
+
+       * tclconfig/tcl.m4,install-sh (new):
+       * config/* (removed):
+       * aclocal.m4: 
+       * configure: 
+       * configure.in: 
+       * Makefile.in: Updated build system to use tclconfig (TEA 2002)
+       structure.
+
+2002-03-09  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvCmd.c: fixed memory leak when copying objects
+       using custom object duplicator. If a duplicator was registered
+       more than once, we were leaking memory.
+
+2002-03-08  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: added thread::configure -unwindonerror
+       configuration option. See docs for usage.
+       
+       * doc/thread.n: added docs for thread::configure -unwindonerror
+       
+2002-03-07  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadSvCmd.c: tsv::names will skip reporting shared
+       arrays with leading dot in their names. This is turned-on 
+       only for AOLserver builds with the HIDE_DOTNAMES. For the
+       regular Tcl builds, all arrays are reported, regardless of
+       the name. Motivation behind this feature is to allow certain
+       data privacy. It is not name-clash proof, though.
+
+2002-02-12  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed thread::preserve glitch. We never
+       actually did bump the reservation counter by a silly mistake.
+
+2002-02-12  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: added thread::preserve and thread::release
+       commands. These allow for a simple reference counting when creating
+       and/or tearing-down threads. Instead of calling thread::unwind in
+       the target thread, one can use "thread::release id" to dispose it.
+       This is much easier to use and it can be coupled with calls to
+       thread::preserve to implement simple thread reservation mechanism.
+
+       * doc/thread.n: added docs for thread::preserve/thread::release
+       
+2002-02-09  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: added thread::configure interface.
+       Currently only "-eventmark" option is supported.
+       Allows for AOLserver builds to change the "thread::" prefix
+       by re-defining the "NS" compile-time constant.
+
+       * doc/thread.n: added docs for thread::configure
+
+2002-02-06  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/aolserv.cpp: (new) added for loading into the AOLserver.
+       Still needs to fix the Makefile and friends to get it up and
+       running.
+
+       * generic/threadCmd.c: added conditional setup of the command
+       prefix. Now, the "NS" can be used to select the command prefix
+       for thread::* commands.
+
+2002-01-26  David Gravereaux <davygrvy@pobox.com>
+
+       * generic/threadSvCmd.c:  A small 'const' qualifier change to remove a
+       warning.  It's a bit more wordy now, but reads a little clearer to me.
+       Unscambling pointer math gives me a headache and combined with a cast
+       tends to get dangerous.
+
+       * win/threadWin.c: new idea for thread::kill added.  It's wrapped in an
+       #if 0/#endif for now.  I do notice that tcl.h is now typedef'ing
+       ClientData as an 'int *'.  It used to 'void *', didn't it??  The
+       ISO/ANSI/CLEAN C style of setting a typed pointer to a void* now doesn't
+       want to work.  Maybe I do too much C++ to have noticed this before...
+
+2002-01-23  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed address of the target interpreter when
+       doing the callback async script processing. All messages went to the
+       main interpreter instead of the selected interpreter, causing process
+       to hung when posting callbacks to more that one interp at the same time.
+       (thanks Jean-Luc Fontaine for the tip)
+
+2002-01-20  Zoran Vasiljevic <zv@archiware.com>
+
+       * generic/threadCmd.c: fixed multiple async reporting of error events
+       (thanks Jean-Luc Fontaine for the tip)
+   
+2002-01-02  Zoran Vasiljevic <zv@archiware.com>
+
+        * generic/threadSvListCmd.* (new): added for the new implementation
+        of the thread-shared-variable (tsv) interface.
+        * generic/threadSvCmd.c: now uses shared Tcl objects instead of strings
+        for storing data in shared arrays. This improves performance on large
+        shared data structures.
+        Added new tsv::* syntax, per request. This replaces older thread::sv_*
+        interface. Older commands are still present but will be removed as
+        soon we hit the 3.0 version.
+        * generic/threadCmd.c: revamped to support asynchronous backfiring
+        of scripts so we can vwait on the results of thread processing.
+        This also corrected the bug #464340. Affected command is thread::send.
+        * doc/thread.n: added docs for all thread::* and tsv::* commands.
+        This fixes #416850 bug report. The html/tmml files are still out of date.
+        * configure: built with autoconf 2.52
+        * config/config.guess (new): needed for the new configure
+        * config/config.sub (new): needed for the new configure
+        * Makefile.in: added lines for new generic/threadSvListCmd.c
+        * configure.in: moving to 2.4 version.
+        * unix/threadUnix.c: removed traces of ThreadKill. It is still not clear
+        wether we should implement this functionality or not.
+        * win/threadWin.c: see above.
+        * pkgIndex.tcl.in: fixed to correctly handle version for different Tcl core
+        versions.
+
+2001-09-05  David Gravereaux <davygrvy@pobox.com>
+
+       * generic/*:
+       * win/threadWin.c (new): updated for a new threadWin.c and finished
+       replacing use of thread.h with tclThread.h.  threadWin.c is an
+       experiment to add a 'thread::kill' command.  Not done yet.
+
+       * win/vc/thread.rc (removed):
+       * win/thread.rc (new): moved it up a directory.
+
+2001-09-04  David Gravereaux <davygrvy@pobox.com>
+
+       * generic/thread.h (deleted):
+       * generic/tclThread.h (new):
+       * generic/threadCmd.c:  decided to change the name of 'thread.h' to
+       'tclThread.h', per request.
+
+       * generic/thread.h:
+       * generic/threadCmd.c:  Re-added original implimentation of [thread::exit].
+       for `emergency use only`.  You have been warned ;)
+
+       * configure.in:
+       * configure:
+       * win/vc/thread.dsp:
+       * win/vc/pkg.vc:  Upped version numbers to 2.3 and 2.1.3 because I just cut
+       a release.
+
+2001-09-04  David Gravereaux <davygrvy@pobox.com>
+
+       -=[ Official 2.2 Tagged and cut. ]=-
+
+2001-05-27  David Gravereaux <davygrvy@pobox.com>
+
+       * tests/thread.test: fixed small typo in comments.
+
+2001-08-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in: corrected handling of VERSION
+
+       * generic/threadCmd.c:
+       * generic/thread.h: added Thread_SafeInit
+
+       * win/vc/makefile.vc: added -DBUILD_thread to cflags.
+
+2001-05-27  David Gravereaux <davygrvy@pobox.com>
+
+       * configure:
+       * configure.in:
+       * Makefile.in:
+               Added package versions to the compile flags. [bug #421246]
+
+2001-04-28  David Gravereaux <davygrvy@pobox.com>
+
+       * generic/threadCmd.c (NewThread): removed the previous addition of
+       Tcl_FinalizeThread.  Tcl_ExitThread calls it anyways (my mistake).
+       The resource leak was in the core.  See ->
+       http://sourceforge.net/tracker/?func=detail&atid=110894&aid=419683&group_id=10894
+       for the fix.  That patch is pending approval.
+
+       To acheive the same behavior of emptying the event loop the way
+       thread::wait used to work, use the following:
+               set T [thread::create {thread::wait; update}]
+               thread::send -async $T thread::unwind
+
+       * generic/thread.h:
+       * win/vc/makefile.vc:
+       * win/vc/thread.rc:
+       * win/vc/pkg.vc (new): Moved version numbers from the header file.  It isn't
+       an export API or anything.  Moved version numbers to the build files.  I'll
+       modify configure.in and makefile.in a little later.
+
+2001-04-26  David Gravereaux <davygrvy@pobox.com>
+
+       * config/* (new): old site-wide config directory re-added.
+
+       * generic/threadCmd.c (ThreadEventProc): ThreadErrorProc now
+       supported in asyncronous sends when Tcl_Eval returns other than
+       TCL_OK.  Errors were silently ignored prior to this. Bug #219324
+
+       ==== INTERFACE CHANGE ====
+       * generic/threadCmd.c:
+       * generic/thread.h: thread::exit renamed to thread::unwind. The
+       name of 'exit' is misleading.  An exit implies an unconditional
+       return.  But there are conditions.  'unwind' describes with more
+       clarity what's happening to the prior thread::wait.  For example:
+
+         # parent thread
+         set T [thread::create {source worker.tcl}]
+         ....
+         thread::send -async $T doStuff
+         ....
+         thread::send -async $T doStuff
+         ....
+         thread::send -async $T thread::unwind
+
+         # worker.tcl
+         proc init    {} {#do initialization}
+         proc cleanup {} {#do cleanup}
+         proc doStuff {} {#the work}
+         init
+         thread::wait
+         cleanup
+
+       When worker.tcl is sourced, the execution stops at thread::wait and
+       the event loop is entered.  When thread::unwind is sent to the worker,
+       thread::wait falls-out and cleanup is called.  The condition for
+       thread::unwind to cause an exit is determined by the script.  If
+       thread::wait was the last Tcl command in the script, yes the thread
+       will exit.  But if thread::wait is not the last, the execution of the
+       script is just continued.  Hence, the name change to clarify this fact.
+
+       Package version has not been changed.  There hasn't been an official
+       release of 2.2, so it stays.
+
+       * doc/thread.n:
+       * tests/thread.test: Replaced thread::exit with thread::unwind and
+       documented the change and clarified the subtleties.
+
+       * win/vc/makefile.vc:
+       * win/vc/thread.dsp: Changed NODEBUG macro to be DEBUG instead.
+       Double negatives give me a headache.  DEBUG=1 makes more sense
+       to me than NODEBUG=0.  Not that I didn't think you wouldn't have
+       disagreed it was confusing, no?
+
+       * win/vc/config.vc: Added a reminder to edit before using.
+       * win/vc/thread.rc: Added authors and removed the Ajuba branding.
+
+2001-04-25  David Gravereaux <davygrvy@pobox.com>
+
+       * generic/threadCmd.c (ThreadWait)(NewThread): Removed the event
+       loop sinking which was probably done because Tcl_FinalizeThread
+       was missing from NewThread().  Now the event loop is cleaned
+       by Tcl_FinalizeThread and ThreadWait doesn't manipulate events
+       that don't belong to it.  Bug #418689 and #418693
+
+       * generic/threadCmd.c (Thread_Init): logic fix in a version check
+       for determining the 8.3 package subset.
+
+2000-11-02  David Gravereaux <davygrvy@ajubasolutions.com>
+
+       * generic/threadCmd.c (NewThread): Added logic to test for a
+       working Tcl_Init() based on the core version at runtime and ignore
+       its failure in versions 8.3.[1,2] and 8.4a1.  [BUG: 5301]
+
+2000-10-26  David Gravereaux <davygrvy@ajubasolutions.com>
+
+       * generic/thread.h:
+       * win/vc/config.vc:
+       * win/vc/makefile.vc:
+       * win/vc/thread.dsp: upped version numbers to 2.2 along with adding
+       a new macro (THREAD_VERSION_SUBSET83) defining the version when
+       loaded into an 8.3 core.  Which happens to be "2.1.1" at this time.
+
+       * generic/threadCmd.c (Thread_Init): Added logic to allow setting
+       the package version at runtime to "2.2" when compiled against 8.4
+       and loaded into 8.4.  When compiled against 8.4, yet loaded into
+       8.3, thread::join and thread::transfer are not added to the interp
+       and the package version is set to "2.1.1" instead from the single
+       binary.  [ie. multiple interfaces in one binary]  When compiled
+       against 8.3, thread::join and thread::transfer are non-existant and
+       the package version is always "2.1.1" to maintain a consistent
+       interface in all combinations (as per discussions with Don Porter).
+
+2000-10-16  Zoran Vasiljevic <zv@munich.com>
+
+       * generic/threadSvCmd.c ThreadSvUnsetObjCmd(): deadlocked.
+        Forgot to release shared-array lock which resulted in
+        deadlock after first successful unset of the variable.
+
+2000-08-29  David Gravereaux <davygrvy@ajubasolutions.com>
+
+       * generic/threadCmd.c (NewThread): Tcl_Init return value wasn't
+       being verified.  Added a check and failure logic to fall-out.
+       [Bug: 5301]
+
+2000-08-28  David Gravereaux <davygrvy@ajubasolutions.com>
+
+       * generic/threadCmds.c (Thread_Init): Added logic to enable
+       thread::join and thread::transfer when loaded into an 8.4+ core.
+       We don't want a seg fault when the Stubs tables don't match for
+       the functions that don't exist in an 8.3 core.
+
+2000-08-23  Brent Welch <welch@ajubasolutions.com>
+
+       * configure.in:
+       * win/vc/makefile.vc: Changed to version 2.1
+       * generic/threadCmds.c: Made the code that uses new Tcl 8.4 APIs
+       conditional using #ifdef.  Tested with 8.3.2
+       * Applied thread-2-1 tag for use with tclhttpd bundled release.
+
+2000-08-21  David Gravereaux <davygrvy@ajubasolutions.com>
+
+       * win/vc/makefile.vc:
+       * win/vc/thread.rc: added version numbers to filename to follow
+       Tcl standards.
+
+       * doc/thread.tmml(new): Initial TMML document.
+
+2000-08-20  David Gravereaux <davygrvy@ajubasolutions.com>
+
+       * win/vc/config.vc:
+       * win/vc/makefile.vc:
+       * win/vc/README.txt:
+       * win/vc/thread.dsp:  A near top down rewrite that adds
+       four more build configurations.  See README.TXT for the
+       details.
+
+       * win/vc/.cvsignore:  A few more glob patterns added to match
+       the new build directories.
+
+2000-08-09  David Gravereaux <davygrvy@ajubasolutions.com>
+
+       * win/vc/thread.rc: swapped "Scriptics Corp" for "Ajuba
+       Solutions"
+
+       * win/vc/config.vc:
+       * win/vc/makefile.vc: cleaned-up old cruft.  Added new files
+       from Zoran's patches.  made swapping to MSDev 6.0 easier.
+       Removed the '!if $(_NMAKE_VER) > 162' test for 2 reasons.
+
+       1) batchmode inference rules are valid since MSDev 5.0 and
+       the core can't be built with less.  So don't bother testing.
+
+       2) nmake.exe that comes with MSDev 6.0 has a bug with the
+       meaning of that macro and MS decided to use a string instead
+       breaking the integer comparison test.
+
+       Also added vcvars32.bat to a new setup rule and got config.vc
+       much smaller.
+
+       * win/vc/thread.dsp: Added new files from Zoran's patch.
+
+       * win/.cvsignore(deleted):
+       * win/vc/.cvsignore(added): moved file to help keep a cleaner
+       build environment.
+
+       * generic/threadSvCmd.c: Added some additional casting of
+       Tcl_GetHashValue to prevent compiler warnings.
+
+       * generic/threadCmd.c(ThreadWait): Removed the event loop
+       sinking after the "while(..) Tcl_DoOneEvent();" because this
+       extension is only responsible for it's own events in the event
+       loop.  Any other extension that's queueing events must be
+       responsible for it's own cleanup and should be aware of when
+       the interp (ie. this thread) is going away when we fall-out
+       to Tcl_DeleteInterp from the Tcl_Eval in NewThread().  If other
+       extensions (like Tk) don't become aware, then they need to add
+       a Tcl_CallWhenDeleted handler.
+
+2000-07-14 Zoran Vasiljevic <zv@munich.com>
+
+       * generic/threadCmd.c: improved thread::exit behaviour
+         now does a better job of draining the event loop before exit.
+         may have some wishes open, though - see ThreadWait().
+       
+       * generic/threadSpCmd.c, generic/threadSvCmd.c:
+         added some comments in function headers.
+         docs/tests for above still pending.
+       
+2000-07-03 Zoran Vasiljevic <zv@munich.com>
+       
+       Summary of changes:
+
+       * generic/threadSpCmd.c: new file with implementation of 
+         "thread::mutex" and "thread::cond" commands. Documentation 
+         and tests are still pending.
+       
+       * generic/threadSvCmd.c: new file with implementation of 
+         "thread::sv_*" family of commands modeled after AOLserver
+         nsv_* ones. Documentation and tests are still pending.
+
+       * Makefile.in: fixed for the two above
+
+       * doc/thread.html 
+       * doc/thread.n: added 'thread::exists' docs
+
+       * generic/thread.h added declarations for new commands (above)
+       
+       * generic/threadCmd.c:
+       
+         Added "thread::exists" command.
+
+         Moved most of internal functions in threadCmd.c to statics,
+          except the Thread*ObjCmd(). 
+
+         Changed behaviour of "thread::exit". It now simply flips the
+          bit to signal thread stuck in thread::wait to gracefuly exit.
+          Consequence: command now does not trigger error on thread exit.
+          Also, thread event queue is now properly cleared.
+          ThreadWait() and ThreadStop() are newly added to support this.
+          Also the ThreadSpecificData has one more integer: "stopped"
+
+         Replaced ref's to obsolete Tcl_GlobalEval() with Tcl_EvalEx().
+
+         Fixed broken 'thread::create -joinable script';
+          was missing initialization of script variable
+
+         Added calls to initialize new commands in threadSpCmd.c
+         and threadSvCmd.c files.
+
+2000-05-18 Brent Welch <welch@scriptics.com>
+
+       * Restored Andreas' changes for transferring sockets.
+
+2000-05-16 Brent Welch <welch@scriptics.com>
+
+       * Temprarily rolled back Andreas' changes so I can fix up
+       the 2.0 release (configure and Make).  Also need to apply
+       a 2.0 tag.
+
+2000-05-09 Andreas Kupries  <a.kupries@westend.com>
+
+       * tests/thread.test: Removed dependency on aclocals.m4. Using a
+         real temporary file now, as created by a call to
+         tcltest::makeFile. Updated test 6.3 to use the correct length
+         information.
+
+2000-05-04  Andreas Kupries <a.kupries@westend.com>
+
+       * Overall changes:
+         (1) Added joinable threads.
+         (2) Added transfer of channels between threads.
+
+       * generic/threadCmd.c: Added functions Thread_Join and
+         ThreadJoinObjCmd.
+
+         Extended function ThreadCreateObjCmd to handle a
+         -joinable flag.
+
+         Fixed bug in Thread_Create, the argument 'stacksize' was not
+         used.
+
+         Removed declaration of ThreadObjCmd, which was not used anywhere
+         else in the code.
+
+         Added functions Thread_Transfer, ThreadTransferEventProc and
+         ThreadTransferObjCmd. Extended behaviour of ThreadDeleteEvent
+         and ThreadExitProc to deal with the new class of events.
+
+         Changed usage of ckfree to the more canonical Tcl_Free. Same for
+         ckalloc and Tcl_Alloc.
+
+       * Makefile.in: Fixed bug with regard to the installation of
+         documentation.
+
+       * doc/thread.*: Added documentation of create -joinable,
+         thread::join and thread::transfer.
+
+       * tests/thread.test: Added tests for joining of threads and moving
+         channels between threads.
+
+2000-04-19  Brent Welch <welch@scriptics.com>
+
+       * win/vc/config.rc, Makefile.vc: Fixes from David Gravereaux
+
+2000-04-18  Brent Welch <welch@scriptics.com>
+
+       * Makefile.in: Fixes for make install
+
+2000-04-17  Brent Welch <welch@scriptics.com>
+
+       * generic/threadCmd.c
+       Added Tcl_CreateThreadType and TCL_RETURN_THREAD_TYPE
+       macros for declaring the NewThread callback proc.
+
+2000-04-11  Brent Welch <welch@scriptics.com>
+
+       * Picked up minor changes from David Gravereaux <davygrvy@bigfoot.com>
+       * for compilation on windows with his alternate project files.
+
+2000-04-10  Brent Welch <welch@scriptics.com>
+
+       * Moved all the configure.in, Makefile.in etc. up to the top level out
+       * of the unix (and win) subdirectories.  These are now shared.
+       * If you are using CVS, you'll want to get the "config" module into
+       * this directory, or do the checkout of thread again so the config
+       * module is brought in.  You should have a "config" subdirectory of
+       * your main thread workspace directory.
+
+2000-04-09  Brent Welch <welch@scriptics.com>
+
+       * Updated to compile against 8.3.1 export thread APIs
+       * Added Windows makefiles
+
+2000-03-27  Brent Welch <welch@scriptics.com> (proxy for Andreas Kupries)
+
+       * tests/all.tcl: Added this file
+       * tests/thread.test: fixed to use tcltest
+       * doc/thread.n: Added this file as clone of thread.html
+       # doc/thread.html: fixed typo
+
diff --git a/8.x/thread/Makefile.in b/8.x/thread/Makefile.in
new file mode 100644 (file)
index 0000000..139d694
--- /dev/null
@@ -0,0 +1,429 @@
+# Makefile.in --
+#
+#      This file is a Makefile for the Thread Extension.  If it has the name
+#      "Makefile.in" then it is a template for a Makefile;  to generate the
+#      actual Makefile, run "./configure", which is a configuration script
+#      generated by the "autoconf" program (constructs like "@foo@" will get
+#      replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: Makefile.in,v 1.26 2007/08/07 06:59:05 das Exp $
+
+#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#========================================================================
+# Nothing of the variables below this line should need to be changed.
+# Please check the TARGETS section below to make sure the make targets
+# are correct.
+#========================================================================
+
+#========================================================================
+# The names of the source files is defined in the configure script.
+# The object files are used for linking into the final library.
+# This will be used when a dist target is added to the Makefile.
+# It is not important to specify the directory, as long as it is the
+# $(srcdir) or in the generic, win or unix subdirectory.
+#========================================================================
+
+PKG_SOURCES    = @PKG_SOURCES@
+PKG_OBJECTS    = @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+#========================================================================
+# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
+# this package that need to be installed, if any.
+#========================================================================
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+
+#========================================================================
+# This is a list of public header files to be installed, if any.
+#========================================================================
+
+PKG_HEADERS    = @PKG_HEADERS@
+
+#========================================================================
+# "PKG_LIB_FILE" refers to the library (dynamic or static as per
+# configuration options) composed of the named objects.
+#========================================================================
+
+PKG_LIB_FILE   = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES   = $(PKG_LIB_FILE)
+BINARIES       = $(lib_BINARIES)
+
+SHELL          = @SHELL@
+
+srcdir         = @srcdir@
+prefix         = @prefix@
+exec_prefix    = @exec_prefix@
+
+bindir         = @bindir@
+libdir         = @libdir@
+includedir     = @includedir@
+datarootdir     = @datarootdir@
+datadir                = @datadir@
+mandir         = @mandir@
+
+DESTDIR                =
+
+PKG_DIR                = $(PACKAGE_NAME)$(PACKAGE_VERSION)
+pkgdatadir     = $(datadir)/$(PKG_DIR)
+pkglibdir      = $(libdir)/$(PKG_DIR)
+pkgincludedir  = $(includedir)/$(PKG_DIR)
+
+top_builddir   = .
+
+INSTALL                = @INSTALL@
+INSTALL_PROGRAM        = @INSTALL_PROGRAM@
+INSTALL_DATA   = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+PACKAGE_NAME   = @PACKAGE_NAME@
+PACKAGE_VERSION        = @PACKAGE_VERSION@
+CC             = @CC@
+CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+EXEEXT         = @EXEEXT@
+LDFLAGS_DEFAULT        = @LDFLAGS_DEFAULT@
+MAKE_LIB       = @MAKE_LIB@
+MAKE_SHARED_LIB        = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB        = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB  = @MAKE_STUB_LIB@
+OBJEXT         = @OBJEXT@
+RANLIB         = @RANLIB@
+RANLIB_STUB    = @RANLIB_STUB@
+SHLIB_CFLAGS   = @SHLIB_CFLAGS@
+SHLIB_LD       = @SHLIB_LD@
+SHLIB_LD_LIBS  = @SHLIB_LD_LIBS@
+STLIB_LD       = @STLIB_LD@
+#TCL_DEFS      = @TCL_DEFS@
+TCL_BIN_DIR    = @TCL_BIN_DIR@
+TCL_SRC_DIR    = @TCL_SRC_DIR@
+
+# Not used, but retained for reference of what libs Tcl required
+#TCL_LIBS      = @TCL_LIBS@
+
+#========================================================================
+# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
+# package without installing.  The other environment variables allow us
+# to test against an uninstalled Tcl.  Add special env vars that you
+# require for testing here (like TCLX_LIBRARY).
+#========================================================================
+
+EXTRA_PATH     = $(top_builddir):$(TCL_BIN_DIR)
+TCLLIBPATH     = $(top_builddir)
+TCLSH_ENV      = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
+                 TCL_THREAD_LIBRARY=`@CYGPATH@ $(srcdir)/lib` \
+                 @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+                 PATH="$(EXTRA_PATH):$(PATH)" \
+                 TCLLIBPATH="$(TCLLIBPATH) $(top_builddir)/../lib"
+
+TCLSH_PROG     = @TCLSH_PROG@
+TCLSH          = $(TCLSH_ENV) $(TCLSH_PROG)
+
+SHARED_BUILD   = @SHARED_BUILD@
+
+INCLUDES       = @PKG_INCLUDES@ @TCL_INCLUDES@
+
+PKG_CFLAGS     = @PKG_CFLAGS@
+
+# TCL_DEFS is not strictly need here, but if you remove it, then you
+# must make sure that configure.in checks for the necessary components
+# that your library may use.  TCL_DEFS can actually be a problem if
+# you do not compile with a similar machine setup as the Tcl core was
+# compiled with.
+#DEFS          = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
+DEFS           = @DEFS@ $(PKG_CFLAGS)
+
+CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
+CLEANFILES     = @CLEANFILES@
+
+CPPFLAGS       = @CPPFLAGS@
+LIBS           = @PKG_LIBS@ @LIBS@
+AR             = @AR@
+CFLAGS         = @CFLAGS@
+COMPILE                = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+#========================================================================
+# Start of user-definable TARGETS section
+#========================================================================
+
+#========================================================================
+# TEA TARGETS.  Please note that the "libraries:" target refers to platform
+# independent files, and the "binaries:" target inclues executable programs and
+# platform-dependent libraries.  Modify these targets so that they install
+# the various pieces of your package.  The make and install rules
+# for the BINARIES that you specified above have already been done.
+#========================================================================
+
+all: binaries libraries doc
+
+#========================================================================
+# The binaries target builds executable programs, Windows .dll's, unix
+# shared/static libraries, and any other platform-dependent files.
+# The list of targets to build for "binaries:" is specified at the top
+# of the Makefile, in the "BINARIES" variable.
+#========================================================================
+
+binaries: $(BINARIES)
+
+libraries:
+
+doc:
+
+install: all install-binaries install-libraries install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+
+#========================================================================
+# This rule installs platform-independent files, such as header files.
+# The list=...; for p in $$list handles the empty list case x-platform.
+#========================================================================
+
+install-libraries: libraries
+       @mkdir -p $(DESTDIR)$(includedir)
+       @echo "Installing header files in $(DESTDIR)$(includedir)"
+       @list='$(PKG_HEADERS)'; for i in $$list; do \
+           echo "Installing $(srcdir)/$$i" ; \
+           $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+       done;
+
+#========================================================================
+# Install documentation.  Unix manpages should go in the $(mandir)
+# directory.
+#========================================================================
+
+install-doc: doc
+       @mkdir -p $(DESTDIR)$(mandir)/mann
+       @echo "Installing documentation in $(DESTDIR)$(mandir)"
+       @list='$(srcdir)/doc/man/*.n'; for i in $$list; do \
+           echo "Installing $$i"; \
+           rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
+           $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
+       done
+
+test: binaries libraries
+       $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+shell: binaries libraries
+       @$(TCLSH) $(SCRIPT)
+
+gdb:
+       $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+#========================================================================
+# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
+# mentioned above.  That will ensure that this target is built when you
+# run "make binaries".
+#
+# The $(PKG_OBJECTS) objects are created and linked into the final
+# library.  In most cases these object files will correspond to the
+# source files above.
+#========================================================================
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+       -rm -f $(PKG_LIB_FILE)
+       ${MAKE_LIB}
+       $(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+       -rm -f $(PKG_STUB_LIB_FILE)
+       ${MAKE_STUB_LIB}
+       $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#========================================================================
+# We need to enumerate the list of .c to .o lines here.
+#
+# In the following lines, $(srcdir) refers to the toplevel directory
+# containing your extension.  If your sources are in a subdirectory,
+# you will have to modify the paths to reflect this:
+#
+# sample.$(OBJEXT): $(srcdir)/generic/sample.c
+#      $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
+#
+# Setting the VPATH variable to a list of paths will cause the makefile
+# to look into these paths when resolving .c to .obj dependencies.
+# As necessary, add $(srcdir):$(srcdir)/compat:....
+#========================================================================
+
+VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win
+
+.c.@OBJEXT@:
+       $(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#========================================================================
+# Distribution creation
+# You may need to tweak this target to make it work correctly.
+#========================================================================
+
+#COMPRESS      = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS       = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT      = /tmp/dist
+DIST_DIR       = $(DIST_ROOT)/$(PKG_DIR)
+
+dist-clean:
+       rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
+
+dist: dist-clean
+       mkdir -p $(DIST_DIR)
+       cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license.terms \
+               $(srcdir)/aclocal.m4 $(srcdir)/aolserver.m4 $(srcdir)/configure \
+        $(srcdir)/*.in \
+               $(DIST_DIR)/
+       chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
+       chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
+
+       mkdir $(DIST_DIR)/tclconfig
+       cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
+               $(DIST_DIR)/tclconfig/
+       chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
+       chmod +x $(DIST_DIR)/tclconfig/install-sh
+
+       mkdir $(DIST_DIR)/unix
+       cp $(srcdir)/unix/README $(srcdir)/unix/CONFIG \
+               $(srcdir)/unix/threadUnix.c $(DIST_DIR)/unix/
+
+       mkdir $(DIST_DIR)/win
+       cp $(srcdir)/win/README.txt $(srcdir)/win/CONFIG $(srcdir)/win/thread.rc \
+               $(srcdir)/win/threadWin.c $(DIST_DIR)/win/
+
+       mkdir $(DIST_DIR)/win/vc
+       cp $(srcdir)/win/vc/README.txt  $(srcdir)/win/vc/makefile.vc \
+               $(srcdir)/win/vc/nmakehlp.c $(srcdir)/win/vc/pkg.vc \
+               $(srcdir)/win/vc/rules.vc   $(srcdir)/win/vc/thread_win.dsw \
+               $(srcdir)/win/vc/thread_win.dsp $(DIST_DIR)/win/vc/
+
+       mkdir $(DIST_DIR)/tcl
+       cp $(srcdir)/tcl/README $(DIST_DIR)/tcl/
+
+       list='tests doc doc/man doc/html generic lib tcl/cmdsrv tcl/phttpd tcl/tpool';\
+       for p in $$list; do \
+           if test -d $(srcdir)/$$p ; then \
+               mkdir -p $(DIST_DIR)/$$p; \
+               cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
+           fi; \
+       done
+
+       (cd $(DIST_ROOT); $(COMPRESS);)
+
+#========================================================================
+# End of user-definable section
+#========================================================================
+
+#========================================================================
+# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
+# variable in configure.in
+#========================================================================
+
+clean:  
+       -test -z "$(BINARIES)" || rm -f $(BINARIES)
+       -rm -f *.$(OBJEXT) core *.core
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+       -rm -f *.tab.c
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log config.status
+
+#========================================================================
+# Install binary object libraries.  On Windows this includes both .dll and
+# .lib files.  Because the .lib files are not explicitly listed anywhere,
+# we need to deduce their existence from the .dll file of the same name.
+# Library files go into the lib directory.
+# In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh shell)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-lib-binaries: binaries
+       @mkdir -p $(DESTDIR)$(pkglibdir)
+       @list='$(lib_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+           stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
+           if test "x$$stub" = "xstub"; then \
+               echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
+           else \
+               echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
+           fi; \
+           ext=`echo $$p|sed -e "s/.*\.//"`; \
+           if test "x$$ext" = "xdll"; then \
+               lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+               if test -f $$lib; then \
+                   echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
+                   $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+               fi; \
+           fi; \
+         fi; \
+       done
+       @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         if test -f $(srcdir)/$$p; then \
+           destp=`basename $$p`; \
+           echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
+           $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
+         fi; \
+       done
+       @if test "x$(SHARED_BUILD)" = "x1"; then \
+           echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
+           $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
+       fi
+
+#========================================================================
+# Install binary executables (e.g. .exe files and dependent .dll files)
+# This is for files that must go in the bin directory (located next to
+# wish and tclsh), like dependent .dll files on Windows.
+#
+# You should not have to modify this target, except to define bin_BINARIES
+# above if necessary.
+#========================================================================
+
+install-bin-binaries: binaries
+       @mkdir -p $(DESTDIR)$(bindir)
+       @list='$(bin_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+         fi; \
+       done
+
+.SUFFIXES: .c .$(OBJEXT)
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+       list='$(lib_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         p=`basename $$p`; \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(bin_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/$$p; \
+       done
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/8.x/thread/README b/8.x/thread/README
new file mode 100644 (file)
index 0000000..6c60093
--- /dev/null
@@ -0,0 +1,55 @@
+
+WHAT IS THIS ?
+==============
+
+This is the source distribution of the Tcl Thread extension. 
+You can use this extension to gain script-level access to Tcl 
+threading capabilities.
+The extension can be used with Tcl cores starting from Tcl8.4 and later.
+Also, this extension supports, i.e. can be used as a loadable module of,
+AOLserver 4.x series of the highly-scalable web server from America Online. 
+
+You need to have your Tcl core compiled with "--enable-threads" in order
+to turn on internal directives supporting thread-specific details of the
+Tcl API. The extension will not load in an Tcl shell built w/o thread
+support. 
+
+This extension is a freely available open source package. You can do 
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.  See the "license.terms"
+file in the top-level distribution directory for complete information.
+
+
+HOW TO COMPILE ?
+================
+
+Only Unix-like and Windows platforms are supported at the moment. Depending
+on your platform (Unix-like or Windows) go to the appropriate directory 
+(unix or win) and start with the README file. Macintosh platform is supported
+with the Mac OS X only. The Mac OS 9 (and previous) are not supported.
+
+
+WHERE IS THE DOCUMENTATION ?
+============================
+
+Documentation in Unix man and standard HTML format is available in the
+doc/man and doc/html directories respectively. 
+Currently, documentation is in reference-style only. The tutorial-style
+documentation will be provided with future releases of the extension.
+That is, if I ever get time to do that. Everybody is more than welcome
+to jump in and help with the docs.
+
+
+HOW TO GET SUPPORT ?
+====================
+
+The extension is maintained, enhanced, and distributed freely by the Tcl
+community. The home for sources and bug/patch database is on SourceForge:
+
+        http://tcl.sourceforge.net/
+
+Alternatively, you are always welcome to post your questions, problems
+and/or suggestions relating the extension (or any other Tcl issue)
+to news:comp.lang.tcl newsgroup.
+
+-EOF-
diff --git a/8.x/thread/aclocal.m4 b/8.x/thread/aclocal.m4
new file mode 100644 (file)
index 0000000..7f06699
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# Pull in the standard Tcl autoconf macros.
+# If you don't have the "tclconfig" subdirectory, it is a dependent CVS
+# module. Either "cvs -d <root> checkout tclconfig" right here, or 
+# re-checkout the thread module
+#
+builtin(include,tclconfig/tcl.m4)
+builtin(include,aolserver.m4)
+
+#
+# Handle the "--with-gdbm" option for linking-in
+# the gdbm-based peristent store for shared arrays.
+# It tries to locate gdbm files in couple of standard
+# system directories and/or common install locations
+# in addition to the directory passed by the user.
+# In the latter case, expect all gdbm lib files and
+# include files located in the same directory.
+#
+
+AC_DEFUN(TCLTHREAD_WITH_GDBM, [
+    AC_ARG_WITH(gdbm,
+       [  --with-gdbm             link with optional GDBM support],\
+       with_gdbm=${withval})
+
+    if test x"${with_gdbm}" != x; then
+
+    AC_MSG_CHECKING([for GNU gdbm library])
+
+    AC_CACHE_VAL(ac_cv_c_gdbm,[
+    if test x"${with_gdbm}" != x -a "${with_gdbm}" != "yes"; then
+        if test -f "${with_gdbm}/gdbm.h" -a x"`ls ${with_gdbm}/libgdbm* 2>/dev/null`" != x; then
+            ac_cv_c_gdbm=`(cd ${with_gdbm}; pwd)`
+            gincdir=$ac_cv_c_gdbm
+            glibdir=$ac_cv_c_gdbm
+            AC_MSG_RESULT([found in $glibdir])
+        else
+            AC_MSG_ERROR([${with_gdbm} directory doesn't contain gdbm library])
+        fi
+    fi
+    ])
+    if test x"${gincdir}" = x -o x"${glibdir}" = x; then
+        for i in \
+                `ls -d ${exec_prefix}/lib 2>/dev/null`\
+                `ls -d ${prefix}/lib 2>/dev/null`\
+                `ls -d /usr/local/lib 2>/dev/null`\
+                `ls -d /usr/lib 2>/dev/null` ; do
+            if test x"`ls $i/libgdbm* 2>/dev/null`" != x ; then
+                glibdir=`(cd $i; pwd)`
+                break
+            fi
+        done
+        for i in \
+                `ls -d ${prefix}/include 2>/dev/null`\
+                `ls -d /usr/local/include 2>/dev/null`\
+                `ls -d /usr/include 2>/dev/null` ; do
+            if test -f "$i/gdbm.h" ; then
+                gincdir=`(cd $i; pwd)`
+                break
+            fi
+        done
+        if test x"$glibdir" = x -o x"$gincdir" = x ; then
+            AC_MSG_ERROR([none found])
+        else
+            AC_MSG_RESULT([found in $glibdir, includes in $gincdir])
+            AC_DEFINE(HAVE_GDBM)
+            GDBM_CFLAGS="-I\"$gincdir\""
+            GDBM_LIBS="-L\"$glibdir\" -lgdbm"
+        fi
+    fi
+    fi
+])
+
+# EOF
diff --git a/8.x/thread/aolserver.m4 b/8.x/thread/aolserver.m4
new file mode 100644 (file)
index 0000000..a53c86f
--- /dev/null
@@ -0,0 +1,57 @@
+
+#------------------------------------------------------------------------
+# NS_PATH_AOLSERVER
+#
+#   Allows the building with support for AOLserver 
+#
+# Arguments:
+#   none
+#   
+# Results:
+#
+#   Adds the following arguments to configure:
+#       --with-aolserver=...
+#
+#   Defines the following vars:
+#       AOL_DIR Full path to the directory containing AOLserver distro
+#       AOL_INCLUDES
+#       AOL_LIBS
+#
+#   Sets the following vars:
+#       NS_AOLSERVER 
+#
+#   Updates following vars:
+#------------------------------------------------------------------------
+
+AC_DEFUN(NS_PATH_AOLSERVER, [
+    AC_MSG_CHECKING([for AOLserver configuration])
+    AC_ARG_WITH(aol, 
+    [  --with-aolserver        directory with AOLserver distribution],\
+    with_aolserver=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_aolserver,[
+    if test x"${with_aolserver}" != x ; then
+        if test -f "${with_aolserver}/include/ns.h" ; then
+            ac_cv_c_aolserver=`(cd ${with_aolserver}; pwd)`
+        else
+            AC_MSG_ERROR([${with_aolserver} directory doesn't contain ns.h])
+        fi
+    fi
+    ])
+    if test x"${ac_cv_c_aolserver}" = x ; then
+        AC_MSG_RESULT([none found])
+    else
+        AOL_DIR=${ac_cv_c_aolserver}
+        AC_MSG_RESULT([found AOLserver in $AOL_DIR])
+        AOL_INCLUDES="-I\"${AOL_DIR}/include\""
+        if test "`uname -s`" = Darwin ; then
+            aollibs=`ls ${AOL_DIR}/lib/libns* 2>/dev/null`
+            if test x"$aollibs" != x ; then
+                AOL_LIBS="-L\"${AOL_DIR}/lib\" -lnsd -lnsthread"
+            fi
+        fi
+        AC_DEFINE(NS_AOLSERVER)
+    fi
+])
+
+# EOF
diff --git a/8.x/thread/configure b/8.x/thread/configure
new file mode 100755 (executable)
index 0000000..952860d
--- /dev/null
@@ -0,0 +1,12258 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.61 for thread 2.6.6.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""       $as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+  if (eval ":") 2>/dev/null; then
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+
+  if test $as_have_required = yes &&    (eval ":
+(as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=\$LINENO
+  as_lineno_2=\$LINENO
+  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+  :
+else
+  as_candidate_shells=
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  case $as_dir in
+        /*)
+          for as_base in sh bash ksh sh5; do
+            as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+          done;;
+       esac
+done
+IFS=$as_save_IFS
+
+
+      for as_shell in $as_candidate_shells $SHELL; do
+        # Try only shells that exist, to save several forks.
+        if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+               { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+  CONFIG_SHELL=$as_shell
+              as_have_required=yes
+              if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+  (exit $1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+  break
+fi
+
+fi
+
+      done
+
+      if test "x$CONFIG_SHELL" != x; then
+  for as_var in BASH_ENV ENV
+        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+        done
+        export CONFIG_SHELL
+        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+    if test $as_have_required = no; then
+  echo This script requires a shell more modern than all the
+      echo shells that I found on your system.  Please install a
+      echo modern shell, or manually run the script under such a
+      echo shell if you do have one.
+      { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+  echo No shell found that supports shell functions.
+  echo Please tell autoconf@gnu.org about your system,
+  echo including any error possibly output before this
+  echo message
+}
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+        test -d "$1/.";
+      else
+       case $1 in
+        -*)set "./$1";;
+       esac;
+       case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+       ???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME='thread'
+PACKAGE_TARNAME='thread'
+PACKAGE_VERSION='2.6.6'
+PACKAGE_STRING='thread 2.6.6'
+PACKAGE_BUGREPORT=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+CYGPATH
+EXEEXT
+PKG_LIB_FILE
+PKG_STUB_LIB_FILE
+PKG_STUB_SOURCES
+PKG_STUB_OBJECTS
+PKG_TCL_SOURCES
+PKG_HEADERS
+PKG_INCLUDES
+PKG_LIBS
+PKG_CFLAGS
+TCL_VERSION
+TCL_BIN_DIR
+TCL_SRC_DIR
+TCL_LIB_FILE
+TCL_LIB_FLAG
+TCL_LIB_SPEC
+TCL_STUB_LIB_FILE
+TCL_STUB_LIB_FLAG
+TCL_STUB_LIB_SPEC
+TCL_LIBS
+TCL_DEFS
+TCL_EXTRA_CFLAGS
+TCL_LD_FLAGS
+TCL_SHLIB_LD_LIBS
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CC
+OBJEXT
+CPP
+INSTALL_PROGRAM
+INSTALL_SCRIPT
+INSTALL_DATA
+SET_MAKE
+RANLIB
+GREP
+EGREP
+MATH_LIBS
+PKG_SOURCES
+PKG_OBJECTS
+CLEANFILES
+TCL_INCLUDES
+TCL_THREADS
+SHARED_BUILD
+AR
+CELIB_DIR
+LIBOBJS
+DL_LIBS
+CFLAGS_DEBUG
+CFLAGS_OPTIMIZE
+CFLAGS_WARNING
+STLIB_LD
+SHLIB_LD
+SHLIB_LD_LIBS
+SHLIB_CFLAGS
+LD_LIBRARY_PATH_VAR
+CFLAGS_DEFAULT
+LDFLAGS_DEFAULT
+TCL_DBGX
+MAKE_LIB
+MAKE_SHARED_LIB
+MAKE_STATIC_LIB
+MAKE_STUB_LIB
+RANLIB_STUB
+TCLSH_PROG
+LTLIBOBJS'
+ac_subst_files=''
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)   ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+    eval enable_$ac_feature=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+    eval enable_$ac_feature=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+    eval with_$ac_package=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+    eval with_$ac_package=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute directory names.
+for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
+               datadir sysconfdir sharedstatedir localstatedir includedir \
+               oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+               libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  { echo "$as_me: error: Working directory cannot be determined" >&2
+   { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  { echo "$as_me: error: pwd does not report name of working directory" >&2
+   { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+       cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+   { (exit 1); exit 1; }; }
+       pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures thread 2.6.6 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR          info documentation [DATAROOTDIR/info]
+  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR           man documentation [DATAROOTDIR/man]
+  --docdir=DIR           documentation root [DATAROOTDIR/doc/thread]
+  --htmldir=DIR          html documentation [DOCDIR]
+  --dvidir=DIR           dvi documentation [DOCDIR]
+  --pdfdir=DIR           pdf documentation [DOCDIR]
+  --psdir=DIR            ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of thread 2.6.6:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-threads        build with threads
+  --enable-shared         build and link with shared libraries (default: on)
+  --enable-64bit          enable 64bit support (default: off)
+  --enable-64bit-vis      enable 64bit Sparc VIS support (default: off)
+  --disable-rpath         disable rpath support (default: on)
+  --enable-wince          enable Win/CE support (where applicable)
+  --enable-load           allow dynamic loading and "load" command (default:
+                          on)
+  --enable-symbols        build with debugging symbols (default: off)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-tcl              directory containing tcl configuration
+                          (tclConfig.sh)
+  --with-gdbm             link with optional GDBM support
+  --with-aolserver        directory with AOLserver distribution
+  --with-tclinclude       directory containing the public Tcl header files
+  --with-celib=DIR        use Windows/CE support library from DIR
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" || continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+thread configure 2.6.6
+generated by GNU Autoconf 2.61
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by thread $as_me 2.6.6, which was
+generated by GNU Autoconf 2.61.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+       "s/'\''/'\''\\\\'\'''\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=\$$ac_var
+       case $ac_val in
+       *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+       esac
+       echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+  set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+  set x "$ac_default_prefix/share/config.site" \
+       "$ac_default_prefix/etc/config.site"
+fi
+shift
+for ac_site_file
+do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.7"
+
+    { echo "$as_me:$LINENO: checking for correct TEA configuration" >&5
+echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6; }
+    if test x"${PACKAGE_NAME}" = x ; then
+       { { echo "$as_me:$LINENO: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5
+echo "$as_me: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test x"3.7" = x ; then
+       { { echo "$as_me:$LINENO: error:
+TEA version not specified." >&5
+echo "$as_me: error:
+TEA version not specified." >&2;}
+   { (exit 1); exit 1; }; }
+    elif test "3.7" != "${TEA_VERSION}" ; then
+       { echo "$as_me:$LINENO: result: warning: requested TEA version \"3.7\", have \"${TEA_VERSION}\"" >&5
+echo "${ECHO_T}warning: requested TEA version \"3.7\", have \"${TEA_VERSION}\"" >&6; }
+    else
+       { echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5
+echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6; }
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*MINGW32_*)
+           # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CYGPATH+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CYGPATH"; then
+  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CYGPATH="cygpath -w"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+  { echo "$as_me:$LINENO: result: $CYGPATH" >&5
+echo "${ECHO_T}$CYGPATH" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *CYGWIN_*)
+           # CYGPATH and TEA_PLATFORM are determined later
+           EXEEXT=".exe"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+
+
+
+    # This package name must be replaced statically for AC_SUBST to work
+
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in tclconfig "$srcdir"/tclconfig; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in tclconfig \"$srcdir\"/tclconfig" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in tclconfig \"$srcdir\"/tclconfig" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+
+
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+
+# Check whether --with-tcl was given.
+if test "${with_tcl+set}" = set; then
+  withval=$with_tcl; with_tclconfig=${withval}
+fi
+
+       { echo "$as_me:$LINENO: checking for Tcl configuration" >&5
+echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6; }
+       if test "${ac_cv_c_tclconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
+echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5
+echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test "${TEA_PLATFORM}" = "windows" \
+                           -a -f "$i/win/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/win; pwd)`
+                       break
+                   fi
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # TEA specific: on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test "${TEA_PLATFORM}" = "windows" \
+                           -a -f "$i/win/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/win; pwd)`
+                       break
+                   fi
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+
+fi
+
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           { { echo "$as_me:$LINENO: error: Can't find Tcl configuration definitions" >&5
+echo "$as_me: error: Can't find Tcl configuration definitions" >&2;}
+   { (exit 1); exit 1; }; }
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           { echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
+       fi
+    fi
+
+
+    { echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6; }
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        { echo "$as_me:$LINENO: result: loading" >&5
+echo "${ECHO_T}loading" >&6; }
+       . "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        { echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitrary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+
+
+
+
+
+
+
+
+
+
+
+
+    case "`uname -s`" in
+       *CYGWIN_*)
+           { echo "$as_me:$LINENO: checking for cygwin variant" >&5
+echo $ECHO_N "checking for cygwin variant... $ECHO_C" >&6; }
+           case ${TCL_EXTRA_CFLAGS} in
+               *-mwin32*|*-mno-cygwin*)
+                   TEA_PLATFORM="windows"
+                   { echo "$as_me:$LINENO: result: win32" >&5
+echo "${ECHO_T}win32" >&6; }
+                   # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CYGPATH+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CYGPATH"; then
+  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CYGPATH="cygpath -w"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+  { echo "$as_me:$LINENO: result: $CYGPATH" >&5
+echo "${ECHO_T}$CYGPATH" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+                   ;;
+               *)
+                   TEA_PLATFORM="unix"
+                   { echo "$as_me:$LINENO: result: unix" >&5
+echo "${ECHO_T}unix" >&6; }
+                   ;;
+           esac
+           EXEEXT=".exe"
+           ;;
+       *)
+           ;;
+    esac
+
+    # TEA specific:
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+#TEA_PATH_TKCONFIG
+#TEA_LOAD_TKCONFIG
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
+echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
+           prefix=${TCL_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5
+echo "$as_me: --prefix defaulting to /usr/local" >&6;}
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
+echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5
+echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;}
+           exec_prefix=$prefix
+       fi
+    fi
+
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
+# the basic setup necessary to compile executables.
+#-----------------------------------------------------------------------
+
+
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort.  b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions.  Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+       then :; else
+          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       fi
+       # We set ac_cv_exeext here because the later test for it is not
+       # safe: cross compilers may not add the suffix if given an `-o'
+       # argument, so we may need to know it at that point already.
+       # Even if this section looks crufty: it has the advantage of
+       # actually working.
+       break;;
+    * )
+       break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+if test -z "$ac_file"; then
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
+
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       CFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_c_werror_flag=$ac_save_c_werror_flag
+        CFLAGS="-g"
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_c89=$ac_arg
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+  xno)
+    { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+    # Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+IFS=$as_save_IFS
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
+set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+       @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  SET_MAKE=
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+
+
+
+
+
+{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Extract the first word of "grep ggrep" to use in msg output
+if test -z "$GREP"; then
+set dummy grep ggrep; ac_prog_name=$2
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_GREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in grep ggrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+    # Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_GREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+GREP="$ac_cv_path_GREP"
+if test -z "$GREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     # Extract the first word of "egrep" to use in msg output
+if test -z "$EGREP"; then
+set dummy egrep; ac_prog_name=$2
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_EGREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in egrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+    # Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_EGREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+EGREP="$ac_cv_path_EGREP"
+if test -z "$EGREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+
+   fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       { echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5
+echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6; }
+if test "${tcl_cv_cc_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_cc_pipe=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_cc_pipe=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           CFLAGS=$hold_cflags
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5
+echo "${ECHO_T}$tcl_cv_cc_pipe" >&6; }
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; }
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if  ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \
+       && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN)
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_c_bigendian=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       # It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long int l;
+    char c[sizeof (long int)];
+  } u;
+  u.l = 1;
+  return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6; }
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+    if test "${TEA_PLATFORM}" = "unix" ; then
+
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    { echo "$as_me:$LINENO: checking for sin" >&5
+echo $ECHO_N "checking for sin... $ECHO_C" >&6; }
+if test "${ac_cv_func_sin+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define sin to an innocuous variant, in case <limits.h> declares sin.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define sin innocuous_sin
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char sin (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef sin
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sin ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_sin || defined __stub___sin
+choke me
+#endif
+
+int
+main ()
+{
+return sin ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_sin=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_sin=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5
+echo "${ECHO_T}$ac_cv_func_sin" >&6; }
+if test $ac_cv_func_sin = yes; then
+  MATH_LIBS=""
+else
+  MATH_LIBS="-lm"
+fi
+
+    { echo "$as_me:$LINENO: checking for main in -lieee" >&5
+echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6; }
+if test "${ac_cv_lib_ieee_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lieee  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_ieee_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_ieee_main=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5
+echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6; }
+if test $ac_cv_lib_ieee_main = yes; then
+  MATH_LIBS="-lieee $MATH_LIBS"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    { echo "$as_me:$LINENO: checking for main in -linet" >&5
+echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6; }
+if test "${ac_cv_lib_inet_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_inet_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_inet_main=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5
+echo "${ECHO_T}$ac_cv_lib_inet_main" >&6; }
+if test $ac_cv_lib_inet_main = yes; then
+  LIBS="$LIBS -linet"
+fi
+
+    if test "${ac_cv_header_net_errno_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking net/errno.h usability" >&5
+echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <net/errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking net/errno.h presence" >&5
+echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <net/errno.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: net/errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_net_errno_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6; }
+
+fi
+if test $ac_cv_header_net_errno_h = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NET_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    { echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6; }
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_connect || defined __stub___connect
+choke me
+#endif
+
+int
+main ()
+{
+return connect ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_connect=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6; }
+if test $ac_cv_func_connect = yes; then
+  tcl_checkSocket=0
+else
+  tcl_checkSocket=1
+fi
+
+    if test "$tcl_checkSocket" = 1; then
+       { echo "$as_me:$LINENO: checking for setsockopt" >&5
+echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6; }
+if test "${ac_cv_func_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define setsockopt to an innocuous variant, in case <limits.h> declares setsockopt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define setsockopt innocuous_setsockopt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char setsockopt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef setsockopt
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_setsockopt || defined __stub___setsockopt
+choke me
+#endif
+
+int
+main ()
+{
+return setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_setsockopt=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_func_setsockopt" >&6; }
+if test $ac_cv_func_setsockopt = yes; then
+  :
+else
+  { echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5
+echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6; }
+if test "${ac_cv_lib_socket_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_socket_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_socket_setsockopt=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6; }
+if test $ac_cv_lib_socket_setsockopt = yes; then
+  LIBS="$LIBS -lsocket"
+else
+  tcl_checkBoth=1
+fi
+
+fi
+
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       { echo "$as_me:$LINENO: checking for accept" >&5
+echo $ECHO_N "checking for accept... $ECHO_C" >&6; }
+if test "${ac_cv_func_accept+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define accept to an innocuous variant, in case <limits.h> declares accept.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define accept innocuous_accept
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char accept (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef accept
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char accept ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_accept || defined __stub___accept
+choke me
+#endif
+
+int
+main ()
+{
+return accept ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_accept=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_accept=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5
+echo "${ECHO_T}$ac_cv_func_accept" >&6; }
+if test $ac_cv_func_accept = yes; then
+  tcl_checkNsl=0
+else
+  LIBS=$tk_oldLibs
+fi
+
+    fi
+    { echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6; }
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_gethostbyname || defined __stub___gethostbyname
+choke me
+#endif
+
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_gethostbyname=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6; }
+if test $ac_cv_func_gethostbyname = yes; then
+  :
+else
+  { echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_nsl_gethostbyname=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  LIBS="$LIBS -lnsl"
+fi
+
+fi
+
+
+    # TEA specific: Don't perform the eval of the libraries here because
+    # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+
+
+
+
+    { echo "$as_me:$LINENO: checking dirent.h" >&5
+echo $ECHO_N "checking dirent.h... $ECHO_C" >&6; }
+if test "${tcl_cv_dirent_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_dirent_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_dirent_h=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5
+echo "${ECHO_T}$tcl_cv_dirent_h" >&6; }
+
+    if test $tcl_cv_dirent_h = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DIRENT_H 1
+_ACEOF
+
+    fi
+
+    # TEA specific:
+    if test "${ac_cv_header_errno_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking errno.h usability" >&5
+echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking errno.h presence" >&5
+echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <errno.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_errno_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6; }
+
+fi
+if test $ac_cv_header_errno_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_float_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking float.h usability" >&5
+echo $ECHO_N "checking float.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <float.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking float.h presence" >&5
+echo $ECHO_N "checking float.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <float.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: float.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_float_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6; }
+
+fi
+if test $ac_cv_header_float_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_FLOAT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_values_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking values.h usability" >&5
+echo $ECHO_N "checking values.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <values.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking values.h presence" >&5
+echo $ECHO_N "checking values.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <values.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: values.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_values_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6; }
+
+fi
+if test $ac_cv_header_values_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_VALUES_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_limits_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking limits.h usability" >&5
+echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <limits.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking limits.h presence" >&5
+echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <limits.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: limits.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_limits_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6; }
+
+fi
+if test $ac_cv_header_limits_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIMITS_H 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_LIMITS_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_stdlib_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking stdlib.h usability" >&5
+echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <stdlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking stdlib.h presence" >&5
+echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: stdlib.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_stdlib_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6; }
+
+fi
+if test $ac_cv_header_stdlib_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtol" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtoul" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtod" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STDLIB_H 1
+_ACEOF
+
+    fi
+    if test "${ac_cv_header_string_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking string.h usability" >&5
+echo $ECHO_N "checking string.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <string.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking string.h presence" >&5
+echo $ECHO_N "checking string.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: string.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_string_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6; }
+
+fi
+if test $ac_cv_header_string_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strstr" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strerror" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STRING_H 1
+_ACEOF
+
+    fi
+
+    if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking sys/wait.h usability" >&5
+echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <sys/wait.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking sys/wait.h presence" >&5
+echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/wait.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_wait_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; }
+
+fi
+if test $ac_cv_header_sys_wait_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking dlfcn.h usability" >&5
+echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <dlfcn.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking dlfcn.h presence" >&5
+echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <dlfcn.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_dlfcn_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6; }
+
+fi
+if test $ac_cv_header_dlfcn_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DLFCN_H 1
+_ACEOF
+
+fi
+
+
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+
+for ac_header in sys/param.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+
+
+#--------------------------------------------------------------------
+# Check if building with optional Gdbm package. This will declare
+# GDBM_CFLAGS and GDBM_LIBS variables.
+#--------------------------------------------------------------------
+
+
+
+# Check whether --with-gdbm was given.
+if test "${with_gdbm+set}" = set; then
+  withval=$with_gdbm; \
+       with_gdbm=${withval}
+fi
+
+
+    if test x"${with_gdbm}" != x; then
+
+    { echo "$as_me:$LINENO: checking for GNU gdbm library" >&5
+echo $ECHO_N "checking for GNU gdbm library... $ECHO_C" >&6; }
+
+    if test "${ac_cv_c_gdbm+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    if test x"${with_gdbm}" != x -a "${with_gdbm}" != "yes"; then
+        if test -f "${with_gdbm}/gdbm.h" -a x"`ls ${with_gdbm}/libgdbm* 2>/dev/null`" != x; then
+            ac_cv_c_gdbm=`(cd ${with_gdbm}; pwd)`
+            gincdir=$ac_cv_c_gdbm
+            glibdir=$ac_cv_c_gdbm
+            { echo "$as_me:$LINENO: result: found in $glibdir" >&5
+echo "${ECHO_T}found in $glibdir" >&6; }
+        else
+            { { echo "$as_me:$LINENO: error: ${with_gdbm} directory doesn't contain gdbm library" >&5
+echo "$as_me: error: ${with_gdbm} directory doesn't contain gdbm library" >&2;}
+   { (exit 1); exit 1; }; }
+        fi
+    fi
+
+fi
+
+    if test x"${gincdir}" = x -o x"${glibdir}" = x; then
+        for i in \
+                `ls -d ${exec_prefix}/lib 2>/dev/null`\
+                `ls -d ${prefix}/lib 2>/dev/null`\
+                `ls -d /usr/local/lib 2>/dev/null`\
+                `ls -d /usr/lib 2>/dev/null` ; do
+            if test x"`ls $i/libgdbm* 2>/dev/null`" != x ; then
+                glibdir=`(cd $i; pwd)`
+                break
+            fi
+        done
+        for i in \
+                `ls -d ${prefix}/include 2>/dev/null`\
+                `ls -d /usr/local/include 2>/dev/null`\
+                `ls -d /usr/include 2>/dev/null` ; do
+            if test -f "$i/gdbm.h" ; then
+                gincdir=`(cd $i; pwd)`
+                break
+            fi
+        done
+        if test x"$glibdir" = x -o x"$gincdir" = x ; then
+            { { echo "$as_me:$LINENO: error: none found" >&5
+echo "$as_me: error: none found" >&2;}
+   { (exit 1); exit 1; }; }
+        else
+            { echo "$as_me:$LINENO: result: found in $glibdir, includes in $gincdir" >&5
+echo "${ECHO_T}found in $glibdir, includes in $gincdir" >&6; }
+            cat >>confdefs.h <<\_ACEOF
+#define HAVE_GDBM 1
+_ACEOF
+
+            GDBM_CFLAGS="-I\"$gincdir\""
+            GDBM_LIBS="-L\"$glibdir\" -lgdbm"
+        fi
+    fi
+    fi
+
+
+#--------------------------------------------------------------------
+# Locate the AOLserver dir for compilation as AOLserver module.
+# This will declare AOL_INCLUDES, AOL_LIBS and define NS_AOLSERVER.
+#--------------------------------------------------------------------
+
+
+    { echo "$as_me:$LINENO: checking for AOLserver configuration" >&5
+echo $ECHO_N "checking for AOLserver configuration... $ECHO_C" >&6; }
+
+# Check whether --with-aol was given.
+if test "${with_aol+set}" = set; then
+  withval=$with_aol; \
+    with_aolserver=${withval}
+fi
+
+
+    if test "${ac_cv_c_aolserver+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    if test x"${with_aolserver}" != x ; then
+        if test -f "${with_aolserver}/include/ns.h" ; then
+            ac_cv_c_aolserver=`(cd ${with_aolserver}; pwd)`
+        else
+            { { echo "$as_me:$LINENO: error: ${with_aolserver} directory doesn't contain ns.h" >&5
+echo "$as_me: error: ${with_aolserver} directory doesn't contain ns.h" >&2;}
+   { (exit 1); exit 1; }; }
+        fi
+    fi
+
+fi
+
+    if test x"${ac_cv_c_aolserver}" = x ; then
+        { echo "$as_me:$LINENO: result: none found" >&5
+echo "${ECHO_T}none found" >&6; }
+    else
+        AOL_DIR=${ac_cv_c_aolserver}
+        { echo "$as_me:$LINENO: result: found AOLserver in $AOL_DIR" >&5
+echo "${ECHO_T}found AOLserver in $AOL_DIR" >&6; }
+        AOL_INCLUDES="-I\"${AOL_DIR}/include\""
+        if test "`uname -s`" = Darwin ; then
+            aollibs=`ls ${AOL_DIR}/lib/libns* 2>/dev/null`
+            if test x"$aollibs" != x ; then
+                AOL_LIBS="-L\"${AOL_DIR}/lib\" -lnsd -lnsthread"
+            fi
+        fi
+        cat >>confdefs.h <<\_ACEOF
+#define NS_AOLSERVER 1
+_ACEOF
+
+    fi
+
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+
+    vars="generic/threadCmd.c          \
+                 generic/threadSvCmd.c        \
+                 generic/threadSpCmd.c        \
+                 generic/threadPoolCmd.c      \
+                 generic/psGdbm.c             \
+                 generic/threadSvListCmd.c    \
+                 generic/threadSvKeylistCmd.c \
+                 generic/tclXkeylist.c        \
+"
+    for i in $vars; do
+       case $i in
+           \$*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               # To add more dirs here (like 'src'), you have to update VPATH
+               # in Makefile.in as well
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5
+echo "$as_me: error: could not find source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+
+
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+
+
+
+    vars="${AOL_INCLUDES}"
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+
+
+
+    vars="${GDBM_LIBS} ${AOL_LIBS}"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+
+    PKG_CFLAGS="$PKG_CFLAGS ${GDBM_CFLAGS}"
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5
+echo "$as_me: error: could not find stub source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+
+
+
+
+    vars="lib/ttrace.tcl"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+
+
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_sample in this case) so
+# that we create the export library with the dll.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    cat >>confdefs.h <<\_ACEOF
+#define BUILD_thread 1
+_ACEOF
+
+    CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+
+    vars="win/threadWin.c"
+    for i in $vars; do
+       case $i in
+           \$*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               # To add more dirs here (like 'src'), you have to update VPATH
+               # in Makefile.in as well
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5
+echo "$as_me: error: could not find source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+
+
+
+
+    vars="-I\"$(${CYGPATH} ${srcdir}/win)\""
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+
+
+else
+
+    vars="unix/threadUnix.c"
+    for i in $vars; do
+       case $i in
+           \$*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               # To add more dirs here (like 'src'), you have to update VPATH
+               # in Makefile.in as well
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5
+echo "$as_me: error: could not find source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+
+
+
+fi
+
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
+#--------------------------------------------------------------------
+
+
+    { echo "$as_me:$LINENO: checking for Tcl public headers" >&5
+echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6; }
+
+
+# Check whether --with-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then
+  withval=$with_tclinclude; with_tclinclude=${withval}
+fi
+
+
+    if test "${ac_cv_c_tclh+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5
+echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;}
+   { (exit 1); exit 1; }; }
+           fi
+       else
+           list=""
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+
+fi
+
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       { { echo "$as_me:$LINENO: error: tcl.h not found.  Please specify its location with --with-tclinclude" >&5
+echo "$as_me: error: tcl.h not found.  Please specify its location with --with-tclinclude" >&2;}
+   { (exit 1); exit 1; }; }
+    else
+       { echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5
+echo "${ECHO_T}${ac_cv_c_tclh}" >&6; }
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+
+
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+
+    # Check whether --enable-threads was given.
+if test "${enable_threads+set}" = set; then
+  enableval=$enable_threads; tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi
+
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_THREAD_ALLOC 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+           if test "`uname -s`" = "SunOS" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+           fi
+
+cat >>confdefs.h <<\_ACEOF
+#define _THREAD_SAFE 1
+_ACEOF
+
+           { echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6; }
+if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6; }
+if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               { echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6; }
+if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __pthread_mutex_init ();
+int
+main ()
+{
+return __pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_pthread___pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_pthread___pthread_mutex_init=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6; }
+if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               { echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6; }
+if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_pthreads_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_pthreads_pthread_mutex_init=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6; }
+if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   { echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6; }
+if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_c_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_c_pthread_mutex_init=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6; }
+if test $ac_cv_lib_c_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                   if test "$tcl_ok" = "no"; then
+                       { echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6; }
+if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc_r  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_c_r_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_c_r_pthread_mutex_init=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6; }
+if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           { echo "$as_me:$LINENO: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5
+echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;}
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    { echo "$as_me:$LINENO: checking for building with threads" >&5
+echo $ECHO_N "checking for building with threads... $ECHO_C" >&6; }
+    if test "${TCL_THREADS}" = 1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_THREADS 1
+_ACEOF
+
+       { echo "$as_me:$LINENO: result: yes (default)" >&5
+echo "${ECHO_T}yes (default)" >&6; }
+    else
+       { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               { echo "$as_me:$LINENO: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&5
+echo "$as_me: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&2;}
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               { echo "$as_me:$LINENO: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&5
+echo "$as_me: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&2;}
+           fi
+           ;;
+    esac
+
+
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+
+    { echo "$as_me:$LINENO: checking how to build libraries" >&5
+echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6; }
+    # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval=$enable_shared; tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi
+
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       { echo "$as_me:$LINENO: result: shared" >&5
+echo "${ECHO_T}shared" >&6; }
+       SHARED_BUILD=1
+    else
+       { echo "$as_me:$LINENO: result: static" >&5
+echo "${ECHO_T}static" >&6; }
+       SHARED_BUILD=0
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_BUILD 1
+_ACEOF
+
+    fi
+
+
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+
+
+
+    # Step 0.a: Enable 64 bit support?
+
+    { echo "$as_me:$LINENO: checking if 64bit support is requested" >&5
+echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6; }
+    # Check whether --enable-64bit was given.
+if test "${enable_64bit+set}" = set; then
+  enableval=$enable_64bit; do64bit=$enableval
+else
+  do64bit=no
+fi
+
+    { echo "$as_me:$LINENO: result: $do64bit" >&5
+echo "${ECHO_T}$do64bit" >&6; }
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    { echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5
+echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6; }
+    # Check whether --enable-64bit-vis was given.
+if test "${enable_64bit_vis+set}" = set; then
+  enableval=$enable_64bit_vis; do64bitVIS=$enableval
+else
+  do64bitVIS=no
+fi
+
+    { echo "$as_me:$LINENO: result: $do64bitVIS" >&5
+echo "${ECHO_T}$do64bitVIS" >&6; }
+    # Force 64bit on with VIS
+    if test "$do64bitVIS" = "yes"; then
+  do64bit=yes
+fi
+
+
+    # Step 0.c: Check if visibility support is available. Do this here so
+    # that platform specific alternatives can be used below if this fails.
+
+    { echo "$as_me:$LINENO: checking if compiler supports visibility \"hidden\"" >&5
+echo $ECHO_N "checking if compiler supports visibility \"hidden\"... $ECHO_C" >&6; }
+if test "${tcl_cv_cc_visibility_hidden+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+           extern __attribute__((__visibility__("hidden"))) void f(void);
+           void f(void) {}
+int
+main ()
+{
+f();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_cc_visibility_hidden=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_cc_visibility_hidden=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+       CFLAGS=$hold_cflags
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5
+echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6; }
+    if test $tcl_cv_cc_visibility_hidden = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define MODULE_SCOPE extern __attribute__((__visibility__("hidden")))
+_ACEOF
+
+
+fi
+
+
+    # Step 0.d: Disable -rpath support?
+
+    { echo "$as_me:$LINENO: checking if rpath support is requested" >&5
+echo $ECHO_N "checking if rpath support is requested... $ECHO_C" >&6; }
+    # Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then
+  enableval=$enable_rpath; doRpath=$enableval
+else
+  doRpath=yes
+fi
+
+    { echo "$as_me:$LINENO: result: $doRpath" >&5
+echo "${ECHO_T}$doRpath" >&6; }
+
+    # TEA specific: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = windows; then
+
+       { echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5
+echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6; }
+       # Check whether --enable-wince was given.
+if test "${enable_wince+set}" = set; then
+  enableval=$enable_wince; doWince=$enableval
+else
+  doWince=no
+fi
+
+       { echo "$as_me:$LINENO: result: $doWince" >&5
+echo "${ECHO_T}$doWince" >&6; }
+
+fi
+
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+
+    { echo "$as_me:$LINENO: checking system version" >&5
+echo $ECHO_N "checking system version... $ECHO_C" >&6; }
+if test "${tcl_cv_sys_version+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       # TEA specific:
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5
+echo "$as_me: WARNING: can't find uname command" >&2;}
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $3}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5
+echo "${ECHO_T}$tcl_cv_sys_version" >&6; }
+    system=$tcl_cv_sys_version
+
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_dl_dlopen=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
+if test $ac_cv_lib_dl_dlopen = yes; then
+  have_dl=yes
+else
+  have_dl=no
+fi
+
+
+    # Require ranlib early so we can override it in special cases below.
+
+
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    if test "$GCC" = yes; then
+
+       # TEA specific:
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall"
+
+else
+  CFLAGS_WARNING=""
+fi
+
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+    # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    if test "x$SHLIB_VERSION" = x; then
+  SHLIB_VERSION="1.0"
+fi
+
+    case $system in
+       # TEA specific:
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+                   { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5
+echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+                   do64bit="no"
+               else
+                   { echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
+echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6; }
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5
+echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               if test "$GCC" = "yes" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5
+echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+
+# Check whether --with-celib was given.
+if test "${with_celib+set}" = set; then
+  withval=$with_celib; with_celibconfig=${withval}
+fi
+
+       { echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
+echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6; }
+       if test "${ac_cv_c_celibconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5
+echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+fi
+
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5
+echo "$as_me: error: Cannot find celib support library directory" >&2;}
+   { (exit 1); exit 1; }; }
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           { echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5
+echo "${ECHO_T}found $CELIB_DIR" >&6; }
+       fi
+    fi
+
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
+           if ($1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
+           if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
+           if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5
+echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;}
+   { (exit 1); exit 1; }; }
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+
+    vars="bufferoverflowU.lib"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower($0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+
+cat >>confdefs.h <<_ACEOF
+#define $i 1
+_ACEOF
+
+                   done
+
+cat >>confdefs.h <<_ACEOF
+#define _WIN32_WCE $CEVERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNDER_CE $CEVERSION
+_ACEOF
+
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # and also
+               # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug -debugtype:cv"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then
+
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r|*_r\ *)
+                       # ok ...
+                       ;;
+                   *)
+                       # Make sure only first arg gets _r
+                       CC=`echo "$CC" | sed -e 's/^\([^ ]*\)/\1_r/'`
+                       ;;
+               esac
+               { echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5
+echo "${ECHO_T}Using $CC for compiling with threads" >&6; }
+
+fi
+
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           if test "$do64bit" = yes -a "`uname -v`" -gt 3; then
+
+               if test "$GCC" = yes; then
+
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+
+else
+
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+
+fi
+
+
+fi
+
+
+           if test "`uname -m`" = ia64; then
+
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               if test "$GCC" = yes; then
+
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+
+else
+
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+
+fi
+
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+
+else
+
+               if test "$GCC" = yes; then
+  SHLIB_LD='${CC} -shared'
+else
+
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+
+fi
+
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               # TEA specific: use PACKAGE_VERSION instead of VERSION
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+
+fi
+
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           if test "$system" = "AIX-4.1" -o "`uname -v`" -lt 4; then
+
+               case " $LIBOBJS " in
+  *" tclLoadAix.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext"
+ ;;
+esac
+
+               DL_LIBS="-lld"
+
+fi
+
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           { echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5
+echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6; }
+if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gettimeofday ();
+int
+main ()
+{
+return gettimeofday ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_bsd_gettimeofday=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_bsd_gettimeofday=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5
+echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6; }
+if test $ac_cv_lib_bsd_gettimeofday = yes; then
+  libbsd=yes
+else
+  libbsd=no
+fi
+
+           if test $libbsd = yes; then
+
+               MATH_LIBS="$MATH_LIBS -lbsd"
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_DELTA_FOR_TZ 1
+_ACEOF
+
+
+fi
+
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -nostart'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           { echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5
+echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6; }
+if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbind  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntoa ();
+int
+main ()
+{
+return inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_bind_inet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_bind_inet_ntoa=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6; }
+if test $ac_cv_lib_bind_inet_ntoa = yes; then
+  LIBS="$LIBS -lbind -lsocket"
+fi
+
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD='${CC} -shared'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       Haiku*)
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-lroot"
+           { echo "$as_me:$LINENO: checking for inet_ntoa in -lnetwork" >&5
+echo $ECHO_N "checking for inet_ntoa in -lnetwork... $ECHO_C" >&6; }
+if test "${ac_cv_lib_network_inet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetwork  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntoa ();
+int
+main ()
+{
+return inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_network_inet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_network_inet_ntoa=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_network_inet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_network_inet_ntoa" >&6; }
+if test $ac_cv_lib_network_inet_ntoa = yes; then
+  LIBS="$LIBS -lnetwork"
+fi
+
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+
+cat >>confdefs.h <<\_ACEOF
+#define _XOPEN_SOURCE_EXTENDED 1
+_ACEOF
+
+           # TEA specific: Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           if test "`uname -m`" = ia64; then
+
+               SHLIB_SUFFIX=".so"
+               # Use newer C++ library for C++ extensions
+               #if test "$GCC" != "yes" ; then
+               #   CPPFLAGS="-AA"
+               #fi
+
+else
+
+               SHLIB_SUFFIX=".sl"
+
+fi
+
+           { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_dld_shl_load=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; }
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+
+fi
+
+           if test "$GCC" = yes; then
+
+               SHLIB_LD='${CC} -shared'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+else
+
+               CFLAGS="$CFLAGS -z"
+               # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+               #CFLAGS="$CFLAGS +DAportable"
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+
+fi
+
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes"; then
+
+               if test "$GCC" = yes; then
+
+                   case `${CC} -dumpmachine` in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD='${CC} -shared'
+                           SHLIB_LD_LIBS='${LIBS}'
+                           if test $doRpath = yes; then
+
+                               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+                           ;;
+                   esac
+
+else
+
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+
+fi
+
+
+fi
+ ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_dld_shl_load=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; }
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+
+fi
+ ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           if test "$GCC" = yes; then
+
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+
+else
+
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+
+fi
+
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           if test "$do64bit" = yes; then
+
+               if test "$GCC" = yes; then
+
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5
+echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
+
+else
+
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+
+fi
+
+
+fi
+
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           # TEA specific:
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "`uname -m`" = "alpha"; then
+  CFLAGS="$CFLAGS -mieee"
+fi
+
+           if test $do64bit = yes; then
+
+               { echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6; }
+if test "${tcl_cv_cc_m64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_cc_m64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_cc_m64=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+                   CFLAGS=$hold_cflags
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5
+echo "${ECHO_T}$tcl_cv_cc_m64" >&6; }
+               if test $tcl_cv_cc_m64 = yes; then
+
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+
+fi
+
+
+fi
+
+
+           # The combo of gcc + glibc has a bug related to inlining of
+           # functions like strtod(). The -fno-builtin flag should address
+           # this problem but it does not work. The -fno-inline flag is kind
+           # of overkill but it works. Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+
+           if test x"${USE_COMPAT}" != x; then
+  CFLAGS="$CFLAGS -fno-inline"
+fi
+
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD='${CC} -shared'
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           if test "`uname -m`" = "alpha"; then
+  CFLAGS="$CFLAGS -mieee"
+fi
+
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD='${CC} -shared'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-1.*|FreeBSD-[1-2].*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           { echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6; }
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6; }
+           if test $tcl_cv_ld_elf = yes; then
+
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+
+else
+
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+
+fi
+
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+           { echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6; }
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6; }
+           if test $tcl_cv_ld_elf = yes; then
+
+               LDFLAGS=-Wl,-export-dynamic
+
+else
+  LDFLAGS=""
+fi
+
+           if test "${TCL_THREADS}" = "1"; then
+
+               # OpenBSD builds and links with -pthread, never -lpthread.
+               LIBS=`echo $LIBS | sed s/-lpthread//`
+               CFLAGS="$CFLAGS -pthread"
+               SHLIB_CFLAGS="$SHLIB_CFLAGS -pthread"
+
+fi
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       NetBSD-*|FreeBSD-[3-4].*)
+           # FreeBSD 3.* and greater have ELF.
+           # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "${TCL_THREADS}" = "1"; then
+
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+
+fi
+
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       FreeBSD-*)
+           # This configuration from FreeBSD Ports.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -shared"
+           TCL_SHLIB_LD_EXTRAS="-soname \$@"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           if test "${TCL_THREADS}" = "1"; then
+
+               # The -pthread needs to go in the LDFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+               LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
+fi
+
+           # Version numbers are dot-stripped by system policy.
+           TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           # To avoid discrepancies between what headers configure sees during
+           # preprocessing tests and compiling tests, move any -isysroot and
+           # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+           CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
+           CFLAGS="`echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
+           if test $do64bit = yes; then
+
+               case `arch` in
+                   ppc)
+                       { echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6; }
+if test "${tcl_cv_cc_arch_ppc64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_cc_arch_ppc64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_cc_arch_ppc64=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6; }
+                       if test $tcl_cv_cc_arch_ppc64 = yes; then
+
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+
+fi
+;;
+                   i386)
+                       { echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6; }
+if test "${tcl_cv_cc_arch_x86_64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_cc_arch_x86_64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_cc_arch_x86_64=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6; }
+                       if test $tcl_cv_cc_arch_x86_64 = yes; then
+
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+
+fi
+;;
+                   *)
+                       { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
+               esac
+
+else
+
+               # Check for combined 32-bit and 64-bit fat build
+               if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+                   && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then
+
+                   fat_32_64=yes
+fi
+
+
+fi
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           { echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5
+echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6; }
+if test "${tcl_cv_ld_single_module+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_ld_single_module=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_ld_single_module=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5
+echo "${ECHO_T}$tcl_cv_ld_single_module" >&6; }
+           if test $tcl_cv_ld_single_module = yes; then
+
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+
+fi
+
+           # TEA specific: link shlib with current and compatiblity version flags
+           vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([0-9]\{1,5\}\)\(\(\.[0-9]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+           SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
+               "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then
+
+               LDFLAGS="$LDFLAGS -prebind"
+fi
+
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           { echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5
+echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6; }
+if test "${tcl_cv_ld_search_paths_first+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_ld_search_paths_first=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_ld_search_paths_first=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5
+echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6; }
+           if test $tcl_cv_ld_search_paths_first = yes; then
+
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+
+fi
+
+           if test "$tcl_cv_cc_visibility_hidden" != yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define MODULE_SCOPE __private_extern__
+_ACEOF
+
+
+fi
+
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+           # TEA specific: for combined 32 & 64 bit fat builds of Tk
+           # extensions, verify that 64-bit build is possible.
+           if test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"; then
+
+               if test "${TEA_WINDOWINGSYSTEM}" = x11; then
+
+                   { echo "$as_me:$LINENO: checking for 64-bit X11" >&5
+echo $ECHO_N "checking for 64-bit X11... $ECHO_C" >&6; }
+if test "${tcl_cv_lib_x11_64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+                       done
+                       CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+                       LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+                       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_lib_x11_64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_lib_x11_64=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval $v'="$hold_'$v'"'
+                       done
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_lib_x11_64" >&5
+echo "${ECHO_T}$tcl_cv_lib_x11_64" >&6; }
+
+fi
+
+               if test "${TEA_WINDOWINGSYSTEM}" = aqua; then
+
+                   { echo "$as_me:$LINENO: checking for 64-bit Tk" >&5
+echo $ECHO_N "checking for 64-bit Tk... $ECHO_C" >&6; }
+if test "${tcl_cv_lib_tk_64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+                       done
+                       CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+                       LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+                       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <tk.h>
+int
+main ()
+{
+Tk_InitStubs(NULL, "", 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_lib_tk_64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_lib_tk_64=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval $v'="$hold_'$v'"'
+                       done
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_lib_tk_64" >&5
+echo "${ECHO_T}$tcl_cv_lib_tk_64" >&6; }
+
+fi
+
+               # remove 64-bit arch flags from CFLAGS et al. if configuration
+               # does not support 64-bit.
+               if test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no; then
+
+                   { echo "$as_me:$LINENO: Removing 64-bit architectures from compiler & linker flags" >&5
+echo "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;}
+                   for v in CFLAGS CPPFLAGS LDFLAGS; do
+                       eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+                   done
+fi
+
+
+fi
+
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD='${CC} -nostdlib -r'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+
+cat >>confdefs.h <<\_ACEOF
+#define _OE_SOCKETS 1
+_ACEOF
+
+           ;;
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export :'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           if test "$SHARED_BUILD" = 1; then
+  SHLIB_LD="ld -shared"
+else
+
+               SHLIB_LD="ld -non_shared"
+
+fi
+
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           if test "$SHARED_BUILD" = 1; then
+
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+
+else
+
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+
+fi
+
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           if test $doRpath = yes; then
+
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+           if test "$GCC" = yes; then
+  CFLAGS="$CFLAGS -mieee"
+else
+
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+fi
+
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           if test "${TCL_THREADS}" = 1; then
+
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               if test "$GCC" = yes; then
+
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+
+else
+
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+
+fi
+
+
+fi
+
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           if test "$GCC" = yes; then
+
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+
+else
+
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+
+fi
+
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[0-6])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = yes; then
+
+               SHLIB_LD='${CC} -shared'
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+else
+
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+fi
+
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = yes; then
+
+               arch=`isainfo`
+               if test "$arch" = "sparcv9 sparc"; then
+
+                   if test "$GCC" = yes; then
+
+                       if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then
+
+                           { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
+
+else
+
+                           do64bit_ok=yes
+                           CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                           LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                           SHLIB_CFLAGS="-fPIC"
+
+fi
+
+
+else
+
+                       do64bit_ok=yes
+                       if test "$do64bitVIS" = yes; then
+
+                           CFLAGS="$CFLAGS -xarch=v9a"
+                           LDFLAGS_ARCH="-xarch=v9a"
+
+else
+
+                           CFLAGS="$CFLAGS -xarch=v9"
+                           LDFLAGS_ARCH="-xarch=v9"
+
+fi
+
+                       # Solaris 64 uses this as well
+                       #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+
+fi
+
+
+else
+  if test "$arch" = "amd64 i386"; then
+
+                   if test "$GCC" = yes; then
+
+                       case $system in
+                           SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64"
+                               LDFLAGS="$LDFLAGS -m64";;
+                           *)
+                               { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
+                       esac
+
+else
+
+                       do64bit_ok=yes
+                       case $system in
+                           SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
+                               CFLAGS="$CFLAGS -m64"
+                               LDFLAGS="$LDFLAGS -m64";;
+                           *)
+                               CFLAGS="$CFLAGS -xarch=amd64"
+                               LDFLAGS="$LDFLAGS -xarch=amd64";;
+                       esac
+
+fi
+
+
+else
+  { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5
+echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+fi
+
+fi
+
+
+fi
+
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = yes; then
+
+               SHLIB_LD='${CC} -shared'
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               if test "$do64bit_ok" = yes; then
+
+                   if test "$arch" = "sparcv9 sparc"; then
+
+                       # We need to specify -static-libgcc or we need to
+                       # add the path to the sparv9 libgcc.
+                       # JH: static-libgcc is necessary for core Tcl, but may
+                       # not be necessary for extensions.
+                       SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                       # for finding sparcv9 libgcc, get the regular libgcc
+                       # path, remove so name and append 'sparcv9'
+                       #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                       #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+
+else
+  if test "$arch" = "amd64 i386"; then
+
+                       # JH: static-libgcc is necessary for core Tcl, but may
+                       # not be necessary for extensions.
+                       SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+
+fi
+
+fi
+
+
+fi
+
+
+else
+
+               case $system in
+                   SunOS-5.[1-9][0-9]*)
+                       # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+                       SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+                   *)
+                       SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+               esac
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+
+fi
+
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           { echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5
+echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6; }
+if test "${tcl_cv_ld_Bexport+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  tcl_cv_ld_Bexport=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_ld_Bexport=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5
+echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6; }
+           if test $tcl_cv_ld_Bexport = yes; then
+
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+
+fi
+
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    if test "$do64bit" = yes -a "$do64bit_ok" = no; then
+
+       { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+
+fi
+
+
+
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    # Check whether --enable-load was given.
+if test "${enable_load+set}" = set; then
+  enableval=$enable_load; tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi
+
+    if test "$tcl_ok" = no; then
+  DL_OBJS=""
+fi
+
+
+    if test "x$DL_OBJS" != x; then
+  BUILD_DLTEST="\$(DLTEST_TARGETS)"
+else
+
+       { echo "$as_me:$LINENO: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5
+echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;}
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+
+fi
+
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then
+
+       case $system in
+           AIX-*) ;;
+           BSD/OS*) ;;
+           IRIX*) ;;
+           NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+           Darwin-*) ;;
+           SCO_SV-3.2*) ;;
+           windows) ;;
+           *) SHLIB_CFLAGS="-fPIC" ;;
+       esac
+fi
+
+
+    if test "$SHARED_LIB_SUFFIX" = ""; then
+
+       # TEA specific: use PACKAGE_VERSION instead of VERSION
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+fi
+
+    if test "$UNSHARED_LIB_SUFFIX" = ""; then
+
+       # TEA specific: use PACKAGE_VERSION instead of VERSION
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+
+    { echo "$as_me:$LINENO: checking for required early compiler flags" >&5
+echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6; }
+    tcl_flags=""
+
+    if test "${tcl_cv_flag__isoc99_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_flag__isoc99_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_flag__isoc99_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_flag__isoc99_source=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _ISOC99_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _ISOC99_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile64_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_flag__largefile64_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE64_SOURCE 1
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_flag__largefile64_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_flag__largefile64_source=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE64_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile_source64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_flag__largefile_source64=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE_SOURCE64 1
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_flag__largefile_source64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_flag__largefile_source64=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE_SOURCE64 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
+    fi
+
+    if test "x${tcl_flags}" = "x" ; then
+       { echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6; }
+    else
+       { echo "$as_me:$LINENO: result: ${tcl_flags}" >&5
+echo "${ECHO_T}${tcl_flags}" >&6; }
+    fi
+
+
+    { echo "$as_me:$LINENO: checking for 64-bit integer type" >&5
+echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6; }
+    if test "${tcl_cv_type_64bit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__int64 value = (__int64) 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_type_64bit=__int64
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_type_64bit="long long"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+switch (0) {
+            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+        }
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_type_64bit=${tcl_type_64bit}
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "${tcl_cv_type_64bit}" = none ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_WIDE_INT_IS_LONG 1
+_ACEOF
+
+       { echo "$as_me:$LINENO: result: using long" >&5
+echo "${ECHO_T}using long" >&6; }
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # TEA specific: We actually want to use the default tcl.h checks in
+       # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       { echo "$as_me:$LINENO: result: using Tcl header defaults" >&5
+echo "${ECHO_T}using Tcl header defaults" >&6; }
+    else
+
+cat >>confdefs.h <<_ACEOF
+#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
+_ACEOF
+
+       { echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5
+echo "${ECHO_T}${tcl_cv_type_64bit}" >&6; }
+
+       # Now check for auxiliary declarations
+       { echo "$as_me:$LINENO: checking for struct dirent64" >&5
+echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6; }
+if test "${tcl_cv_struct_dirent64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/dirent.h>
+int
+main ()
+{
+struct dirent64 p;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_struct_dirent64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_struct_dirent64=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5
+echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6; }
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_DIRENT64 1
+_ACEOF
+
+       fi
+
+       { echo "$as_me:$LINENO: checking for struct stat64" >&5
+echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6; }
+if test "${tcl_cv_struct_stat64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 p;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_struct_stat64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_struct_stat64=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5
+echo "${ECHO_T}$tcl_cv_struct_stat64" >&6; }
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_STAT64 1
+_ACEOF
+
+       fi
+
+
+
+for ac_func in open64 lseek64
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+       { echo "$as_me:$LINENO: checking for off64_t" >&5
+echo $ECHO_N "checking for off64_t... $ECHO_C" >&6; }
+       if test "${tcl_cv_type_off64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+off64_t offset;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  tcl_cv_type_off64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       tcl_cv_type_off64_t=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+                       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TYPE_OFF64_T 1
+_ACEOF
+
+           { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+       else
+           { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+       fi
+    fi
+
+
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+
+
+    { echo "$as_me:$LINENO: checking for build with symbols" >&5
+echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6; }
+    # Check whether --enable-symbols was given.
+if test "${enable_symbols+set}" = set; then
+  enableval=$enable_symbols; tcl_ok=$enableval
+else
+  tcl_ok=no
+fi
+
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           { echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
+echo "${ECHO_T}yes (standard debugging)" >&6; }
+       fi
+    fi
+    # TEA specific:
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+
+
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_MEM_DEBUG 1
+_ACEOF
+
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           { echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5
+echo "${ECHO_T}enabled symbols mem debugging" >&6; }
+       else
+           { echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
+echo "${ECHO_T}enabled $tcl_ok debugging" >&6; }
+       fi
+    fi
+
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.  Add Tk too if necessary.
+#--------------------------------------------------------------------
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_TCL_STUBS 1
+_ACEOF
+
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+
+    { echo "$as_me:$LINENO: checking for tclsh" >&5
+echo $ECHO_N "checking for tclsh... $ECHO_C" >&6; }
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+    fi
+    { echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5
+echo "${ECHO_T}${TCLSH_PROG}" >&6; }
+
+
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+# You may alternatively have a special pkgIndex.tcl.in or other files
+# which require substituting th AC variables in.  Include these here.
+#--------------------------------------------------------------------
+
+ac_config_files="$ac_config_files Makefile pkgIndex.tcl"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+t clear
+:clear
+s/^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[     `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+       g
+       s/^\n//
+       s/\n/ /g
+       p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""       $as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\/\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+        test -d "$1/.";
+      else
+       case $1 in
+        -*)set "./$1";;
+       esac;
+       case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+       ???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by thread $as_me 2.6.6, which was
+generated by GNU Autoconf 2.61.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+thread config.status 2.6.6
+configured by $0, generated by GNU Autoconf 2.61,
+  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  CONFIG_SHELL=$SHELL
+  export CONFIG_SHELL
+  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "pkgIndex.tcl") CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;;
+
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+CYGPATH!$CYGPATH$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+PKG_LIB_FILE!$PKG_LIB_FILE$ac_delim
+PKG_STUB_LIB_FILE!$PKG_STUB_LIB_FILE$ac_delim
+PKG_STUB_SOURCES!$PKG_STUB_SOURCES$ac_delim
+PKG_STUB_OBJECTS!$PKG_STUB_OBJECTS$ac_delim
+PKG_TCL_SOURCES!$PKG_TCL_SOURCES$ac_delim
+PKG_HEADERS!$PKG_HEADERS$ac_delim
+PKG_INCLUDES!$PKG_INCLUDES$ac_delim
+PKG_LIBS!$PKG_LIBS$ac_delim
+PKG_CFLAGS!$PKG_CFLAGS$ac_delim
+TCL_VERSION!$TCL_VERSION$ac_delim
+TCL_BIN_DIR!$TCL_BIN_DIR$ac_delim
+TCL_SRC_DIR!$TCL_SRC_DIR$ac_delim
+TCL_LIB_FILE!$TCL_LIB_FILE$ac_delim
+TCL_LIB_FLAG!$TCL_LIB_FLAG$ac_delim
+TCL_LIB_SPEC!$TCL_LIB_SPEC$ac_delim
+TCL_STUB_LIB_FILE!$TCL_STUB_LIB_FILE$ac_delim
+TCL_STUB_LIB_FLAG!$TCL_STUB_LIB_FLAG$ac_delim
+TCL_STUB_LIB_SPEC!$TCL_STUB_LIB_SPEC$ac_delim
+TCL_LIBS!$TCL_LIBS$ac_delim
+TCL_DEFS!$TCL_DEFS$ac_delim
+TCL_EXTRA_CFLAGS!$TCL_EXTRA_CFLAGS$ac_delim
+TCL_LD_FLAGS!$TCL_LD_FLAGS$ac_delim
+TCL_SHLIB_LD_LIBS!$TCL_SHLIB_LD_LIBS$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+CPP!$CPP$ac_delim
+INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
+INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
+INSTALL_DATA!$INSTALL_DATA$ac_delim
+SET_MAKE!$SET_MAKE$ac_delim
+RANLIB!$RANLIB$ac_delim
+GREP!$GREP$ac_delim
+EGREP!$EGREP$ac_delim
+MATH_LIBS!$MATH_LIBS$ac_delim
+PKG_SOURCES!$PKG_SOURCES$ac_delim
+PKG_OBJECTS!$PKG_OBJECTS$ac_delim
+CLEANFILES!$CLEANFILES$ac_delim
+TCL_INCLUDES!$TCL_INCLUDES$ac_delim
+TCL_THREADS!$TCL_THREADS$ac_delim
+SHARED_BUILD!$SHARED_BUILD$ac_delim
+AR!$AR$ac_delim
+CELIB_DIR!$CELIB_DIR$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+DL_LIBS!$DL_LIBS$ac_delim
+CFLAGS_DEBUG!$CFLAGS_DEBUG$ac_delim
+CFLAGS_OPTIMIZE!$CFLAGS_OPTIMIZE$ac_delim
+CFLAGS_WARNING!$CFLAGS_WARNING$ac_delim
+STLIB_LD!$STLIB_LD$ac_delim
+SHLIB_LD!$SHLIB_LD$ac_delim
+SHLIB_LD_LIBS!$SHLIB_LD_LIBS$ac_delim
+SHLIB_CFLAGS!$SHLIB_CFLAGS$ac_delim
+LD_LIBRARY_PATH_VAR!$LD_LIBRARY_PATH_VAR$ac_delim
+CFLAGS_DEFAULT!$CFLAGS_DEFAULT$ac_delim
+LDFLAGS_DEFAULT!$LDFLAGS_DEFAULT$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+CEOF$ac_eof
+_ACEOF
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+TCL_DBGX!$TCL_DBGX$ac_delim
+MAKE_LIB!$MAKE_LIB$ac_delim
+MAKE_SHARED_LIB!$MAKE_SHARED_LIB$ac_delim
+MAKE_STATIC_LIB!$MAKE_STATIC_LIB$ac_delim
+MAKE_STUB_LIB!$MAKE_STUB_LIB$ac_delim
+RANLIB_STUB!$RANLIB_STUB$ac_delim
+TCLSH_PROG!$TCLSH_PROG$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 8; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[    ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[      ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in  :F $CONFIG_FILES
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+   { (exit 1); exit 1; }; };;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+        # (if the path is not absolute).  The absolute path cannot be DOS-style,
+        # because $ac_f cannot contain `:'.
+        test -f "$ac_f" ||
+          case $ac_f in
+          [\\/$]*) false;;
+          *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+          esac ||
+          { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+   { (exit 1); exit 1; }; };;
+      esac
+      ac_file_inputs="$ac_file_inputs $ac_f"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input="Generated from "`IFS=:
+         echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    fi
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin";;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+  { as_dir="$ac_dir"
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+   { (exit 1); exit 1; }; }; }
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+    s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out"; rm -f "$tmp/out";;
+  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+  esac
+ ;;
+
+
+
+  esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/8.x/thread/configure.in b/8.x/thread/configure.in
new file mode 100644 (file)
index 0000000..0a51bfb
--- /dev/null
@@ -0,0 +1,207 @@
+#!/bin/bash -norc
+dnl    This file is an input file used by the GNU "autoconf" program to
+dnl    generate the file "configure", which is run during Tcl installation
+dnl    to configure the system for the local environment.
+#
+# RCS: @(#) $Id: configure.in,v 1.32 2010/03/31 08:51:18 vasiljevic Exp $
+
+#-----------------------------------------------------------------------
+# Sample configure.in for Tcl Extensions.  The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Set your package name and version numbers here.
+#
+# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
+# set as provided.  These will also be added as -D defs in your Makefile
+# so you can encode the package version directly into the source files.
+#-----------------------------------------------------------------------
+
+AC_INIT([thread], [2.6.6])
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+TEA_INIT([3.7])
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+#TEA_PATH_TKCONFIG
+#TEA_LOAD_TKCONFIG
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+TEA_PREFIX
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
+# the basic setup necessary to compile executables.
+#-----------------------------------------------------------------------
+
+TEA_SETUP_COMPILER
+
+#--------------------------------------------------------------------
+# Check if building with optional Gdbm package. This will declare 
+# GDBM_CFLAGS and GDBM_LIBS variables.
+#--------------------------------------------------------------------
+
+TCLTHREAD_WITH_GDBM
+
+#--------------------------------------------------------------------
+# Locate the AOLserver dir for compilation as AOLserver module.
+# This will declare AOL_INCLUDES, AOL_LIBS and define NS_AOLSERVER.
+#--------------------------------------------------------------------
+
+NS_PATH_AOLSERVER
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+TEA_ADD_SOURCES([generic/threadCmd.c          \
+                 generic/threadSvCmd.c        \
+                 generic/threadSpCmd.c        \
+                 generic/threadPoolCmd.c      \
+                 generic/psGdbm.c             \
+                 generic/threadSvListCmd.c    \
+                 generic/threadSvKeylistCmd.c \
+                 generic/tclXkeylist.c        \
+])
+
+TEA_ADD_HEADERS([])
+TEA_ADD_INCLUDES([${AOL_INCLUDES}])
+TEA_ADD_LIBS([${GDBM_LIBS} ${AOL_LIBS}])
+TEA_ADD_CFLAGS([${GDBM_CFLAGS}])
+TEA_ADD_STUB_SOURCES([])
+TEA_ADD_TCL_SOURCES([lib/ttrace.tcl])
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_sample in this case) so
+# that we create the export library with the dll.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    AC_DEFINE(BUILD_thread)
+    CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+    TEA_ADD_SOURCES([win/threadWin.c])
+    TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+    TEA_ADD_SOURCES([unix/threadUnix.c])
+fi
+AC_SUBST(CLEANFILES)
+
+#--------------------------------------------------------------------
+# __CHANGE__
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
+#--------------------------------------------------------------------
+
+TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_THREADS
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SHARED
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+TEA_CONFIG_CFLAGS
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SYMBOLS
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.  Add Tk too if necessary.
+#--------------------------------------------------------------------
+
+AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+TEA_MAKE_LIB
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+TEA_PROG_TCLSH
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+# You may alternatively have a special pkgIndex.tcl.in or other files
+# which require substituting th AC variables in.  Include these here.
+#--------------------------------------------------------------------
+
+AC_OUTPUT([Makefile pkgIndex.tcl])
diff --git a/8.x/thread/doc/format.tcl b/8.x/thread/doc/format.tcl
new file mode 100644 (file)
index 0000000..394c462
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/local/bin/tclsh
+set mydir [file dirname [info script]]
+lappend auto_path /usr/local/lib
+package req doctools
+doctools::new dt
+set wd [pwd]
+cd $mydir
+file rename html htm
+set code [catch {
+    set f [open man.macros]
+    set m [read $f]
+    close $f
+    foreach file [glob -nocomplain *.man] {
+        set xx [file root $file]
+        set f [open $xx.man]
+        set t [read $f]
+        close $f
+        foreach {fmt ext dir} {nroff n man html html htm} {
+            dt configure -format $fmt
+            set o [dt format $t]
+            set f [open $dir/$xx.$ext w]
+            if {$fmt == "nroff"} {
+                set o [string map [list {.so man.macros} $m] $o]
+            }
+            puts $f $o
+            close $f
+        }
+    }
+} err]
+file rename htm html
+cd $wd
+if {$code} {
+    error $err
+}
+exit 0
diff --git a/8.x/thread/doc/html/thread.html b/8.x/thread/doc/html/thread.html
new file mode 100644 (file)
index 0000000..faadf66
--- /dev/null
@@ -0,0 +1,729 @@
+<! -- -*- tcl -*- doctools manpage
+   -->
+<html><head>
+<title>thread - Tcl Threading </title>
+</head>
+<! -- Generated from file '' by tcllib/doctools with format 'html'
+   -->
+<! -- CVS: $Id: thread.html,v 1.23 2006/10/07 09:19:39 vasiljevic Exp $ thread.n
+   -->
+
+<body>
+<h1> thread(n) 2.6  &quot;Tcl Threading&quot;</h1>
+<h2><a name="name">NAME</a></h2>
+<p>
+<p> thread - Extension for script access to Tcl threading
+
+
+
+
+
+<h2><a name="table_of_contents">TABLE OF CONTENTS</a></h2>
+<p>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#table_of_contents">TABLE OF CONTENTS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#synopsis">SYNOPSIS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#description">DESCRIPTION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#commands">COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#discussion">DISCUSSION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#see_also">SEE ALSO</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#keywords">KEYWORDS</a><br>
+<h2><a name="synopsis">SYNOPSIS</a></h2>
+<p>
+package require <b>Tcl 8.4</b><br>
+package require <b>Thread ?2.6?</b><br>
+<br><table border=1 width=100% cellspacing=0 cellpadding=0><tr            bgcolor=lightyellow><td bgcolor=lightyellow><table 0 width=100% cellspacing=0 cellpadding=0><tr valign=top ><td ><a href="#1"><b class='cmd'>thread::create</b> ?-joinable? ?-preserved? ?script?</a></td></tr>
+<tr valign=top ><td ><a href="#2"><b class='cmd'>thread::preserve</b> ?id?</a></td></tr>
+<tr valign=top ><td ><a href="#3"><b class='cmd'>thread::release</b> ?-wait? ?id?</a></td></tr>
+<tr valign=top ><td ><a href="#4"><b class='cmd'>thread::id</b> </a></td></tr>
+<tr valign=top ><td ><a href="#5"><b class='cmd'>thread::errorproc</b> ?procname?</a></td></tr>
+<tr valign=top ><td ><a href="#6"><b class='cmd'>thread::unwind</b> </a></td></tr>
+<tr valign=top ><td ><a href="#7"><b class='cmd'>thread::exit</b> </a></td></tr>
+<tr valign=top ><td ><a href="#8"><b class='cmd'>thread::names</b> </a></td></tr>
+<tr valign=top ><td ><a href="#9"><b class='cmd'>thread::exists</b> <i class='arg'>id</i></a></td></tr>
+<tr valign=top ><td ><a href="#10"><b class='cmd'>thread::send</b> ?-async? ?-head? <i class='arg'>id</i> <i class='arg'>script</i> ?varname?</a></td></tr>
+<tr valign=top ><td ><a href="#11"><b class='cmd'>thread::broadcast</b> <i class='arg'>id</i> <i class='arg'>script</i></a></td></tr>
+<tr valign=top ><td ><a href="#12"><b class='cmd'>thread::wait</b> </a></td></tr>
+<tr valign=top ><td ><a href="#13"><b class='cmd'>thread::eval</b> ?-lock mutex? <i class='arg'>arg</i> ?arg ...?</a></td></tr>
+<tr valign=top ><td ><a href="#14"><b class='cmd'>thread::join</b> <i class='arg'>id</i></a></td></tr>
+<tr valign=top ><td ><a href="#15"><b class='cmd'>thread::configure</b> <i class='arg'>id</i> ?option? ?value? ?...?</a></td></tr>
+<tr valign=top ><td ><a href="#16"><b class='cmd'>thread::transfer</b> <i class='arg'>id</i> <i class='arg'>channel</i></a></td></tr>
+<tr valign=top ><td ><a href="#17"><b class='cmd'>thread::detach</b> <i class='arg'>channel</i></a></td></tr>
+<tr valign=top ><td ><a href="#18"><b class='cmd'>thread::attach</b> <i class='arg'>channel</i></a></td></tr>
+<tr valign=top ><td ><a href="#19"><b class='cmd'>thread::mutex</b> </a></td></tr>
+<tr valign=top ><td ><a href="#20"><b class='cmd'>thread::mutex</b> <strong>create</strong> ?-recursive?</a></td></tr>
+<tr valign=top ><td ><a href="#21"><b class='cmd'>thread::mutex</b> <strong>destroy</strong> <i class='arg'>mutex</i></a></td></tr>
+<tr valign=top ><td ><a href="#22"><b class='cmd'>thread::mutex</b> <strong>lock</strong> <i class='arg'>mutex</i></a></td></tr>
+<tr valign=top ><td ><a href="#23"><b class='cmd'>thread::mutex</b> <strong>unlock</strong> <i class='arg'>mutex</i></a></td></tr>
+<tr valign=top ><td ><a href="#24"><b class='cmd'>thread::rwmutex</b> </a></td></tr>
+<tr valign=top ><td ><a href="#25"><b class='cmd'>thread::rwmutex</b> <strong>create</strong></a></td></tr>
+<tr valign=top ><td ><a href="#26"><b class='cmd'>thread::rwmutex</b> <strong>destroy</strong> <i class='arg'>mutex</i></a></td></tr>
+<tr valign=top ><td ><a href="#27"><b class='cmd'>thread::rwmutex</b> <strong>rlock</strong> <i class='arg'>mutex</i></a></td></tr>
+<tr valign=top ><td ><a href="#28"><b class='cmd'>thread::rwmutex</b> <strong>wlock</strong> <i class='arg'>mutex</i></a></td></tr>
+<tr valign=top ><td ><a href="#29"><b class='cmd'>thread::rwmutex</b> <strong>unlock</strong> <i class='arg'>mutex</i></a></td></tr>
+<tr valign=top ><td ><a href="#30"><b class='cmd'>thread::cond</b> </a></td></tr>
+<tr valign=top ><td ><a href="#31"><b class='cmd'>thread::cond</b> <strong>create</strong></a></td></tr>
+<tr valign=top ><td ><a href="#32"><b class='cmd'>thread::cond</b> <strong>destroy</strong> <i class='arg'>cond</i></a></td></tr>
+<tr valign=top ><td ><a href="#33"><b class='cmd'>thread::cond</b> <strong>notify</strong> <i class='arg'>cond</i></a></td></tr>
+<tr valign=top ><td ><a href="#34"><b class='cmd'>thread::cond</b> <strong>wait</strong> <i class='arg'>cond</i> <i class='arg'>mutex</i> ?ms?</a></td></tr>
+</table></td></tr></table>
+<h2><a name="description">DESCRIPTION</a></h2>
+<p>
+The <strong>thread</strong> extension creates threads that contain Tcl 
+interpreters, and it lets you send scripts to those threads for
+evaluation.
+
+Additionaly, it provides script-level access to basic thread 
+synchronization primitives, like mutexes and condition variables.
+
+<h2><a name="commands">COMMANDS</a></h2>
+<p>
+This section describes commands for creating and destroying threads
+and sending scripts to threads for evaluation.
+
+
+
+<dl>
+
+<dt><a name="1"><b class='cmd'>thread::create</b> ?-joinable? ?-preserved? ?script?</a><dd>
+
+
+This command creates a thread that contains a Tcl interpreter. 
+The Tcl interpreter either evaluates the optional <strong>script</strong>, if
+specified, or it waits in the event loop for scripts that arrive via
+the <b class='cmd'>thread::send</b> command. The result, if any, of the
+optional <strong>script</strong> is never returned to the caller.
+The result of <b class='cmd'>thread::create</b> is the ID of the thread. This is
+the opaque handle which identifies the newly created thread for
+all other package commands. The handle of the thread goes out of scope
+automatically when thread is marked for exit
+(see the <b class='cmd'>thread::release</b> command below).
+
+<br><br>
+
+If the optional <strong>script</strong> argument contains the <b class='cmd'>thread::wait</b>
+command the thread will enter into the event loop. If such command is not
+found  in the <strong>script</strong> the thread will run the <strong>script</strong> to 
+the end and exit. In that case, the handle may be safely ignored since it 
+refers to a thread which does not exists any more at the time when the 
+command returns.
+
+<br><br>
+
+Using flag <strong>-joinable</strong> it is possible to create a joinable
+thread, i.e. one upon whose exit can be waited upon by using 
+<b class='cmd'>thread::join</b> command. 
+Note that failure to join a thread created with <strong>-joinable</strong> flag
+results in resource and memory leaks. 
+
+
+<br><br>
+
+Threads created by the <b class='cmd'>thread::create</b> cannot be destroyed 
+forcefully. Consequently, there is no corresponding thread destroy
+command. A thread may only be released using the <b class='cmd'>thread::release</b> 
+and if its internal reference count drops to zero, the thread is 
+marked for exit. This kicks the thread out of the event loop 
+servicing and the thread continues to execute commands passed in 
+the <strong>script</strong> argument, following the <b class='cmd'>thread::wait</b>
+command. If this was the last command in the script, as usualy the
+case, the thread will exit.
+
+<br><br>
+
+It is possible to create a situation in which it may be impossible
+to terminate the thread, for example by putting some endless loop 
+after the <b class='cmd'>thread::wait</b> or entering the event loop again by 
+doing an vwait-type of command. In such cases, the thread may never
+exit. This is considered to be a bad practice and should be avoided 
+if possible. This is best illustrated by the example below:
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    # You should never do ...
+    set tid [thread::create {
+        package require Http
+        thread::wait
+        vwait forever ; # &lt;-- this!
+    }]
+</pre></td></tr></table></p>
+
+The thread created in the above example will never be able to exit.
+After it has been released with the last matching <b class='cmd'>thread::release</b>
+call, the thread will jump out of the <b class='cmd'>thread::wait</b> and continue 
+to execute commands following. It will enter <b class='cmd'>vwait</b> command and 
+wait endlessly for events. There is no way one can terminate such thread,
+so you wouldn't want to do this!
+
+<br><br>
+
+Each newly created has its internal reference counter set to 0 (zero), 
+i.e. it is unreserved. This counter gets incremented by a call to 
+<b class='cmd'>thread::preserve</b> and decremented by a call to <b class='cmd'>thread::release</b>
+command. These two commands implement simple but effective thread 
+reservation system and offer predictable and controllable thread 
+termination capabilities. It is however possible to create initialy 
+preserved threads by using flag <strong>-preserved</strong> of the 
+<b class='cmd'>thread::create</b> command. Threads created with this flag have the 
+initial value of the reference counter of 1 (one), and are thus 
+initially marked reserved. 
+
+
+<br><br>
+<dt><a name="2"><b class='cmd'>thread::preserve</b> ?id?</a><dd>
+
+
+This command increments the thread reference counter. Each call
+to this command increments the reference counter by one (1). 
+Command returns the value of the reference counter after the increment. 
+If called with the optional thread <strong>id</strong>, the command preserves
+the given thread. Otherwise the current thread is preserved.
+
+<br><br>
+
+With reference counting, one can implement controlled access to a 
+shared Tcl thread. By incrementing the reference counter, the 
+caller signalizes that he/she wishes to use the thread for a longer
+period of time. By decrementing the counter, caller signalizes that 
+he/she has finished using the thread.
+
+<br><br>
+<dt><a name="3"><b class='cmd'>thread::release</b> ?-wait? ?id?</a><dd>
+
+
+This command decrements the thread reference counter. Each call to 
+this command decrements the reference counter by one (1). 
+If called with the optional thread <strong>id</strong>, the command releases
+the given thread. Otherwise, the current thread is released.
+Command returns the value of the reference counter after the decrement.
+When the reference counter reaches zero (0), the target thread is 
+marked for termination. You should not reference the thread after the
+<b class='cmd'>thread::release</b> command returns zero or negative integer. 
+The handle of the thread goes out of scope and should not be used any
+more. Any following reference to the same thread handle will result 
+in Tcl error.
+
+<br><br>
+
+Optional flag <strong>-wait</strong> instructs the caller thread to wait for 
+the target thread to exit, if the effect of the command would result 
+in termination of the target thread, i.e. if the return result would
+be zero (0). Without the flag, the caller thread does not wait for 
+the target thread to exit. Care must be taken when using the 
+<strong>-wait</strong>, since this may block the caller thread indefinitely.
+This option has been implemented for some special uses of the extension
+and is deprecated for regular use. Regular users should create joinable
+threads by using the <strong>-joinable</strong> option of the <b class='cmd'>thread::create</b>
+command and the <b class='cmd'>thread::join</b> to wait for thread to exit. 
+
+<br><br>
+<dt><a name="4"><b class='cmd'>thread::id</b> </a><dd>
+
+
+This command returns the ID of the current thread.
+
+<br><br>
+<dt><a name="5"><b class='cmd'>thread::errorproc</b> ?procname?</a><dd>
+
+
+This command sets a handler for errors that occur in scripts sent 
+asynchronously, using the <strong>-async</strong> flag of the 
+<b class='cmd'>thread::send</b> command, to other threads. If no handler 
+is specified, the current handler is returned. The empty string
+resets the handler to default (unspecified) value.
+An uncaught error in a thread causes an error message to be sent
+to the standard error channel. This default reporting scheme can
+be changed by registering a procedure which is called to report
+the error. The <i class='arg'>procname</i> is called in the interpreter that
+invoked the <b class='cmd'>thread::errorproc</b> command. The <i class='arg'>procname</i>
+is called like this:
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    myerrorproc thread_id errorInfo
+</pre></td></tr></table></p>
+
+<br><br>
+<dt><a name="6"><b class='cmd'>thread::unwind</b> </a><dd>
+
+
+Use of this command is deprecated in favour of more advanced thread
+reservation system implemented with <b class='cmd'>thread::preserve</b> and 
+<b class='cmd'>thread::release</b> commands. Support for <b class='cmd'>thread::unwind</b> 
+command will dissapear in some future major release of the extension.
+<br><br>
+This command stops a prior <b class='cmd'>thread::wait</b> command. Execution of
+the script passed to newly created thread will continue from the 
+<b class='cmd'>thread::wait</b> command. If <b class='cmd'>thread::wait</b> was the last command
+in the script, the thread will exit. The command returns empty result
+but may trigger Tcl error with the message &quot;target thread died&quot; in some
+situations.
+
+
+<br><br>
+<dt><a name="7"><b class='cmd'>thread::exit</b> </a><dd>
+
+
+Use of this command is deprecated in favour of more advanced thread
+reservation system implemented with <b class='cmd'>thread::preserve</b> and 
+<b class='cmd'>thread::release</b> commands. Support for <b class='cmd'>thread::exit</b> 
+command will dissapear in some future major release of the extension.
+<br><br>
+This command forces a thread stuck in the <b class='cmd'>thread::wait</b>
+command to unconditionaly exit. The execution of <b class='cmd'>thread::exit</b>
+command is guaranteed to leave the program memory in the unconsistent
+state, produce memory leaks and otherwise affect other subsytem(s)
+of the Tcl application in an unpredictable manner. The command 
+returns empty result but may trigger Tcl error with the message
+&quot;target thread died&quot; in some situations.
+
+<br><br>
+<dt><a name="8"><b class='cmd'>thread::names</b> </a><dd>
+
+
+This command returns a list of thread IDs. These are only for
+threads that have been created via <b class='cmd'>thread::create</b> command.
+If your application creates other threads at the C level, they
+are not reported by this command.
+
+
+<br><br>
+<dt><a name="9"><b class='cmd'>thread::exists</b> <i class='arg'>id</i></a><dd>
+
+
+Returns true (1) if thread given by the <i class='arg'>id</i> parameter exists, 
+false (0) otherwise. This applies only for threads that have
+been created via <b class='cmd'>thread::create</b> command.
+
+
+<br><br>
+<dt><a name="10"><b class='cmd'>thread::send</b> ?-async? ?-head? <i class='arg'>id</i> <i class='arg'>script</i> ?varname?</a><dd>
+
+
+This command passes a <i class='arg'>script</i> to another thread and, optionally,
+waits for the result. If the <strong>-async</strong> flag is specified, the 
+command does not wait for the result and it returns empty string.
+The target thread must enter it's event loop in order to receive 
+scripts sent via this command. This is done by default for threads 
+created without a startup script. Threads can enter the event loop 
+explicitly by calling <b class='cmd'>thread::wait</b> or any other relevant Tcl/Tk
+command, like <b class='cmd'>update</b>, <b class='cmd'>vwait</b>, etc. 
+
+<br><br>
+
+Optional <strong>varname</strong> specifies name of the variable to store
+the result of the <i class='arg'>script</i>. Without the <strong>-async</strong> flag,
+the command returns the evaluation code, similarily to the standard 
+Tcl <b class='cmd'>catch</b> command. If, however, the <strong>-async</strong> flag is
+specified, the command returns immediately and caller can later 
+<b class='cmd'>vwait</b> on ?varname? to get the result of the passed <i class='arg'>script</i>
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    set t1 [thread::create]
+    set t2 [thread::create] 
+    thread::send -async $t1 &quot;set a 1&quot; result
+    thread::send -async $t2 &quot;set b 2&quot; result 
+    for {set i 0} {$i &lt; 2} {incr i} {
+        vwait result
+    }
+</pre></td></tr></table></p>
+
+In the above example, two threads were fed work and both of them were
+instructed to signalize the same variable &quot;result&quot; in the calling thread.
+The caller entered the event loop twice to get both results. Note, 
+however, that the order of the received results may vary, depending on 
+the current system load, type of work done, etc, etc.
+
+<br><br>
+
+Many threads can simultaneously send scripts to the target thread for 
+execution. All of them are entered into the event queue of the target 
+thread and executed on the FIFO basis, intermingled with optional other
+events pending in the event queue of the target thread.
+Using the optional ?-head? switch, scripts posted to the thread's
+event queue can be placed on the head, instead on the tail of the queue,
+thus being executed in the LIFO fashion.
+
+
+<br><br>
+<dt><a name="11"><b class='cmd'>thread::broadcast</b> <i class='arg'>id</i> <i class='arg'>script</i></a><dd>
+
+
+This command passes a <i class='arg'>script</i> to all threads created by the
+package for execution. It does not wait for response from any of
+the threads.
+
+<br><br>
+<dt><a name="12"><b class='cmd'>thread::wait</b> </a><dd>
+
+
+This enters the event loop so a thread can receive messages from 
+the <b class='cmd'>thread::send</b> command. This command should only be used
+within the script passed to the <b class='cmd'>thread::create</b>. It should
+be the very last command in the script. If this is not the case,
+the exiting thread will continue executing the script lines pass
+the <b class='cmd'>thread::wait</b> which is usually not what you want and/or
+expect.
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    set t1 [thread::create {
+        #
+        # Do some initialization work here
+        #
+        thread::wait ; # Enter the event loop
+    }]
+</pre></td></tr></table></p>
+
+<br><br>
+<dt><a name="13"><b class='cmd'>thread::eval</b> ?-lock mutex? <i class='arg'>arg</i> ?arg ...?</a><dd>
+
+
+This command concatenates passed arguments and evaluates the 
+resulting script under the mutex protection. If no mutex is
+specified by using the ?-lock mutex? optional argument,
+the internal static mutex is used.
+
+
+<br><br>
+<dt><a name="14"><b class='cmd'>thread::join</b> <i class='arg'>id</i></a><dd>
+
+
+This command waits for the thread with ID <i class='arg'>id</i> to exit and
+then returns it's exit code. Errors will be returned for threads
+which are not joinable or already waited upon by another thread.
+Upon the join the handle of the thread has gone out of scope and
+should not be used any more.
+
+
+<br><br>
+<dt><a name="15"><b class='cmd'>thread::configure</b> <i class='arg'>id</i> ?option? ?value? ?...?</a><dd>
+
+
+This command configures various low-level aspects of the thread with
+ID <i class='arg'>id</i> in the similar way as the standard Tcl command 
+<b class='cmd'>fconfigure</b> configures some Tcl channel options. Options currently
+supported are: <strong>-eventmark</strong> and <strong>-unwindonerror</strong>.
+
+<br><br>
+
+The <strong>-eventmark</strong> option, when set, limits the number of 
+asynchronously posted scripts to the thread event loop. 
+The <b class='cmd'>thread::send -async</b> command will block until the number
+of pending scripts in the event loop does not drop below the value
+configured with <strong>-eventmark</strong>. Default value for the 
+<strong>-eventmark</strong> is 0 (zero) which effectively disables the checking,
+i.e. allows for unlimited number of posted scripts.
+
+<br><br>
+
+The <strong>-unwindonerror</strong> option, when set, causes the 
+target thread to unwind if the result of the script processing 
+resulted in error. Default value for the <strong>-unwindonerror</strong>
+is 0 (false), i.e. thread continues to process scripts after one
+of the posted scripts fails.
+
+
+<br><br>
+<dt><a name="16"><b class='cmd'>thread::transfer</b> <i class='arg'>id</i> <i class='arg'>channel</i></a><dd>
+
+
+This moves the specified <i class='arg'>channel</i> from the current thread 
+and interpreter to the main interpreter of the thread with the 
+given <i class='arg'>id</i>. After the move the current interpreter has no
+access to the channel any more, but the main interpreter of the
+target thread will be able to use it from now on.
+The command waits until the other thread has incorporated the
+channel. Because of this it is possible to deadlock the 
+participating threads by commanding the other through a 
+synchronous <b class='cmd'>thread::send</b> to transfer a channel to us.
+This easily extends into longer loops of threads waiting for 
+each other. Other restrictions: the channel in question must 
+not be shared among multiple interpreters running in the 
+sending thread. This automatically excludes the special channels
+for standard input, output and error.
+
+<br><br>
+
+Due to the internal Tcl core implementation and the restriction on 
+transferring shared channels, one has to take extra measures when
+transferring socket channels created by accepting the connection
+out of the <b class='cmd'>socket</b> commands callback procedures:
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    socket -server _Accept 2200
+    proc _Accept {s ipaddr port} {
+        after idle [list Accept $s $ipaddr $port]
+    }
+    proc Accept {s ipaddr port} {
+        set tid [thread::create]
+        thread::transfer $tid $s
+    }
+</pre></td></tr></table></p>
+
+<br><br>
+<dt><a name="17"><b class='cmd'>thread::detach</b> <i class='arg'>channel</i></a><dd>
+
+
+This detaches the specified <i class='arg'>channel</i> from the current thread and 
+interpreter. After that, the current interpreter has no access to the
+channel any more. The channel is in the parked state until some other
+(or the same) thread attaches the channel again with <b class='cmd'>thread::attach</b>.
+Restrictions: same as for transferring shared channels with the
+<b class='cmd'>thread::transfer</b> command.
+
+<br><br>
+<dt><a name="18"><b class='cmd'>thread::attach</b> <i class='arg'>channel</i></a><dd>
+
+
+This attaches the previously detached <i class='arg'>channel</i> in the
+current thread/interpreter. For already existing channels, 
+the command does nothing, i.e. it is not an error to attach the
+same channel more than once. The first operation will actualy
+perform the operation, while all subsequent operation will just
+do nothing. Command throws error if the <i class='arg'>channel</i> cannot be
+found in the list of detached channels and/or in the current
+interpreter.
+
+<br><br>
+<dt><a name="19"><b class='cmd'>thread::mutex</b> </a><dd>
+
+
+Mutexes are most common thread synchronization primitives. 
+They are used to synchronize access from two or more threads to one or 
+more shared resources. This command provides script-level access to 
+exclusive and/or recursive mutexes. Exclusive mutexes can be locked 
+only once by one thread, while recursive mutexes can be locked many 
+times by the same thread. For recursive mutexes, number of lock and 
+unlock operations must match, otherwise, the mutex will never be 
+released, which would lead to various deadlock situations.
+<br><br>
+Care has to be taken when using mutexes in an multithreading program.
+Improper use of mutexes may lead to various deadlock situations, 
+especially when using exclusive mutexes.
+
+<br><br>
+
+The <b class='cmd'>thread::mutex</b> command supports following subcommands and options:
+
+<br><br>
+<dl>
+
+<dt><a name="20"><b class='cmd'>thread::mutex</b> <strong>create</strong> ?-recursive?</a><dd>
+
+
+Creates the mutex and returns it's opaque handle. This handle
+should be used for any future reference to the newly created mutex.
+If no optional ?-recursive? argument was specified, the command
+creates the exclusive mutex. With the ?-recursive? argument,
+the command creates a recursive mutex.
+
+<br><br>
+<dt><a name="21"><b class='cmd'>thread::mutex</b> <strong>destroy</strong> <i class='arg'>mutex</i></a><dd>
+
+
+Destroys the <i class='arg'>mutex</i>. Mutex should be in unlocked state before
+the destroy attempt. If the mutex is locked, the command will throw 
+Tcl error. 
+
+<br><br>
+<dt><a name="22"><b class='cmd'>thread::mutex</b> <strong>lock</strong> <i class='arg'>mutex</i></a><dd>
+
+
+Locks the <i class='arg'>mutex</i>. Locking the exclusive mutex may throw Tcl 
+error if on attempt to lock the same mutex twice from the same
+thread. If your program logic forces you to lock the same mutex 
+twice or more from the same thread (this may happen in recursive 
+procedure invocations) you should consider using the recursive mutexes. 
+
+<br><br>
+<dt><a name="23"><b class='cmd'>thread::mutex</b> <strong>unlock</strong> <i class='arg'>mutex</i></a><dd>
+
+
+Unlocks the <i class='arg'>mutex</i> so some other thread may lock it again.
+Attempt to unlock the already unlocked mutex will throw Tcl error.
+
+</dl>
+
+<br><br>
+
+<dt><a name="24"><b class='cmd'>thread::rwmutex</b> </a><dd>
+
+
+This command creates many-readers/single-writer mutexes. Reader/writer
+mutexes allow you to serialize access to a shared resource more optimally. 
+In situations where a shared resource gets mostly read and seldom modified, 
+you might gain some performace by using reader/writer mutexes instead of 
+exclusive or recursive mutexes. 
+<br><br>
+For reading the resource, thread should obtain a read lock on the resource.
+Read lock is non-exclusive, meaning that more than one thread can
+obtain a read lock to the same resource, without waiting on other readers.
+For changing the resource, however, a thread must obtain a exclusive
+write lock. This lock effectively blocks all threads from gaining the
+read-lock while the resource is been modified by the writer thread.
+Only after the write lock has been released, the resource may be read-locked
+again. 
+
+<br><br>
+
+The <b class='cmd'>thread::rwmutex</b> command supports following subcommands and options:
+
+<br><br>
+<dl>
+
+<dt><a name="25"><b class='cmd'>thread::rwmutex</b> <strong>create</strong></a><dd>
+
+
+Creates the reader/writer mutex and returns it's opaque handle.
+This handle should be used for any future reference to the newly 
+created mutex.
+
+<br><br>
+<dt><a name="26"><b class='cmd'>thread::rwmutex</b> <strong>destroy</strong> <i class='arg'>mutex</i></a><dd>
+
+
+Destroys the reader/writer <i class='arg'>mutex</i>. If the mutex is already locked,
+attempt to destroy it will throw Tcl error.
+
+<br><br>
+<dt><a name="27"><b class='cmd'>thread::rwmutex</b> <strong>rlock</strong> <i class='arg'>mutex</i></a><dd>
+
+
+Locks the <i class='arg'>mutex</i> for reading. More than one thread may read-lock
+the same <i class='arg'>mutex</i> at the same time.
+
+<br><br>
+<dt><a name="28"><b class='cmd'>thread::rwmutex</b> <strong>wlock</strong> <i class='arg'>mutex</i></a><dd>
+
+
+Locks the <i class='arg'>mutex</i> for writing. Only one thread may write-lock
+the same <i class='arg'>mutex</i> at the same time. Attempt to write-lock same
+<i class='arg'>mutex</i> twice from the same thread will throw Tcl error.
+
+<br><br>
+<dt><a name="29"><b class='cmd'>thread::rwmutex</b> <strong>unlock</strong> <i class='arg'>mutex</i></a><dd>
+
+
+Unlocks the <i class='arg'>mutex</i> so some other thread may lock it again.
+Attempt to unlock already unlocked <i class='arg'>mutex</i> will throw Tcl error.
+
+</dl>
+
+<br><br>
+
+<dt><a name="30"><b class='cmd'>thread::cond</b> </a><dd>
+
+
+This command provides script-level access to condition variables.
+A condition variable creates a safe environment for the program 
+to test some condition, sleep on it when false and be awakened 
+when it might have become true. A condition variable is always 
+used in the conjuction with an exclusive mutex. If you attempt
+to use other type of mutex in conjuction with the condition 
+variable, a Tcl error will be thrown.
+
+<br><br>
+
+The command supports following subcommands and options:
+
+<br><br>
+<dl>
+
+<dt><a name="31"><b class='cmd'>thread::cond</b> <strong>create</strong></a><dd>
+
+
+Creates the condition variable and returns it's opaque handle.
+This handle should be used for any future reference to newly 
+created condition variable.
+
+<br><br>
+<dt><a name="32"><b class='cmd'>thread::cond</b> <strong>destroy</strong> <i class='arg'>cond</i></a><dd>
+
+
+Destroys condition variable <i class='arg'>cond</i>. Extreme care has to be taken 
+that nobody is using (i.e. waiting on) the condition variable, 
+otherwise unexpected errors may happen.
+
+<br><br>
+<dt><a name="33"><b class='cmd'>thread::cond</b> <strong>notify</strong> <i class='arg'>cond</i></a><dd>
+
+
+Wakes up all threads waiting on the condition variable <i class='arg'>cond</i>.
+
+<br><br>
+<dt><a name="34"><b class='cmd'>thread::cond</b> <strong>wait</strong> <i class='arg'>cond</i> <i class='arg'>mutex</i> ?ms?</a><dd>
+
+
+This command is used to suspend program execution until the condition
+variable <i class='arg'>cond</i> has been signalled or the optional timer has expired.
+The exclusive <i class='arg'>mutex</i> must be locked by the calling thread on entrance
+to this command. If the mutex is not locked, Tcl error is thrown.
+While waiting on the <i class='arg'>cond</i>, the command releases <i class='arg'>mutex</i>. 
+Before returning to the calling thread, the command re-acquires the 
+<i class='arg'>mutex</i> again. Unlocking the <i class='arg'>mutex</i> and waiting on the 
+condition variable <i class='arg'>cond</i> is done atomically.
+
+<br><br>
+
+The <strong>ms</strong> command option, if given, must be an integer specifying
+time interval in milliseconds the command waits to be signalled. 
+Otherwise the command waits on condition notify forever.
+
+<br><br>
+
+In multithreading programs, there are many situations where a thread has
+to wait for some event to happen until it is allowed to proceed.
+This is usually accomplished by repeatedly testing a condition under the
+mutex protection and waiting on the condition variable until the condition
+evaluates to true:
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    set mutex [thread::mutex create]
+    set cond  [thread::cond  create]
+
+    thread::mutex lock $mutex
+    while {&lt;some_condition_is_true&gt;} {
+        thread::cond wait $cond $mutex
+    }
+    # Do some work under mutex protection
+    thread::mutex unlock $mutex
+</pre></td></tr></table></p>
+
+Repeated testing of the condition is needed since the condition variable 
+may get signalled without the condition being actually changed (spurious 
+thread wake-ups, for example).
+
+</dl>
+
+</dl>
+
+<h2><a name="discussion">DISCUSSION</a></h2>
+<p>
+The fundamental threading model in Tcl is that there can be one or
+more Tcl interpreters per thread, but each Tcl interpreter should
+only be used by a single thread which created it.
+A &quot;shared memory&quot; abstraction is awkward to provide in Tcl because
+Tcl makes assumptions about variable and data ownership. Therefore
+this extension supports a simple form of threading where the main
+thread can manage several background, or &quot;worker&quot; threads. 
+For example, an event-driven server can pass requests to worker 
+threads, and then await responses from worker threads or new client
+requests. Everything goes through the common Tcl event loop, so 
+message passing between threads works naturally with event-driven I/O, 
+<b class='cmd'>vwait</b> on variables, and so forth. For the transfer of bulk
+information it is possible to move channels between the threads.
+
+<p>
+
+For advanced multithreading scripts, script-level access to two
+basic synchronization primitives, mutex and condition variables,
+is also supported.
+
+
+
+
+
+<h2><a name="see_also">SEE ALSO</a></h2>
+<p>
+<a href="http://www.tcl.tk/doc/howto/thread_model.html">http://www.tcl.tk/doc/howto/thread_model.html</a>, tpool, tsv, ttrace
+<h2><a name="keywords">KEYWORDS</a></h2>
+<p>
+events, message passing, mutex, synchronization, thread
+</body></html>
+
diff --git a/8.x/thread/doc/html/tpool.html b/8.x/thread/doc/html/tpool.html
new file mode 100644 (file)
index 0000000..8146496
--- /dev/null
@@ -0,0 +1,276 @@
+<! -- -*- tcl -*- doctools manpage
+   -->
+<html><head>
+<title>tpool - Tcl Threading </title>
+</head>
+<! -- Generated from file '' by tcllib/doctools with format 'html'
+   -->
+<! -- CVS: $Id: tpool.html,v 1.16 2009/05/04 21:56:51 ferrieux Exp $ tpool.n
+   -->
+
+<body>
+<h1> tpool(n) 2.6  &quot;Tcl Threading&quot;</h1>
+<h2><a name="name">NAME</a></h2>
+<p>
+<p> tpool - 
+    Part of the Tcl threading extension implementing pools of worker threads.
+
+
+
+
+
+
+<h2><a name="table_of_contents">TABLE OF CONTENTS</a></h2>
+<p>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#table_of_contents">TABLE OF CONTENTS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#synopsis">SYNOPSIS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#description">DESCRIPTION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#commands">COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#discussion">DISCUSSION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#see_also">SEE ALSO</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#keywords">KEYWORDS</a><br>
+<h2><a name="synopsis">SYNOPSIS</a></h2>
+<p>
+package require <b>Tcl 8.4</b><br>
+package require <b>Thread ?2.6?</b><br>
+<br><table border=1 width=100% cellspacing=0 cellpadding=0><tr            bgcolor=lightyellow><td bgcolor=lightyellow><table 0 width=100% cellspacing=0 cellpadding=0><tr valign=top ><td ><a href="#1"><b class='cmd'>tpool::create</b> ?options?</a></td></tr>
+<tr valign=top ><td ><a href="#2"><b class='cmd'>tpool::names</b> </a></td></tr>
+<tr valign=top ><td ><a href="#3"><b class='cmd'>tpool::post</b> ?-detached? ?-nowait? <i class='arg'>tpool</i> <i class='arg'>script</i></a></td></tr>
+<tr valign=top ><td ><a href="#4"><b class='cmd'>tpool::wait</b> <i class='arg'>tpool</i> <i class='arg'>joblist</i> ?varname?</a></td></tr>
+<tr valign=top ><td ><a href="#5"><b class='cmd'>tpool::cancel</b> <i class='arg'>tpool</i> <i class='arg'>joblist</i> ?varname?</a></td></tr>
+<tr valign=top ><td ><a href="#6"><b class='cmd'>tpool::get</b> <i class='arg'>tpool</i> <i class='arg'>job</i></a></td></tr>
+<tr valign=top ><td ><a href="#7"><b class='cmd'>tpool::preserve</b> <i class='arg'>tpool</i></a></td></tr>
+<tr valign=top ><td ><a href="#8"><b class='cmd'>tpool::release</b> <i class='arg'>tpool</i></a></td></tr>
+</table></td></tr></table>
+<h2><a name="description">DESCRIPTION</a></h2>
+<p>
+This package creates and manages pools of worker threads. It allows you
+to post jobs to worker threads and wait for their completion. The 
+threadpool implementation is Tcl event-loop aware. That means that any
+time a caller is forced to wait for an event (job being completed or 
+a worker thread becoming idle or initialized), the implementation will
+enter the event loop and allow for servicing of other pending file or
+timer (or any other supported) events.
+
+<h2><a name="commands">COMMANDS</a></h2>
+<p>
+
+<dl>
+
+<dt><a name="1"><b class='cmd'>tpool::create</b> ?options?</a><dd>
+
+
+This command creates new threadpool. It accepts several options as
+key-value pairs. Options are used to tune some threadpool parameters.
+The command returns the ID of the newly created threadpool.
+<br><br>
+Following options are supported:
+
+<br><br>
+<dl>
+
+<dt>-minworkers number<dd>
+Minimum number of worker threads needed for this threadpool instance.
+During threadpool creation, the implementation will create somany
+worker threads upfront and will keep at least number of them alive
+during the lifetime of the threadpool instance.
+Default value of this parameter is 0 (zero). which means that a newly
+threadpool will have no worker threads initialy. All worker threads
+will be started on demand by callers running <b class='cmd'>tpool::post</b> command
+and posting jobs to the job queue.
+
+<br><br>
+<dt>-maxworkers number<dd>
+Maximum number of worker threads allowed for this threadpool instance.
+If a new job is pending and there are no idle worker threads available,
+the implementation will try to create new worker thread. If the number
+of available worker threads is lower than the given number,
+new worker thread will start. The caller will automatically enter the
+event loop and wait until the worker thread has initialized. If. however,
+the number of available worker threads is equal to the given number, 
+the caller will enter the event loop and wait for the first worker thread
+to get idle, thus ready to run the job.
+Default value of this parameter is 4 (four), which means that the 
+threadpool instance will allow maximum of 4 worker threads running jobs
+or being idle waiting for new jobs to get posted to the job queue.
+
+
+<br><br>
+<dt>-idletime seconds<dd>
+Time in seconds an idle worker thread waits for the job to get posted
+to the job queue. If no job arrives during this interval and the time
+expires, the worker thread will check the number of currently available
+worker threads and if the number is higher than the number set by the
+<strong>minthreads</strong> option, it will exit. 
+If an <strong>exitscript</strong> has been defined, the exiting worker thread 
+will first run the script and then exit. Errors from the exit script, 
+if any, are ignored.
+<br><br>
+The idle worker thread is not servicing the event loop. If you, however,
+put the worker thread into the event loop, by evaluating the
+<b class='cmd'>vwait</b> or other related Tcl commands, the worker thread 
+will not be in the idle state, hence the idle timer will not be 
+taken into account.
+Default value for this option is unspecified, hence, the Tcl interpreter
+of the worker thread will contain just the initial set of Tcl commands.
+
+<br><br>
+<dt>-initcmd script<dd>
+
+Sets a Tcl script used to initialize new worker thread. This is usually
+used to load packages and commands in the worker, set default variables,
+create namespaces, and such. If the passed script runs into a Tcl error, 
+the worker will not be created and the initiating command (either the
+<b class='cmd'>tpool::create</b> or <b class='cmd'>tpool::post</b>) will throw error.
+Default value for this option is unspecified, hence, the Tcl interpreter of 
+the worker thread will contain just the initial set of Tcl commands.
+
+<br><br>
+<dt>-exitcmd script<dd>
+
+Sets a Tcl script run when the idle worker thread exits. This is normaly
+used to cleanup the state of the worker thread, release reserved resources,
+cleanup memory and such.
+Default value for this option is unspecified, thus no Tcl script will run
+on the worker thread exit.
+
+</dl>
+
+<br><br> 
+
+<dt><a name="2"><b class='cmd'>tpool::names</b> </a><dd>
+
+
+This command returns a list of IDs of threadpools created with the 
+<b class='cmd'>tpool::create</b> command. If no threadpools were found, the
+command will return empty list.
+
+<br><br>
+<dt><a name="3"><b class='cmd'>tpool::post</b> ?-detached? ?-nowait? <i class='arg'>tpool</i> <i class='arg'>script</i></a><dd>
+
+
+This command sends a <i class='arg'>script</i> to the target <i class='arg'>tpool</i> threadpool
+for execution. The script will be executed in the first available idle 
+worker thread. If there are no idle worker threads available, the command
+will create new one, enter the event loop and service events until the 
+newly created thread is initialized. If the current number of worker 
+threads is equal to the maximum number of worker threads, as defined 
+during the threadpool creation, the command will enter the event loop and
+service events while waiting for one of the worker threads to become idle.
+If the optional ?-nowait? argument is given, the command will not wait
+for one idle worker. It will just place the job in the pool's job queue
+and return immediately.
+<br><br>
+The command returns the ID of the posted job. This ID is used for subsequent
+<b class='cmd'>tpool::wait</b>, <b class='cmd'>tpool::get</b> and <b class='cmd'>tpool::cancel</b> commands to wait
+for and retrieve result of the posted script, or cancel the posted job
+respectively. If the optional ?-detached? argument is specified, the 
+command will post a detached job. A detached job can not be cancelled or 
+waited upon and is not identified by the job ID.
+<br><br>
+If the threadpool <i class='arg'>tpool</i> is not found in the list of active
+thread pools, the command will throw error. The error will also be triggered
+if the newly created worker thread fails to initialize.
+
+<br><br>
+<dt><a name="4"><b class='cmd'>tpool::wait</b> <i class='arg'>tpool</i> <i class='arg'>joblist</i> ?varname?</a><dd>
+
+
+This command waits for one or many jobs, whose job IDs are given in the
+<i class='arg'>joblist</i> to get processed by the worker thread(s). If none of the
+specified jobs are ready, the command will enter the event loop, service
+events and wait for the first job to get ready.
+<br><br>
+The command returns the list of completed job IDs. If the optional variable
+?varname? is given, it will be set to the list of jobs in the 
+<i class='arg'>joblist</i> which are still pending. If the threadpool <i class='arg'>tpool</i> 
+is not found in the list of active thread pools, the command will throw error.
+
+<br><br>
+<dt><a name="5"><b class='cmd'>tpool::cancel</b> <i class='arg'>tpool</i> <i class='arg'>joblist</i> ?varname?</a><dd>
+
+
+This command cancels the previously posted jobs given by the <i class='arg'>joblist</i>
+to the pool <i class='arg'>tpool</i>. Job cancellation succeeds only for job still
+waiting to be processed. If the job is already being executed by one of
+the worker threads, the job will not be cancelled.
+The command returns the list of cancelled job IDs. If the optional variable
+?varname? is given, it will be set to the list of jobs in the 
+<i class='arg'>joblist</i> which were not cancelled. If the threadpool <i class='arg'>tpool</i> 
+is not found in the list of active thread pools, the command will throw error.
+
+<br><br>
+<dt><a name="6"><b class='cmd'>tpool::get</b> <i class='arg'>tpool</i> <i class='arg'>job</i></a><dd>
+
+
+This command retrieves the result of the previously posted <i class='arg'>job</i>.
+Only results of jobs waited upon with the <b class='cmd'>tpool::wait</b> command
+can be retrieved. If the execution of the script resulted in error, 
+the command will throw the error and update the <strong>errorInfo</strong> and
+<strong>errorCode</strong> variables correspondingly. If the pool <i class='arg'>tpool</i>
+is not found in the list of threadpools, the command will throw error.
+If the job <i class='arg'>job</i> is not ready for retrieval, because it is currently
+being executed by the worker thread, the command will throw error.
+
+<br><br>
+<dt><a name="7"><b class='cmd'>tpool::preserve</b> <i class='arg'>tpool</i></a><dd>
+
+
+Each call to this command increments the reference counter of the
+threadpool <i class='arg'>tpool</i> by one (1). Command returns the value of the 
+reference counter after the increment.
+By incrementing the reference counter, the caller signalizes that
+he/she wishes to use the resource for a longer period of time.
+
+<br><br>
+<dt><a name="8"><b class='cmd'>tpool::release</b> <i class='arg'>tpool</i></a><dd>
+
+
+Each call to this command decrements the reference counter of the 
+threadpool <i class='arg'>tpool</i> by one (1).Command returns the value of the 
+reference counter after the decrement. 
+When the reference counter reaches zero (0), the threadpool <i class='arg'>tpool</i>
+is marked for termination. You should not reference the threadpool 
+after the <b class='cmd'>tpool::release</b> command returns zero. The <i class='arg'>tpool</i>
+handle goes out of scope and should not be used any more. Any following
+reference to the same threadpool handle will result in Tcl error.
+
+</dl>
+
+
+<h2><a name="discussion">DISCUSSION</a></h2>
+<p>
+
+Threadpool is one of the most common threading paradigm when it comes
+to server applications handling a large number of relatively small tasks.
+A very simplistic model for building a server application would be to 
+create a new thread each time a request arrives and service the request 
+in the new thread. One of the disadvantages of this approach is that 
+the overhead of creating a new thread for each request is significant; 
+a server that created a new thread for each request would spend more time
+and consume more system resources in creating and destroying threads than
+in processing actual user requests. In addition to the overhead of 
+creating and destroying threads, active threads consume system resources.
+Creating too many threads can cause the system to run out of memory or
+trash due to excessive memory consumption.
+<p>
+A thread pool offers a solution to both the problem of thread life-cycle 
+overhead and the problem of resource trashing. By reusing threads for 
+multiple tasks, the thread-creation overhead is spread over many tasks.
+As a bonus, because the thread already exists when a request arrives, 
+the delay introduced by thread creation is eliminated. Thus, the request
+can be serviced immediately. Furthermore, by properly tuning the number 
+of threads in the thread pool, resource thrashing may also be eliminated
+by forcing any request to wait until a thread is available to process it.
+
+
+
+
+
+<h2><a name="see_also">SEE ALSO</a></h2>
+<p>
+thread, tsv, ttrace
+<h2><a name="keywords">KEYWORDS</a></h2>
+<p>
+thread, threadpool
+</body></html>
+
diff --git a/8.x/thread/doc/html/tsv.html b/8.x/thread/doc/html/tsv.html
new file mode 100644 (file)
index 0000000..5d398a4
--- /dev/null
@@ -0,0 +1,473 @@
+<! -- -*- tcl -*- doctools manpage
+   -->
+<html><head>
+<title>tsv - Tcl Threading </title>
+</head>
+<! -- Generated from file '' by tcllib/doctools with format 'html'
+   -->
+<! -- CVS: $Id: tsv.html,v 1.16 2006/10/07 09:19:39 vasiljevic Exp $ tsv.n
+   -->
+
+<body>
+<h1> tsv(n) 2.6  &quot;Tcl Threading&quot;</h1>
+<h2><a name="name">NAME</a></h2>
+<p>
+<p> tsv - 
+    Part of the Tcl threading extension allowing script level
+    manipulation of data shared between threads.
+
+
+
+
+
+
+<h2><a name="table_of_contents">TABLE OF CONTENTS</a></h2>
+<p>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#table_of_contents">TABLE OF CONTENTS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#synopsis">SYNOPSIS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#description">DESCRIPTION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#element_commands">ELEMENT COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#list_commands">LIST COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#array_commands">ARRAY COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#keyed_list_commands">KEYED LIST COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#discussion">DISCUSSION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#credits">CREDITS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#see_also">SEE ALSO</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#keywords">KEYWORDS</a><br>
+<h2><a name="synopsis">SYNOPSIS</a></h2>
+<p>
+package require <b>Tcl 8.4</b><br>
+package require <b>Thread ?2.6?</b><br>
+<br><table border=1 width=100% cellspacing=0 cellpadding=0><tr            bgcolor=lightyellow><td bgcolor=lightyellow><table 0 width=100% cellspacing=0 cellpadding=0><tr valign=top ><td ><a href="#1"><b class='cmd'>tsv::names</b> ?pattern?</a></td></tr>
+<tr valign=top ><td ><a href="#2"><b class='cmd'>tsv::object</b> <i class='arg'>varname</i> <i class='arg'>element</i></a></td></tr>
+<tr valign=top ><td ><a href="#3"><b class='cmd'>tsv::set</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?value?</a></td></tr>
+<tr valign=top ><td ><a href="#4"><b class='cmd'>tsv::get</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?namedvar?</a></td></tr>
+<tr valign=top ><td ><a href="#5"><b class='cmd'>tsv::unset</b> <i class='arg'>varname</i> ?element?</a></td></tr>
+<tr valign=top ><td ><a href="#6"><b class='cmd'>tsv::exists</b> <i class='arg'>varname</i> <i class='arg'>element</i></a></td></tr>
+<tr valign=top ><td ><a href="#7"><b class='cmd'>tsv::pop</b> <i class='arg'>varname</i> <i class='arg'>element</i></a></td></tr>
+<tr valign=top ><td ><a href="#8"><b class='cmd'>tsv::move</b> <i class='arg'>varname</i> <i class='arg'>oldname</i> <i class='arg'>newname</i></a></td></tr>
+<tr valign=top ><td ><a href="#9"><b class='cmd'>tsv::incr</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?count?</a></td></tr>
+<tr valign=top ><td ><a href="#10"><b class='cmd'>tsv::append</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>value</i> ?value ...?</a></td></tr>
+<tr valign=top ><td ><a href="#11"><b class='cmd'>tsv::lock</b> <i class='arg'>varname</i> <i class='arg'>arg</i> ?arg ...?</a></td></tr>
+<tr valign=top ><td ><a href="#12"><b class='cmd'>tsv::lappend</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>value</i> ?value ...?</a></td></tr>
+<tr valign=top ><td ><a href="#13"><b class='cmd'>tsv::linsert</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>index</i> <i class='arg'>value</i> ?value ...?</a></td></tr>
+<tr valign=top ><td ><a href="#14"><b class='cmd'>tsv::lreplace</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>first</i> <i class='arg'>last</i> ?value ...?</a></td></tr>
+<tr valign=top ><td ><a href="#15"><b class='cmd'>tsv::llength</b> <i class='arg'>varname</i> <i class='arg'>element</i></a></td></tr>
+<tr valign=top ><td ><a href="#16"><b class='cmd'>tsv::lindex</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?index?</a></td></tr>
+<tr valign=top ><td ><a href="#17"><b class='cmd'>tsv::lrange</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>from</i> <i class='arg'>to</i></a></td></tr>
+<tr valign=top ><td ><a href="#18"><b class='cmd'>tsv::lsearch</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?options? <i class='arg'>pattern</i></a></td></tr>
+<tr valign=top ><td ><a href="#19"><b class='cmd'>tsv::lset</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>index</i> ?index ...? <i class='arg'>value</i></a></td></tr>
+<tr valign=top ><td ><a href="#20"><b class='cmd'>tsv::lpop</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?index?</a></td></tr>
+<tr valign=top ><td ><a href="#21"><b class='cmd'>tsv::lpush</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?index?</a></td></tr>
+<tr valign=top ><td ><a href="#22"><b class='cmd'>tsv::array set</b> <i class='arg'>varname</i> <i class='arg'>list</i></a></td></tr>
+<tr valign=top ><td ><a href="#23"><b class='cmd'>tsv::array get</b> <i class='arg'>varname</i> ?pattern?</a></td></tr>
+<tr valign=top ><td ><a href="#24"><b class='cmd'>tsv::array names</b> <i class='arg'>varname</i> ?pattern?</a></td></tr>
+<tr valign=top ><td ><a href="#25"><b class='cmd'>tsv::array size</b> <i class='arg'>varname</i></a></td></tr>
+<tr valign=top ><td ><a href="#26"><b class='cmd'>tsv::array reset</b> <i class='arg'>varname</i> <i class='arg'>list</i></a></td></tr>
+<tr valign=top ><td ><a href="#27"><b class='cmd'>tsv::array bind</b> <i class='arg'>varname</i> <i class='arg'>handle</i></a></td></tr>
+<tr valign=top ><td ><a href="#28"><b class='cmd'>tsv::array unbind</b> <i class='arg'>varname</i></a></td></tr>
+<tr valign=top ><td ><a href="#29"><b class='cmd'>tsv::array isbound</b> <i class='arg'>varname</i></a></td></tr>
+<tr valign=top ><td ><a href="#30"><b class='cmd'>tsv::keyldel</b> <i class='arg'>varname</i> <i class='arg'>keylist</i> <i class='arg'>key</i></a></td></tr>
+<tr valign=top ><td ><a href="#31"><b class='cmd'>tsv::keylget</b> <i class='arg'>varname</i> <i class='arg'>keylist</i> <i class='arg'>key</i> ?retvar?</a></td></tr>
+<tr valign=top ><td ><a href="#32"><b class='cmd'>tsv::keylkeys</b> <i class='arg'>varname</i> <i class='arg'>keylist</i> ?key?</a></td></tr>
+<tr valign=top ><td ><a href="#33"><b class='cmd'>tsv::keylset</b> <i class='arg'>varname</i> <i class='arg'>keylist</i> <i class='arg'>key</i> <i class='arg'>value</i> ?key value..?</a></td></tr>
+</table></td></tr></table>
+<h2><a name="description">DESCRIPTION</a></h2>
+<p>
+This section describes commands implementing thread shared variables.
+A thread shared variable is very similar to a Tcl array but in 
+contrast to a Tcl array it is created in shared memory and can
+be accessed from many threads at the same time. Important feature of
+thread shared variable is that each access to the variable is internaly
+protected by a mutex so script programmer does not have to take care 
+about locking the variable himself.
+<p>
+Thread shared variables are not bound to any thread explicitly. That 
+means that when a thread which created any of thread shared variables
+exits, the variable and associated memory is not unset/reclaimed.
+User has to explicitly unset the variable to reclaim the memory 
+consumed by the variable.
+
+<h2><a name="element_commands">ELEMENT COMMANDS</a></h2>
+<p>
+
+<dl>
+
+<dt><a name="1"><b class='cmd'>tsv::names</b> ?pattern?</a><dd>
+
+
+Returns names of shared variables matching optional ?pattern? 
+or all known variables if pattern is ommited.
+
+<br><br>
+<dt><a name="2"><b class='cmd'>tsv::object</b> <i class='arg'>varname</i> <i class='arg'>element</i></a><dd>
+
+
+Creates object accessor command for the <i class='arg'>element</i> in the
+shared variable <i class='arg'>varname</i>. Using this command, one can apply most 
+of the other shared variable commands as method functions of
+the element object command. The object command is automatically
+deleted when the element which this command is pointing to is unset.
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    % tsv::set foo bar &quot;A shared string&quot;
+    % set string [tsv::object foo bar]
+    % $string append &quot; appended&quot;
+    =&gt; A shared string appended
+</pre></td></tr></table></p>
+
+<br><br>
+<dt><a name="3"><b class='cmd'>tsv::set</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?value?</a><dd>
+
+
+Sets the value of the <i class='arg'>element</i> in the shared variable <i class='arg'>varname</i> 
+to <i class='arg'>value</i> and returns the value to caller. The <i class='arg'>value</i>
+may be ommited, in which case the command will return the current 
+value of the element. If the element cannot be found, error is triggered.
+
+<br><br>
+<dt><a name="4"><b class='cmd'>tsv::get</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?namedvar?</a><dd>
+
+
+Retrieves the value of the <i class='arg'>element</i> from the shared variable <i class='arg'>varname</i>.
+If the optional argument <i class='arg'>namedvar</i> is given, the value is
+stored in the named variable. Return value of the command depends 
+of the existence of the optional argument <i class='arg'>namedvar</i>.
+If the argument is ommited and the requested element cannot be found 
+in the shared array, the command triggers error. If, however, the 
+optional argument is given on the command line, the command returns 
+true (1) if the element is found or false (0) if the element is not found.
+
+<br><br>
+<dt><a name="5"><b class='cmd'>tsv::unset</b> <i class='arg'>varname</i> ?element?</a><dd>
+
+
+Unsets the <i class='arg'>element</i> from the shared variable <i class='arg'>varname</i>.
+If the optional element is not given, it deletes the variable.
+
+<br><br>
+<dt><a name="6"><b class='cmd'>tsv::exists</b> <i class='arg'>varname</i> <i class='arg'>element</i></a><dd>
+
+
+Checks wether the <i class='arg'>element</i> exists in the shared variable <i class='arg'>varname</i>
+and returns true (1) if it does or false (0) if it doesn't.
+
+<br><br>
+<dt><a name="7"><b class='cmd'>tsv::pop</b> <i class='arg'>varname</i> <i class='arg'>element</i></a><dd>
+
+
+Returns value of the <i class='arg'>element</i> in the shared variable <i class='arg'>varname</i>
+and unsets the element, all in one atomic operation.
+
+<br><br>
+<dt><a name="8"><b class='cmd'>tsv::move</b> <i class='arg'>varname</i> <i class='arg'>oldname</i> <i class='arg'>newname</i></a><dd>
+
+
+Renames the element <i class='arg'>oldname</i> to the <i class='arg'>newname</i> in the
+shared variable <i class='arg'>varname</i>. This effectively performs an get/unset/set
+sequence of operations but all in one atomic step.
+
+<br><br>
+<dt><a name="9"><b class='cmd'>tsv::incr</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?count?</a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>incr</b> command but increments the value
+of the <i class='arg'>element</i> in shared variaboe <i class='arg'>varname</i> instead of 
+the Tcl variable.
+
+<br><br>
+<dt><a name="10"><b class='cmd'>tsv::append</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>value</i> ?value ...?</a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>append</b> command but appends one or more
+values to the <i class='arg'>element</i> in shared variable <i class='arg'>varname</i> instead of the 
+Tcl variable.
+
+<br><br>
+<dt><a name="11"><b class='cmd'>tsv::lock</b> <i class='arg'>varname</i> <i class='arg'>arg</i> ?arg ...?</a><dd>
+
+
+This command concatenates passed arguments and evaluates the
+resulting script under the internal mutex protection. During the
+script evaluation, the entire shared variable is locked. For shared
+variable commands within the script, internal locking is disabled
+so no deadlock can occur. It is also allowed to unset the shared
+variable from within the script. The shared variable is automatically
+created if it did not exists at the time of the first lock operation.
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    % tsv::lock foo {
+        tsv::lappend foo bar 1
+        tsv::lappend foo bar 2
+        puts stderr [tsv::set foo bar]
+        tsv::unset foo
+    }
+</pre></td></tr></table></p>
+
+</dl>
+
+<h2><a name="list_commands">LIST COMMANDS</a></h2>
+<p>
+
+Those command are similar to the equivalently named Tcl command. The difference
+is that they operate on elements of shared arrays.
+
+<dl>
+
+<dt><a name="12"><b class='cmd'>tsv::lappend</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>value</i> ?value ...?</a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>lappend</b> command but appends one
+or more values to the <i class='arg'>element</i> in shared variable <i class='arg'>varname</i> 
+instead of the Tcl variable.
+
+<br><br>
+<dt><a name="13"><b class='cmd'>tsv::linsert</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>index</i> <i class='arg'>value</i> ?value ...?</a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>linsert</b> command but inserts one
+or more values at the <i class='arg'>index</i> list position in the 
+<i class='arg'>element</i> in the shared variable <i class='arg'>varname</i> instead of the Tcl variable.
+
+<br><br>
+<dt><a name="14"><b class='cmd'>tsv::lreplace</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>first</i> <i class='arg'>last</i> ?value ...?</a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>lreplace</b> command but replaces one
+or more values between the <i class='arg'>first</i> and <i class='arg'>last</i> position 
+in the <i class='arg'>element</i> of the shared variable <i class='arg'>varname</i> instead of 
+the Tcl variable.
+
+<br><br>
+<dt><a name="15"><b class='cmd'>tsv::llength</b> <i class='arg'>varname</i> <i class='arg'>element</i></a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>llength</b> command but returns length 
+of the <i class='arg'>element</i> in the shared variable <i class='arg'>varname</i> instead of the Tcl
+variable.
+
+<br><br>
+<dt><a name="16"><b class='cmd'>tsv::lindex</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?index?</a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>lindex</b> command but returns the value
+at the <i class='arg'>index</i> list position of the <i class='arg'>element</i> from
+the shared variable <i class='arg'>varname</i> instead of the Tcl variable.
+
+<br><br>
+<dt><a name="17"><b class='cmd'>tsv::lrange</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>from</i> <i class='arg'>to</i></a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>lrange</b> command but returns values
+between <i class='arg'>from</i> and <i class='arg'>to</i> list positions from the
+<i class='arg'>element</i> in the shared variable <i class='arg'>varname</i> instead of the Tcl variable.
+
+<br><br>
+<dt><a name="18"><b class='cmd'>tsv::lsearch</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?options? <i class='arg'>pattern</i></a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>lsearch</b> command but searches the <i class='arg'>element</i>
+in the shared variable <i class='arg'>varname</i> instead of the Tcl variable.
+
+<br><br>
+<dt><a name="19"><b class='cmd'>tsv::lset</b> <i class='arg'>varname</i> <i class='arg'>element</i> <i class='arg'>index</i> ?index ...? <i class='arg'>value</i></a><dd>
+
+
+Similar to standard Tcl <b class='cmd'>lset</b> command but sets the <i class='arg'>element</i>
+in the shared variable <i class='arg'>varname</i> instead of the Tcl variable.
+
+<br><br>
+<dt><a name="20"><b class='cmd'>tsv::lpop</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?index?</a><dd>
+
+
+Similar to the standard Tcl <b class='cmd'>lindex</b> command but in addition to
+returning, it also splices the value out of the <i class='arg'>element</i>
+from the shared variable <i class='arg'>varname</i> in one atomic operation. 
+In contrast to the Tcl <b class='cmd'>lindex</b> command, this command returns 
+no value to the caller.
+
+<br><br>
+<dt><a name="21"><b class='cmd'>tsv::lpush</b> <i class='arg'>varname</i> <i class='arg'>element</i> ?index?</a><dd>
+
+
+This command performes the opposite of the <b class='cmd'>tsv::lpop</b> command.
+As its counterpart, it returns no value to the caller.
+
+</dl>
+
+<h2><a name="array_commands">ARRAY COMMANDS</a></h2>
+<p>
+
+This command supports most of the options of the standard Tcl
+<b class='cmd'>array</b> command. In addition to those, it allows binding
+a shared variable to some persisten storage databases. Currently 
+the only persistent option supported is the famous GNU Gdbm 
+database. This option has to be selected during the package 
+compilation time. The implementation provides hooks for 
+defining other persistency layers, if needed.
+
+<dl>
+
+<dt><a name="22"><b class='cmd'>tsv::array set</b> <i class='arg'>varname</i> <i class='arg'>list</i></a><dd>
+
+
+Does the same as standard Tcl <b class='cmd'>array set</b>.
+
+<br><br>
+<dt><a name="23"><b class='cmd'>tsv::array get</b> <i class='arg'>varname</i> ?pattern?</a><dd>
+
+
+Does the same as standard Tcl <b class='cmd'>array get</b>.
+
+<br><br>
+<dt><a name="24"><b class='cmd'>tsv::array names</b> <i class='arg'>varname</i> ?pattern?</a><dd>
+
+
+Does the same as standard Tcl <b class='cmd'>array names</b>.
+
+<br><br>
+<dt><a name="25"><b class='cmd'>tsv::array size</b> <i class='arg'>varname</i></a><dd>
+
+
+Does the same as standard Tcl <b class='cmd'>array size</b>.
+
+<br><br>
+<dt><a name="26"><b class='cmd'>tsv::array reset</b> <i class='arg'>varname</i> <i class='arg'>list</i></a><dd>
+
+
+Does the same as standard Tcl <b class='cmd'>array set</b> but it clears
+the <i class='arg'>varname</i> and sets new values from the list atomically.
+
+<br><br>
+<dt><a name="27"><b class='cmd'>tsv::array bind</b> <i class='arg'>varname</i> <i class='arg'>handle</i></a><dd>
+
+Binds the <i class='arg'>varname</i> to the persistent storage <i class='arg'>handle</i>.
+The format of the <i class='arg'>handle</i> is &lt;handler&gt;:&lt;address&gt;. For the built-in
+GNU Gdbm persistence layer, the format of the handle is &quot;gdbm:&lt;path&gt;&quot;
+where &lt;path&gt; is the path to the Gdbm database file.
+
+<br><br>
+<dt><a name="28"><b class='cmd'>tsv::array unbind</b> <i class='arg'>varname</i></a><dd>
+
+Unbinds the shared <i class='arg'>array</i> from its bound persistent storage.
+
+<br><br>
+<dt><a name="29"><b class='cmd'>tsv::array isbound</b> <i class='arg'>varname</i></a><dd>
+
+Returns true (1) if the shared <i class='arg'>varname</i> is bound to some 
+persistent storage or zero (0) if not.
+
+
+</dl>
+
+<h2><a name="keyed_list_commands">KEYED LIST COMMANDS</a></h2>
+<p>
+
+Keyed list commands are borrowed from the TclX package. Keyed lists provide
+a structured data type built upon standard Tcl lists. This is a functionality
+similar to structs in the C programming language.
+<p>
+A keyed list is a list in which each element contains a key and value 
+pair. These element pairs are stored as lists themselves, where the key
+is the first element of the list, and the value is the second. The 
+key-value pairs are referred to as fields.  This is an example of a
+keyed list:
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    {{NAME  {Frank  Zappa}} {JOB {musician and composer}}}
+</pre></td></tr></table></p>
+
+Fields may contain subfields; `.' is the separator character. Subfields 
+are actually fields  where the value is another keyed list. Thus the 
+following list has the top level fields ID and NAME, and subfields 
+NAME.FIRST and NAME.LAST:
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+    {ID 106} {NAME {{FIRST Frank} {LAST Zappa}}}
+</pre></td></tr></table></p>
+
+There is no limit to the recursive depth of subfields,
+allowing one to build complex data structures. Keyed lists are constructed
+and accessed via a number of commands. All  keyed  list management 
+commands take the name of the variable containing the keyed list as an 
+argument (i.e. passed by reference), rather than passing the list directly.
+
+<dl>
+
+<dt><a name="30"><b class='cmd'>tsv::keyldel</b> <i class='arg'>varname</i> <i class='arg'>keylist</i> <i class='arg'>key</i></a><dd>
+
+
+Delete the field specified by <i class='arg'>key</i> from the keyed list <i class='arg'>keylist</i>
+in the shared variable <i class='arg'>varname</i>.
+This removes both the key and the value from the keyed list.
+
+<br><br>
+<dt><a name="31"><b class='cmd'>tsv::keylget</b> <i class='arg'>varname</i> <i class='arg'>keylist</i> <i class='arg'>key</i> ?retvar?</a><dd>
+
+
+Return the value associated with <i class='arg'>key</i> from the keyed list <i class='arg'>keylist</i>
+in the shared variable <i class='arg'>varname</i>.
+If the optional <i class='arg'>retvar</i> is not specified, then the value will be 
+returned as the result of the command. In this case, if key is not found 
+in the list, an error will result.
+<br><br>
+If <i class='arg'>retvar</i> is specified and <i class='arg'>key</i> is in the list, then the value 
+is returned in the variable <i class='arg'>retvar</i> and the command returns 1 if the
+key was present within the list. If <i class='arg'>key</i> isn't in the list, the 
+command will return 0, and <i class='arg'>retvar</i> will be left unchanged. If {} is
+specified for <i class='arg'>retvar</i>, the value is not returned, allowing the Tcl
+programmer to determine if a <i class='arg'>key</i> is present in a keyed list without
+setting a variable as a side-effect.
+
+<br><br>
+<dt><a name="32"><b class='cmd'>tsv::keylkeys</b> <i class='arg'>varname</i> <i class='arg'>keylist</i> ?key?</a><dd>
+
+Return  the a list of the keys in the keyed list <i class='arg'>keylist</i> in the 
+shared variable <i class='arg'>varname</i>. If <i class='arg'>key</i> is specified, then it is 
+the name of a key field who's subfield keys are to be retrieved.
+
+
+<br><br>
+<dt><a name="33"><b class='cmd'>tsv::keylset</b> <i class='arg'>varname</i> <i class='arg'>keylist</i> <i class='arg'>key</i> <i class='arg'>value</i> ?key value..?</a><dd>
+
+Set the value associated with <i class='arg'>key</i>, in the keyed list <i class='arg'>keylist</i>
+to <i class='arg'>value</i>. If the <i class='arg'>keylist</i> does not exists, it is created. 
+If <i class='arg'>key</i> is not currently in the list, it will be added. If it already
+exists, <i class='arg'>value</i> replaces the existing value. Multiple keywords and 
+values may be specified, if desired.
+
+</dl>
+
+
+<h2><a name="discussion">DISCUSSION</a></h2>
+<p>
+The current implementation of thread shared variables allows for easy and
+convenient access to data shared between different threads.
+Internally, the data is stored in Tcl objects and all package commands
+operate on internal data representation, thus minimizing shimmering and
+improving performance. Special care has been taken to assure that all 
+object data is properly locked and deep-copied when moving objects between
+threads.
+<p>
+Due to the internal design of the Tcl core, there is no provision of full 
+integration of shared variables within the Tcl syntax, unfortunately. All
+access to shared data must be performed with the supplied package commands.
+Also, variable traces are not supported. But even so, benefits of easy, 
+simple and safe shared data manipulation outweights imposed limitations.
+
+<h2><a name="credits">CREDITS</a></h2>
+<p>
+Thread shared variables are inspired by the nsv interface found in 
+AOLserver, a highly scalable Web server from America Online.
+
+
+
+
+
+<h2><a name="see_also">SEE ALSO</a></h2>
+<p>
+thread, tpool, ttrace
+<h2><a name="keywords">KEYWORDS</a></h2>
+<p>
+locking, synchronization, thread shared data, threads
+</body></html>
+
diff --git a/8.x/thread/doc/html/ttrace.html b/8.x/thread/doc/html/ttrace.html
new file mode 100644 (file)
index 0000000..08ba53d
--- /dev/null
@@ -0,0 +1,317 @@
+<! -- -*- tcl -*- doctools manpage
+   -->
+<html><head>
+<title>ttrace - Tcl Threading </title>
+</head>
+<! -- Generated from file '' by tcllib/doctools with format 'html'
+   -->
+<! -- CVS: $Id: ttrace.html,v 1.12 2006/10/07 09:19:39 vasiljevic Exp $ ttrace.n
+   -->
+
+<body>
+<h1> ttrace(n) 2.6  &quot;Tcl Threading&quot;</h1>
+<h2><a name="name">NAME</a></h2>
+<p>
+<p> ttrace - Trace-based interpreter initialization
+
+
+
+
+
+<h2><a name="table_of_contents">TABLE OF CONTENTS</a></h2>
+<p>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#table_of_contents">TABLE OF CONTENTS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#synopsis">SYNOPSIS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#description">DESCRIPTION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#user_commands">USER COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#callback_commands">CALLBACK COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#discussion">DISCUSSION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#see_also">SEE ALSO</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#keywords">KEYWORDS</a><br>
+<h2><a name="synopsis">SYNOPSIS</a></h2>
+<p>
+package require <b>Tcl 8.4</b><br>
+package require <b>Thread ?2.6?</b><br>
+<br><table border=1 width=100% cellspacing=0 cellpadding=0><tr            bgcolor=lightyellow><td bgcolor=lightyellow><table 0 width=100% cellspacing=0 cellpadding=0><tr valign=top ><td ><a href="#1"><b class='cmd'>ttrace::eval</b> <i class='arg'>arg</i> ?arg ...?</a></td></tr>
+<tr valign=top ><td ><a href="#2"><b class='cmd'>ttrace::enable</b> </a></td></tr>
+<tr valign=top ><td ><a href="#3"><b class='cmd'>ttrace::disable</b> </a></td></tr>
+<tr valign=top ><td ><a href="#4"><b class='cmd'>ttrace::cleanup</b> </a></td></tr>
+<tr valign=top ><td ><a href="#5"><b class='cmd'>ttrace::update</b> ?epoch?</a></td></tr>
+<tr valign=top ><td ><a href="#6"><b class='cmd'>ttrace::getscript</b> </a></td></tr>
+<tr valign=top ><td ><a href="#7"><b class='cmd'>ttrace::atenable</b> <i class='arg'>cmd</i> <i class='arg'>arglist</i> <i class='arg'>body</i></a></td></tr>
+<tr valign=top ><td ><a href="#8"><b class='cmd'>ttrace::atdisable</b> <i class='arg'>cmd</i> <i class='arg'>arglist</i> <i class='arg'>body</i></a></td></tr>
+<tr valign=top ><td ><a href="#9"><b class='cmd'>ttrace::addtrace</b> <i class='arg'>cmd</i> <i class='arg'>arglist</i> <i class='arg'>body</i></a></td></tr>
+<tr valign=top ><td ><a href="#10"><b class='cmd'>ttrace::addscript</b> <i class='arg'>name</i> <i class='arg'>body</i></a></td></tr>
+<tr valign=top ><td ><a href="#11"><b class='cmd'>ttrace::addresolver</b> <i class='arg'>cmd</i> <i class='arg'>arglist</i> <i class='arg'>body</i></a></td></tr>
+<tr valign=top ><td ><a href="#12"><b class='cmd'>ttrace::addcleanup</b> <i class='arg'>body</i></a></td></tr>
+<tr valign=top ><td ><a href="#13"><b class='cmd'>ttrace::addentry</b> <i class='arg'>cmd</i> <i class='arg'>var</i> <i class='arg'>val</i></a></td></tr>
+<tr valign=top ><td ><a href="#14"><b class='cmd'>ttrace::getentry</b> <i class='arg'>cmd</i> <i class='arg'>var</i></a></td></tr>
+<tr valign=top ><td ><a href="#15"><b class='cmd'>ttrace::getentries</b> <i class='arg'>cmd</i> ?pattern?</a></td></tr>
+<tr valign=top ><td ><a href="#16"><b class='cmd'>ttrace::delentry</b> <i class='arg'>cmd</i></a></td></tr>
+<tr valign=top ><td ><a href="#17"><b class='cmd'>ttrace::preload</b> <i class='arg'>cmd</i></a></td></tr>
+</table></td></tr></table>
+<h2><a name="description">DESCRIPTION</a></h2>
+<p>
+This package creates a framework for on-demand replication of the
+interpreter state accross threads in an multithreading application.
+It relies on the mechanics of Tcl command tracing and the Tcl 
+<b class='cmd'>unknown</b> command and mechanism.
+<p>
+The package requires Tcl threading extension but can be alternatively
+used stand-alone within the AOLserver, a scalable webserver from 
+America Online.
+<p>
+In a nutshell, a short sample illustrating the usage of the ttrace
+with the Tcl threading extension:
+
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+
+    % package require Ttrace
+    2.6.5
+
+    % set t1 [thread::create {package require Ttrace; thread::wait}]
+    tid0x1802800
+
+    % ttrace::eval {proc test args {return test-[thread::id]}}
+    % thread::send $t1 test
+    test-tid0x1802800
+
+    % set t2 [thread::create {package require Ttrace; thread::wait}]
+    tid0x1804000
+
+    % thread::send $t2 test
+    test-tid0x1804000
+
+</pre></td></tr></table></p>
+<p>
+As seen from above, the <b class='cmd'>ttrace::eval</b> and <b class='cmd'>ttrace::update</b>
+commands are used to create a thread-wide definition of a simple 
+Tcl procedure and replicate that definition to all, already existing
+or later created, threads.
+
+<h2><a name="user_commands">USER COMMANDS</a></h2>
+<p>
+This section describes user-level commands. Those commands can be
+used by script writers to control the execution of the tracing
+framework.
+
+<dl>
+
+<dt><a name="1"><b class='cmd'>ttrace::eval</b> <i class='arg'>arg</i> ?arg ...?</a><dd>
+
+
+This command concatenates given arguments and evaluates the resulting
+Tcl command with trace framework enabled. If the command execution
+was ok, it takes necessary steps to automatically propagate the
+trace epoch change to all threads in the application. 
+For AOLserver, only newly created threads actually receive the
+epoch change. For the Tcl threading extension, all threads created by
+the extension are automatically updated. If the command execution 
+resulted in Tcl error, no state propagation takes place.
+<br><br>
+This is the most important user-level command of the package as
+it wraps most of the commands described below. This greatly
+simplifies things, because user need to learn just this (one)
+command in order to effectively use the package. Other commands, 
+as desribed below, are included mostly for the sake of completeness.
+
+<br><br>
+<dt><a name="2"><b class='cmd'>ttrace::enable</b> </a><dd>
+
+
+Activates all registered callbacks in the framework
+and starts a new trace epoch. The trace epoch encapsulates all
+changes done to the interpreter during the time traces are activated.
+
+<br><br>
+<dt><a name="3"><b class='cmd'>ttrace::disable</b> </a><dd>
+
+
+Deactivates all registered callbacks in the framework
+and closes the current trace epoch.
+
+<br><br>
+<dt><a name="4"><b class='cmd'>ttrace::cleanup</b> </a><dd>
+
+
+Used to clean-up all on-demand loaded resources in the interpreter. 
+It effectively brings Tcl interpreter to its pristine state.
+
+<br><br>
+<dt><a name="5"><b class='cmd'>ttrace::update</b> ?epoch?</a><dd>
+
+
+Used to refresh the state of the interpreter to match the optional 
+trace ?epoch?. If the optional ?epoch? is not given, it takes
+the most recent trace epoch.
+
+<br><br>
+<dt><a name="6"><b class='cmd'>ttrace::getscript</b> </a><dd>
+
+
+Returns a synthetized Tcl script which may be sourced in any interpreter.
+This script sets the stage for the Tcl <b class='cmd'>unknown</b> command so it can
+load traced resources from the in-memory database. Normally, this command
+is automatically invoked by other higher-level commands like
+<b class='cmd'>ttrace::eval</b> and <b class='cmd'>ttrace::update</b>.
+
+</dl>
+
+<h2><a name="callback_commands">CALLBACK COMMANDS</a></h2>
+<p>
+A word upfront: the package already includes callbacks for tracing 
+following Tcl commands: <b class='cmd'>proc</b>, <b class='cmd'>namespace</b>, <b class='cmd'>variable</b>,
+<b class='cmd'>load</b>, and <b class='cmd'>rename</b>. Additionaly, a set of callbacks for 
+tracing resources (object, clasess) for the XOTcl v1.3.8+, an 
+OO-extension to Tcl, is also provided.
+This gives a solid base for solving most of the real-life needs and
+serves as an example for people wanting to customize the package 
+to cover their specific needs.
+<p>
+Below, you can find commands for registering callbacks in the
+framework and for writing callback scripts. These callbacks are
+invoked by the framework in order to gather interpreter state
+changes, build in-memory database, perform custom-cleanups and
+various other tasks.
+
+
+<dl>
+
+<dt><a name="7"><b class='cmd'>ttrace::atenable</b> <i class='arg'>cmd</i> <i class='arg'>arglist</i> <i class='arg'>body</i></a><dd>
+
+
+Registers Tcl callback to be activated at <b class='cmd'>ttrace::enable</b>.
+Registered callbacks are activated on FIFO basis. The callback
+definition includes the name of the callback, <i class='arg'>cmd</i>, a list
+of callback arguments, <i class='arg'>arglist</i> and the <i class='arg'>body</i> of the
+callback. Effectively, this actually resembles the call interface
+of the standard Tcl <b class='cmd'>proc</b> command.
+
+
+<br><br>
+<dt><a name="8"><b class='cmd'>ttrace::atdisable</b> <i class='arg'>cmd</i> <i class='arg'>arglist</i> <i class='arg'>body</i></a><dd>
+
+
+Registers Tcl callback to be activated at <b class='cmd'>ttrace::disable</b>.
+Registered callbacks are activated on FIFO basis. The callback
+definition includes the name of the callback, <i class='arg'>cmd</i>, a list
+of callback arguments, <i class='arg'>arglist</i> and the <i class='arg'>body</i> of the
+callback. Effectively, this actually resembles the call interface
+of the standard Tcl <b class='cmd'>proc</b> command.
+
+
+<br><br>
+<dt><a name="9"><b class='cmd'>ttrace::addtrace</b> <i class='arg'>cmd</i> <i class='arg'>arglist</i> <i class='arg'>body</i></a><dd>
+
+
+Registers Tcl callback to be activated for tracing the Tcl 
+<b class='cmd'>cmd</b> command. The callback definition includes the name of 
+the Tcl command to trace, <i class='arg'>cmd</i>, a list of callback arguments, 
+<i class='arg'>arglist</i> and the <i class='arg'>body</i> of the callback. Effectively, 
+this actually resembles the call interface of the standard Tcl 
+<b class='cmd'>proc</b> command.
+
+
+<br><br>
+<dt><a name="10"><b class='cmd'>ttrace::addscript</b> <i class='arg'>name</i> <i class='arg'>body</i></a><dd>
+
+
+Registers Tcl callback to be activated for building a Tcl
+script to be passed to other interpreters. This script is
+used to set the stage for the Tcl <b class='cmd'>unknown</b> command.
+Registered callbacks are activated on FIFO basis.
+The callback definition includes the name of the callback,
+<i class='arg'>name</i> and the <i class='arg'>body</i> of the callback.
+
+<br><br>
+<dt><a name="11"><b class='cmd'>ttrace::addresolver</b> <i class='arg'>cmd</i> <i class='arg'>arglist</i> <i class='arg'>body</i></a><dd>
+
+
+Registers Tcl callback to be activated by the overloaded Tcl
+<b class='cmd'>unknown</b> command.
+Registered callbacks are activated on FIFO basis.
+This callback is used to resolve the resource and load the 
+resource in the current interpreter.
+
+<br><br>
+<dt><a name="12"><b class='cmd'>ttrace::addcleanup</b> <i class='arg'>body</i></a><dd>
+
+
+Registers Tcl callback to be activated by the <b class='cmd'>trace::cleanup</b>.
+Registered callbacks are activated on FIFO basis.
+
+<br><br>
+<dt><a name="13"><b class='cmd'>ttrace::addentry</b> <i class='arg'>cmd</i> <i class='arg'>var</i> <i class='arg'>val</i></a><dd>
+
+
+Adds one entry to the named in-memory database.
+
+<br><br>
+<dt><a name="14"><b class='cmd'>ttrace::getentry</b> <i class='arg'>cmd</i> <i class='arg'>var</i></a><dd>
+
+
+Returns the value of the entry from the named in-memory database. 
+
+<br><br>
+<dt><a name="15"><b class='cmd'>ttrace::getentries</b> <i class='arg'>cmd</i> ?pattern?</a><dd>
+
+
+Returns names of all entries from the named in-memory database.
+
+<br><br>
+<dt><a name="16"><b class='cmd'>ttrace::delentry</b> <i class='arg'>cmd</i></a><dd>
+
+
+Deletes an entry from the named in-memory database.
+
+<br><br>
+<dt><a name="17"><b class='cmd'>ttrace::preload</b> <i class='arg'>cmd</i></a><dd>
+
+
+Registers the Tcl command to be loaded in the interpreter.
+Commands registered this way will always be the part of 
+the interpreter and not be on-demand loaded by the Tcl
+<b class='cmd'>unknown</b> command.
+
+</dl>
+
+<h2><a name="discussion">DISCUSSION</a></h2>
+<p>
+Common introspective state-replication approaches use a custom Tcl
+script to introspect the running interpreter and synthesize another
+Tcl script to replicate this state in some other interpreter.
+This package, on the contrary, uses Tcl command traces. Command 
+traces are registered on selected Tcl commands, like <b class='cmd'>proc</b>, 
+<b class='cmd'>namespace</b>, <b class='cmd'>load</b> and other standard (and/or user-defined)
+Tcl commands. When activated, those traces build an in-memory
+database of created resources. This database is used as a resource
+repository for the (overloaded) Tcl <b class='cmd'>unknown</b> command which 
+creates the requested resource in the interpreter on demand. 
+This way, users can update just one interpreter (master) in one 
+thread and replicate that interpreter state (or part of it) to other 
+threads/interpreters in the process.
+<p>
+Immediate benefit of such approach is the much smaller memory footprint
+of the application and much faster thread creation. By not actually 
+loading all necessary procedures (and other resources) in every thread
+at the thread initialization time, but by deffering this to the time the
+resource is actually referenced, significant improvements in both
+memory consumption and thread initialization time can be achieved. Some
+tests have shown that memory footprint of an multithreading Tcl application
+went down more than three times and thread startup time was reduced for
+about 50 times. Note that your mileage may vary.
+
+Other benefits include much finer control about what (and when) gets 
+replicated from the master to other Tcl thread/interpreters.
+
+
+
+
+
+<h2><a name="see_also">SEE ALSO</a></h2>
+<p>
+thread, tpool, tsv
+<h2><a name="keywords">KEYWORDS</a></h2>
+<p>
+command tracing, introspection
+</body></html>
+
diff --git a/8.x/thread/doc/man.macros b/8.x/thread/doc/man.macros
new file mode 100644 (file)
index 0000000..b0d523f
--- /dev/null
@@ -0,0 +1,238 @@
+'\" The definitions below are for supplemental macros used in Tcl/Tk
+'\" manual entries.
+'\"
+'\" .AP type name in/out ?indent?
+'\"    Start paragraph describing an argument to a library procedure.
+'\"    type is type of argument (int, etc.), in/out is either "in", "out",
+'\"    or "in/out" to describe whether procedure reads or modifies arg,
+'\"    and indent is equivalent to second arg of .IP (shouldn't ever be
+'\"    needed;  use .AS below instead)
+'\"
+'\" .AS ?type? ?name?
+'\"    Give maximum sizes of arguments for setting tab stops.  Type and
+'\"    name are examples of largest possible arguments that will be passed
+'\"    to .AP later.  If args are omitted, default tab stops are used.
+'\"
+'\" .BS
+'\"    Start box enclosure.  From here until next .BE, everything will be
+'\"    enclosed in one large box.
+'\"
+'\" .BE
+'\"    End of box enclosure.
+'\"
+'\" .CS
+'\"    Begin code excerpt.
+'\"
+'\" .CE
+'\"    End code excerpt.
+'\"
+'\" .VS ?version? ?br?
+'\"    Begin vertical sidebar, for use in marking newly-changed parts
+'\"    of man pages.  The first argument is ignored and used for recording
+'\"    the version when the .VS was added, so that the sidebars can be
+'\"    found and removed when they reach a certain age.  If another argument
+'\"    is present, then a line break is forced before starting the sidebar.
+'\"
+'\" .VE
+'\"    End of vertical sidebar.
+'\"
+'\" .DS
+'\"    Begin an indented unfilled display.
+'\"
+'\" .DE
+'\"    End of indented unfilled display.
+'\"
+'\" .SO
+'\"    Start of list of standard options for a Tk widget.  The
+'\"    options follow on successive lines, in four columns separated
+'\"    by tabs.
+'\"
+'\" .SE
+'\"    End of list of standard options for a Tk widget.
+'\"
+'\" .OP cmdName dbName dbClass
+'\"    Start of description of a specific option.  cmdName gives the
+'\"    option's name as specified in the class command, dbName gives
+'\"    the option's name in the option database, and dbClass gives
+'\"    the option's class in the option database.
+'\"
+'\" .UL arg1 arg2
+'\"    Print arg1 underlined, then print arg2 normally.
+'\"
+'\" RCS: @(#) $Id: man.macros,v 1.1 2003/11/25 18:16:27 vasiljevic Exp $
+'\"
+'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+'\"    # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ta \\n()Au \\n()Bu
+.ie !"\\$3"" \{\
+\&\\$1 \\fI\\$2\\fP    (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"    # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+'\"    # BS - start boxed text
+'\"    # ^y = starting y location
+'\"    # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"    # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"    Draw four-sided box normally, but don't draw top of
+.\"    box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"    # VS - start vertical sidebar
+'\"    # ^Y = starting y location
+'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"    # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"    # Special macro to handle page bottom:  finish off current
+'\"    # box/sidebar if in box/sidebar mode, then invoked standard
+'\"    # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"    Draw three-sided box if this is the box's first page,
+.\"    draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"    # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"    # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+'\"    # SO - start of list of standard options
+.de SO
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 5.5c 11c
+.ft B
+..
+'\"    # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\fBoptions\\fR manual entry for details on the standard options.
+..
+'\"    # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name:     \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class:        \\fB\\$3\\fR
+.fi
+.IP
+..
+'\"    # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+.if t .ft C
+..
+'\"    # CE - end code excerpt
+.de CE
+.fi
+.if t .ft R
+.RE
+..
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
diff --git a/8.x/thread/doc/man/thread.n b/8.x/thread/doc/man/thread.n
new file mode 100644 (file)
index 0000000..f540a05
--- /dev/null
@@ -0,0 +1,801 @@
+'\"
+'\" Generated from file '' by tcllib/doctools with format 'nroff'
+'\"
+'\" -*- tcl -*- doctools manpage
+'\" The definitions below are for supplemental macros used in Tcl/Tk
+'\" manual entries.
+'\"
+'\" .AP type name in/out ?indent?
+'\"    Start paragraph describing an argument to a library procedure.
+'\"    type is type of argument (int, etc.), in/out is either "in", "out",
+'\"    or "in/out" to describe whether procedure reads or modifies arg,
+'\"    and indent is equivalent to second arg of .IP (shouldn't ever be
+'\"    needed;  use .AS below instead)
+'\"
+'\" .AS ?type? ?name?
+'\"    Give maximum sizes of arguments for setting tab stops.  Type and
+'\"    name are examples of largest possible arguments that will be passed
+'\"    to .AP later.  If args are omitted, default tab stops are used.
+'\"
+'\" .BS
+'\"    Start box enclosure.  From here until next .BE, everything will be
+'\"    enclosed in one large box.
+'\"
+'\" .BE
+'\"    End of box enclosure.
+'\"
+'\" .CS
+'\"    Begin code excerpt.
+'\"
+'\" .CE
+'\"    End code excerpt.
+'\"
+'\" .VS ?version? ?br?
+'\"    Begin vertical sidebar, for use in marking newly-changed parts
+'\"    of man pages.  The first argument is ignored and used for recording
+'\"    the version when the .VS was added, so that the sidebars can be
+'\"    found and removed when they reach a certain age.  If another argument
+'\"    is present, then a line break is forced before starting the sidebar.
+'\"
+'\" .VE
+'\"    End of vertical sidebar.
+'\"
+'\" .DS
+'\"    Begin an indented unfilled display.
+'\"
+'\" .DE
+'\"    End of indented unfilled display.
+'\"
+'\" .SO
+'\"    Start of list of standard options for a Tk widget.  The
+'\"    options follow on successive lines, in four columns separated
+'\"    by tabs.
+'\"
+'\" .SE
+'\"    End of list of standard options for a Tk widget.
+'\"
+'\" .OP cmdName dbName dbClass
+'\"    Start of description of a specific option.  cmdName gives the
+'\"    option's name as specified in the class command, dbName gives
+'\"    the option's name in the option database, and dbClass gives
+'\"    the option's class in the option database.
+'\"
+'\" .UL arg1 arg2
+'\"    Print arg1 underlined, then print arg2 normally.
+'\"
+'\" RCS: @(#) $Id: thread.n,v 1.26 2006/10/07 09:19:39 vasiljevic Exp $
+'\"
+'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+'\"    # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ta \\n()Au \\n()Bu
+.ie !"\\$3"" \{\
+\&\\$1 \\fI\\$2\\fP    (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"    # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+'\"    # BS - start boxed text
+'\"    # ^y = starting y location
+'\"    # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"    # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"    Draw four-sided box normally, but don't draw top of
+.\"    box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"    # VS - start vertical sidebar
+'\"    # ^Y = starting y location
+'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"    # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"    # Special macro to handle page bottom:  finish off current
+'\"    # box/sidebar if in box/sidebar mode, then invoked standard
+'\"    # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"    Draw three-sided box if this is the box's first page,
+.\"    draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"    # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"    # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+'\"    # SO - start of list of standard options
+.de SO
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 5.5c 11c
+.ft B
+..
+'\"    # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\fBoptions\\fR manual entry for details on the standard options.
+..
+'\"    # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name:     \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class:        \\fB\\$3\\fR
+.fi
+.IP
+..
+'\"    # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+.if t .ft C
+..
+'\"    # CE - end code excerpt
+.de CE
+.fi
+.if t .ft R
+.RE
+..
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+
+.TH "thread" n 2.6  "Tcl Threading"
+.BS
+.SH "NAME"
+thread \- Extension for script access to Tcl threading
+.SH "SYNOPSIS"
+package require \fBTcl  8.4\fR
+.sp
+package require \fBThread  ?2.6?\fR
+.sp
+\fBthread::create\fR ?-joinable? ?-preserved? ?script?
+.sp
+\fBthread::preserve\fR ?id?
+.sp
+\fBthread::release\fR ?-wait? ?id?
+.sp
+\fBthread::id\fR
+.sp
+\fBthread::errorproc\fR ?procname?
+.sp
+\fBthread::unwind\fR
+.sp
+\fBthread::exit\fR
+.sp
+\fBthread::names\fR
+.sp
+\fBthread::exists\fR \fIid\fR
+.sp
+\fBthread::send\fR ?-async? ?-head? \fIid\fR \fIscript\fR ?varname?
+.sp
+\fBthread::broadcast\fR \fIid\fR \fIscript\fR
+.sp
+\fBthread::wait\fR
+.sp
+\fBthread::eval\fR ?-lock mutex? \fIarg\fR ?arg ...?
+.sp
+\fBthread::join\fR \fIid\fR
+.sp
+\fBthread::configure\fR \fIid\fR ?option? ?value? ?...?
+.sp
+\fBthread::transfer\fR \fIid\fR \fIchannel\fR
+.sp
+\fBthread::detach\fR \fIchannel\fR
+.sp
+\fBthread::attach\fR \fIchannel\fR
+.sp
+\fBthread::mutex\fR
+.sp
+\fBthread::mutex\fR \fBcreate\fR ?-recursive?
+.sp
+\fBthread::mutex\fR \fBdestroy\fR \fImutex\fR
+.sp
+\fBthread::mutex\fR \fBlock\fR \fImutex\fR
+.sp
+\fBthread::mutex\fR \fBunlock\fR \fImutex\fR
+.sp
+\fBthread::rwmutex\fR
+.sp
+\fBthread::rwmutex\fR \fBcreate\fR
+.sp
+\fBthread::rwmutex\fR \fBdestroy\fR \fImutex\fR
+.sp
+\fBthread::rwmutex\fR \fBrlock\fR \fImutex\fR
+.sp
+\fBthread::rwmutex\fR \fBwlock\fR \fImutex\fR
+.sp
+\fBthread::rwmutex\fR \fBunlock\fR \fImutex\fR
+.sp
+\fBthread::cond\fR
+.sp
+\fBthread::cond\fR \fBcreate\fR
+.sp
+\fBthread::cond\fR \fBdestroy\fR \fIcond\fR
+.sp
+\fBthread::cond\fR \fBnotify\fR \fIcond\fR
+.sp
+\fBthread::cond\fR \fBwait\fR \fIcond\fR \fImutex\fR ?ms?
+.sp
+.BE
+.SH "DESCRIPTION"
+The \fBthread\fR extension creates threads that contain Tcl
+interpreters, and it lets you send scripts to those threads for
+evaluation.
+Additionaly, it provides script-level access to basic thread
+synchronization primitives, like mutexes and condition variables.
+.SH "COMMANDS"
+This section describes commands for creating and destroying threads
+and sending scripts to threads for evaluation.
+.TP
+\fBthread::create\fR ?-joinable? ?-preserved? ?script?
+This command creates a thread that contains a Tcl interpreter.
+The Tcl interpreter either evaluates the optional \fBscript\fR, if
+specified, or it waits in the event loop for scripts that arrive via
+the \fBthread::send\fR command. The result, if any, of the
+optional \fBscript\fR is never returned to the caller.
+The result of \fBthread::create\fR is the ID of the thread. This is
+the opaque handle which identifies the newly created thread for
+all other package commands. The handle of the thread goes out of scope
+automatically when thread is marked for exit
+(see the \fBthread::release\fR command below).
+.sp
+If the optional \fBscript\fR argument contains the \fBthread::wait\fR
+command the thread will enter into the event loop. If such command is not
+found  in the \fBscript\fR the thread will run the \fBscript\fR to
+the end and exit. In that case, the handle may be safely ignored since it
+refers to a thread which does not exists any more at the time when the
+command returns.
+.sp
+Using flag \fB-joinable\fR it is possible to create a joinable
+thread, i.e. one upon whose exit can be waited upon by using
+\fBthread::join\fR command.
+Note that failure to join a thread created with \fB-joinable\fR flag
+results in resource and memory leaks.
+.sp
+Threads created by the \fBthread::create\fR cannot be destroyed
+forcefully. Consequently, there is no corresponding thread destroy
+command. A thread may only be released using the \fBthread::release\fR
+and if its internal reference count drops to zero, the thread is
+marked for exit. This kicks the thread out of the event loop
+servicing and the thread continues to execute commands passed in
+the \fBscript\fR argument, following the \fBthread::wait\fR
+command. If this was the last command in the script, as usualy the
+case, the thread will exit.
+.sp
+It is possible to create a situation in which it may be impossible
+to terminate the thread, for example by putting some endless loop
+after the \fBthread::wait\fR or entering the event loop again by
+doing an vwait-type of command. In such cases, the thread may never
+exit. This is considered to be a bad practice and should be avoided
+if possible. This is best illustrated by the example below:
+.nf
+    # You should never do ...
+    set tid [thread::create {
+        package require Http
+        thread::wait
+        vwait forever ; # <-- this!
+    }]
+.fi
+The thread created in the above example will never be able to exit.
+After it has been released with the last matching \fBthread::release\fR
+call, the thread will jump out of the \fBthread::wait\fR and continue
+to execute commands following. It will enter \fBvwait\fR command and
+wait endlessly for events. There is no way one can terminate such thread,
+so you wouldn't want to do this!
+.sp
+Each newly created has its internal reference counter set to 0 (zero),
+i.e. it is unreserved. This counter gets incremented by a call to
+\fBthread::preserve\fR and decremented by a call to \fBthread::release\fR
+command. These two commands implement simple but effective thread
+reservation system and offer predictable and controllable thread
+termination capabilities. It is however possible to create initialy
+preserved threads by using flag \fB-preserved\fR of the
+\fBthread::create\fR command. Threads created with this flag have the
+initial value of the reference counter of 1 (one), and are thus
+initially marked reserved.
+.TP
+\fBthread::preserve\fR ?id?
+This command increments the thread reference counter. Each call
+to this command increments the reference counter by one (1).
+Command returns the value of the reference counter after the increment.
+If called with the optional thread \fBid\fR, the command preserves
+the given thread. Otherwise the current thread is preserved.
+.sp
+With reference counting, one can implement controlled access to a
+shared Tcl thread. By incrementing the reference counter, the
+caller signalizes that he/she wishes to use the thread for a longer
+period of time. By decrementing the counter, caller signalizes that
+he/she has finished using the thread.
+.TP
+\fBthread::release\fR ?-wait? ?id?
+This command decrements the thread reference counter. Each call to
+this command decrements the reference counter by one (1).
+If called with the optional thread \fBid\fR, the command releases
+the given thread. Otherwise, the current thread is released.
+Command returns the value of the reference counter after the decrement.
+When the reference counter reaches zero (0), the target thread is
+marked for termination. You should not reference the thread after the
+\fBthread::release\fR command returns zero or negative integer.
+The handle of the thread goes out of scope and should not be used any
+more. Any following reference to the same thread handle will result
+in Tcl error.
+.sp
+Optional flag \fB-wait\fR instructs the caller thread to wait for
+the target thread to exit, if the effect of the command would result
+in termination of the target thread, i.e. if the return result would
+be zero (0). Without the flag, the caller thread does not wait for
+the target thread to exit. Care must be taken when using the
+\fB-wait\fR, since this may block the caller thread indefinitely.
+This option has been implemented for some special uses of the extension
+and is deprecated for regular use. Regular users should create joinable
+threads by using the \fB-joinable\fR option of the \fBthread::create\fR
+command and the \fBthread::join\fR to wait for thread to exit.
+.TP
+\fBthread::id\fR
+This command returns the ID of the current thread.
+.TP
+\fBthread::errorproc\fR ?procname?
+This command sets a handler for errors that occur in scripts sent
+asynchronously, using the \fB-async\fR flag of the
+\fBthread::send\fR command, to other threads. If no handler
+is specified, the current handler is returned. The empty string
+resets the handler to default (unspecified) value.
+An uncaught error in a thread causes an error message to be sent
+to the standard error channel. This default reporting scheme can
+be changed by registering a procedure which is called to report
+the error. The \fIprocname\fR is called in the interpreter that
+invoked the \fBthread::errorproc\fR command. The \fIprocname\fR
+is called like this:
+.nf
+    myerrorproc thread_id errorInfo
+.fi
+.TP
+\fBthread::unwind\fR
+Use of this command is deprecated in favour of more advanced thread
+reservation system implemented with \fBthread::preserve\fR and
+\fBthread::release\fR commands. Support for \fBthread::unwind\fR
+command will dissapear in some future major release of the extension.
+.sp
+This command stops a prior \fBthread::wait\fR command. Execution of
+the script passed to newly created thread will continue from the
+\fBthread::wait\fR command. If \fBthread::wait\fR was the last command
+in the script, the thread will exit. The command returns empty result
+but may trigger Tcl error with the message "target thread died" in some
+situations.
+.TP
+\fBthread::exit\fR
+Use of this command is deprecated in favour of more advanced thread
+reservation system implemented with \fBthread::preserve\fR and
+\fBthread::release\fR commands. Support for \fBthread::exit\fR
+command will dissapear in some future major release of the extension.
+.sp
+This command forces a thread stuck in the \fBthread::wait\fR
+command to unconditionaly exit. The execution of \fBthread::exit\fR
+command is guaranteed to leave the program memory in the unconsistent
+state, produce memory leaks and otherwise affect other subsytem(s)
+of the Tcl application in an unpredictable manner. The command
+returns empty result but may trigger Tcl error with the message
+"target thread died" in some situations.
+.TP
+\fBthread::names\fR
+This command returns a list of thread IDs. These are only for
+threads that have been created via \fBthread::create\fR command.
+If your application creates other threads at the C level, they
+are not reported by this command.
+.TP
+\fBthread::exists\fR \fIid\fR
+Returns true (1) if thread given by the \fIid\fR parameter exists,
+false (0) otherwise. This applies only for threads that have
+been created via \fBthread::create\fR command.
+.TP
+\fBthread::send\fR ?-async? ?-head? \fIid\fR \fIscript\fR ?varname?
+This command passes a \fIscript\fR to another thread and, optionally,
+waits for the result. If the \fB-async\fR flag is specified, the
+command does not wait for the result and it returns empty string.
+The target thread must enter it's event loop in order to receive
+scripts sent via this command. This is done by default for threads
+created without a startup script. Threads can enter the event loop
+explicitly by calling \fBthread::wait\fR or any other relevant Tcl/Tk
+command, like \fBupdate\fR, \fBvwait\fR, etc.
+.sp
+Optional \fBvarname\fR specifies name of the variable to store
+the result of the \fIscript\fR. Without the \fB-async\fR flag,
+the command returns the evaluation code, similarily to the standard
+Tcl \fBcatch\fR command. If, however, the \fB-async\fR flag is
+specified, the command returns immediately and caller can later
+\fBvwait\fR on ?varname? to get the result of the passed \fIscript\fR
+.nf
+    set t1 [thread::create]
+    set t2 [thread::create]
+    thread::send -async $t1 "set a 1" result
+    thread::send -async $t2 "set b 2" result
+    for {set i 0} {$i < 2} {incr i} {
+        vwait result
+    }
+.fi
+In the above example, two threads were fed work and both of them were
+instructed to signalize the same variable "result" in the calling thread.
+The caller entered the event loop twice to get both results. Note,
+however, that the order of the received results may vary, depending on
+the current system load, type of work done, etc, etc.
+.sp
+Many threads can simultaneously send scripts to the target thread for
+execution. All of them are entered into the event queue of the target
+thread and executed on the FIFO basis, intermingled with optional other
+events pending in the event queue of the target thread.
+Using the optional ?-head? switch, scripts posted to the thread's
+event queue can be placed on the head, instead on the tail of the queue,
+thus being executed in the LIFO fashion.
+.TP
+\fBthread::broadcast\fR \fIid\fR \fIscript\fR
+This command passes a \fIscript\fR to all threads created by the
+package for execution. It does not wait for response from any of
+the threads.
+.TP
+\fBthread::wait\fR
+This enters the event loop so a thread can receive messages from
+the \fBthread::send\fR command. This command should only be used
+within the script passed to the \fBthread::create\fR. It should
+be the very last command in the script. If this is not the case,
+the exiting thread will continue executing the script lines pass
+the \fBthread::wait\fR which is usually not what you want and/or
+expect.
+.nf
+    set t1 [thread::create {
+        #
+        # Do some initialization work here
+        #
+        thread::wait ; # Enter the event loop
+    }]
+.fi
+.TP
+\fBthread::eval\fR ?-lock mutex? \fIarg\fR ?arg ...?
+This command concatenates passed arguments and evaluates the
+resulting script under the mutex protection. If no mutex is
+specified by using the ?-lock mutex? optional argument,
+the internal static mutex is used.
+.TP
+\fBthread::join\fR \fIid\fR
+This command waits for the thread with ID \fIid\fR to exit and
+then returns it's exit code. Errors will be returned for threads
+which are not joinable or already waited upon by another thread.
+Upon the join the handle of the thread has gone out of scope and
+should not be used any more.
+.TP
+\fBthread::configure\fR \fIid\fR ?option? ?value? ?...?
+This command configures various low-level aspects of the thread with
+ID \fIid\fR in the similar way as the standard Tcl command
+\fBfconfigure\fR configures some Tcl channel options. Options currently
+supported are: \fB-eventmark\fR and \fB-unwindonerror\fR.
+.sp
+The \fB-eventmark\fR option, when set, limits the number of
+asynchronously posted scripts to the thread event loop.
+The \fBthread::send -async\fR command will block until the number
+of pending scripts in the event loop does not drop below the value
+configured with \fB-eventmark\fR. Default value for the
+\fB-eventmark\fR is 0 (zero) which effectively disables the checking,
+i.e. allows for unlimited number of posted scripts.
+.sp
+The \fB-unwindonerror\fR option, when set, causes the
+target thread to unwind if the result of the script processing
+resulted in error. Default value for the \fB-unwindonerror\fR
+is 0 (false), i.e. thread continues to process scripts after one
+of the posted scripts fails.
+.TP
+\fBthread::transfer\fR \fIid\fR \fIchannel\fR
+This moves the specified \fIchannel\fR from the current thread
+and interpreter to the main interpreter of the thread with the
+given \fIid\fR. After the move the current interpreter has no
+access to the channel any more, but the main interpreter of the
+target thread will be able to use it from now on.
+The command waits until the other thread has incorporated the
+channel. Because of this it is possible to deadlock the
+participating threads by commanding the other through a
+synchronous \fBthread::send\fR to transfer a channel to us.
+This easily extends into longer loops of threads waiting for
+each other. Other restrictions: the channel in question must
+not be shared among multiple interpreters running in the
+sending thread. This automatically excludes the special channels
+for standard input, output and error.
+.sp
+Due to the internal Tcl core implementation and the restriction on
+transferring shared channels, one has to take extra measures when
+transferring socket channels created by accepting the connection
+out of the \fBsocket\fR commands callback procedures:
+.nf
+    socket -server _Accept 2200
+    proc _Accept {s ipaddr port} {
+        after idle [list Accept $s $ipaddr $port]
+    }
+    proc Accept {s ipaddr port} {
+        set tid [thread::create]
+        thread::transfer $tid $s
+    }
+.fi
+.TP
+\fBthread::detach\fR \fIchannel\fR
+This detaches the specified \fIchannel\fR from the current thread and
+interpreter. After that, the current interpreter has no access to the
+channel any more. The channel is in the parked state until some other
+(or the same) thread attaches the channel again with \fBthread::attach\fR.
+Restrictions: same as for transferring shared channels with the
+\fBthread::transfer\fR command.
+.TP
+\fBthread::attach\fR \fIchannel\fR
+This attaches the previously detached \fIchannel\fR in the
+current thread/interpreter. For already existing channels,
+the command does nothing, i.e. it is not an error to attach the
+same channel more than once. The first operation will actualy
+perform the operation, while all subsequent operation will just
+do nothing. Command throws error if the \fIchannel\fR cannot be
+found in the list of detached channels and/or in the current
+interpreter.
+.TP
+\fBthread::mutex\fR
+Mutexes are most common thread synchronization primitives.
+They are used to synchronize access from two or more threads to one or
+more shared resources. This command provides script-level access to
+exclusive and/or recursive mutexes. Exclusive mutexes can be locked
+only once by one thread, while recursive mutexes can be locked many
+times by the same thread. For recursive mutexes, number of lock and
+unlock operations must match, otherwise, the mutex will never be
+released, which would lead to various deadlock situations.
+.sp
+Care has to be taken when using mutexes in an multithreading program.
+Improper use of mutexes may lead to various deadlock situations,
+especially when using exclusive mutexes.
+.sp
+The \fBthread::mutex\fR command supports following subcommands and options:
+.RS
+.TP
+\fBthread::mutex\fR \fBcreate\fR ?-recursive?
+Creates the mutex and returns it's opaque handle. This handle
+should be used for any future reference to the newly created mutex.
+If no optional ?-recursive? argument was specified, the command
+creates the exclusive mutex. With the ?-recursive? argument,
+the command creates a recursive mutex.
+.TP
+\fBthread::mutex\fR \fBdestroy\fR \fImutex\fR
+Destroys the \fImutex\fR. Mutex should be in unlocked state before
+the destroy attempt. If the mutex is locked, the command will throw
+Tcl error.
+.TP
+\fBthread::mutex\fR \fBlock\fR \fImutex\fR
+Locks the \fImutex\fR. Locking the exclusive mutex may throw Tcl
+error if on attempt to lock the same mutex twice from the same
+thread. If your program logic forces you to lock the same mutex
+twice or more from the same thread (this may happen in recursive
+procedure invocations) you should consider using the recursive mutexes.
+.TP
+\fBthread::mutex\fR \fBunlock\fR \fImutex\fR
+Unlocks the \fImutex\fR so some other thread may lock it again.
+Attempt to unlock the already unlocked mutex will throw Tcl error.
+.RE
+.sp
+.TP
+\fBthread::rwmutex\fR
+This command creates many-readers/single-writer mutexes. Reader/writer
+mutexes allow you to serialize access to a shared resource more optimally.
+In situations where a shared resource gets mostly read and seldom modified,
+you might gain some performace by using reader/writer mutexes instead of
+exclusive or recursive mutexes.
+.sp
+For reading the resource, thread should obtain a read lock on the resource.
+Read lock is non-exclusive, meaning that more than one thread can
+obtain a read lock to the same resource, without waiting on other readers.
+For changing the resource, however, a thread must obtain a exclusive
+write lock. This lock effectively blocks all threads from gaining the
+read-lock while the resource is been modified by the writer thread.
+Only after the write lock has been released, the resource may be read-locked
+again.
+.sp
+The \fBthread::rwmutex\fR command supports following subcommands and options:
+.RS
+.TP
+\fBthread::rwmutex\fR \fBcreate\fR
+Creates the reader/writer mutex and returns it's opaque handle.
+This handle should be used for any future reference to the newly
+created mutex.
+.TP
+\fBthread::rwmutex\fR \fBdestroy\fR \fImutex\fR
+Destroys the reader/writer \fImutex\fR. If the mutex is already locked,
+attempt to destroy it will throw Tcl error.
+.TP
+\fBthread::rwmutex\fR \fBrlock\fR \fImutex\fR
+Locks the \fImutex\fR for reading. More than one thread may read-lock
+the same \fImutex\fR at the same time.
+.TP
+\fBthread::rwmutex\fR \fBwlock\fR \fImutex\fR
+Locks the \fImutex\fR for writing. Only one thread may write-lock
+the same \fImutex\fR at the same time. Attempt to write-lock same
+\fImutex\fR twice from the same thread will throw Tcl error.
+.TP
+\fBthread::rwmutex\fR \fBunlock\fR \fImutex\fR
+Unlocks the \fImutex\fR so some other thread may lock it again.
+Attempt to unlock already unlocked \fImutex\fR will throw Tcl error.
+.RE
+.sp
+.TP
+\fBthread::cond\fR
+This command provides script-level access to condition variables.
+A condition variable creates a safe environment for the program
+to test some condition, sleep on it when false and be awakened
+when it might have become true. A condition variable is always
+used in the conjuction with an exclusive mutex. If you attempt
+to use other type of mutex in conjuction with the condition
+variable, a Tcl error will be thrown.
+.sp
+The command supports following subcommands and options:
+.RS
+.TP
+\fBthread::cond\fR \fBcreate\fR
+Creates the condition variable and returns it's opaque handle.
+This handle should be used for any future reference to newly
+created condition variable.
+.TP
+\fBthread::cond\fR \fBdestroy\fR \fIcond\fR
+Destroys condition variable \fIcond\fR. Extreme care has to be taken
+that nobody is using (i.e. waiting on) the condition variable,
+otherwise unexpected errors may happen.
+.TP
+\fBthread::cond\fR \fBnotify\fR \fIcond\fR
+Wakes up all threads waiting on the condition variable \fIcond\fR.
+.TP
+\fBthread::cond\fR \fBwait\fR \fIcond\fR \fImutex\fR ?ms?
+This command is used to suspend program execution until the condition
+variable \fIcond\fR has been signalled or the optional timer has expired.
+The exclusive \fImutex\fR must be locked by the calling thread on entrance
+to this command. If the mutex is not locked, Tcl error is thrown.
+While waiting on the \fIcond\fR, the command releases \fImutex\fR.
+Before returning to the calling thread, the command re-acquires the
+\fImutex\fR again. Unlocking the \fImutex\fR and waiting on the
+condition variable \fIcond\fR is done atomically.
+.sp
+The \fBms\fR command option, if given, must be an integer specifying
+time interval in milliseconds the command waits to be signalled.
+Otherwise the command waits on condition notify forever.
+.sp
+In multithreading programs, there are many situations where a thread has
+to wait for some event to happen until it is allowed to proceed.
+This is usually accomplished by repeatedly testing a condition under the
+mutex protection and waiting on the condition variable until the condition
+evaluates to true:
+.nf
+    set mutex [thread::mutex create]
+    set cond  [thread::cond  create]
+
+    thread::mutex lock $mutex
+    while {<some_condition_is_true>} {
+        thread::cond wait $cond $mutex
+    }
+    # Do some work under mutex protection
+    thread::mutex unlock $mutex
+.fi
+Repeated testing of the condition is needed since the condition variable
+may get signalled without the condition being actually changed (spurious
+thread wake-ups, for example).
+.RE
+.SH "DISCUSSION"
+The fundamental threading model in Tcl is that there can be one or
+more Tcl interpreters per thread, but each Tcl interpreter should
+only be used by a single thread which created it.
+A "shared memory" abstraction is awkward to provide in Tcl because
+Tcl makes assumptions about variable and data ownership. Therefore
+this extension supports a simple form of threading where the main
+thread can manage several background, or "worker" threads.
+For example, an event-driven server can pass requests to worker
+threads, and then await responses from worker threads or new client
+requests. Everything goes through the common Tcl event loop, so
+message passing between threads works naturally with event-driven I/O,
+\fBvwait\fR on variables, and so forth. For the transfer of bulk
+information it is possible to move channels between the threads.
+.PP
+For advanced multithreading scripts, script-level access to two
+basic synchronization primitives, mutex and condition variables,
+is also supported.
+.SH "SEE ALSO"
+\fIhttp://www.tcl.tk/doc/howto/thread_model.html\fR, tpool, tsv, ttrace
+.SH "KEYWORDS"
+events, message passing, mutex, synchronization, thread
diff --git a/8.x/thread/doc/man/tpool.n b/8.x/thread/doc/man/tpool.n
new file mode 100644 (file)
index 0000000..282c8c3
--- /dev/null
@@ -0,0 +1,450 @@
+'\"
+'\" Generated from file '' by tcllib/doctools with format 'nroff'
+'\"
+'\" -*- tcl -*- doctools manpage
+'\" The definitions below are for supplemental macros used in Tcl/Tk
+'\" manual entries.
+'\"
+'\" .AP type name in/out ?indent?
+'\"    Start paragraph describing an argument to a library procedure.
+'\"    type is type of argument (int, etc.), in/out is either "in", "out",
+'\"    or "in/out" to describe whether procedure reads or modifies arg,
+'\"    and indent is equivalent to second arg of .IP (shouldn't ever be
+'\"    needed;  use .AS below instead)
+'\"
+'\" .AS ?type? ?name?
+'\"    Give maximum sizes of arguments for setting tab stops.  Type and
+'\"    name are examples of largest possible arguments that will be passed
+'\"    to .AP later.  If args are omitted, default tab stops are used.
+'\"
+'\" .BS
+'\"    Start box enclosure.  From here until next .BE, everything will be
+'\"    enclosed in one large box.
+'\"
+'\" .BE
+'\"    End of box enclosure.
+'\"
+'\" .CS
+'\"    Begin code excerpt.
+'\"
+'\" .CE
+'\"    End code excerpt.
+'\"
+'\" .VS ?version? ?br?
+'\"    Begin vertical sidebar, for use in marking newly-changed parts
+'\"    of man pages.  The first argument is ignored and used for recording
+'\"    the version when the .VS was added, so that the sidebars can be
+'\"    found and removed when they reach a certain age.  If another argument
+'\"    is present, then a line break is forced before starting the sidebar.
+'\"
+'\" .VE
+'\"    End of vertical sidebar.
+'\"
+'\" .DS
+'\"    Begin an indented unfilled display.
+'\"
+'\" .DE
+'\"    End of indented unfilled display.
+'\"
+'\" .SO
+'\"    Start of list of standard options for a Tk widget.  The
+'\"    options follow on successive lines, in four columns separated
+'\"    by tabs.
+'\"
+'\" .SE
+'\"    End of list of standard options for a Tk widget.
+'\"
+'\" .OP cmdName dbName dbClass
+'\"    Start of description of a specific option.  cmdName gives the
+'\"    option's name as specified in the class command, dbName gives
+'\"    the option's name in the option database, and dbClass gives
+'\"    the option's class in the option database.
+'\"
+'\" .UL arg1 arg2
+'\"    Print arg1 underlined, then print arg2 normally.
+'\"
+'\" RCS: @(#) $Id: tpool.n,v 1.16 2009/05/04 21:56:51 ferrieux Exp $
+'\"
+'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+'\"    # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ta \\n()Au \\n()Bu
+.ie !"\\$3"" \{\
+\&\\$1 \\fI\\$2\\fP    (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"    # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+'\"    # BS - start boxed text
+'\"    # ^y = starting y location
+'\"    # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"    # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"    Draw four-sided box normally, but don't draw top of
+.\"    box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"    # VS - start vertical sidebar
+'\"    # ^Y = starting y location
+'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"    # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"    # Special macro to handle page bottom:  finish off current
+'\"    # box/sidebar if in box/sidebar mode, then invoked standard
+'\"    # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"    Draw three-sided box if this is the box's first page,
+.\"    draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"    # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"    # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+'\"    # SO - start of list of standard options
+.de SO
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 5.5c 11c
+.ft B
+..
+'\"    # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\fBoptions\\fR manual entry for details on the standard options.
+..
+'\"    # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name:     \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class:        \\fB\\$3\\fR
+.fi
+.IP
+..
+'\"    # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+.if t .ft C
+..
+'\"    # CE - end code excerpt
+.de CE
+.fi
+.if t .ft R
+.RE
+..
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+
+.TH "tpool" n 2.6  "Tcl Threading"
+.BS
+.SH "NAME"
+tpool \-
+Part of the Tcl threading extension implementing pools of worker threads.
+.SH "SYNOPSIS"
+package require \fBTcl  8.4\fR
+.sp
+package require \fBThread  ?2.6?\fR
+.sp
+\fBtpool::create\fR ?options?
+.sp
+\fBtpool::names\fR
+.sp
+\fBtpool::post\fR ?-detached? ?-nowait? \fItpool\fR \fIscript\fR
+.sp
+\fBtpool::wait\fR \fItpool\fR \fIjoblist\fR ?varname?
+.sp
+\fBtpool::cancel\fR \fItpool\fR \fIjoblist\fR ?varname?
+.sp
+\fBtpool::get\fR \fItpool\fR \fIjob\fR
+.sp
+\fBtpool::preserve\fR \fItpool\fR
+.sp
+\fBtpool::release\fR \fItpool\fR
+.sp
+.BE
+.SH "DESCRIPTION"
+This package creates and manages pools of worker threads. It allows you
+to post jobs to worker threads and wait for their completion. The
+threadpool implementation is Tcl event-loop aware. That means that any
+time a caller is forced to wait for an event (job being completed or
+a worker thread becoming idle or initialized), the implementation will
+enter the event loop and allow for servicing of other pending file or
+timer (or any other supported) events.
+.SH "COMMANDS"
+.TP
+\fBtpool::create\fR ?options?
+This command creates new threadpool. It accepts several options as
+key-value pairs. Options are used to tune some threadpool parameters.
+The command returns the ID of the newly created threadpool.
+.sp
+Following options are supported:
+.RS
+.TP
+-minworkers number
+Minimum number of worker threads needed for this threadpool instance.
+During threadpool creation, the implementation will create somany
+worker threads upfront and will keep at least number of them alive
+during the lifetime of the threadpool instance.
+Default value of this parameter is 0 (zero). which means that a newly
+threadpool will have no worker threads initialy. All worker threads
+will be started on demand by callers running \fBtpool::post\fR command
+and posting jobs to the job queue.
+.TP
+-maxworkers number
+Maximum number of worker threads allowed for this threadpool instance.
+If a new job is pending and there are no idle worker threads available,
+the implementation will try to create new worker thread. If the number
+of available worker threads is lower than the given number,
+new worker thread will start. The caller will automatically enter the
+event loop and wait until the worker thread has initialized. If. however,
+the number of available worker threads is equal to the given number,
+the caller will enter the event loop and wait for the first worker thread
+to get idle, thus ready to run the job.
+Default value of this parameter is 4 (four), which means that the
+threadpool instance will allow maximum of 4 worker threads running jobs
+or being idle waiting for new jobs to get posted to the job queue.
+.TP
+-idletime seconds
+Time in seconds an idle worker thread waits for the job to get posted
+to the job queue. If no job arrives during this interval and the time
+expires, the worker thread will check the number of currently available
+worker threads and if the number is higher than the number set by the
+\fBminthreads\fR option, it will exit.
+If an \fBexitscript\fR has been defined, the exiting worker thread
+will first run the script and then exit. Errors from the exit script,
+if any, are ignored.
+.sp
+The idle worker thread is not servicing the event loop. If you, however,
+put the worker thread into the event loop, by evaluating the
+\fBvwait\fR or other related Tcl commands, the worker thread
+will not be in the idle state, hence the idle timer will not be
+taken into account.
+Default value for this option is unspecified, hence, the Tcl interpreter
+of the worker thread will contain just the initial set of Tcl commands.
+.TP
+-initcmd script
+Sets a Tcl script used to initialize new worker thread. This is usually
+used to load packages and commands in the worker, set default variables,
+create namespaces, and such. If the passed script runs into a Tcl error,
+the worker will not be created and the initiating command (either the
+\fBtpool::create\fR or \fBtpool::post\fR) will throw error.
+Default value for this option is unspecified, hence, the Tcl interpreter of
+the worker thread will contain just the initial set of Tcl commands.
+.TP
+-exitcmd script
+Sets a Tcl script run when the idle worker thread exits. This is normaly
+used to cleanup the state of the worker thread, release reserved resources,
+cleanup memory and such.
+Default value for this option is unspecified, thus no Tcl script will run
+on the worker thread exit.
+.RE
+.sp
+.TP
+\fBtpool::names\fR
+This command returns a list of IDs of threadpools created with the
+\fBtpool::create\fR command. If no threadpools were found, the
+command will return empty list.
+.TP
+\fBtpool::post\fR ?-detached? ?-nowait? \fItpool\fR \fIscript\fR
+This command sends a \fIscript\fR to the target \fItpool\fR threadpool
+for execution. The script will be executed in the first available idle
+worker thread. If there are no idle worker threads available, the command
+will create new one, enter the event loop and service events until the
+newly created thread is initialized. If the current number of worker
+threads is equal to the maximum number of worker threads, as defined
+during the threadpool creation, the command will enter the event loop and
+service events while waiting for one of the worker threads to become idle.
+If the optional ?-nowait? argument is given, the command will not wait
+for one idle worker. It will just place the job in the pool's job queue
+and return immediately.
+.sp
+The command returns the ID of the posted job. This ID is used for subsequent
+\fBtpool::wait\fR, \fBtpool::get\fR and \fBtpool::cancel\fR commands to wait
+for and retrieve result of the posted script, or cancel the posted job
+respectively. If the optional ?-detached? argument is specified, the
+command will post a detached job. A detached job can not be cancelled or
+waited upon and is not identified by the job ID.
+.sp
+If the threadpool \fItpool\fR is not found in the list of active
+thread pools, the command will throw error. The error will also be triggered
+if the newly created worker thread fails to initialize.
+.TP
+\fBtpool::wait\fR \fItpool\fR \fIjoblist\fR ?varname?
+This command waits for one or many jobs, whose job IDs are given in the
+\fIjoblist\fR to get processed by the worker thread(s). If none of the
+specified jobs are ready, the command will enter the event loop, service
+events and wait for the first job to get ready.
+.sp
+The command returns the list of completed job IDs. If the optional variable
+?varname? is given, it will be set to the list of jobs in the
+\fIjoblist\fR which are still pending. If the threadpool \fItpool\fR
+is not found in the list of active thread pools, the command will throw error.
+.TP
+\fBtpool::cancel\fR \fItpool\fR \fIjoblist\fR ?varname?
+This command cancels the previously posted jobs given by the \fIjoblist\fR
+to the pool \fItpool\fR. Job cancellation succeeds only for job still
+waiting to be processed. If the job is already being executed by one of
+the worker threads, the job will not be cancelled.
+The command returns the list of cancelled job IDs. If the optional variable
+?varname? is given, it will be set to the list of jobs in the
+\fIjoblist\fR which were not cancelled. If the threadpool \fItpool\fR
+is not found in the list of active thread pools, the command will throw error.
+.TP
+\fBtpool::get\fR \fItpool\fR \fIjob\fR
+This command retrieves the result of the previously posted \fIjob\fR.
+Only results of jobs waited upon with the \fBtpool::wait\fR command
+can be retrieved. If the execution of the script resulted in error,
+the command will throw the error and update the \fBerrorInfo\fR and
+\fBerrorCode\fR variables correspondingly. If the pool \fItpool\fR
+is not found in the list of threadpools, the command will throw error.
+If the job \fIjob\fR is not ready for retrieval, because it is currently
+being executed by the worker thread, the command will throw error.
+.TP
+\fBtpool::preserve\fR \fItpool\fR
+Each call to this command increments the reference counter of the
+threadpool \fItpool\fR by one (1). Command returns the value of the
+reference counter after the increment.
+By incrementing the reference counter, the caller signalizes that
+he/she wishes to use the resource for a longer period of time.
+.TP
+\fBtpool::release\fR \fItpool\fR
+Each call to this command decrements the reference counter of the
+threadpool \fItpool\fR by one (1).Command returns the value of the
+reference counter after the decrement.
+When the reference counter reaches zero (0), the threadpool \fItpool\fR
+is marked for termination. You should not reference the threadpool
+after the \fBtpool::release\fR command returns zero. The \fItpool\fR
+handle goes out of scope and should not be used any more. Any following
+reference to the same threadpool handle will result in Tcl error.
+.SH "DISCUSSION"
+Threadpool is one of the most common threading paradigm when it comes
+to server applications handling a large number of relatively small tasks.
+A very simplistic model for building a server application would be to
+create a new thread each time a request arrives and service the request
+in the new thread. One of the disadvantages of this approach is that
+the overhead of creating a new thread for each request is significant;
+a server that created a new thread for each request would spend more time
+and consume more system resources in creating and destroying threads than
+in processing actual user requests. In addition to the overhead of
+creating and destroying threads, active threads consume system resources.
+Creating too many threads can cause the system to run out of memory or
+trash due to excessive memory consumption.
+.PP
+A thread pool offers a solution to both the problem of thread life-cycle
+overhead and the problem of resource trashing. By reusing threads for
+multiple tasks, the thread-creation overhead is spread over many tasks.
+As a bonus, because the thread already exists when a request arrives,
+the delay introduced by thread creation is eliminated. Thus, the request
+can be serviced immediately. Furthermore, by properly tuning the number
+of threads in the thread pool, resource thrashing may also be eliminated
+by forcing any request to wait until a thread is available to process it.
+.SH "SEE ALSO"
+thread, tsv, ttrace
+.SH "KEYWORDS"
+thread, threadpool
diff --git a/8.x/thread/doc/man/tsv.n b/8.x/thread/doc/man/tsv.n
new file mode 100644 (file)
index 0000000..5b07ec6
--- /dev/null
@@ -0,0 +1,581 @@
+'\"
+'\" Generated from file '' by tcllib/doctools with format 'nroff'
+'\"
+'\" -*- tcl -*- doctools manpage
+'\" The definitions below are for supplemental macros used in Tcl/Tk
+'\" manual entries.
+'\"
+'\" .AP type name in/out ?indent?
+'\"    Start paragraph describing an argument to a library procedure.
+'\"    type is type of argument (int, etc.), in/out is either "in", "out",
+'\"    or "in/out" to describe whether procedure reads or modifies arg,
+'\"    and indent is equivalent to second arg of .IP (shouldn't ever be
+'\"    needed;  use .AS below instead)
+'\"
+'\" .AS ?type? ?name?
+'\"    Give maximum sizes of arguments for setting tab stops.  Type and
+'\"    name are examples of largest possible arguments that will be passed
+'\"    to .AP later.  If args are omitted, default tab stops are used.
+'\"
+'\" .BS
+'\"    Start box enclosure.  From here until next .BE, everything will be
+'\"    enclosed in one large box.
+'\"
+'\" .BE
+'\"    End of box enclosure.
+'\"
+'\" .CS
+'\"    Begin code excerpt.
+'\"
+'\" .CE
+'\"    End code excerpt.
+'\"
+'\" .VS ?version? ?br?
+'\"    Begin vertical sidebar, for use in marking newly-changed parts
+'\"    of man pages.  The first argument is ignored and used for recording
+'\"    the version when the .VS was added, so that the sidebars can be
+'\"    found and removed when they reach a certain age.  If another argument
+'\"    is present, then a line break is forced before starting the sidebar.
+'\"
+'\" .VE
+'\"    End of vertical sidebar.
+'\"
+'\" .DS
+'\"    Begin an indented unfilled display.
+'\"
+'\" .DE
+'\"    End of indented unfilled display.
+'\"
+'\" .SO
+'\"    Start of list of standard options for a Tk widget.  The
+'\"    options follow on successive lines, in four columns separated
+'\"    by tabs.
+'\"
+'\" .SE
+'\"    End of list of standard options for a Tk widget.
+'\"
+'\" .OP cmdName dbName dbClass
+'\"    Start of description of a specific option.  cmdName gives the
+'\"    option's name as specified in the class command, dbName gives
+'\"    the option's name in the option database, and dbClass gives
+'\"    the option's class in the option database.
+'\"
+'\" .UL arg1 arg2
+'\"    Print arg1 underlined, then print arg2 normally.
+'\"
+'\" RCS: @(#) $Id: tsv.n,v 1.15 2006/10/07 09:19:39 vasiljevic Exp $
+'\"
+'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+'\"    # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ta \\n()Au \\n()Bu
+.ie !"\\$3"" \{\
+\&\\$1 \\fI\\$2\\fP    (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"    # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+'\"    # BS - start boxed text
+'\"    # ^y = starting y location
+'\"    # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"    # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"    Draw four-sided box normally, but don't draw top of
+.\"    box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"    # VS - start vertical sidebar
+'\"    # ^Y = starting y location
+'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"    # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"    # Special macro to handle page bottom:  finish off current
+'\"    # box/sidebar if in box/sidebar mode, then invoked standard
+'\"    # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"    Draw three-sided box if this is the box's first page,
+.\"    draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"    # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"    # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+'\"    # SO - start of list of standard options
+.de SO
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 5.5c 11c
+.ft B
+..
+'\"    # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\fBoptions\\fR manual entry for details on the standard options.
+..
+'\"    # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name:     \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class:        \\fB\\$3\\fR
+.fi
+.IP
+..
+'\"    # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+.if t .ft C
+..
+'\"    # CE - end code excerpt
+.de CE
+.fi
+.if t .ft R
+.RE
+..
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+
+.TH "tsv" n 2.6  "Tcl Threading"
+.BS
+.SH "NAME"
+tsv \-
+Part of the Tcl threading extension allowing script level
+manipulation of data shared between threads.
+.SH "SYNOPSIS"
+package require \fBTcl  8.4\fR
+.sp
+package require \fBThread  ?2.6?\fR
+.sp
+\fBtsv::names\fR ?pattern?
+.sp
+\fBtsv::object\fR \fIvarname\fR \fIelement\fR
+.sp
+\fBtsv::set\fR \fIvarname\fR \fIelement\fR ?value?
+.sp
+\fBtsv::get\fR \fIvarname\fR \fIelement\fR ?namedvar?
+.sp
+\fBtsv::unset\fR \fIvarname\fR ?element?
+.sp
+\fBtsv::exists\fR \fIvarname\fR \fIelement\fR
+.sp
+\fBtsv::pop\fR \fIvarname\fR \fIelement\fR
+.sp
+\fBtsv::move\fR \fIvarname\fR \fIoldname\fR \fInewname\fR
+.sp
+\fBtsv::incr\fR \fIvarname\fR \fIelement\fR ?count?
+.sp
+\fBtsv::append\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value ...?
+.sp
+\fBtsv::lock\fR \fIvarname\fR \fIarg\fR ?arg ...?
+.sp
+\fBtsv::lappend\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value ...?
+.sp
+\fBtsv::linsert\fR \fIvarname\fR \fIelement\fR \fIindex\fR \fIvalue\fR ?value ...?
+.sp
+\fBtsv::lreplace\fR \fIvarname\fR \fIelement\fR \fIfirst\fR \fIlast\fR ?value ...?
+.sp
+\fBtsv::llength\fR \fIvarname\fR \fIelement\fR
+.sp
+\fBtsv::lindex\fR \fIvarname\fR \fIelement\fR ?index?
+.sp
+\fBtsv::lrange\fR \fIvarname\fR \fIelement\fR \fIfrom\fR \fIto\fR
+.sp
+\fBtsv::lsearch\fR \fIvarname\fR \fIelement\fR ?options? \fIpattern\fR
+.sp
+\fBtsv::lset\fR \fIvarname\fR \fIelement\fR \fIindex\fR ?index ...? \fIvalue\fR
+.sp
+\fBtsv::lpop\fR \fIvarname\fR \fIelement\fR ?index?
+.sp
+\fBtsv::lpush\fR \fIvarname\fR \fIelement\fR ?index?
+.sp
+\fBtsv::array set\fR \fIvarname\fR \fIlist\fR
+.sp
+\fBtsv::array get\fR \fIvarname\fR ?pattern?
+.sp
+\fBtsv::array names\fR \fIvarname\fR ?pattern?
+.sp
+\fBtsv::array size\fR \fIvarname\fR
+.sp
+\fBtsv::array reset\fR \fIvarname\fR \fIlist\fR
+.sp
+\fBtsv::array bind\fR \fIvarname\fR \fIhandle\fR
+.sp
+\fBtsv::array unbind\fR \fIvarname\fR
+.sp
+\fBtsv::array isbound\fR \fIvarname\fR
+.sp
+\fBtsv::keyldel\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR
+.sp
+\fBtsv::keylget\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR ?retvar?
+.sp
+\fBtsv::keylkeys\fR \fIvarname\fR \fIkeylist\fR ?key?
+.sp
+\fBtsv::keylset\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR \fIvalue\fR ?key value..?
+.sp
+.BE
+.SH "DESCRIPTION"
+This section describes commands implementing thread shared variables.
+A thread shared variable is very similar to a Tcl array but in
+contrast to a Tcl array it is created in shared memory and can
+be accessed from many threads at the same time. Important feature of
+thread shared variable is that each access to the variable is internaly
+protected by a mutex so script programmer does not have to take care
+about locking the variable himself.
+.PP
+Thread shared variables are not bound to any thread explicitly. That
+means that when a thread which created any of thread shared variables
+exits, the variable and associated memory is not unset/reclaimed.
+User has to explicitly unset the variable to reclaim the memory
+consumed by the variable.
+.SH "ELEMENT COMMANDS"
+.TP
+\fBtsv::names\fR ?pattern?
+Returns names of shared variables matching optional ?pattern?
+or all known variables if pattern is ommited.
+.TP
+\fBtsv::object\fR \fIvarname\fR \fIelement\fR
+Creates object accessor command for the \fIelement\fR in the
+shared variable \fIvarname\fR. Using this command, one can apply most
+of the other shared variable commands as method functions of
+the element object command. The object command is automatically
+deleted when the element which this command is pointing to is unset.
+.nf
+    % tsv::set foo bar "A shared string"
+    % set string [tsv::object foo bar]
+    % $string append " appended"
+    => A shared string appended
+.fi
+.TP
+\fBtsv::set\fR \fIvarname\fR \fIelement\fR ?value?
+Sets the value of the \fIelement\fR in the shared variable \fIvarname\fR
+to \fIvalue\fR and returns the value to caller. The \fIvalue\fR
+may be ommited, in which case the command will return the current
+value of the element. If the element cannot be found, error is triggered.
+.TP
+\fBtsv::get\fR \fIvarname\fR \fIelement\fR ?namedvar?
+Retrieves the value of the \fIelement\fR from the shared variable \fIvarname\fR.
+If the optional argument \fInamedvar\fR is given, the value is
+stored in the named variable. Return value of the command depends
+of the existence of the optional argument \fInamedvar\fR.
+If the argument is ommited and the requested element cannot be found
+in the shared array, the command triggers error. If, however, the
+optional argument is given on the command line, the command returns
+true (1) if the element is found or false (0) if the element is not found.
+.TP
+\fBtsv::unset\fR \fIvarname\fR ?element?
+Unsets the \fIelement\fR from the shared variable \fIvarname\fR.
+If the optional element is not given, it deletes the variable.
+.TP
+\fBtsv::exists\fR \fIvarname\fR \fIelement\fR
+Checks wether the \fIelement\fR exists in the shared variable \fIvarname\fR
+and returns true (1) if it does or false (0) if it doesn't.
+.TP
+\fBtsv::pop\fR \fIvarname\fR \fIelement\fR
+Returns value of the \fIelement\fR in the shared variable \fIvarname\fR
+and unsets the element, all in one atomic operation.
+.TP
+\fBtsv::move\fR \fIvarname\fR \fIoldname\fR \fInewname\fR
+Renames the element \fIoldname\fR to the \fInewname\fR in the
+shared variable \fIvarname\fR. This effectively performs an get/unset/set
+sequence of operations but all in one atomic step.
+.TP
+\fBtsv::incr\fR \fIvarname\fR \fIelement\fR ?count?
+Similar to standard Tcl \fBincr\fR command but increments the value
+of the \fIelement\fR in shared variaboe \fIvarname\fR instead of
+the Tcl variable.
+.TP
+\fBtsv::append\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value ...?
+Similar to standard Tcl \fBappend\fR command but appends one or more
+values to the \fIelement\fR in shared variable \fIvarname\fR instead of the
+Tcl variable.
+.TP
+\fBtsv::lock\fR \fIvarname\fR \fIarg\fR ?arg ...?
+This command concatenates passed arguments and evaluates the
+resulting script under the internal mutex protection. During the
+script evaluation, the entire shared variable is locked. For shared
+variable commands within the script, internal locking is disabled
+so no deadlock can occur. It is also allowed to unset the shared
+variable from within the script. The shared variable is automatically
+created if it did not exists at the time of the first lock operation.
+.nf
+    % tsv::lock foo {
+        tsv::lappend foo bar 1
+        tsv::lappend foo bar 2
+        puts stderr [tsv::set foo bar]
+        tsv::unset foo
+    }
+.fi
+.SH "LIST COMMANDS"
+Those command are similar to the equivalently named Tcl command. The difference
+is that they operate on elements of shared arrays.
+.TP
+\fBtsv::lappend\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value ...?
+Similar to standard Tcl \fBlappend\fR command but appends one
+or more values to the \fIelement\fR in shared variable \fIvarname\fR
+instead of the Tcl variable.
+.TP
+\fBtsv::linsert\fR \fIvarname\fR \fIelement\fR \fIindex\fR \fIvalue\fR ?value ...?
+Similar to standard Tcl \fBlinsert\fR command but inserts one
+or more values at the \fIindex\fR list position in the
+\fIelement\fR in the shared variable \fIvarname\fR instead of the Tcl variable.
+.TP
+\fBtsv::lreplace\fR \fIvarname\fR \fIelement\fR \fIfirst\fR \fIlast\fR ?value ...?
+Similar to standard Tcl \fBlreplace\fR command but replaces one
+or more values between the \fIfirst\fR and \fIlast\fR position
+in the \fIelement\fR of the shared variable \fIvarname\fR instead of
+the Tcl variable.
+.TP
+\fBtsv::llength\fR \fIvarname\fR \fIelement\fR
+Similar to standard Tcl \fBllength\fR command but returns length
+of the \fIelement\fR in the shared variable \fIvarname\fR instead of the Tcl
+variable.
+.TP
+\fBtsv::lindex\fR \fIvarname\fR \fIelement\fR ?index?
+Similar to standard Tcl \fBlindex\fR command but returns the value
+at the \fIindex\fR list position of the \fIelement\fR from
+the shared variable \fIvarname\fR instead of the Tcl variable.
+.TP
+\fBtsv::lrange\fR \fIvarname\fR \fIelement\fR \fIfrom\fR \fIto\fR
+Similar to standard Tcl \fBlrange\fR command but returns values
+between \fIfrom\fR and \fIto\fR list positions from the
+\fIelement\fR in the shared variable \fIvarname\fR instead of the Tcl variable.
+.TP
+\fBtsv::lsearch\fR \fIvarname\fR \fIelement\fR ?options? \fIpattern\fR
+Similar to standard Tcl \fBlsearch\fR command but searches the \fIelement\fR
+in the shared variable \fIvarname\fR instead of the Tcl variable.
+.TP
+\fBtsv::lset\fR \fIvarname\fR \fIelement\fR \fIindex\fR ?index ...? \fIvalue\fR
+Similar to standard Tcl \fBlset\fR command but sets the \fIelement\fR
+in the shared variable \fIvarname\fR instead of the Tcl variable.
+.TP
+\fBtsv::lpop\fR \fIvarname\fR \fIelement\fR ?index?
+Similar to the standard Tcl \fBlindex\fR command but in addition to
+returning, it also splices the value out of the \fIelement\fR
+from the shared variable \fIvarname\fR in one atomic operation.
+In contrast to the Tcl \fBlindex\fR command, this command returns
+no value to the caller.
+.TP
+\fBtsv::lpush\fR \fIvarname\fR \fIelement\fR ?index?
+This command performes the opposite of the \fBtsv::lpop\fR command.
+As its counterpart, it returns no value to the caller.
+.SH "ARRAY COMMANDS"
+This command supports most of the options of the standard Tcl
+\fBarray\fR command. In addition to those, it allows binding
+a shared variable to some persisten storage databases. Currently
+the only persistent option supported is the famous GNU Gdbm
+database. This option has to be selected during the package
+compilation time. The implementation provides hooks for
+defining other persistency layers, if needed.
+.TP
+\fBtsv::array set\fR \fIvarname\fR \fIlist\fR
+Does the same as standard Tcl \fBarray set\fR.
+.TP
+\fBtsv::array get\fR \fIvarname\fR ?pattern?
+Does the same as standard Tcl \fBarray get\fR.
+.TP
+\fBtsv::array names\fR \fIvarname\fR ?pattern?
+Does the same as standard Tcl \fBarray names\fR.
+.TP
+\fBtsv::array size\fR \fIvarname\fR
+Does the same as standard Tcl \fBarray size\fR.
+.TP
+\fBtsv::array reset\fR \fIvarname\fR \fIlist\fR
+Does the same as standard Tcl \fBarray set\fR but it clears
+the \fIvarname\fR and sets new values from the list atomically.
+.TP
+\fBtsv::array bind\fR \fIvarname\fR \fIhandle\fR
+Binds the \fIvarname\fR to the persistent storage \fIhandle\fR.
+The format of the \fIhandle\fR is <handler>:<address>. For the built-in
+GNU Gdbm persistence layer, the format of the handle is "gdbm:<path>"
+where <path> is the path to the Gdbm database file.
+.TP
+\fBtsv::array unbind\fR \fIvarname\fR
+Unbinds the shared \fIarray\fR from its bound persistent storage.
+.TP
+\fBtsv::array isbound\fR \fIvarname\fR
+Returns true (1) if the shared \fIvarname\fR is bound to some
+persistent storage or zero (0) if not.
+.SH "KEYED LIST COMMANDS"
+Keyed list commands are borrowed from the TclX package. Keyed lists provide
+a structured data type built upon standard Tcl lists. This is a functionality
+similar to structs in the C programming language.
+.PP
+A keyed list is a list in which each element contains a key and value
+pair. These element pairs are stored as lists themselves, where the key
+is the first element of the list, and the value is the second. The
+key-value pairs are referred to as fields.  This is an example of a
+keyed list:
+.nf
+    {{NAME  {Frank  Zappa}} {JOB {musician and composer}}}
+.fi
+Fields may contain subfields; `.' is the separator character. Subfields
+are actually fields  where the value is another keyed list. Thus the
+following list has the top level fields ID and NAME, and subfields
+NAME.FIRST and NAME.LAST:
+.nf
+    {ID 106} {NAME {{FIRST Frank} {LAST Zappa}}}
+.fi
+There is no limit to the recursive depth of subfields,
+allowing one to build complex data structures. Keyed lists are constructed
+and accessed via a number of commands. All  keyed  list management
+commands take the name of the variable containing the keyed list as an
+argument (i.e. passed by reference), rather than passing the list directly.
+.TP
+\fBtsv::keyldel\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR
+Delete the field specified by \fIkey\fR from the keyed list \fIkeylist\fR
+in the shared variable \fIvarname\fR.
+This removes both the key and the value from the keyed list.
+.TP
+\fBtsv::keylget\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR ?retvar?
+Return the value associated with \fIkey\fR from the keyed list \fIkeylist\fR
+in the shared variable \fIvarname\fR.
+If the optional \fIretvar\fR is not specified, then the value will be
+returned as the result of the command. In this case, if key is not found
+in the list, an error will result.
+.sp
+If \fIretvar\fR is specified and \fIkey\fR is in the list, then the value
+is returned in the variable \fIretvar\fR and the command returns 1 if the
+key was present within the list. If \fIkey\fR isn't in the list, the
+command will return 0, and \fIretvar\fR will be left unchanged. If {} is
+specified for \fIretvar\fR, the value is not returned, allowing the Tcl
+programmer to determine if a \fIkey\fR is present in a keyed list without
+setting a variable as a side-effect.
+.TP
+\fBtsv::keylkeys\fR \fIvarname\fR \fIkeylist\fR ?key?
+Return  the a list of the keys in the keyed list \fIkeylist\fR in the
+shared variable \fIvarname\fR. If \fIkey\fR is specified, then it is
+the name of a key field who's subfield keys are to be retrieved.
+.TP
+\fBtsv::keylset\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR \fIvalue\fR ?key value..?
+Set the value associated with \fIkey\fR, in the keyed list \fIkeylist\fR
+to \fIvalue\fR. If the \fIkeylist\fR does not exists, it is created.
+If \fIkey\fR is not currently in the list, it will be added. If it already
+exists, \fIvalue\fR replaces the existing value. Multiple keywords and
+values may be specified, if desired.
+.SH "DISCUSSION"
+The current implementation of thread shared variables allows for easy and
+convenient access to data shared between different threads.
+Internally, the data is stored in Tcl objects and all package commands
+operate on internal data representation, thus minimizing shimmering and
+improving performance. Special care has been taken to assure that all
+object data is properly locked and deep-copied when moving objects between
+threads.
+.PP
+Due to the internal design of the Tcl core, there is no provision of full
+integration of shared variables within the Tcl syntax, unfortunately. All
+access to shared data must be performed with the supplied package commands.
+Also, variable traces are not supported. But even so, benefits of easy,
+simple and safe shared data manipulation outweights imposed limitations.
+.SH "CREDITS"
+Thread shared variables are inspired by the nsv interface found in
+AOLserver, a highly scalable Web server from America Online.
+.SH "SEE ALSO"
+thread, tpool, ttrace
+.SH "KEYWORDS"
+locking, synchronization, thread shared data, threads
diff --git a/8.x/thread/doc/man/ttrace.n b/8.x/thread/doc/man/ttrace.n
new file mode 100644 (file)
index 0000000..29f19c9
--- /dev/null
@@ -0,0 +1,474 @@
+'\"
+'\" Generated from file '' by tcllib/doctools with format 'nroff'
+'\"
+'\" -*- tcl -*- doctools manpage
+'\" The definitions below are for supplemental macros used in Tcl/Tk
+'\" manual entries.
+'\"
+'\" .AP type name in/out ?indent?
+'\"    Start paragraph describing an argument to a library procedure.
+'\"    type is type of argument (int, etc.), in/out is either "in", "out",
+'\"    or "in/out" to describe whether procedure reads or modifies arg,
+'\"    and indent is equivalent to second arg of .IP (shouldn't ever be
+'\"    needed;  use .AS below instead)
+'\"
+'\" .AS ?type? ?name?
+'\"    Give maximum sizes of arguments for setting tab stops.  Type and
+'\"    name are examples of largest possible arguments that will be passed
+'\"    to .AP later.  If args are omitted, default tab stops are used.
+'\"
+'\" .BS
+'\"    Start box enclosure.  From here until next .BE, everything will be
+'\"    enclosed in one large box.
+'\"
+'\" .BE
+'\"    End of box enclosure.
+'\"
+'\" .CS
+'\"    Begin code excerpt.
+'\"
+'\" .CE
+'\"    End code excerpt.
+'\"
+'\" .VS ?version? ?br?
+'\"    Begin vertical sidebar, for use in marking newly-changed parts
+'\"    of man pages.  The first argument is ignored and used for recording
+'\"    the version when the .VS was added, so that the sidebars can be
+'\"    found and removed when they reach a certain age.  If another argument
+'\"    is present, then a line break is forced before starting the sidebar.
+'\"
+'\" .VE
+'\"    End of vertical sidebar.
+'\"
+'\" .DS
+'\"    Begin an indented unfilled display.
+'\"
+'\" .DE
+'\"    End of indented unfilled display.
+'\"
+'\" .SO
+'\"    Start of list of standard options for a Tk widget.  The
+'\"    options follow on successive lines, in four columns separated
+'\"    by tabs.
+'\"
+'\" .SE
+'\"    End of list of standard options for a Tk widget.
+'\"
+'\" .OP cmdName dbName dbClass
+'\"    Start of description of a specific option.  cmdName gives the
+'\"    option's name as specified in the class command, dbName gives
+'\"    the option's name in the option database, and dbClass gives
+'\"    the option's class in the option database.
+'\"
+'\" .UL arg1 arg2
+'\"    Print arg1 underlined, then print arg2 normally.
+'\"
+'\" RCS: @(#) $Id: ttrace.n,v 1.12 2006/10/07 09:19:39 vasiljevic Exp $
+'\"
+'\"    # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+'\"    # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ta \\n()Au \\n()Bu
+.ie !"\\$3"" \{\
+\&\\$1 \\fI\\$2\\fP    (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+'\"    # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+'\"    # BS - start boxed text
+'\"    # ^y = starting y location
+'\"    # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+'\"    # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"    Draw four-sided box normally, but don't draw top of
+.\"    box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+'\"    # VS - start vertical sidebar
+'\"    # ^Y = starting y location
+'\"    # ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+'\"    # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+'\"    # Special macro to handle page bottom:  finish off current
+'\"    # box/sidebar if in box/sidebar mode, then invoked standard
+'\"    # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"    Draw three-sided box if this is the box's first page,
+.\"    draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+'\"    # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+'\"    # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+'\"    # SO - start of list of standard options
+.de SO
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 5.5c 11c
+.ft B
+..
+'\"    # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\fBoptions\\fR manual entry for details on the standard options.
+..
+'\"    # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name:     \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class:        \\fB\\$3\\fR
+.fi
+.IP
+..
+'\"    # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+.if t .ft C
+..
+'\"    # CE - end code excerpt
+.de CE
+.fi
+.if t .ft R
+.RE
+..
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+
+.TH "ttrace" n 2.6  "Tcl Threading"
+.BS
+.SH "NAME"
+ttrace \- Trace-based interpreter initialization
+.SH "SYNOPSIS"
+package require \fBTcl  8.4\fR
+.sp
+package require \fBThread  ?2.6?\fR
+.sp
+\fBttrace::eval\fR \fIarg\fR ?arg ...?
+.sp
+\fBttrace::enable\fR
+.sp
+\fBttrace::disable\fR
+.sp
+\fBttrace::cleanup\fR
+.sp
+\fBttrace::update\fR ?epoch?
+.sp
+\fBttrace::getscript\fR
+.sp
+\fBttrace::atenable\fR \fIcmd\fR \fIarglist\fR \fIbody\fR
+.sp
+\fBttrace::atdisable\fR \fIcmd\fR \fIarglist\fR \fIbody\fR
+.sp
+\fBttrace::addtrace\fR \fIcmd\fR \fIarglist\fR \fIbody\fR
+.sp
+\fBttrace::addscript\fR \fIname\fR \fIbody\fR
+.sp
+\fBttrace::addresolver\fR \fIcmd\fR \fIarglist\fR \fIbody\fR
+.sp
+\fBttrace::addcleanup\fR \fIbody\fR
+.sp
+\fBttrace::addentry\fR \fIcmd\fR \fIvar\fR \fIval\fR
+.sp
+\fBttrace::getentry\fR \fIcmd\fR \fIvar\fR
+.sp
+\fBttrace::getentries\fR \fIcmd\fR ?pattern?
+.sp
+\fBttrace::delentry\fR \fIcmd\fR
+.sp
+\fBttrace::preload\fR \fIcmd\fR
+.sp
+.BE
+.SH "DESCRIPTION"
+This package creates a framework for on-demand replication of the
+interpreter state accross threads in an multithreading application.
+It relies on the mechanics of Tcl command tracing and the Tcl
+\fBunknown\fR command and mechanism.
+.PP
+The package requires Tcl threading extension but can be alternatively
+used stand-alone within the AOLserver, a scalable webserver from
+America Online.
+.PP
+In a nutshell, a short sample illustrating the usage of the ttrace
+with the Tcl threading extension:
+.nf
+
+    % package require Ttrace
+    2.6.5
+
+    % set t1 [thread::create {package require Ttrace; thread::wait}]
+    tid0x1802800
+
+    % ttrace::eval {proc test args {return test-[thread::id]}}
+    % thread::send $t1 test
+    test-tid0x1802800
+
+    % set t2 [thread::create {package require Ttrace; thread::wait}]
+    tid0x1804000
+
+    % thread::send $t2 test
+    test-tid0x1804000
+
+.fi
+.PP
+As seen from above, the \fBttrace::eval\fR and \fBttrace::update\fR
+commands are used to create a thread-wide definition of a simple
+Tcl procedure and replicate that definition to all, already existing
+or later created, threads.
+.SH "USER COMMANDS"
+This section describes user-level commands. Those commands can be
+used by script writers to control the execution of the tracing
+framework.
+.TP
+\fBttrace::eval\fR \fIarg\fR ?arg ...?
+This command concatenates given arguments and evaluates the resulting
+Tcl command with trace framework enabled. If the command execution
+was ok, it takes necessary steps to automatically propagate the
+trace epoch change to all threads in the application.
+For AOLserver, only newly created threads actually receive the
+epoch change. For the Tcl threading extension, all threads created by
+the extension are automatically updated. If the command execution
+resulted in Tcl error, no state propagation takes place.
+.sp
+This is the most important user-level command of the package as
+it wraps most of the commands described below. This greatly
+simplifies things, because user need to learn just this (one)
+command in order to effectively use the package. Other commands,
+as desribed below, are included mostly for the sake of completeness.
+.TP
+\fBttrace::enable\fR
+Activates all registered callbacks in the framework
+and starts a new trace epoch. The trace epoch encapsulates all
+changes done to the interpreter during the time traces are activated.
+.TP
+\fBttrace::disable\fR
+Deactivates all registered callbacks in the framework
+and closes the current trace epoch.
+.TP
+\fBttrace::cleanup\fR
+Used to clean-up all on-demand loaded resources in the interpreter.
+It effectively brings Tcl interpreter to its pristine state.
+.TP
+\fBttrace::update\fR ?epoch?
+Used to refresh the state of the interpreter to match the optional
+trace ?epoch?. If the optional ?epoch? is not given, it takes
+the most recent trace epoch.
+.TP
+\fBttrace::getscript\fR
+Returns a synthetized Tcl script which may be sourced in any interpreter.
+This script sets the stage for the Tcl \fBunknown\fR command so it can
+load traced resources from the in-memory database. Normally, this command
+is automatically invoked by other higher-level commands like
+\fBttrace::eval\fR and \fBttrace::update\fR.
+.SH "CALLBACK COMMANDS"
+A word upfront: the package already includes callbacks for tracing
+following Tcl commands: \fBproc\fR, \fBnamespace\fR, \fBvariable\fR,
+\fBload\fR, and \fBrename\fR. Additionaly, a set of callbacks for
+tracing resources (object, clasess) for the XOTcl v1.3.8+, an
+OO-extension to Tcl, is also provided.
+This gives a solid base for solving most of the real-life needs and
+serves as an example for people wanting to customize the package
+to cover their specific needs.
+.PP
+Below, you can find commands for registering callbacks in the
+framework and for writing callback scripts. These callbacks are
+invoked by the framework in order to gather interpreter state
+changes, build in-memory database, perform custom-cleanups and
+various other tasks.
+.TP
+\fBttrace::atenable\fR \fIcmd\fR \fIarglist\fR \fIbody\fR
+Registers Tcl callback to be activated at \fBttrace::enable\fR.
+Registered callbacks are activated on FIFO basis. The callback
+definition includes the name of the callback, \fIcmd\fR, a list
+of callback arguments, \fIarglist\fR and the \fIbody\fR of the
+callback. Effectively, this actually resembles the call interface
+of the standard Tcl \fBproc\fR command.
+.TP
+\fBttrace::atdisable\fR \fIcmd\fR \fIarglist\fR \fIbody\fR
+Registers Tcl callback to be activated at \fBttrace::disable\fR.
+Registered callbacks are activated on FIFO basis. The callback
+definition includes the name of the callback, \fIcmd\fR, a list
+of callback arguments, \fIarglist\fR and the \fIbody\fR of the
+callback. Effectively, this actually resembles the call interface
+of the standard Tcl \fBproc\fR command.
+.TP
+\fBttrace::addtrace\fR \fIcmd\fR \fIarglist\fR \fIbody\fR
+Registers Tcl callback to be activated for tracing the Tcl
+\fBcmd\fR command. The callback definition includes the name of
+the Tcl command to trace, \fIcmd\fR, a list of callback arguments,
+\fIarglist\fR and the \fIbody\fR of the callback. Effectively,
+this actually resembles the call interface of the standard Tcl
+\fBproc\fR command.
+.TP
+\fBttrace::addscript\fR \fIname\fR \fIbody\fR
+Registers Tcl callback to be activated for building a Tcl
+script to be passed to other interpreters. This script is
+used to set the stage for the Tcl \fBunknown\fR command.
+Registered callbacks are activated on FIFO basis.
+The callback definition includes the name of the callback,
+\fIname\fR and the \fIbody\fR of the callback.
+.TP
+\fBttrace::addresolver\fR \fIcmd\fR \fIarglist\fR \fIbody\fR
+Registers Tcl callback to be activated by the overloaded Tcl
+\fBunknown\fR command.
+Registered callbacks are activated on FIFO basis.
+This callback is used to resolve the resource and load the
+resource in the current interpreter.
+.TP
+\fBttrace::addcleanup\fR \fIbody\fR
+Registers Tcl callback to be activated by the \fBtrace::cleanup\fR.
+Registered callbacks are activated on FIFO basis.
+.TP
+\fBttrace::addentry\fR \fIcmd\fR \fIvar\fR \fIval\fR
+Adds one entry to the named in-memory database.
+.TP
+\fBttrace::getentry\fR \fIcmd\fR \fIvar\fR
+Returns the value of the entry from the named in-memory database.
+.TP
+\fBttrace::getentries\fR \fIcmd\fR ?pattern?
+Returns names of all entries from the named in-memory database.
+.TP
+\fBttrace::delentry\fR \fIcmd\fR
+Deletes an entry from the named in-memory database.
+.TP
+\fBttrace::preload\fR \fIcmd\fR
+Registers the Tcl command to be loaded in the interpreter.
+Commands registered this way will always be the part of
+the interpreter and not be on-demand loaded by the Tcl
+\fBunknown\fR command.
+.SH "DISCUSSION"
+Common introspective state-replication approaches use a custom Tcl
+script to introspect the running interpreter and synthesize another
+Tcl script to replicate this state in some other interpreter.
+This package, on the contrary, uses Tcl command traces. Command
+traces are registered on selected Tcl commands, like \fBproc\fR,
+\fBnamespace\fR, \fBload\fR and other standard (and/or user-defined)
+Tcl commands. When activated, those traces build an in-memory
+database of created resources. This database is used as a resource
+repository for the (overloaded) Tcl \fBunknown\fR command which
+creates the requested resource in the interpreter on demand.
+This way, users can update just one interpreter (master) in one
+thread and replicate that interpreter state (or part of it) to other
+threads/interpreters in the process.
+.PP
+Immediate benefit of such approach is the much smaller memory footprint
+of the application and much faster thread creation. By not actually
+loading all necessary procedures (and other resources) in every thread
+at the thread initialization time, but by deffering this to the time the
+resource is actually referenced, significant improvements in both
+memory consumption and thread initialization time can be achieved. Some
+tests have shown that memory footprint of an multithreading Tcl application
+went down more than three times and thread startup time was reduced for
+about 50 times. Note that your mileage may vary.
+Other benefits include much finer control about what (and when) gets
+replicated from the master to other Tcl thread/interpreters.
+.SH "SEE ALSO"
+thread, tpool, tsv
+.SH "KEYWORDS"
+command tracing, introspection
diff --git a/8.x/thread/doc/thread.man b/8.x/thread/doc/thread.man
new file mode 100644 (file)
index 0000000..e758a5d
--- /dev/null
@@ -0,0 +1,594 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin thread n 2.6]
+[moddesc {Tcl Threading}]
+[titledesc {Extension for script access to Tcl threading}]
+[require Tcl 8.4]
+[require Thread [opt 2.6]]
+
+[description]
+The [package thread] extension creates threads that contain Tcl 
+interpreters, and it lets you send scripts to those threads for
+evaluation.
+
+Additionaly, it provides script-level access to basic thread 
+synchronization primitives, like mutexes and condition variables.
+
+[section COMMANDS]
+This section describes commands for creating and destroying threads
+and sending scripts to threads for evaluation.
+
+
+
+[list_begin definitions]
+
+[call [cmd thread::create] [opt -joinable] [opt -preserved] [opt script]]
+
+This command creates a thread that contains a Tcl interpreter. 
+The Tcl interpreter either evaluates the optional [option script], if
+specified, or it waits in the event loop for scripts that arrive via
+the [cmd thread::send] command. The result, if any, of the
+optional [option script] is never returned to the caller.
+The result of [cmd thread::create] is the ID of the thread. This is
+the opaque handle which identifies the newly created thread for
+all other package commands. The handle of the thread goes out of scope
+automatically when thread is marked for exit
+(see the [cmd thread::release] command below).
+
+[nl]
+
+If the optional [option script] argument contains the [cmd thread::wait]
+command the thread will enter into the event loop. If such command is not
+found  in the [option script] the thread will run the [option script] to 
+the end and exit. In that case, the handle may be safely ignored since it 
+refers to a thread which does not exists any more at the time when the 
+command returns.
+
+[nl]
+
+Using flag [option -joinable] it is possible to create a joinable
+thread, i.e. one upon whose exit can be waited upon by using 
+[cmd thread::join] command. 
+Note that failure to join a thread created with [option -joinable] flag
+results in resource and memory leaks. 
+
+
+[nl]
+
+Threads created by the [cmd thread::create] cannot be destroyed 
+forcefully. Consequently, there is no corresponding thread destroy
+command. A thread may only be released using the [cmd thread::release] 
+and if its internal reference count drops to zero, the thread is 
+marked for exit. This kicks the thread out of the event loop 
+servicing and the thread continues to execute commands passed in 
+the [option script] argument, following the [cmd thread::wait]
+command. If this was the last command in the script, as usualy the
+case, the thread will exit.
+
+[nl]
+
+It is possible to create a situation in which it may be impossible
+to terminate the thread, for example by putting some endless loop 
+after the [cmd thread::wait] or entering the event loop again by 
+doing an vwait-type of command. In such cases, the thread may never
+exit. This is considered to be a bad practice and should be avoided 
+if possible. This is best illustrated by the example below:
+
+[example {
+    # You should never do ...
+    set tid [thread::create {
+        package require Http
+        thread::wait
+        vwait forever ; # <-- this!
+    }]
+}]
+
+The thread created in the above example will never be able to exit.
+After it has been released with the last matching [cmd thread::release]
+call, the thread will jump out of the [cmd thread::wait] and continue 
+to execute commands following. It will enter [cmd vwait] command and 
+wait endlessly for events. There is no way one can terminate such thread,
+so you wouldn't want to do this!
+
+[nl]
+
+Each newly created has its internal reference counter set to 0 (zero), 
+i.e. it is unreserved. This counter gets incremented by a call to 
+[cmd thread::preserve] and decremented by a call to [cmd thread::release]
+command. These two commands implement simple but effective thread 
+reservation system and offer predictable and controllable thread 
+termination capabilities. It is however possible to create initialy 
+preserved threads by using flag [option -preserved] of the 
+[cmd thread::create] command. Threads created with this flag have the 
+initial value of the reference counter of 1 (one), and are thus 
+initially marked reserved. 
+
+
+[call [cmd thread::preserve] [opt id]]
+
+This command increments the thread reference counter. Each call
+to this command increments the reference counter by one (1). 
+Command returns the value of the reference counter after the increment. 
+If called with the optional thread [option id], the command preserves
+the given thread. Otherwise the current thread is preserved.
+
+[nl]
+
+With reference counting, one can implement controlled access to a 
+shared Tcl thread. By incrementing the reference counter, the 
+caller signalizes that he/she wishes to use the thread for a longer
+period of time. By decrementing the counter, caller signalizes that 
+he/she has finished using the thread.
+
+[call [cmd thread::release] [opt -wait] [opt id]]
+
+This command decrements the thread reference counter. Each call to 
+this command decrements the reference counter by one (1). 
+If called with the optional thread [option id], the command releases
+the given thread. Otherwise, the current thread is released.
+Command returns the value of the reference counter after the decrement.
+When the reference counter reaches zero (0), the target thread is 
+marked for termination. You should not reference the thread after the
+[cmd thread::release] command returns zero or negative integer. 
+The handle of the thread goes out of scope and should not be used any
+more. Any following reference to the same thread handle will result 
+in Tcl error.
+
+[nl]
+
+Optional flag [option -wait] instructs the caller thread to wait for 
+the target thread to exit, if the effect of the command would result 
+in termination of the target thread, i.e. if the return result would
+be zero (0). Without the flag, the caller thread does not wait for 
+the target thread to exit. Care must be taken when using the 
+[option -wait], since this may block the caller thread indefinitely.
+This option has been implemented for some special uses of the extension
+and is deprecated for regular use. Regular users should create joinable
+threads by using the [option -joinable] option of the [cmd thread::create]
+command and the [cmd thread::join] to wait for thread to exit. 
+
+[call [cmd thread::id]]
+
+This command returns the ID of the current thread.
+
+[call [cmd thread::errorproc] [opt procname]]
+
+This command sets a handler for errors that occur in scripts sent 
+asynchronously, using the [option -async] flag of the 
+[cmd thread::send] command, to other threads. If no handler 
+is specified, the current handler is returned. The empty string
+resets the handler to default (unspecified) value.
+An uncaught error in a thread causes an error message to be sent
+to the standard error channel. This default reporting scheme can
+be changed by registering a procedure which is called to report
+the error. The [arg procname] is called in the interpreter that
+invoked the [cmd thread::errorproc] command. The [arg procname]
+is called like this:
+
+[example {
+    myerrorproc thread_id errorInfo
+}]
+
+[call [cmd thread::unwind]]
+
+Use of this command is deprecated in favour of more advanced thread
+reservation system implemented with [cmd thread::preserve] and 
+[cmd thread::release] commands. Support for [cmd thread::unwind] 
+command will dissapear in some future major release of the extension.
+[nl]
+This command stops a prior [cmd thread::wait] command. Execution of
+the script passed to newly created thread will continue from the 
+[cmd thread::wait] command. If [cmd thread::wait] was the last command
+in the script, the thread will exit. The command returns empty result
+but may trigger Tcl error with the message "target thread died" in some
+situations.
+
+
+[call [cmd thread::exit]]
+
+Use of this command is deprecated in favour of more advanced thread
+reservation system implemented with [cmd thread::preserve] and 
+[cmd thread::release] commands. Support for [cmd thread::exit] 
+command will dissapear in some future major release of the extension.
+[nl]
+This command forces a thread stuck in the [cmd thread::wait]
+command to unconditionaly exit. The execution of [cmd thread::exit]
+command is guaranteed to leave the program memory in the unconsistent
+state, produce memory leaks and otherwise affect other subsytem(s)
+of the Tcl application in an unpredictable manner. The command 
+returns empty result but may trigger Tcl error with the message
+"target thread died" in some situations.
+
+[call [cmd thread::names]]
+
+This command returns a list of thread IDs. These are only for
+threads that have been created via [cmd thread::create] command.
+If your application creates other threads at the C level, they
+are not reported by this command.
+
+
+[call [cmd thread::exists] [arg id]]
+
+Returns true (1) if thread given by the [arg id] parameter exists, 
+false (0) otherwise. This applies only for threads that have
+been created via [cmd thread::create] command.
+
+
+[call [cmd thread::send] [opt -async] [opt -head] [arg id] [arg script] [opt varname]]
+
+This command passes a [arg script] to another thread and, optionally,
+waits for the result. If the [option -async] flag is specified, the 
+command does not wait for the result and it returns empty string.
+The target thread must enter it's event loop in order to receive 
+scripts sent via this command. This is done by default for threads 
+created without a startup script. Threads can enter the event loop 
+explicitly by calling [cmd thread::wait] or any other relevant Tcl/Tk
+command, like [cmd update], [cmd vwait], etc. 
+
+[nl]
+
+Optional [option varname] specifies name of the variable to store
+the result of the [arg script]. Without the [option -async] flag,
+the command returns the evaluation code, similarily to the standard 
+Tcl [cmd catch] command. If, however, the [option -async] flag is
+specified, the command returns immediately and caller can later 
+[cmd vwait] on [opt varname] to get the result of the passed [arg script]
+
+[example {
+    set t1 [thread::create]
+    set t2 [thread::create] 
+    thread::send -async $t1 "set a 1" result
+    thread::send -async $t2 "set b 2" result 
+    for {set i 0} {$i < 2} {incr i} {
+        vwait result
+    }
+}]
+
+In the above example, two threads were fed work and both of them were
+instructed to signalize the same variable "result" in the calling thread.
+The caller entered the event loop twice to get both results. Note, 
+however, that the order of the received results may vary, depending on 
+the current system load, type of work done, etc, etc.
+
+[nl]
+
+Many threads can simultaneously send scripts to the target thread for 
+execution. All of them are entered into the event queue of the target 
+thread and executed on the FIFO basis, intermingled with optional other
+events pending in the event queue of the target thread.
+Using the optional [opt -head] switch, scripts posted to the thread's
+event queue can be placed on the head, instead on the tail of the queue,
+thus being executed in the LIFO fashion.
+
+
+[call [cmd thread::broadcast] [arg id] [arg script]]
+
+This command passes a [arg script] to all threads created by the
+package for execution. It does not wait for response from any of
+the threads.
+
+[call [cmd thread::wait]]
+
+This enters the event loop so a thread can receive messages from 
+the [cmd thread::send] command. This command should only be used
+within the script passed to the [cmd thread::create]. It should
+be the very last command in the script. If this is not the case,
+the exiting thread will continue executing the script lines past
+the [cmd thread::wait] which is usually not what you want and/or
+expect.
+
+[example {
+    set t1 [thread::create {
+        #
+        # Do some initialization work here
+        #
+        thread::wait ; # Enter the event loop
+    }]
+}]
+
+[call [cmd thread::eval] [opt {-lock mutex}] [arg arg] [opt {arg ...}]]
+
+This command concatenates passed arguments and evaluates the 
+resulting script under the mutex protection. If no mutex is
+specified by using the [opt {-lock mutex}] optional argument,
+the internal static mutex is used.
+
+
+[call [cmd thread::join] [arg id]]
+
+This command waits for the thread with ID [arg id] to exit and
+then returns it's exit code. Errors will be returned for threads
+which are not joinable or already waited upon by another thread.
+Upon the join the handle of the thread has gone out of scope and
+should not be used any more.
+
+
+[call [cmd thread::configure] [arg id] [opt option] [opt value] [opt ...]]
+
+This command configures various low-level aspects of the thread with
+ID [arg id] in the similar way as the standard Tcl command 
+[cmd fconfigure] configures some Tcl channel options. Options currently
+supported are: [option -eventmark] and [option -unwindonerror].
+
+[nl]
+
+The [option -eventmark] option, when set, limits the number of 
+asynchronously posted scripts to the thread event loop. 
+The [cmd {thread::send -async}] command will block until the number
+of pending scripts in the event loop does not drop below the value
+configured with [option -eventmark]. Default value for the 
+[option -eventmark] is 0 (zero) which effectively disables the checking,
+i.e. allows for unlimited number of posted scripts.
+
+[nl]
+
+The [option -unwindonerror] option, when set, causes the 
+target thread to unwind if the result of the script processing 
+resulted in error. Default value for the [option -unwindonerror]
+is 0 (false), i.e. thread continues to process scripts after one
+of the posted scripts fails.
+
+
+[call [cmd thread::transfer] [arg id] [arg channel]]
+
+This moves the specified [arg channel] from the current thread 
+and interpreter to the main interpreter of the thread with the 
+given [arg id]. After the move the current interpreter has no
+access to the channel any more, but the main interpreter of the
+target thread will be able to use it from now on.
+The command waits until the other thread has incorporated the
+channel. Because of this it is possible to deadlock the 
+participating threads by commanding the other through a 
+synchronous [cmd thread::send] to transfer a channel to us.
+This easily extends into longer loops of threads waiting for 
+each other. Other restrictions: the channel in question must 
+not be shared among multiple interpreters running in the 
+sending thread. This automatically excludes the special channels
+for standard input, output and error.
+
+[nl]
+
+Due to the internal Tcl core implementation and the restriction on 
+transferring shared channels, one has to take extra measures when
+transferring socket channels created by accepting the connection
+out of the [cmd socket] commands callback procedures:
+
+[example {
+    socket -server _Accept 2200
+    proc _Accept {s ipaddr port} {
+        after idle [list Accept $s $ipaddr $port]
+    }
+    proc Accept {s ipaddr port} {
+        set tid [thread::create]
+        thread::transfer $tid $s
+    }
+}]
+
+[call [cmd thread::detach] [arg channel]]
+
+This detaches the specified [arg channel] from the current thread and 
+interpreter. After that, the current interpreter has no access to the
+channel any more. The channel is in the parked state until some other
+(or the same) thread attaches the channel again with [cmd thread::attach].
+Restrictions: same as for transferring shared channels with the
+[cmd thread::transfer] command.
+
+[call [cmd thread::attach] [arg channel]]
+
+This attaches the previously detached [arg channel] in the
+current thread/interpreter. For already existing channels, 
+the command does nothing, i.e. it is not an error to attach the
+same channel more than once. The first operation will actualy
+perform the operation, while all subsequent operation will just
+do nothing. Command throws error if the [arg channel] cannot be
+found in the list of detached channels and/or in the current
+interpreter.
+
+[call [cmd thread::mutex]]
+
+Mutexes are most common thread synchronization primitives. 
+They are used to synchronize access from two or more threads to one or 
+more shared resources. This command provides script-level access to 
+exclusive and/or recursive mutexes. Exclusive mutexes can be locked 
+only once by one thread, while recursive mutexes can be locked many 
+times by the same thread. For recursive mutexes, number of lock and 
+unlock operations must match, otherwise, the mutex will never be 
+released, which would lead to various deadlock situations.
+[nl]
+Care has to be taken when using mutexes in an multithreading program.
+Improper use of mutexes may lead to various deadlock situations, 
+especially when using exclusive mutexes.
+
+[nl]
+
+The [cmd thread::mutex] command supports following subcommands and options:
+
+[list_begin definitions]
+
+[call [cmd thread::mutex] [method create] [opt -recursive]]
+
+Creates the mutex and returns it's opaque handle. This handle
+should be used for any future reference to the newly created mutex.
+If no optional [opt -recursive] argument was specified, the command
+creates the exclusive mutex. With the [opt -recursive] argument,
+the command creates a recursive mutex.
+
+[call [cmd thread::mutex] [method destroy] [arg mutex]]
+
+Destroys the [arg mutex]. Mutex should be in unlocked state before
+the destroy attempt. If the mutex is locked, the command will throw 
+Tcl error. 
+
+[call [cmd thread::mutex] [method lock] [arg mutex]]
+
+Locks the [arg mutex]. Locking the exclusive mutex may throw Tcl 
+error if on attempt to lock the same mutex twice from the same
+thread. If your program logic forces you to lock the same mutex 
+twice or more from the same thread (this may happen in recursive 
+procedure invocations) you should consider using the recursive mutexes. 
+
+[call [cmd thread::mutex] [method unlock] [arg mutex]]
+
+Unlocks the [arg mutex] so some other thread may lock it again.
+Attempt to unlock the already unlocked mutex will throw Tcl error.
+
+[list_end]
+
+[nl]
+
+[call [cmd thread::rwmutex]]
+
+This command creates many-readers/single-writer mutexes. Reader/writer
+mutexes allow you to serialize access to a shared resource more optimally. 
+In situations where a shared resource gets mostly read and seldom modified, 
+you might gain some performace by using reader/writer mutexes instead of 
+exclusive or recursive mutexes. 
+[nl]
+For reading the resource, thread should obtain a read lock on the resource.
+Read lock is non-exclusive, meaning that more than one thread can
+obtain a read lock to the same resource, without waiting on other readers.
+For changing the resource, however, a thread must obtain a exclusive
+write lock. This lock effectively blocks all threads from gaining the
+read-lock while the resource is been modified by the writer thread.
+Only after the write lock has been released, the resource may be read-locked
+again. 
+
+[nl]
+
+The [cmd thread::rwmutex] command supports following subcommands and options:
+
+[list_begin definitions]
+
+[call [cmd thread::rwmutex] [method create]]
+
+Creates the reader/writer mutex and returns it's opaque handle.
+This handle should be used for any future reference to the newly 
+created mutex.
+
+[call [cmd thread::rwmutex] [method destroy] [arg mutex]]
+
+Destroys the reader/writer [arg mutex]. If the mutex is already locked,
+attempt to destroy it will throw Tcl error.
+
+[call [cmd thread::rwmutex] [method rlock] [arg mutex]]
+
+Locks the [arg mutex] for reading. More than one thread may read-lock
+the same [arg mutex] at the same time.
+
+[call [cmd thread::rwmutex] [method wlock] [arg mutex]]
+
+Locks the [arg mutex] for writing. Only one thread may write-lock
+the same [arg mutex] at the same time. Attempt to write-lock same
+[arg mutex] twice from the same thread will throw Tcl error.
+
+[call [cmd thread::rwmutex] [method unlock] [arg mutex]]
+
+Unlocks the [arg mutex] so some other thread may lock it again.
+Attempt to unlock already unlocked [arg mutex] will throw Tcl error.
+
+[list_end]
+
+[nl]
+
+[call [cmd thread::cond]]
+
+This command provides script-level access to condition variables.
+A condition variable creates a safe environment for the program 
+to test some condition, sleep on it when false and be awakened 
+when it might have become true. A condition variable is always 
+used in the conjuction with an exclusive mutex. If you attempt
+to use other type of mutex in conjuction with the condition 
+variable, a Tcl error will be thrown.
+
+[nl]
+
+The command supports following subcommands and options:
+
+[list_begin definitions]
+
+[call [cmd thread::cond] [method create]]
+
+Creates the condition variable and returns it's opaque handle.
+This handle should be used for any future reference to newly 
+created condition variable.
+
+[call [cmd thread::cond] [method destroy] [arg cond]]
+
+Destroys condition variable [arg cond]. Extreme care has to be taken 
+that nobody is using (i.e. waiting on) the condition variable, 
+otherwise unexpected errors may happen.
+
+[call [cmd thread::cond] [method notify] [arg cond]]
+
+Wakes up all threads waiting on the condition variable [arg cond].
+
+[call [cmd thread::cond] [method wait] [arg cond] [arg mutex] [opt ms]]
+
+This command is used to suspend program execution until the condition
+variable [arg cond] has been signalled or the optional timer has expired.
+The exclusive [arg mutex] must be locked by the calling thread on entrance
+to this command. If the mutex is not locked, Tcl error is thrown.
+While waiting on the [arg cond], the command releases [arg mutex]. 
+Before returning to the calling thread, the command re-acquires the 
+[arg mutex] again. Unlocking the [arg mutex] and waiting on the 
+condition variable [arg cond] is done atomically.
+
+[nl]
+
+The [option ms] command option, if given, must be an integer specifying
+time interval in milliseconds the command waits to be signalled. 
+Otherwise the command waits on condition notify forever.
+
+[nl]
+
+In multithreading programs, there are many situations where a thread has
+to wait for some event to happen until it is allowed to proceed.
+This is usually accomplished by repeatedly testing a condition under the
+mutex protection and waiting on the condition variable until the condition
+evaluates to true:
+
+[example {
+    set mutex [thread::mutex create]
+    set cond  [thread::cond  create]
+
+    thread::mutex lock $mutex
+    while {<some_condition_is_true>} {
+        thread::cond wait $cond $mutex
+    }
+    # Do some work under mutex protection
+    thread::mutex unlock $mutex
+}]
+
+Repeated testing of the condition is needed since the condition variable 
+may get signalled without the condition being actually changed (spurious 
+thread wake-ups, for example).
+
+[list_end]
+
+[list_end]
+
+[section DISCUSSION]
+The fundamental threading model in Tcl is that there can be one or
+more Tcl interpreters per thread, but each Tcl interpreter should
+only be used by a single thread which created it.
+A "shared memory" abstraction is awkward to provide in Tcl because
+Tcl makes assumptions about variable and data ownership. Therefore
+this extension supports a simple form of threading where the main
+thread can manage several background, or "worker" threads. 
+For example, an event-driven server can pass requests to worker 
+threads, and then await responses from worker threads or new client
+requests. Everything goes through the common Tcl event loop, so 
+message passing between threads works naturally with event-driven I/O, 
+[cmd vwait] on variables, and so forth. For the transfer of bulk
+information it is possible to move channels between the threads.
+
+[para]
+
+For advanced multithreading scripts, script-level access to two
+basic synchronization primitives, mutex and condition variables,
+is also supported.
+
+[see_also tsv tpool ttrace [uri http://www.tcl.tk/doc/howto/thread_model.html]]
+
+[keywords thread events {message passing} synchronization mutex]
+
+[manpage_end]
diff --git a/8.x/thread/doc/tpool.man b/8.x/thread/doc/tpool.man
new file mode 100644 (file)
index 0000000..a4aa634
--- /dev/null
@@ -0,0 +1,231 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tpool n 2.6]
+[moddesc {Tcl Threading}]
+[titledesc {
+    Part of the Tcl threading extension implementing pools of worker threads.
+}]
+[require Tcl 8.4]
+[require Thread [opt 2.6]]
+
+[description]
+This package creates and manages pools of worker threads. It allows you
+to post jobs to worker threads and wait for their completion. The 
+threadpool implementation is Tcl event-loop aware. That means that any
+time a caller is forced to wait for an event (job being completed or 
+a worker thread becoming idle or initialized), the implementation will
+enter the event loop and allow for servicing of other pending file or
+timer (or any other supported) events.
+
+[section COMMANDS]
+
+[list_begin definitions]
+
+[call [cmd tpool::create] [opt options]]
+
+This command creates new threadpool. It accepts several options as
+key-value pairs. Options are used to tune some threadpool parameters.
+The command returns the ID of the newly created threadpool.
+[nl]
+Following options are supported:
+
+[list_begin definitions]
+
+[lst_item {-minworkers number}]
+Minimum number of worker threads needed for this threadpool instance.
+During threadpool creation, the implementation will create somany
+worker threads upfront and will keep at least number of them alive
+during the lifetime of the threadpool instance.
+Default value of this parameter is 0 (zero). which means that a newly
+threadpool will have no worker threads initialy. All worker threads
+will be started on demand by callers running [cmd tpool::post] command
+and posting jobs to the job queue.
+
+[lst_item {-maxworkers number}]
+Maximum number of worker threads allowed for this threadpool instance.
+If a new job is pending and there are no idle worker threads available,
+the implementation will try to create new worker thread. If the number
+of available worker threads is lower than the given number,
+new worker thread will start. The caller will automatically enter the
+event loop and wait until the worker thread has initialized. If. however,
+the number of available worker threads is equal to the given number, 
+the caller will enter the event loop and wait for the first worker thread
+to get idle, thus ready to run the job.
+Default value of this parameter is 4 (four), which means that the 
+threadpool instance will allow maximum of 4 worker threads running jobs
+or being idle waiting for new jobs to get posted to the job queue.
+
+
+[lst_item {-idletime seconds}]
+Time in seconds an idle worker thread waits for the job to get posted
+to the job queue. If no job arrives during this interval and the time
+expires, the worker thread will check the number of currently available
+worker threads and if the number is higher than the number set by the
+[option minthreads] option, it will exit. 
+If an [option exitscript] has been defined, the exiting worker thread 
+will first run the script and then exit. Errors from the exit script, 
+if any, are ignored.
+[nl]
+The idle worker thread is not servicing the event loop. If you, however,
+put the worker thread into the event loop, by evaluating the
+[cmd vwait] or other related Tcl commands, the worker thread 
+will not be in the idle state, hence the idle timer will not be 
+taken into account.
+Default value for this option is unspecified, hence, the Tcl interpreter
+of the worker thread will contain just the initial set of Tcl commands.
+
+[lst_item {-initcmd script}]
+
+Sets a Tcl script used to initialize new worker thread. This is usually
+used to load packages and commands in the worker, set default variables,
+create namespaces, and such. If the passed script runs into a Tcl error, 
+the worker will not be created and the initiating command (either the
+[cmd tpool::create] or [cmd tpool::post]) will throw error.
+Default value for this option is unspecified, hence, the Tcl interpreter of 
+the worker thread will contain just the initial set of Tcl commands.
+
+[lst_item {-exitcmd script}]
+
+Sets a Tcl script run when the idle worker thread exits. This is normaly
+used to cleanup the state of the worker thread, release reserved resources,
+cleanup memory and such.
+Default value for this option is unspecified, thus no Tcl script will run
+on the worker thread exit.
+
+[list_end]
+
+[nl] 
+
+[call [cmd tpool::names]]
+
+This command returns a list of IDs of threadpools created with the 
+[cmd tpool::create] command. If no threadpools were found, the
+command will return empty list.
+
+[call [cmd tpool::post] [opt -detached] [opt -nowait] [arg tpool] [arg script]]
+
+This command sends a [arg script] to the target [arg tpool] threadpool
+for execution. The script will be executed in the first available idle 
+worker thread. If there are no idle worker threads available, the command
+will create new one, enter the event loop and service events until the 
+newly created thread is initialized. If the current number of worker 
+threads is equal to the maximum number of worker threads, as defined 
+during the threadpool creation, the command will enter the event loop and
+service events while waiting for one of the worker threads to become idle.
+If the optional [opt -nowait] argument is given, the command will not wait
+for one idle worker. It will just place the job in the pool's job queue
+and return immediately.
+[nl]
+The command returns the ID of the posted job. This ID is used for subsequent
+[cmd tpool::wait], [cmd tpool::get] and [cmd tpool::cancel] commands to wait
+for and retrieve result of the posted script, or cancel the posted job
+respectively. If the optional [opt -detached] argument is specified, the 
+command will post a detached job. A detached job can not be cancelled or 
+waited upon and is not identified by the job ID.
+[nl]
+If the threadpool [arg tpool] is not found in the list of active
+thread pools, the command will throw error. The error will also be triggered
+if the newly created worker thread fails to initialize.
+
+[call [cmd tpool::wait] [arg tpool] [arg joblist] [opt varname]]
+
+This command waits for one or many jobs, whose job IDs are given in the
+[arg joblist] to get processed by the worker thread(s). If none of the
+specified jobs are ready, the command will enter the event loop, service
+events and wait for the first job to get ready.
+[nl]
+The command returns the list of completed job IDs. If the optional variable
+[opt varname] is given, it will be set to the list of jobs in the 
+[arg joblist] which are still pending. If the threadpool [arg tpool] 
+is not found in the list of active thread pools, the command will throw error.
+
+[call [cmd tpool::cancel] [arg tpool] [arg joblist] [opt varname]]
+
+This command cancels the previously posted jobs given by the [arg joblist]
+to the pool [arg tpool]. Job cancellation succeeds only for job still
+waiting to be processed. If the job is already being executed by one of
+the worker threads, the job will not be cancelled.
+The command returns the list of cancelled job IDs. If the optional variable
+[opt varname] is given, it will be set to the list of jobs in the 
+[arg joblist] which were not cancelled. If the threadpool [arg tpool] 
+is not found in the list of active thread pools, the command will throw error.
+
+[call [cmd tpool::get] [arg tpool] [arg job]]
+
+This command retrieves the result of the previously posted [arg job].
+Only results of jobs waited upon with the [cmd tpool::wait] command
+can be retrieved. If the execution of the script resulted in error, 
+the command will throw the error and update the [var errorInfo] and
+[var errorCode] variables correspondingly. If the pool [arg tpool]
+is not found in the list of threadpools, the command will throw error.
+If the job [arg job] is not ready for retrieval, because it is currently
+being executed by the worker thread, the command will throw error.
+
+[call [cmd tpool::preserve] [arg tpool]]
+
+Each call to this command increments the reference counter of the
+threadpool [arg tpool] by one (1). Command returns the value of the 
+reference counter after the increment.
+By incrementing the reference counter, the caller signalizes that
+he/she wishes to use the resource for a longer period of time.
+
+[call [cmd tpool::release] [arg tpool]]
+
+Each call to this command decrements the reference counter of the 
+threadpool [arg tpool] by one (1).Command returns the value of the 
+reference counter after the decrement. 
+When the reference counter reaches zero (0), the threadpool [arg tpool]
+is marked for termination. You should not reference the threadpool 
+after the [cmd tpool::release] command returns zero. The [arg tpool]
+handle goes out of scope and should not be used any more. Any following
+reference to the same threadpool handle will result in Tcl error.
+
+[call [cmd tpool::suspend] [arg tpool]]
+
+Suspends processing work on this queue. All pool workers are paused
+but additional work can be added to the pool. Note that adding the
+additional work will not increase the number of workers dynamically
+as the pool processing is suspended. Number of workers is maintained
+to the count that was found prior suspending worker activity.
+If you need to assure certain number of worker threads, use the 
+[option minworkers] option of the [cmd tpool::create] command.
+
+[call [cmd tpool::resume] [arg tpool]]
+
+Resume processing work on this queue. All paused (suspended) 
+workers are free to get work from the pool. Note that resuming pool
+operation will just let already created workers to proceed. 
+It will not create additional worker threads to handle the work 
+posted to the pool's work queue.
+
+[list_end]
+
+
+[section DISCUSSION]
+
+Threadpool is one of the most common threading paradigm when it comes
+to server applications handling a large number of relatively small tasks.
+A very simplistic model for building a server application would be to 
+create a new thread each time a request arrives and service the request 
+in the new thread. One of the disadvantages of this approach is that 
+the overhead of creating a new thread for each request is significant; 
+a server that created a new thread for each request would spend more time
+and consume more system resources in creating and destroying threads than
+in processing actual user requests. In addition to the overhead of 
+creating and destroying threads, active threads consume system resources.
+Creating too many threads can cause the system to run out of memory or
+trash due to excessive memory consumption.
+[para]
+A thread pool offers a solution to both the problem of thread life-cycle 
+overhead and the problem of resource trashing. By reusing threads for 
+multiple tasks, the thread-creation overhead is spread over many tasks.
+As a bonus, because the thread already exists when a request arrives, 
+the delay introduced by thread creation is eliminated. Thus, the request
+can be serviced immediately. Furthermore, by properly tuning the number 
+of threads in the thread pool, resource thrashing may also be eliminated
+by forcing any request to wait until a thread is available to process it.
+
+[see_also tsv ttrace thread]
+
+[keywords thread threadpool]
+
+[manpage_end]
diff --git a/8.x/thread/doc/tsv.man b/8.x/thread/doc/tsv.man
new file mode 100644 (file)
index 0000000..26b3f01
--- /dev/null
@@ -0,0 +1,334 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin tsv n 2.6]
+[moddesc {Tcl Threading}]
+[titledesc {
+    Part of the Tcl threading extension allowing script level
+    manipulation of data shared between threads.
+}]
+[require Tcl 8.4]
+[require Thread [opt 2.6]]
+
+[description]
+This section describes commands implementing thread shared variables.
+A thread shared variable is very similar to a Tcl array but in 
+contrast to a Tcl array it is created in shared memory and can
+be accessed from many threads at the same time. Important feature of
+thread shared variable is that each access to the variable is internaly
+protected by a mutex so script programmer does not have to take care 
+about locking the variable himself.
+[para]
+Thread shared variables are not bound to any thread explicitly. That 
+means that when a thread which created any of thread shared variables
+exits, the variable and associated memory is not unset/reclaimed.
+User has to explicitly unset the variable to reclaim the memory 
+consumed by the variable.
+
+[section {ELEMENT COMMANDS}]
+
+[list_begin definitions]
+
+[call [cmd tsv::names] [opt pattern]]
+
+Returns names of shared variables matching optional [opt pattern] 
+or all known variables if pattern is ommited.
+
+[call [cmd tsv::object] [arg varname] [arg element]]
+
+Creates object accessor command for the [arg element] in the
+shared variable [arg varname]. Using this command, one can apply most 
+of the other shared variable commands as method functions of
+the element object command. The object command is automatically
+deleted when the element which this command is pointing to is unset.
+
+[example {
+    % tsv::set foo bar "A shared string"
+    % set string [tsv::object foo bar]
+    % $string append " appended"
+    => A shared string appended
+}]
+
+[call [cmd tsv::set] [arg varname] [arg element] [opt value]]
+
+Sets the value of the [arg element] in the shared variable [arg varname] 
+to [arg value] and returns the value to caller. The [arg value]
+may be ommited, in which case the command will return the current 
+value of the element. If the element cannot be found, error is triggered.
+
+[call [cmd tsv::get] [arg varname] [arg element] [opt namedvar]]
+
+Retrieves the value of the [arg element] from the shared variable [arg varname].
+If the optional argument [arg namedvar] is given, the value is
+stored in the named variable. Return value of the command depends 
+of the existence of the optional argument [arg namedvar].
+If the argument is ommited and the requested element cannot be found 
+in the shared array, the command triggers error. If, however, the 
+optional argument is given on the command line, the command returns 
+true (1) if the element is found or false (0) if the element is not found.
+
+[call [cmd tsv::unset] [arg varname] [opt element]]
+
+Unsets the [arg element] from the shared variable [arg varname].
+If the optional element is not given, it deletes the variable.
+
+[call [cmd tsv::exists] [arg varname] [arg element]]
+
+Checks wether the [arg element] exists in the shared variable [arg varname]
+and returns true (1) if it does or false (0) if it doesn't.
+
+[call [cmd tsv::pop] [arg varname] [arg element]]
+
+Returns value of the [arg element] in the shared variable [arg varname]
+and unsets the element, all in one atomic operation.
+
+[call [cmd tsv::move] [arg varname] [arg oldname] [arg newname]]
+
+Renames the element [arg oldname] to the [arg newname] in the
+shared variable [arg varname]. This effectively performs an get/unset/set
+sequence of operations but all in one atomic step.
+
+[call [cmd tsv::incr] [arg varname] [arg element] [opt count]]
+
+Similar to standard Tcl [cmd incr] command but increments the value
+of the [arg element] in shared variaboe [arg varname] instead of 
+the Tcl variable.
+
+[call [cmd tsv::append] [arg varname] [arg element] [arg value] [opt {value ...}]]
+
+Similar to standard Tcl [cmd append] command but appends one or more
+values to the [arg element] in shared variable [arg varname] instead of the 
+Tcl variable.
+
+[call [cmd tsv::lock] [arg varname] [arg arg] [opt {arg ...}]]
+
+This command concatenates passed arguments and evaluates the
+resulting script under the internal mutex protection. During the
+script evaluation, the entire shared variable is locked. For shared
+variable commands within the script, internal locking is disabled
+so no deadlock can occur. It is also allowed to unset the shared
+variable from within the script. The shared variable is automatically
+created if it did not exists at the time of the first lock operation.
+
+[example {
+    % tsv::lock foo {
+        tsv::lappend foo bar 1
+        tsv::lappend foo bar 2
+        puts stderr [tsv::set foo bar]
+        tsv::unset foo
+    }
+}]
+
+[list_end]
+
+[section {LIST COMMANDS}]
+
+Those command are similar to the equivalently named Tcl command. The difference
+is that they operate on elements of shared arrays.
+
+[list_begin definitions]
+
+[call [cmd tsv::lappend] [arg varname] [arg element] [arg value] [opt {value ...}]]
+
+Similar to standard Tcl [cmd lappend] command but appends one
+or more values to the [arg element] in shared variable [arg varname] 
+instead of the Tcl variable.
+
+[call [cmd tsv::linsert] [arg varname] [arg element] [arg index] [arg value] [opt {value ...}]]
+
+Similar to standard Tcl [cmd linsert] command but inserts one
+or more values at the [arg index] list position in the 
+[arg element] in the shared variable [arg varname] instead of the Tcl variable.
+
+[call [cmd tsv::lreplace] [arg varname] [arg element] [arg first] [arg last] [opt {value ...}]]
+
+Similar to standard Tcl [cmd lreplace] command but replaces one
+or more values between the [arg first] and [arg last] position 
+in the [arg element] of the shared variable [arg varname] instead of 
+the Tcl variable.
+
+[call [cmd tsv::llength] [arg varname] [arg element]]
+
+Similar to standard Tcl [cmd llength] command but returns length 
+of the [arg element] in the shared variable [arg varname] instead of the Tcl
+variable.
+
+[call [cmd tsv::lindex] [arg varname] [arg element] [opt index]]
+
+Similar to standard Tcl [cmd lindex] command but returns the value
+at the [arg index] list position of the [arg element] from
+the shared variable [arg varname] instead of the Tcl variable.
+
+[call [cmd tsv::lrange] [arg varname] [arg element] [arg from] [arg to]]
+
+Similar to standard Tcl [cmd lrange] command but returns values
+between [arg from] and [arg to] list positions from the
+[arg element] in the shared variable [arg varname] instead of the Tcl variable.
+
+[call [cmd tsv::lsearch] [arg varname] [arg element] [opt options] [arg pattern]]
+
+Similar to standard Tcl [cmd lsearch] command but searches the [arg element]
+in the shared variable [arg varname] instead of the Tcl variable.
+
+[call [cmd tsv::lset] [arg varname] [arg element] [arg index] [opt {index ...}] [arg value]]
+
+Similar to standard Tcl [cmd lset] command but sets the [arg element]
+in the shared variable [arg varname] instead of the Tcl variable.
+
+[call [cmd tsv::lpop] [arg varname] [arg element] [opt index]]
+
+Similar to the standard Tcl [cmd lindex] command but in addition to
+returning, it also splices the value out of the [arg element]
+from the shared variable [arg varname] in one atomic operation. 
+In contrast to the Tcl [cmd lindex] command, this command returns 
+no value to the caller.
+
+[call [cmd tsv::lpush] [arg varname] [arg element] [opt index]]
+
+This command performes the opposite of the [cmd tsv::lpop] command.
+As its counterpart, it returns no value to the caller.
+
+[list_end]
+
+[section {ARRAY COMMANDS}]
+
+This command supports most of the options of the standard Tcl
+[cmd array] command. In addition to those, it allows binding
+a shared variable to some persisten storage databases. Currently 
+the only persistent option supported is the famous GNU Gdbm 
+database. This option has to be selected during the package 
+compilation time. The implementation provides hooks for 
+defining other persistency layers, if needed.
+
+[list_begin definitions]
+
+[call [cmd {tsv::array set}] [arg varname] [arg list]]
+
+Does the same as standard Tcl [cmd {array set}].
+
+[call [cmd {tsv::array get}] [arg varname] [opt pattern]]
+
+Does the same as standard Tcl [cmd {array get}].
+
+[call [cmd {tsv::array names}] [arg varname] [opt pattern]]
+
+Does the same as standard Tcl [cmd {array names}].
+
+[call [cmd {tsv::array size}] [arg varname]]
+
+Does the same as standard Tcl [cmd {array size}].
+
+[call [cmd {tsv::array reset}] [arg varname] [arg list]]
+
+Does the same as standard Tcl [cmd {array set}] but it clears
+the [arg varname] and sets new values from the list atomically.
+
+[call [cmd {tsv::array bind}] [arg varname] [arg handle]]
+Binds the [arg varname] to the persistent storage [arg handle].
+The format of the [arg handle] is <handler>:<address>. For the built-in
+GNU Gdbm persistence layer, the format of the handle is "gdbm:<path>"
+where <path> is the path to the Gdbm database file.
+
+[call [cmd {tsv::array unbind}] [arg varname]]
+Unbinds the shared [arg array] from its bound persistent storage.
+
+[call [cmd {tsv::array isbound}] [arg varname]]
+Returns true (1) if the shared [arg varname] is bound to some 
+persistent storage or zero (0) if not.
+
+
+[list_end]
+
+[section {KEYED LIST COMMANDS}]
+
+Keyed list commands are borrowed from the TclX package. Keyed lists provide
+a structured data type built upon standard Tcl lists. This is a functionality
+similar to structs in the C programming language.
+[para]
+A keyed list is a list in which each element contains a key and value 
+pair. These element pairs are stored as lists themselves, where the key
+is the first element of the list, and the value is the second. The 
+key-value pairs are referred to as fields.  This is an example of a
+keyed list:
+
+[example {
+    {{NAME  {Frank  Zappa}} {JOB {musician and composer}}}
+}]
+
+Fields may contain subfields; `.' is the separator character. Subfields 
+are actually fields  where the value is another keyed list. Thus the 
+following list has the top level fields ID and NAME, and subfields 
+NAME.FIRST and NAME.LAST:
+
+[example {
+    {ID 106} {NAME {{FIRST Frank} {LAST Zappa}}}
+}]
+
+There is no limit to the recursive depth of subfields,
+allowing one to build complex data structures. Keyed lists are constructed
+and accessed via a number of commands. All  keyed  list management 
+commands take the name of the variable containing the keyed list as an 
+argument (i.e. passed by reference), rather than passing the list directly.
+
+[list_begin definitions]
+
+[call [cmd tsv::keyldel] [arg varname] [arg keylist] [arg key]]
+
+Delete the field specified by [arg key] from the keyed list [arg keylist]
+in the shared variable [arg varname].
+This removes both the key and the value from the keyed list.
+
+[call [cmd tsv::keylget] [arg varname] [arg keylist] [arg key] [opt retvar]]
+
+Return the value associated with [arg key] from the keyed list [arg keylist]
+in the shared variable [arg varname].
+If the optional [arg retvar] is not specified, then the value will be 
+returned as the result of the command. In this case, if key is not found 
+in the list, an error will result.
+[nl]
+If [arg retvar] is specified and [arg key] is in the list, then the value 
+is returned in the variable [arg retvar] and the command returns 1 if the
+key was present within the list. If [arg key] isn't in the list, the 
+command will return 0, and [arg retvar] will be left unchanged. If {} is
+specified for [arg retvar], the value is not returned, allowing the Tcl
+programmer to determine if a [arg key] is present in a keyed list without
+setting a variable as a side-effect.
+
+[call [cmd tsv::keylkeys] [arg varname] [arg keylist] [opt key]]
+Return  the a list of the keys in the keyed list [arg keylist] in the 
+shared variable [arg varname]. If [arg key] is specified, then it is 
+the name of a key field who's subfield keys are to be retrieved.
+
+
+[call [cmd tsv::keylset] [arg varname] [arg keylist] [arg key] [arg value] [opt {key value..}]]
+Set the value associated with [arg key], in the keyed list [arg keylist]
+to [arg value]. If the [arg keylist] does not exists, it is created. 
+If [arg key] is not currently in the list, it will be added. If it already
+exists, [arg value] replaces the existing value. Multiple keywords and 
+values may be specified, if desired.
+
+[list_end]
+
+
+[section DISCUSSION]
+The current implementation of thread shared variables allows for easy and
+convenient access to data shared between different threads.
+Internally, the data is stored in Tcl objects and all package commands
+operate on internal data representation, thus minimizing shimmering and
+improving performance. Special care has been taken to assure that all 
+object data is properly locked and deep-copied when moving objects between
+threads.
+[para]
+Due to the internal design of the Tcl core, there is no provision of full 
+integration of shared variables within the Tcl syntax, unfortunately. All
+access to shared data must be performed with the supplied package commands.
+Also, variable traces are not supported. But even so, benefits of easy, 
+simple and safe shared data manipulation outweights imposed limitations.
+
+[section CREDITS]
+Thread shared variables are inspired by the nsv interface found in 
+AOLserver, a highly scalable Web server from America Online.
+
+[see_also tpool ttrace thread]
+
+[keywords threads synchronization locking {thread shared data}]
+
+[manpage_end]
diff --git a/8.x/thread/doc/ttrace.man b/8.x/thread/doc/ttrace.man
new file mode 100644 (file)
index 0000000..75a85d8
--- /dev/null
@@ -0,0 +1,230 @@
+[comment {-*- tcl -*- doctools manpage}]
+[manpage_begin ttrace n 2.6]
+[moddesc {Tcl Threading}]
+[titledesc {Trace-based interpreter initialization}]
+[require Tcl 8.4]
+[require Thread [opt 2.6]]
+
+[description]
+This package creates a framework for on-demand replication of the
+interpreter state accross threads in an multithreading application.
+It relies on the mechanics of Tcl command tracing and the Tcl 
+[cmd unknown] command and mechanism.
+[para]
+The package requires Tcl threading extension but can be alternatively
+used stand-alone within the AOLserver, a scalable webserver from 
+America Online.
+[para]
+In a nutshell, a short sample illustrating the usage of the ttrace
+with the Tcl threading extension:
+
+[example {
+
+    % package require Ttrace
+    2.6.5
+
+    % set t1 [thread::create {package require Ttrace; thread::wait}]
+    tid0x1802800
+
+    % ttrace::eval {proc test args {return test-[thread::id]}}
+    % thread::send $t1 test
+    test-tid0x1802800
+
+    % set t2 [thread::create {package require Ttrace; thread::wait}]
+    tid0x1804000
+
+    % thread::send $t2 test
+    test-tid0x1804000
+
+}]
+[para]
+As seen from above, the [cmd ttrace::eval] and [cmd ttrace::update]
+commands are used to create a thread-wide definition of a simple 
+Tcl procedure and replicate that definition to all, already existing
+or later created, threads.
+
+[section {USER COMMANDS}]
+This section describes user-level commands. Those commands can be
+used by script writers to control the execution of the tracing
+framework.
+
+[list_begin definitions]
+
+[call [cmd ttrace::eval] [arg arg] [opt {arg ...}]]
+
+This command concatenates given arguments and evaluates the resulting
+Tcl command with trace framework enabled. If the command execution
+was ok, it takes necessary steps to automatically propagate the
+trace epoch change to all threads in the application. 
+For AOLserver, only newly created threads actually receive the
+epoch change. For the Tcl threading extension, all threads created by
+the extension are automatically updated. If the command execution 
+resulted in Tcl error, no state propagation takes place.
+[nl]
+This is the most important user-level command of the package as
+it wraps most of the commands described below. This greatly
+simplifies things, because user need to learn just this (one)
+command in order to effectively use the package. Other commands, 
+as desribed below, are included mostly for the sake of completeness.
+
+[call [cmd ttrace::enable]]
+
+Activates all registered callbacks in the framework
+and starts a new trace epoch. The trace epoch encapsulates all
+changes done to the interpreter during the time traces are activated.
+
+[call [cmd ttrace::disable]]
+
+Deactivates all registered callbacks in the framework
+and closes the current trace epoch.
+
+[call [cmd ttrace::cleanup]]
+
+Used to clean-up all on-demand loaded resources in the interpreter. 
+It effectively brings Tcl interpreter to its pristine state.
+
+[call [cmd ttrace::update] [opt epoch]]
+
+Used to refresh the state of the interpreter to match the optional 
+trace [opt epoch]. If the optional [opt epoch] is not given, it takes
+the most recent trace epoch.
+
+[call [cmd ttrace::getscript]]
+
+Returns a synthetized Tcl script which may be sourced in any interpreter.
+This script sets the stage for the Tcl [cmd unknown] command so it can
+load traced resources from the in-memory database. Normally, this command
+is automatically invoked by other higher-level commands like
+[cmd ttrace::eval] and [cmd ttrace::update].
+
+[list_end]
+
+[section {CALLBACK COMMANDS}]
+A word upfront: the package already includes callbacks for tracing 
+following Tcl commands: [cmd proc], [cmd namespace], [cmd variable],
+[cmd load], and [cmd rename]. Additionaly, a set of callbacks for 
+tracing resources (object, clasess) for the XOTcl v1.3.8+, an 
+OO-extension to Tcl, is also provided.
+This gives a solid base for solving most of the real-life needs and
+serves as an example for people wanting to customize the package 
+to cover their specific needs.
+[para]
+Below, you can find commands for registering callbacks in the
+framework and for writing callback scripts. These callbacks are
+invoked by the framework in order to gather interpreter state
+changes, build in-memory database, perform custom-cleanups and
+various other tasks.
+
+
+[list_begin definitions]
+
+[call [cmd ttrace::atenable] [arg cmd] [arg arglist] [arg body]]
+
+Registers Tcl callback to be activated at [cmd ttrace::enable].
+Registered callbacks are activated on FIFO basis. The callback
+definition includes the name of the callback, [arg cmd], a list
+of callback arguments, [arg arglist] and the [arg body] of the
+callback. Effectively, this actually resembles the call interface
+of the standard Tcl [cmd proc] command.
+
+
+[call [cmd ttrace::atdisable] [arg cmd] [arg arglist] [arg body]]
+
+Registers Tcl callback to be activated at [cmd ttrace::disable].
+Registered callbacks are activated on FIFO basis. The callback
+definition includes the name of the callback, [arg cmd], a list
+of callback arguments, [arg arglist] and the [arg body] of the
+callback. Effectively, this actually resembles the call interface
+of the standard Tcl [cmd proc] command.
+
+
+[call [cmd ttrace::addtrace] [arg cmd] [arg arglist] [arg body]]
+
+Registers Tcl callback to be activated for tracing the Tcl 
+[cmd cmd] command. The callback definition includes the name of 
+the Tcl command to trace, [arg cmd], a list of callback arguments, 
+[arg arglist] and the [arg body] of the callback. Effectively, 
+this actually resembles the call interface of the standard Tcl 
+[cmd proc] command.
+
+
+[call [cmd ttrace::addscript] [arg name] [arg body]]
+
+Registers Tcl callback to be activated for building a Tcl
+script to be passed to other interpreters. This script is
+used to set the stage for the Tcl [cmd unknown] command.
+Registered callbacks are activated on FIFO basis.
+The callback definition includes the name of the callback,
+[arg name] and the [arg body] of the callback.
+
+[call [cmd ttrace::addresolver] [arg cmd] [arg arglist] [arg body]]
+
+Registers Tcl callback to be activated by the overloaded Tcl
+[cmd unknown] command.
+Registered callbacks are activated on FIFO basis.
+This callback is used to resolve the resource and load the 
+resource in the current interpreter.
+
+[call [cmd ttrace::addcleanup] [arg body]]
+
+Registers Tcl callback to be activated by the [cmd trace::cleanup].
+Registered callbacks are activated on FIFO basis.
+
+[call [cmd ttrace::addentry] [arg cmd] [arg var] [arg val]]
+
+Adds one entry to the named in-memory database.
+
+[call [cmd ttrace::getentry] [arg cmd] [arg var]]
+
+Returns the value of the entry from the named in-memory database. 
+
+[call [cmd ttrace::getentries] [arg cmd] [opt pattern]]
+
+Returns names of all entries from the named in-memory database.
+
+[call [cmd ttrace::delentry] [arg cmd]]
+
+Deletes an entry from the named in-memory database.
+
+[call [cmd ttrace::preload] [arg cmd]]
+
+Registers the Tcl command to be loaded in the interpreter.
+Commands registered this way will always be the part of 
+the interpreter and not be on-demand loaded by the Tcl
+[cmd unknown] command.
+
+[list_end]
+
+[section DISCUSSION]
+Common introspective state-replication approaches use a custom Tcl
+script to introspect the running interpreter and synthesize another
+Tcl script to replicate this state in some other interpreter.
+This package, on the contrary, uses Tcl command traces. Command 
+traces are registered on selected Tcl commands, like [cmd proc], 
+[cmd namespace], [cmd load] and other standard (and/or user-defined)
+Tcl commands. When activated, those traces build an in-memory
+database of created resources. This database is used as a resource
+repository for the (overloaded) Tcl [cmd unknown] command which 
+creates the requested resource in the interpreter on demand. 
+This way, users can update just one interpreter (master) in one 
+thread and replicate that interpreter state (or part of it) to other 
+threads/interpreters in the process.
+[para]
+Immediate benefit of such approach is the much smaller memory footprint
+of the application and much faster thread creation. By not actually 
+loading all necessary procedures (and other resources) in every thread
+at the thread initialization time, but by deffering this to the time the
+resource is actually referenced, significant improvements in both
+memory consumption and thread initialization time can be achieved. Some
+tests have shown that memory footprint of an multithreading Tcl application
+went down more than three times and thread startup time was reduced for
+about 50 times. Note that your mileage may vary.
+
+Other benefits include much finer control about what (and when) gets 
+replicated from the master to other Tcl thread/interpreters.
+
+[see_also tsv tpool thread]
+
+[keywords {command tracing} introspection]
+
+[manpage_end]
diff --git a/8.x/thread/generic/aolstub.cpp b/8.x/thread/generic/aolstub.cpp
new file mode 100644 (file)
index 0000000..703edd7
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * aolstub.cpp --
+ *
+ * Adds interface for loading the extension into the AOLserver.
+ *
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Rcsid: @(#)$Id: aolstub.cpp,v 1.4 2003/03/17 09:01:23 vasiljevic Exp $
+ * ---------------------------------------------------------------------------
+ */
+
+#ifdef NS_AOLSERVER
+#include <ns.h>
+
+int Ns_ModuleVersion = 1;
+
+/*
+ * Structure to pass to NsThread_Init. This holds the module
+ * and virtual server name for proper interp initializations. 
+ */
+
+struct mydata {
+    char *modname;
+    char *server;
+};
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * NsThread_Init --
+ *
+ *    Loads the package for the first time, i.e. in the startup thread.
+ *
+ * Results:
+ *    Standard Tcl result
+ *
+ * Side effects:
+ *    Package initialized. Tcl commands created.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+NsThread_Init (Tcl_Interp *interp, void *cd)
+{
+    struct mydata *md = (struct mydata*)cd;
+    int ret = Thread_Init(interp);
+
+    if (ret != TCL_OK) {
+        Ns_Log(Warning, "can't load module %s: %s", md->modname,
+               Tcl_GetStringResult(interp));
+        return TCL_ERROR;
+    }
+    Tcl_SetAssocData(interp, "thread:nsd", NULL, (ClientData)md);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------------
+ *
+ * Ns_ModuleInit --
+ *
+ *    Called by the AOLserver when loading shared object file.
+ *
+ * Results:
+ *    Standard AOLserver result
+ *
+ * Side effects:
+ *    Many. Depends on the package.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+Ns_ModuleInit(char *srv, char *mod)
+{
+    struct mydata *md = NULL;
+
+    md = (struct mydata*)ns_malloc(sizeof(struct mydata));
+    md->modname = strcpy(ns_malloc(strlen(mod)+1), mod);
+    md->server  = strcpy(ns_malloc(strlen(srv)+1), srv);
+
+    return (Ns_TclInitInterps(srv, NsThread_Init, (void*)md) == TCL_OK)
+        ? NS_OK : NS_ERROR; 
+}
+
+#endif /* NS_AOLSERVER */
+
+/* EOF $RCSfile: aolstub.cpp,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
diff --git a/8.x/thread/generic/psGdbm.c b/8.x/thread/generic/psGdbm.c
new file mode 100644 (file)
index 0000000..7e8eec0
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * This file implements wrappers for persistent gdbm storage for the
+ * shared variable arrays.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: psGdbm.c,v 1.2 2004/12/18 13:26:03 vasiljevic Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#ifdef HAVE_GDBM
+
+#include "threadSvCmd.h"
+#include <gdbm.h>
+#include <stdlib.h> /* For free() */
+
+/*
+ * Functions implementing the persistent store interface
+ */
+
+static ps_open_proc   ps_gdbm_open;
+static ps_close_proc  ps_gdbm_close;
+static ps_get_proc    ps_gdbm_get;
+static ps_put_proc    ps_gdbm_put;
+static ps_first_proc  ps_gdbm_first;
+static ps_next_proc   ps_gdbm_next;
+static ps_delete_proc ps_gdbm_delete;
+static ps_free_proc   ps_gdbm_free;
+static ps_geterr_proc ps_gdbm_geterr;
+
+/*
+ * This structure collects all the various pointers
+ * to the functions implementing the gdbm store. 
+ */
+
+PsStore GdbmStore = {
+    "gdbm",
+    NULL,
+    ps_gdbm_open,
+    ps_gdbm_get,
+    ps_gdbm_put,
+    ps_gdbm_first,
+    ps_gdbm_next,
+    ps_gdbm_delete,
+    ps_gdbm_close,
+    ps_gdbm_free,
+    ps_gdbm_geterr,
+    NULL
+};
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_RegisterGdbmStore --
+ *
+ *      Register the gdbm store with shared variable implementation.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+void 
+Sv_RegisterGdbmStore(void)
+{
+    Sv_RegisterPsStore(&GdbmStore);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_open --
+ *
+ *      Opens the dbm-based persistent storage.
+ *
+ * Results:
+ *      Opaque handle of the opened dbm storage.
+ *
+ * Side effects:
+ *      The gdbm file might be created if not found.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static ClientData 
+ps_gdbm_open(path)
+    const char *path;
+{
+    GDBM_FILE dbf;
+    char *ext;
+    Tcl_DString toext;
+
+    Tcl_DStringInit(&toext);
+    ext = Tcl_UtfToExternalDString(NULL, (char*)path, strlen(path), &toext);
+    dbf = gdbm_open(ext, 512, GDBM_WRCREAT|GDBM_SYNC|GDBM_NOLOCK, 0666, NULL);
+    Tcl_DStringFree(&toext);
+
+    return (ClientData)dbf;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_close --
+ *
+ *      Closes the gdbm-based persistent storage.
+ *
+ * Results:
+ *      0 - ok
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int 
+ps_gdbm_close(handle)
+    ClientData handle;
+{
+    gdbm_close((GDBM_FILE)handle);
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_get --
+ *
+ *      Retrieves data for the key from the dbm storage.
+ *
+ * Results:
+ *      1 - no such key
+ *      0 - ok
+ *
+ * Side effects:
+ *      Data returned must be freed by the caller. 
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int 
+ps_gdbm_get(handle, key, dataptrptr, lenptr)
+     ClientData handle;
+     const char   *key;
+     char **dataptrptr;
+     int       *lenptr;
+{
+    GDBM_FILE dbf = (GDBM_FILE)handle;
+    datum drec, dkey;
+
+    dkey.dptr  = (char*)key;
+    dkey.dsize = strlen(key) + 1;
+
+    drec = gdbm_fetch(dbf, dkey);
+    if (drec.dptr == NULL) {
+        return 1;
+    }
+    
+    *dataptrptr = drec.dptr;
+    *lenptr = drec.dsize;
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_first --
+ *
+ *      Starts the iterator over the dbm file and returns the first record.
+ *
+ * Results:
+ *      1 - no more records in the iterator
+ *      0 - ok
+ *
+ * Side effects:
+ *      Data returned must be freed by the caller. 
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int 
+ps_gdbm_first(handle, keyptrptr, dataptrptr, lenptr)
+    ClientData  handle;
+    char   **keyptrptr;
+    char  **dataptrptr;
+    int        *lenptr;
+{
+    GDBM_FILE dbf = (GDBM_FILE)handle;
+    datum drec, dkey;
+
+    dkey = gdbm_firstkey(dbf);
+    if (dkey.dptr == NULL) {
+        return 1;
+    }
+    drec = gdbm_fetch(dbf, dkey);
+    if (drec.dptr == NULL) {
+        return 1;
+    }
+    
+    *dataptrptr = drec.dptr;
+    *lenptr = drec.dsize;
+    *keyptrptr = dkey.dptr;
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_next --
+ *
+ *      Uses the iterator over the dbm file and returns the next record.
+ *
+ * Results:
+ *      1 - no more records in the iterator
+ *      0 - ok
+ *
+ * Side effects:
+ *      Data returned must be freed by the caller. 
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int ps_gdbm_next(handle, keyptrptr, dataptrptr, lenptr)
+    ClientData  handle;
+    char   **keyptrptr;
+    char  **dataptrptr;
+    int        *lenptr;
+{
+    GDBM_FILE dbf = (GDBM_FILE)handle;
+    datum drec, dkey, dnext;
+
+    dkey.dptr  = *keyptrptr;
+    dkey.dsize = strlen(*keyptrptr) + 1;
+
+    dnext = gdbm_nextkey(dbf, dkey);
+    free(*keyptrptr), *keyptrptr = NULL;
+
+    if (dnext.dptr == NULL) {
+        return 1;
+    }
+    drec = gdbm_fetch(dbf, dnext);
+    if (drec.dptr == NULL) {
+        return 1;
+    }
+    
+    *dataptrptr = drec.dptr;
+    *lenptr = drec.dsize;
+    *keyptrptr = dnext.dptr;
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_put --
+ *
+ *      Stores used data bound to a key in dbm storage.
+ *
+ * Results:
+ *      0 - ok
+ *     -1 - error; use ps_dbm_geterr to retrieve the error message
+ *
+ * Side effects:
+ *      If the key is already associated with some user data, this will
+ *      be replaced by the new data chunk. 
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int 
+ps_gdbm_put(handle, key, dataptr, len)
+    ClientData handle;
+    const char   *key;
+    char     *dataptr;
+    int           len;
+{
+    GDBM_FILE dbf = (GDBM_FILE)handle;
+    datum drec, dkey;
+    int ret;
+
+    dkey.dptr  = (char*)key;
+    dkey.dsize = strlen(key) + 1;
+
+    drec.dptr  = dataptr;
+    drec.dsize = len;
+
+    ret = gdbm_store(dbf, dkey, drec, GDBM_REPLACE);
+    if (ret == -1) {
+        return -1;
+    }
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_delete --
+ *
+ *      Deletes the key and associated data from the dbm storage.
+ *
+ * Results:
+ *      0 - ok
+ *     -1 - error; use ps_dbm_geterr to retrieve the error message
+ *
+ * Side effects:
+ *      If the key is already associated with some user data, this will
+ *      be replaced by the new data chunk. 
+ *
+ *-----------------------------------------------------------------------------
+ */
+static int 
+ps_gdbm_delete(handle, key)
+    ClientData handle;
+    const char   *key;
+{
+    GDBM_FILE dbf = (GDBM_FILE)handle;
+    datum dkey;
+    int ret;
+
+    dkey.dptr  = (char*)key;
+    dkey.dsize = strlen(key) + 1;
+
+    ret = gdbm_delete(dbf, dkey);
+    if (ret == -1) {
+        return -1;
+    }
+
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_free --
+ *
+ *      Frees memory allocated by the gdbm implementation.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Memory gets reclaimed.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static void
+ps_gdbm_free(data)
+    char   *data;
+{
+    free(data);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ps_gdbm_geterr --
+ *
+ *      Retrieves the textual representation of the error caused
+ *      by the last dbm command.
+ *
+ * Results:
+ *      Pointer to the strimg message.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+static char*
+ps_gdbm_geterr(handle)
+    ClientData handle;
+{
+   /*
+    * The problem with gdbm interface is that it uses the global
+    * gdbm_errno variable which is not per-thread nor mutex
+    * protected. This variable is used to reference array of gdbm
+    * error text strings. It is very dangeours to use this in the
+    * MT-program without proper locking. For this kind of app
+    * we should not be concerned with that, since all ps_gdbm_xxx
+    * operations are performed under shared variable lock anyway.
+    */
+
+    return gdbm_strerror(gdbm_errno);
+}
+
+#endif  /* HAVE_GDBM */
+
+/* EOF $RCSfile*/
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
diff --git a/8.x/thread/generic/psGdbm.h b/8.x/thread/generic/psGdbm.h
new file mode 100644 (file)
index 0000000..536ece0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * psGdbm.h --
+ *
+ * See the file "license.txt" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Rcsid: @(#)$Id: psGdbm.h,v 1.1 2003/09/03 11:24:53 vasiljevic Exp $
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _PSGDBM_H_
+#define _PSGDBM_H_
+
+void Sv_RegisterGdbmStore();
+
+#endif /* _PSGDBM_H_ */
+
+/* EOF $RCSfile */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
diff --git a/8.x/thread/generic/tclThread.h b/8.x/thread/generic/tclThread.h
new file mode 100644 (file)
index 0000000..20166cb
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * --------------------------------------------------------------------------
+ * tclthread.h --
+ *
+ * Global header file for the thread extension.
+ *
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ * 
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tclThread.h,v 1.23 2010/03/31 08:50:24 vasiljevic Exp $
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * Thread extension version numbers are not stored here
+ * because this isn't a public export file.
+ */
+
+#ifndef _TCL_THREAD_H_
+#define _TCL_THREAD_H_
+
+#include <tcl.h>
+#include <stdlib.h> /* For strtoul */
+#include <string.h> /* For memset and friends */
+
+#undef  TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+/*
+ * For linking against AOLserver require V4 at least
+ */
+
+#ifdef NS_AOLSERVER
+# include <ns.h>
+# if !defined(NS_MAJOR_VERSION) || NS_MAJOR_VERSION < 4
+#  error "unsupported AOLserver version"
+# endif
+#endif
+
+/*
+ * Allow for some command names customization.
+ * Only thread:: and tpool:: are handled here.
+ * Shared variable commands are more complicated.
+ * Look into the threadSvCmd.h for more info.
+ */
+
+#define THREAD_CMD_PREFIX "thread::"
+#define TPOOL_CMD_PREFIX  "tpool::"
+
+/*
+ * Exported from threadCmd.c file.
+ */
+
+EXTERN int Thread_Init       _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN int Thread_SafeInit   _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN int Thread_Unload     _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN int Thread_SafeUnload _ANSI_ARGS_((Tcl_Interp *interp));
+
+/*
+ * Exported from threadSvCmd.c file.
+ */
+
+EXTERN int Sv_Init _ANSI_ARGS_((Tcl_Interp *interp));
+
+/*
+ * Exported from threadSpCmd.c file.
+ */
+
+EXTERN int Sp_Init _ANSI_ARGS_((Tcl_Interp *interp));
+
+/*
+ * Exported from threadPoolCmd.c file.
+ */
+
+EXTERN int Tpool_Init _ANSI_ARGS_((Tcl_Interp *interp));
+
+/*
+ * Macros for splicing in/out of linked lists
+ */
+
+#define SpliceIn(a,b)                          \
+    (a)->nextPtr = (b);                        \
+    if ((b) != NULL)                           \
+        (b)->prevPtr = (a);                    \
+    (a)->prevPtr = NULL, (b) = (a)
+
+#define SpliceOut(a,b)                         \
+    if ((a)->prevPtr != NULL)                  \
+        (a)->prevPtr->nextPtr = (a)->nextPtr;  \
+    else                                       \
+        (b) = (a)->nextPtr;                    \
+    if ((a)->nextPtr != NULL)                  \
+        (a)->nextPtr->prevPtr = (a)->prevPtr
+
+/*
+ * Utility macros
+ */ 
+
+#define TCL_CMD(a,b,c) \
+  if (Tcl_CreateObjCommand((a),(b),(c),(ClientData)NULL, NULL) == NULL) \
+    return TCL_ERROR
+
+#define OPT_CMP(a,b) \
+  ((a) && (b) && (*(a)==*(b)) && (*(a+1)==*(b+1)) && (!strcmp((a),(b))))
+
+#ifndef TCL_TSD_INIT
+#define TCL_TSD_INIT(keyPtr) \
+  (ThreadSpecificData*)Tcl_GetThreadData((keyPtr),sizeof(ThreadSpecificData))
+#endif
+
+#undef  TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
+#endif /* _TCL_THREAD_H_ */
diff --git a/8.x/thread/generic/tclXkeylist.c b/8.x/thread/generic/tclXkeylist.c
new file mode 100644 (file)
index 0000000..2306c3f
--- /dev/null
@@ -0,0 +1,1465 @@
+/* 
+ * tclXkeylist.c --
+ *
+ * Extended Tcl keyed list commands and interfaces.
+ *-----------------------------------------------------------------------------
+ * Copyright 1991-1999 Karl Lehenbauer and Mark Diekhans.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies.  Karl Lehenbauer and
+ * Mark Diekhans make no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ *
+ *-----------------------------------------------------------------------------
+ *
+ * This file was synthetized from the TclX distribution and made
+ * self-containing in order to encapsulate the keyed list datatype
+ * for the inclusion in the Tcl threading extension. I have made
+ * some minor changes to it in order to get internal object handling
+ * thread-safe and allow for this datatype to be used from within
+ * the thread shared variables implementation.
+ *
+ * For any questions, contant Zoran Vasiljevic (zoran@archiware.com)
+ *
+ *-----------------------------------------------------------------------------
+ * $Id: tclXkeylist.c,v 1.6 2010/04/01 22:17:42 vasiljevic Exp $
+ *-----------------------------------------------------------------------------
+ */
+
+#include "threadSvCmd.h"
+#include "tclXkeylist.h"
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*     Stuff copied verbatim from the rest of TclX to avoid dependencies     */
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+/*
+ * Assert macro for use in TclX.  Some GCCs libraries are missing a function
+ * used by their macro, so we define out own.
+ */
+
+#ifdef TCLX_DEBUG
+# define TclX_Assert(expr) ((expr) ? (void)0 : \
+                            panic("TclX assertion failure: %s:%d \"%s\"\n",\
+                            __FILE__, __LINE__, "expr"))
+#else
+# define TclX_Assert(expr)
+#endif
+
+#define TRUE  1
+#define FALSE 0
+
+/*
+ * Macro that behaves like strdup, only uses ckalloc.  Also macro that does the
+ * same with a string that might contain zero bytes,
+ */
+
+#define ckstrdup(sourceStr) \
+  (strcpy (ckalloc (strlen (sourceStr) + 1), sourceStr))
+
+#define ckbinstrdup(sourceStr, length) \
+  ((char *) memcpy (ckalloc (length + 1), sourceStr, length + 1))
+
+/*
+ * Used to return argument messages by most commands.
+ */
+static const char *tclXWrongArgs = "wrong # args: ";
+static const Tcl_ObjType *listType;
+static const Tcl_ObjType *stringType;
+
+/*-----------------------------------------------------------------------------
+ * TclX_IsNullObj --
+ *
+ *   Check if an object is {}, either in list or zero-lemngth string form, with
+ * out forcing a conversion.
+ *
+ * Parameters:
+ *   o objPtr - Object to check.
+ * Returns:
+ *   True if NULL, FALSE if not.
+ *-----------------------------------------------------------------------------
+ */
+static int
+TclX_IsNullObj (objPtr)
+    Tcl_Obj *objPtr;
+{
+    int length;
+
+    if (objPtr->typePtr == NULL) {
+        return (objPtr->length == 0);
+    } else {
+        if (objPtr->typePtr == listType) {
+            Tcl_ListObjLength (NULL, objPtr, &length);
+            return (length == 0);
+        } else if (objPtr->typePtr == stringType) {
+            Tcl_GetStringFromObj (objPtr, &length);
+            return (length == 0);
+        }
+    }
+    Tcl_GetStringFromObj (objPtr, &length);
+    return (length == 0);
+}
+
+/*-----------------------------------------------------------------------------
+ * TclX_AppendObjResult --
+ *
+ *   Append a variable number of strings onto the object result already
+ * present for an interpreter.  If the object is shared, the current contents
+ * are discarded.
+ *
+ * Parameters:
+ *   o interp - Interpreter to set the result in.
+ *   o args - Strings to append, terminated by a NULL.
+ *-----------------------------------------------------------------------------
+ */
+static void
+TclX_AppendObjResult TCL_VARARGS_DEF (Tcl_Interp *, arg1)
+{
+    Tcl_Interp *interp;
+    Tcl_Obj *resultPtr;
+    va_list argList;
+    char *string;
+
+    interp = TCL_VARARGS_START (Tcl_Interp *, arg1, argList);
+    resultPtr = Tcl_GetObjResult (interp);
+
+    if (Tcl_IsShared(resultPtr)) {
+        resultPtr = Tcl_NewStringObj((char *)NULL, 0);
+        Tcl_SetObjResult(interp, resultPtr);
+    }
+
+    TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
+    while (1) {
+        string = va_arg(argList, char *);
+        if (string == NULL) {
+            break;
+        }
+        Tcl_AppendToObj (resultPtr, string, -1);
+    }
+    va_end(argList);
+}
+
+/*-----------------------------------------------------------------------------
+ * TclX_WrongArgs --
+ *
+ *   Easily create "wrong # args" error messages.
+ *
+ * Parameters:
+ *   o commandNameObj - Object containing name of command (objv[0])
+ *   o string - Text message to append.
+ * Returns:
+ *   TCL_ERROR
+ *-----------------------------------------------------------------------------
+ */
+static int
+TclX_WrongArgs (interp, commandNameObj, string)
+    Tcl_Interp  *interp;
+    Tcl_Obj     *commandNameObj;
+    char        *string;
+{
+    const char *commandName;
+    Tcl_Obj *resultPtr = Tcl_GetObjResult (interp);
+    int      commandLength;
+
+    commandName = Tcl_GetStringFromObj (commandNameObj, &commandLength);
+    Tcl_ResetResult(interp);
+    Tcl_AppendStringsToObj (resultPtr,
+                            tclXWrongArgs,
+                            commandName,
+                            (char *)NULL);
+
+    if (*string != '\0') {
+        Tcl_AppendStringsToObj (resultPtr, " ", string, (char *)NULL);
+    }
+    return TCL_ERROR;
+}
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*                    Here is where the original file begins                 */
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+/*
+ * Keyed lists are stored as arrays recursively defined objects.  The data
+ * portion of a keyed list entry is a Tcl_Obj which may be a keyed list object
+ * or any other Tcl object.  Since determine the structure of a keyed list is
+ * lazy (you don't know if an element is data or another keyed list) until it
+ * is accessed, the object can be transformed into a keyed list from a Tcl
+ * string or list.
+ */
+
+/*
+ * An entry in a keyed list array.   (FIX: Should key be object?)
+ */
+typedef struct {
+    char    *key;
+    Tcl_Obj *valuePtr;
+} keylEntry_t;
+
+/*
+ * Internal representation of a keyed list object.
+ */
+typedef struct {
+    int          arraySize;   /* Current slots available in the array.  */
+    int          numEntries;  /* Number of actual entries in the array. */
+    keylEntry_t *entries;     /* Array of keyed list entries.           */
+} keylIntObj_t;
+
+/*
+ * Amount to increment array size by when it needs to grow.
+ */
+#define KEYEDLIST_ARRAY_INCR_SIZE 16
+
+/*
+ * Macro to duplicate a child entry of a keyed list if it is share by more
+ * than the parent.
+ */
+#define DupSharedKeyListChild(keylIntPtr, idx) \
+    if (Tcl_IsShared (keylIntPtr->entries [idx].valuePtr)) { \
+        keylIntPtr->entries [idx].valuePtr = \
+            Tcl_DuplicateObj (keylIntPtr->entries [idx].valuePtr); \
+        Tcl_IncrRefCount (keylIntPtr->entries [idx].valuePtr); \
+    }
+
+/*
+ * Macros to validate an keyed list object or internal representation
+ */
+#ifdef TCLX_DEBUG
+#   define KEYL_OBJ_ASSERT(keylAPtr) {\
+        TclX_Assert (keylAPtr->typePtr == &keyedListType); \
+        ValidateKeyedList (keylAIntPtr); \
+    }
+#   define KEYL_REP_ASSERT(keylAIntPtr) \
+        ValidateKeyedList (keylAIntPtr)
+#else
+#  define KEYL_REP_ASSERT(keylAIntPtr)
+#endif
+
+
+/*
+ * Prototypes of internal functions.
+ */
+#ifdef TCLX_DEBUG
+static void
+ValidateKeyedList _ANSI_ARGS_((keylIntObj_t *keylIntPtr));
+#endif
+
+static int
+ValidateKey _ANSI_ARGS_((Tcl_Interp *interp,
+                         const char *key,
+                         int keyLen,
+                         int isPath));
+
+static keylIntObj_t *
+AllocKeyedListIntRep _ANSI_ARGS_((void));
+
+static void
+FreeKeyedListData _ANSI_ARGS_((keylIntObj_t *keylIntPtr));
+
+static void
+EnsureKeyedListSpace _ANSI_ARGS_((keylIntObj_t *keylIntPtr,
+                                  int           newNumEntries));
+
+static void
+DeleteKeyedListEntry _ANSI_ARGS_((keylIntObj_t *keylIntPtr,
+                                  int           entryIdx));
+
+static int
+FindKeyedListEntry _ANSI_ARGS_((keylIntObj_t *keylIntPtr,
+                                const char   *key,
+                                int          *keyLenPtr,
+                                const char   **nextSubKeyPtr));
+
+static int
+ObjToKeyedListEntry _ANSI_ARGS_((Tcl_Interp  *interp,
+                                 Tcl_Obj     *objPtr,
+                                 keylEntry_t *entryPtr));
+
+static void
+DupKeyedListInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
+                                     Tcl_Obj *copyPtr));
+
+static void
+FreeKeyedListInternalRep _ANSI_ARGS_((Tcl_Obj *keylPtr));
+
+static int
+SetKeyedListFromAny _ANSI_ARGS_((Tcl_Interp *interp,
+                                 Tcl_Obj    *objPtr));
+
+static void
+UpdateStringOfKeyedList _ANSI_ARGS_((Tcl_Obj *keylPtr));
+
+static int 
+Tcl_KeylgetObjCmd _ANSI_ARGS_((ClientData   clientData,
+                               Tcl_Interp  *interp,
+                               int          objc,
+                               Tcl_Obj     *const objv[]));
+
+static int
+Tcl_KeylsetObjCmd _ANSI_ARGS_((ClientData   clientData,
+                               Tcl_Interp  *interp,
+                               int          objc,
+                               Tcl_Obj     *const objv[]));
+
+static int 
+Tcl_KeyldelObjCmd _ANSI_ARGS_((ClientData   clientData,
+                               Tcl_Interp  *interp,
+                               int          objc,
+                               Tcl_Obj     *const objv[]));
+
+static int 
+Tcl_KeylkeysObjCmd _ANSI_ARGS_((ClientData   clientData,
+                                Tcl_Interp  *interp,
+                                int          objc,
+                                 Tcl_Obj     *const objv[]));
+
+/*
+ * Type definition.
+ */
+Tcl_ObjType keyedListType = {
+    "keyedList",              /* name */
+    FreeKeyedListInternalRep, /* freeIntRepProc */
+    DupKeyedListInternalRep,  /* dupIntRepProc */
+    UpdateStringOfKeyedList,  /* updateStringProc */
+    SetKeyedListFromAny       /* setFromAnyProc */
+};
+
+\f
+/*-----------------------------------------------------------------------------
+ * ValidateKeyedList --
+ *   Validate a keyed list (only when TCLX_DEBUG is enabled).
+ * Parameters:
+ *   o keylIntPtr - Keyed list internal representation.
+ *-----------------------------------------------------------------------------
+ */
+#ifdef TCLX_DEBUG
+static void
+ValidateKeyedList (keylIntPtr)
+    keylIntObj_t *keylIntPtr;
+{
+    int idx;
+
+    TclX_Assert (keylIntPtr->arraySize >= keylIntPtr->numEntries);
+    TclX_Assert (keylIntPtr->arraySize >= 0);
+    TclX_Assert (keylIntPtr->numEntries >= 0);
+    TclX_Assert ((keylIntPtr->arraySize > 0) ?
+                 (keylIntPtr->entries != NULL) : TRUE);
+    TclX_Assert ((keylIntPtr->numEntries > 0) ?
+                 (keylIntPtr->entries != NULL) : TRUE);
+
+    for (idx = 0; idx < keylIntPtr->numEntries; idx++) {
+        keylEntry_t *entryPtr = &(keylIntPtr->entries [idx]);
+        TclX_Assert (entryPtr->key != NULL);
+        TclX_Assert (entryPtr->valuePtr->refCount >= 1);
+        if (entryPtr->valuePtr->typePtr == &keyedListType) {
+            ValidateKeyedList (entryPtr->valuePtr->internalRep.otherValuePtr);
+        }
+    }
+}
+#endif
+\f
+/*-----------------------------------------------------------------------------
+ * ValidateKey --
+ *   Check that a key or keypath string is a valid value.
+ *
+ * Parameters:
+ *   o interp - Used to return error messages.
+ *   o key - Key string to check.
+ *   o keyLen - Length of the string, used to check for binary data.
+ *   o isPath - TRUE if this is a key path, FALSE if its a simple key and
+ *     thus "." is illegal.
+ * Returns:
+ *    TCL_OK or TCL_ERROR.
+ *-----------------------------------------------------------------------------
+ */
+static int
+ValidateKey (interp, key, keyLen, isPath)
+    Tcl_Interp *interp;
+    const char *key;
+    int keyLen;
+    int isPath;
+{
+    const char *keyp;
+
+    if (strlen (key) != (size_t) keyLen) {
+        Tcl_ResetResult(interp);
+        Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
+                                "keyed list key may not be a ",
+                                "binary string", (char *) NULL);
+        return TCL_ERROR;
+    }
+    if (key [0] == '\0') {
+        Tcl_ResetResult(interp);
+        Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
+                                "keyed list key may not be an ",
+                                "empty string", (char *) NULL);
+        return TCL_ERROR;
+    }
+    for (keyp = key; *keyp != '\0'; keyp++) {
+        if ((!isPath) && (*keyp == '.')) {
+            Tcl_ResetResult(interp);
+            Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
+                                    "keyed list key may not contain a \".\"; ",
+                                    "it is used as a separator in key paths",
+                                    (char *) NULL);
+            return TCL_ERROR;
+        }
+    }
+    return TCL_OK;
+}
+
+\f
+/*-----------------------------------------------------------------------------
+ * AllocKeyedListIntRep --
+ *   Allocate an and initialize the keyed list internal representation.
+ *
+ * Returns:
+ *    A pointer to the keyed list internal structure.
+ *-----------------------------------------------------------------------------
+ */
+static keylIntObj_t *
+AllocKeyedListIntRep ()
+{
+    keylIntObj_t *keylIntPtr;
+
+    keylIntPtr = (keylIntObj_t *) ckalloc (sizeof (keylIntObj_t));
+
+    keylIntPtr->arraySize = 0;
+    keylIntPtr->numEntries = 0;
+    keylIntPtr->entries = NULL;
+
+    return keylIntPtr;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * FreeKeyedListData --
+ *   Free the internal representation of a keyed list.
+ *
+ * Parameters:
+ *   o keylIntPtr - Keyed list internal structure to free.
+ *-----------------------------------------------------------------------------
+ */
+static void
+FreeKeyedListData (keylIntPtr)
+    keylIntObj_t *keylIntPtr;
+{
+    int idx;
+
+    for (idx = 0; idx < keylIntPtr->numEntries ; idx++) {
+        ckfree (keylIntPtr->entries [idx].key);
+        Tcl_DecrRefCount (keylIntPtr->entries [idx].valuePtr);
+    }
+    if (keylIntPtr->entries != NULL)
+        ckfree ((char *) keylIntPtr->entries);
+    ckfree ((char *) keylIntPtr);
+}
+\f
+/*-----------------------------------------------------------------------------
+ * EnsureKeyedListSpace --
+ *   Ensure there is enough room in a keyed list array for a certain number
+ * of entries, expanding if necessary.
+ *
+ * Parameters:
+ *   o keylIntPtr - Keyed list internal representation.
+ *   o newNumEntries - The number of entries that are going to be added to
+ *     the keyed list.
+ *-----------------------------------------------------------------------------
+ */
+static void
+EnsureKeyedListSpace (keylIntPtr, newNumEntries)
+    keylIntObj_t *keylIntPtr;
+    int           newNumEntries;
+{
+    KEYL_REP_ASSERT (keylIntPtr);
+
+    if ((keylIntPtr->arraySize - keylIntPtr->numEntries) < newNumEntries) {
+        int newSize = keylIntPtr->arraySize + newNumEntries +
+            KEYEDLIST_ARRAY_INCR_SIZE;
+        if (keylIntPtr->entries == NULL) {
+            keylIntPtr->entries = (keylEntry_t *)
+                ckalloc (newSize * sizeof (keylEntry_t));
+        } else {
+            keylIntPtr->entries = (keylEntry_t *)
+                ckrealloc ((VOID *) keylIntPtr->entries,
+                           newSize * sizeof (keylEntry_t));
+        }
+        keylIntPtr->arraySize = newSize;
+    }
+
+    KEYL_REP_ASSERT (keylIntPtr);
+}
+\f
+/*-----------------------------------------------------------------------------
+ * DeleteKeyedListEntry --
+ *   Delete an entry from a keyed list.
+ *
+ * Parameters:
+ *   o keylIntPtr - Keyed list internal representation.
+ *   o entryIdx - Index of entry to delete.
+ *-----------------------------------------------------------------------------
+ */
+static void
+DeleteKeyedListEntry (keylIntPtr, entryIdx)
+    keylIntObj_t *keylIntPtr;
+    int           entryIdx;
+{
+    int idx;
+
+    ckfree (keylIntPtr->entries [entryIdx].key);
+    Tcl_DecrRefCount (keylIntPtr->entries [entryIdx].valuePtr);
+
+    for (idx = entryIdx; idx < keylIntPtr->numEntries - 1; idx++)
+        keylIntPtr->entries [idx] = keylIntPtr->entries [idx + 1];
+    keylIntPtr->numEntries--;
+
+    KEYL_REP_ASSERT (keylIntPtr);
+}
+\f
+/*-----------------------------------------------------------------------------
+ * FindKeyedListEntry --
+ *   Find an entry in keyed list.
+ *
+ * Parameters:
+ *   o keylIntPtr - Keyed list internal representation.
+ *   o key - Name of key to search for.
+ *   o keyLenPtr - In not NULL, the length of the key for this
+ *     level is returned here.  This excludes subkeys and the `.' delimiters.
+ *   o nextSubKeyPtr - If not NULL, the start of the name of the next
+ *     sub-key within key is returned.
+ * Returns:
+ *   Index of the entry or -1 if not found.
+ *-----------------------------------------------------------------------------
+ */
+static int
+FindKeyedListEntry (keylIntPtr, key, keyLenPtr, nextSubKeyPtr)
+    keylIntObj_t *keylIntPtr;
+    const char   *key;
+    int          *keyLenPtr;
+    const char   **nextSubKeyPtr;
+{
+    char *keySeparPtr;
+    int keyLen, findIdx;
+
+    keySeparPtr = strchr (key, '.');
+    if (keySeparPtr != NULL) {
+        keyLen = keySeparPtr - key;
+    } else {
+        keyLen = strlen (key);
+    }
+
+    for (findIdx = 0; findIdx < keylIntPtr->numEntries; findIdx++) {
+        if ((strncmp (keylIntPtr->entries [findIdx].key, key, keyLen) == 0) &&
+            (keylIntPtr->entries [findIdx].key [keyLen] == '\0'))
+            break;
+    }
+
+    if (nextSubKeyPtr != NULL) {
+        if (keySeparPtr == NULL) {
+            *nextSubKeyPtr = NULL;
+        } else {
+            *nextSubKeyPtr = keySeparPtr + 1;
+        }
+    }
+    if (keyLenPtr != NULL) {
+        *keyLenPtr = keyLen;
+    }
+    
+    if (findIdx >= keylIntPtr->numEntries) {
+        return -1;
+    }
+    
+    return findIdx;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * ObjToKeyedListEntry --
+ *   Convert an object to a keyed list entry. (Keyword/value pair).
+ *
+ * Parameters:
+ *   o interp - Used to return error messages, if not NULL.
+ *   o objPtr - Object to convert.  Each entry must be a two element list,
+ *     with the first element being the key and the second being the
+ *     value.
+ *   o entryPtr - The keyed list entry to initialize from the object.
+ * Returns:
+ *    TCL_OK or TCL_ERROR.
+ *-----------------------------------------------------------------------------
+ */
+static int
+ObjToKeyedListEntry (interp, objPtr, entryPtr)
+    Tcl_Interp  *interp;
+    Tcl_Obj     *objPtr;
+    keylEntry_t *entryPtr;
+{
+    int objc;
+    Tcl_Obj **objv;
+    const char *key;
+    int keyLen;
+
+    if (Tcl_ListObjGetElements (interp, objPtr, &objc, &objv) != TCL_OK) {
+        Tcl_ResetResult (interp);
+        Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
+                                "keyed list entry not a valid list, ",
+                                "found \"", 
+                                Tcl_GetStringFromObj (objPtr, NULL),
+                                "\"", (char *) NULL);
+        return TCL_ERROR;
+    }
+
+    if (objc != 2) {
+        Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
+                                "keyed list entry must be a two ",
+                                "element list, found \"",
+                                Tcl_GetStringFromObj (objPtr, NULL),
+                                "\"", (char *) NULL);
+        return TCL_ERROR;
+    }
+
+    key = Tcl_GetStringFromObj (objv [0], &keyLen);
+    if (ValidateKey (interp, key, keyLen, FALSE) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+
+    entryPtr->key = ckstrdup (key);
+    entryPtr->valuePtr = Tcl_DuplicateObj (objv [1]);
+    Tcl_IncrRefCount (entryPtr->valuePtr);
+
+    return TCL_OK;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * FreeKeyedListInternalRep --
+ *   Free the internal representation of a keyed list.
+ *
+ * Parameters:
+ *   o keylPtr - Keyed list object being deleted.
+ *-----------------------------------------------------------------------------
+ */
+static void
+FreeKeyedListInternalRep (keylPtr)
+    Tcl_Obj *keylPtr;
+{
+    FreeKeyedListData ((keylIntObj_t *) keylPtr->internalRep.otherValuePtr);
+}
+\f
+/*-----------------------------------------------------------------------------
+ * DupKeyedListInternalRep --
+ *   Duplicate the internal representation of a keyed list.
+ *
+ * Parameters:
+ *   o srcPtr - Keyed list object to copy.
+ *   o copyPtr - Target object to copy internal representation to.
+ *-----------------------------------------------------------------------------
+ */
+static void
+DupKeyedListInternalRep (srcPtr, copyPtr)
+    Tcl_Obj *srcPtr;
+    Tcl_Obj *copyPtr;
+{
+    keylIntObj_t *srcIntPtr =
+        (keylIntObj_t *) srcPtr->internalRep.otherValuePtr;
+    keylIntObj_t *copyIntPtr;
+    int idx;
+
+    KEYL_REP_ASSERT (srcIntPtr);
+
+    copyIntPtr = (keylIntObj_t *) ckalloc (sizeof (keylIntObj_t));
+    copyIntPtr->arraySize = srcIntPtr->arraySize;
+    copyIntPtr->numEntries = srcIntPtr->numEntries;
+    copyIntPtr->entries = (keylEntry_t *)
+        ckalloc (copyIntPtr->arraySize * sizeof (keylEntry_t));
+
+    for (idx = 0; idx < srcIntPtr->numEntries ; idx++) {
+        copyIntPtr->entries [idx].key = 
+            ckstrdup (srcIntPtr->entries [idx].key);
+        copyIntPtr->entries [idx].valuePtr = srcIntPtr->entries [idx].valuePtr;
+        Tcl_IncrRefCount (copyIntPtr->entries [idx].valuePtr);
+    }
+
+    copyPtr->internalRep.otherValuePtr = (VOID *) copyIntPtr;
+    copyPtr->typePtr = &keyedListType;
+
+    KEYL_REP_ASSERT (copyIntPtr);
+}
+\f
+/*-----------------------------------------------------------------------------
+ * DupKeyedListInternalRepShared --
+ *   Same as DupKeyedListInternalRepbut does not reference objects 
+ *   from the srcPtr list. It duplicates them and stores the copy 
+ *   in the list-copy object.
+ *
+ * Parameters:
+ *   o srcPtr - Keyed list object to copy.
+ *   o copyPtr - Target object to copy internal representation to.
+ *-----------------------------------------------------------------------------
+ */
+void
+DupKeyedListInternalRepShared (srcPtr, copyPtr)
+    Tcl_Obj *srcPtr;
+    Tcl_Obj *copyPtr;
+{
+    keylIntObj_t *srcIntPtr =
+        (keylIntObj_t *) srcPtr->internalRep.otherValuePtr;
+    keylIntObj_t *copyIntPtr;
+    int idx;
+
+    KEYL_REP_ASSERT (srcIntPtr);
+
+    copyIntPtr = (keylIntObj_t *) ckalloc (sizeof (keylIntObj_t));
+    copyIntPtr->arraySize = srcIntPtr->arraySize;
+    copyIntPtr->numEntries = srcIntPtr->numEntries;
+    copyIntPtr->entries = (keylEntry_t *)
+        ckalloc (copyIntPtr->arraySize * sizeof (keylEntry_t));
+
+    for (idx = 0; idx < srcIntPtr->numEntries ; idx++) {
+        copyIntPtr->entries [idx].key = 
+            ckstrdup (srcIntPtr->entries [idx].key);
+        copyIntPtr->entries [idx].valuePtr =
+            Sv_DuplicateObj (srcIntPtr->entries [idx].valuePtr);
+        Tcl_IncrRefCount(copyIntPtr->entries [idx].valuePtr);
+    }
+
+    copyPtr->internalRep.otherValuePtr = (VOID *) copyIntPtr;
+    copyPtr->typePtr = &keyedListType;
+
+    KEYL_REP_ASSERT (copyIntPtr);
+}
+\f
+/*-----------------------------------------------------------------------------
+ * SetKeyedListFromAny --
+ *   Convert an object to a keyed list from its string representation.  Only
+ * the first level is converted, as there is no way of knowing how far down
+ * the keyed list recurses until lower levels are accessed.
+ *
+ * Parameters:
+ *   o objPtr - Object to convert to a keyed list.
+ *-----------------------------------------------------------------------------
+ */
+static int
+SetKeyedListFromAny (interp, objPtr) 
+    Tcl_Interp *interp;
+    Tcl_Obj    *objPtr;
+{
+    keylIntObj_t *keylIntPtr;
+    int idx, objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_ListObjGetElements (interp, objPtr, &objc, &objv) != TCL_OK)
+        return TCL_ERROR;
+    
+    keylIntPtr = AllocKeyedListIntRep ();
+
+    EnsureKeyedListSpace (keylIntPtr, objc);
+
+    for (idx = 0; idx < objc; idx++) {
+        if (ObjToKeyedListEntry (interp, objv [idx], 
+                &(keylIntPtr->entries [keylIntPtr->numEntries])) != TCL_OK)
+            goto errorExit;
+        keylIntPtr->numEntries++;
+    }
+
+    if ((objPtr->typePtr != NULL) &&
+        (objPtr->typePtr->freeIntRepProc != NULL)) {
+        (*objPtr->typePtr->freeIntRepProc) (objPtr);
+    }
+    objPtr->internalRep.otherValuePtr = (VOID *) keylIntPtr;
+    objPtr->typePtr = &keyedListType;
+
+    KEYL_REP_ASSERT (keylIntPtr);
+    return TCL_OK;
+    
+  errorExit:
+    FreeKeyedListData (keylIntPtr);
+    return TCL_ERROR;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * UpdateStringOfKeyedList --
+ *    Update the string representation of a keyed list.
+ *
+ * Parameters:
+ *   o objPtr - Object to convert to a keyed list.
+ *-----------------------------------------------------------------------------
+ */
+static void
+UpdateStringOfKeyedList (keylPtr)
+    Tcl_Obj  *keylPtr;
+{
+#define UPDATE_STATIC_SIZE 32
+    int idx, strLen;
+    Tcl_Obj **listObjv, *entryObjv [2], *tmpListObj;
+    Tcl_Obj *staticListObjv [UPDATE_STATIC_SIZE];
+    char *listStr;
+    keylIntObj_t *keylIntPtr =
+        (keylIntObj_t *) keylPtr->internalRep.otherValuePtr;
+
+    /*
+     * Conversion to strings is done via list objects to support binary data.
+     */
+    if (keylIntPtr->numEntries > UPDATE_STATIC_SIZE) {
+        listObjv =
+            (Tcl_Obj **) ckalloc (keylIntPtr->numEntries * sizeof (Tcl_Obj *));
+    } else {
+        listObjv = staticListObjv;
+    }
+
+    /*
+     * Convert each keyed list entry to a two element list object.  No
+     * need to incr/decr ref counts, the list objects will take care of that.
+     * FIX: Keeping key as string object will speed this up.
+     */
+    for (idx = 0; idx < keylIntPtr->numEntries; idx++) {
+        entryObjv [0] = 
+            Tcl_NewStringObj (keylIntPtr->entries [idx].key,
+                              strlen (keylIntPtr->entries [idx].key));
+        entryObjv [1] = keylIntPtr->entries [idx].valuePtr;
+        listObjv [idx] = Tcl_NewListObj (2, entryObjv);
+    }
+
+    tmpListObj = Tcl_NewListObj (keylIntPtr->numEntries, listObjv);
+    listStr = Tcl_GetStringFromObj (tmpListObj, &strLen);
+    keylPtr->bytes = ckbinstrdup (listStr, strLen);
+    keylPtr->length = strLen;
+
+    Tcl_DecrRefCount (tmpListObj);
+    if (listObjv != staticListObjv)
+        ckfree ((VOID*) listObjv);
+}
+\f
+/*-----------------------------------------------------------------------------
+ * TclX_NewKeyedListObj --
+ *   Create and initialize a new keyed list object.
+ *
+ * Returns:
+ *    A pointer to the object.
+ *-----------------------------------------------------------------------------
+ */
+Tcl_Obj *
+TclX_NewKeyedListObj ()
+{
+    Tcl_Obj *keylPtr = Tcl_NewObj ();
+    keylIntObj_t *keylIntPtr = AllocKeyedListIntRep ();
+
+    keylPtr->internalRep.otherValuePtr = (VOID *) keylIntPtr;
+    keylPtr->typePtr = &keyedListType;
+    return keylPtr;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * TclX_KeyedListGet --
+ *   Retrieve a key value from a keyed list.
+ *
+ * Parameters:
+ *   o interp - Error message will be return in result if there is an error.
+ *   o keylPtr - Keyed list object to get key from.
+ *   o key - The name of the key to extract.  Will recusively process sub-keys
+ *     seperated by `.'.
+ *   o valueObjPtrPtr - If the key is found, a pointer to the key object
+ *     is returned here.  NULL is returned if the key is not present.
+ * Returns:
+ *   o TCL_OK - If the key value was returned.
+ *   o TCL_BREAK - If the key was not found.
+ *   o TCL_ERROR - If an error occured.
+ *-----------------------------------------------------------------------------
+ */
+int
+TclX_KeyedListGet (interp, keylPtr, key, valuePtrPtr)
+    Tcl_Interp *interp;
+    Tcl_Obj    *keylPtr;
+    const char *key;
+    Tcl_Obj   **valuePtrPtr;
+{
+    keylIntObj_t *keylIntPtr;
+    const char *nextSubKey;
+    int findIdx;
+
+    if (Tcl_ConvertToType (interp, keylPtr, &keyedListType) != TCL_OK)
+        return TCL_ERROR;
+    keylIntPtr = (keylIntObj_t *) keylPtr->internalRep.otherValuePtr;
+    KEYL_REP_ASSERT (keylIntPtr);
+
+    findIdx = FindKeyedListEntry (keylIntPtr, key, NULL, &nextSubKey);
+
+    /*
+     * If not found, return status.
+     */
+    if (findIdx < 0) {
+        *valuePtrPtr = NULL;
+        return TCL_BREAK;
+    }
+
+    /*
+     * If we are at the last subkey, return the entry, otherwise recurse
+     * down looking for the entry.
+     */
+    if (nextSubKey == NULL) {
+        *valuePtrPtr = keylIntPtr->entries [findIdx].valuePtr;
+        return TCL_OK;
+    } else {
+        return TclX_KeyedListGet (interp, 
+                                  keylIntPtr->entries [findIdx].valuePtr,
+                                  nextSubKey,
+                                  valuePtrPtr);
+    }
+}
+\f
+/*-----------------------------------------------------------------------------
+ * TclX_KeyedListSet --
+ *   Set a key value in keyed list object.
+ *
+ * Parameters:
+ *   o interp - Error message will be return in result object.
+ *   o keylPtr - Keyed list object to update.
+ *   o key - The name of the key to extract.  Will recusively process
+ *     sub-key seperated by `.'.
+ *   o valueObjPtr - The value to set for the key.
+ * Returns:
+ *   TCL_OK or TCL_ERROR.
+ *-----------------------------------------------------------------------------
+ */
+int
+TclX_KeyedListSet (interp, keylPtr, key, valuePtr)
+    Tcl_Interp *interp;
+    Tcl_Obj    *keylPtr;
+    const char *key;
+    Tcl_Obj    *valuePtr;
+{
+    keylIntObj_t *keylIntPtr;
+    const char *nextSubKey;
+    int findIdx, keyLen, status;
+    Tcl_Obj *newKeylPtr;
+
+    if (Tcl_ConvertToType (interp, keylPtr, &keyedListType) != TCL_OK)
+        return TCL_ERROR;
+    keylIntPtr = (keylIntObj_t *) keylPtr->internalRep.otherValuePtr;
+    KEYL_REP_ASSERT (keylIntPtr);
+
+    findIdx = FindKeyedListEntry (keylIntPtr, key,
+                                  &keyLen, &nextSubKey);
+
+    /*
+     * If we are at the last subkey, either update or add an entry.
+     */
+    if (nextSubKey == NULL) {
+        if (findIdx < 0) {
+            EnsureKeyedListSpace (keylIntPtr, 1);
+            findIdx = keylIntPtr->numEntries;
+            keylIntPtr->numEntries++;
+        } else {
+            ckfree (keylIntPtr->entries [findIdx].key);
+            Tcl_DecrRefCount (keylIntPtr->entries [findIdx].valuePtr);
+        }
+        keylIntPtr->entries [findIdx].key =
+            (char *) ckalloc (keyLen + 1);
+        strncpy (keylIntPtr->entries [findIdx].key, key, keyLen);
+        keylIntPtr->entries [findIdx].key [keyLen] = '\0';
+        keylIntPtr->entries [findIdx].valuePtr = valuePtr;
+        Tcl_IncrRefCount (valuePtr);
+        Tcl_InvalidateStringRep (keylPtr);
+
+        KEYL_REP_ASSERT (keylIntPtr);
+        return TCL_OK;
+    }
+
+    /*
+     * If we are not at the last subkey, recurse down, creating new
+     * entries if neccessary.  If this level key was not found, it
+     * means we must build new subtree. Don't insert the new tree until we
+     * come back without error.
+     */
+    if (findIdx >= 0) {
+        DupSharedKeyListChild (keylIntPtr, findIdx);
+        status =
+            TclX_KeyedListSet (interp, 
+                               keylIntPtr->entries [findIdx].valuePtr,
+                               nextSubKey, valuePtr);
+        if (status == TCL_OK) {
+            Tcl_InvalidateStringRep (keylPtr);
+        }
+
+        KEYL_REP_ASSERT (keylIntPtr);
+        return status;
+    } else {
+        newKeylPtr = TclX_NewKeyedListObj ();
+        if (TclX_KeyedListSet (interp, newKeylPtr,
+                               nextSubKey, valuePtr) != TCL_OK) {
+            Tcl_DecrRefCount (newKeylPtr);
+            return TCL_ERROR;
+        }
+        EnsureKeyedListSpace (keylIntPtr, 1);
+        findIdx = keylIntPtr->numEntries++;
+        keylIntPtr->entries [findIdx].key =
+            (char *) ckalloc (keyLen + 1);
+        strncpy (keylIntPtr->entries [findIdx].key, key, keyLen);
+        keylIntPtr->entries [findIdx].key [keyLen] = '\0';
+        keylIntPtr->entries [findIdx].valuePtr = newKeylPtr;
+        Tcl_IncrRefCount (newKeylPtr);
+        Tcl_InvalidateStringRep (keylPtr);
+
+        KEYL_REP_ASSERT (keylIntPtr);
+        return TCL_OK;
+    }
+}
+\f
+/*-----------------------------------------------------------------------------
+ * TclX_KeyedListDelete --
+ *   Delete a key value from keyed list.
+ *
+ * Parameters:
+ *   o interp - Error message will be return in result if there is an error.
+ *   o keylPtr - Keyed list object to update.
+ *   o key - The name of the key to extract.  Will recusively process
+ *     sub-key seperated by `.'.
+ * Returns:
+ *   o TCL_OK - If the key was deleted.
+ *   o TCL_BREAK - If the key was not found.
+ *   o TCL_ERROR - If an error occured.
+ *-----------------------------------------------------------------------------
+ */
+int
+TclX_KeyedListDelete (interp, keylPtr, key)
+    Tcl_Interp *interp;
+    Tcl_Obj    *keylPtr;
+    const char *key;
+{
+    keylIntObj_t *keylIntPtr, *subKeylIntPtr;
+    const char *nextSubKey;
+    int findIdx, status;
+
+    if (Tcl_ConvertToType (interp, keylPtr, &keyedListType) != TCL_OK)
+        return TCL_ERROR;
+    keylIntPtr = (keylIntObj_t *) keylPtr->internalRep.otherValuePtr;
+
+    findIdx = FindKeyedListEntry (keylIntPtr, key, NULL, &nextSubKey);
+
+    /*
+     * If not found, return status.
+     */
+    if (findIdx < 0) {
+        KEYL_REP_ASSERT (keylIntPtr);
+        return TCL_BREAK;
+    }
+
+    /*
+     * If we are at the last subkey, delete the entry.
+     */
+    if (nextSubKey == NULL) {
+        DeleteKeyedListEntry (keylIntPtr, findIdx);
+        Tcl_InvalidateStringRep (keylPtr);
+
+        KEYL_REP_ASSERT (keylIntPtr);
+        return TCL_OK;
+    }
+
+    /*
+     * If we are not at the last subkey, recurse down.  If the entry is
+     * deleted and the sub-keyed list is empty, delete it as well.  Must
+     * invalidate string, as it caches all representations below it.
+     */
+    DupSharedKeyListChild (keylIntPtr, findIdx);
+
+    status = TclX_KeyedListDelete (interp,
+                                   keylIntPtr->entries [findIdx].valuePtr,
+                                   nextSubKey);
+    if (status == TCL_OK) {
+        subKeylIntPtr = (keylIntObj_t *)
+            keylIntPtr->entries [findIdx].valuePtr->internalRep.otherValuePtr;
+        if (subKeylIntPtr->numEntries == 0) {
+            DeleteKeyedListEntry (keylIntPtr, findIdx);
+        }
+        Tcl_InvalidateStringRep (keylPtr);
+    }
+
+    KEYL_REP_ASSERT (keylIntPtr);
+    return status;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * TclX_KeyedListGetKeys --
+ *   Retrieve a list of keyed list keys.
+ *
+ * Parameters:
+ *   o interp - Error message will be return in result if there is an error.
+ *   o keylPtr - Keyed list object to get key from.
+ *   o key - The name of the key to get the sub keys for.  NULL or empty
+ *     to retrieve all top level keys.
+ *   o listObjPtrPtr - List object is returned here with key as values.
+ * Returns:
+ *   o TCL_OK - If the zero or more key where returned.
+ *   o TCL_BREAK - If the key was not found.
+ *   o TCL_ERROR - If an error occured.
+ *-----------------------------------------------------------------------------
+ */
+int
+TclX_KeyedListGetKeys (interp, keylPtr, key, listObjPtrPtr)
+    Tcl_Interp *interp;
+    Tcl_Obj    *keylPtr;
+    const char *key;
+    Tcl_Obj   **listObjPtrPtr;
+{
+    keylIntObj_t *keylIntPtr;
+    Tcl_Obj *nameObjPtr, *listObjPtr;
+    const char *nextSubKey;
+    int idx, findIdx;
+
+    if (Tcl_ConvertToType (interp, keylPtr, &keyedListType) != TCL_OK)
+        return TCL_ERROR;
+    keylIntPtr = (keylIntObj_t *) keylPtr->internalRep.otherValuePtr;
+
+    /*
+     * If key is not NULL or empty, then recurse down until we go past
+     * the end of all of the elements of the key.
+     */
+    if ((key != NULL) && (key [0] != '\0')) {
+        findIdx = FindKeyedListEntry (keylIntPtr, key, NULL, &nextSubKey);
+        if (findIdx < 0) {
+            TclX_Assert (keylIntPtr->arraySize >= keylIntPtr->numEntries);
+            return TCL_BREAK;
+        }
+        TclX_Assert (keylIntPtr->arraySize >= keylIntPtr->numEntries);
+        return TclX_KeyedListGetKeys (interp, 
+                                      keylIntPtr->entries [findIdx].valuePtr,
+                                      nextSubKey,
+                                      listObjPtrPtr);
+    }
+
+    /*
+     * Reached the end of the full key, return all keys at this level.
+     */
+    listObjPtr = Tcl_NewListObj (0, NULL);
+    for (idx = 0; idx < keylIntPtr->numEntries; idx++) {
+        nameObjPtr = Tcl_NewStringObj (keylIntPtr->entries [idx].key,
+                                       -1);
+        if (Tcl_ListObjAppendElement (interp, listObjPtr,
+                                      nameObjPtr) != TCL_OK) {
+            Tcl_DecrRefCount (nameObjPtr);
+            Tcl_DecrRefCount (listObjPtr);
+            return TCL_ERROR;
+        }
+    }
+    *listObjPtrPtr = listObjPtr;
+    TclX_Assert (keylIntPtr->arraySize >= keylIntPtr->numEntries);
+    return TCL_OK;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * Tcl_KeylgetObjCmd --
+ *     Implements the TCL keylget command:
+ *         keylget listvar ?key? ?retvar | {}?
+ *-----------------------------------------------------------------------------
+ */
+static int
+Tcl_KeylgetObjCmd (clientData, interp, objc, objv)
+    ClientData   clientData;
+    Tcl_Interp  *interp;
+    int          objc;
+    Tcl_Obj     *const objv[];
+{
+    Tcl_Obj *keylPtr, *valuePtr;
+    const char *varName, *key;
+    int keyLen, status;
+
+    if ((objc < 2) || (objc > 4)) {
+        return TclX_WrongArgs (interp, objv [0],
+                               "listvar ?key? ?retvar | {}?");
+    }
+    varName = Tcl_GetStringFromObj (objv [1], NULL);
+
+    /*
+     * Handle request for list of keys, use keylkeys command.
+     */
+    if (objc == 2)
+        return Tcl_KeylkeysObjCmd (clientData, interp, objc, objv);
+
+    keylPtr = Tcl_GetVar2Ex(interp, varName, NULL, 
+                            TCL_PARSE_PART1|TCL_LEAVE_ERR_MSG);
+    if (keylPtr == NULL) {
+        return TCL_ERROR;
+    }
+
+    /*
+     * Handle retrieving a value for a specified key.
+     */
+    key = Tcl_GetStringFromObj (objv [2], &keyLen);
+    if (ValidateKey (interp, key, keyLen, TRUE) == TCL_ERROR) {
+        return TCL_ERROR;
+    }
+
+    status = TclX_KeyedListGet (interp, keylPtr, key, &valuePtr);
+    if (status == TCL_ERROR)
+        return TCL_ERROR;
+
+    /*
+     * Handle key not found.
+     */
+    if (status == TCL_BREAK) {
+        if (objc == 3) {
+            TclX_AppendObjResult (interp, "key \"",  key,
+                                  "\" not found in keyed list",
+                                  (char *) NULL);
+            return TCL_ERROR;
+        } else {
+            Tcl_ResetResult(interp);
+            Tcl_SetBooleanObj (Tcl_GetObjResult (interp), FALSE);
+            return TCL_OK;
+        }
+    }
+
+    /*
+     * No variable specified, so return value in the result.
+     */
+    if (objc == 3) {
+        Tcl_SetObjResult (interp, valuePtr);
+        return TCL_OK;
+    }
+
+    /*
+     * Variable (or empty variable name) specified.
+     */
+    if (!TclX_IsNullObj (objv [3])) {
+        if (Tcl_SetVar2Ex(interp, Tcl_GetStringFromObj(objv [3], NULL), NULL,
+                          valuePtr, TCL_PARSE_PART1|TCL_LEAVE_ERR_MSG) == NULL)
+            return TCL_ERROR;
+    }
+    Tcl_ResetResult(interp);
+    Tcl_SetBooleanObj (Tcl_GetObjResult (interp), TRUE);
+    return TCL_OK;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * Tcl_KeylsetObjCmd --
+ *     Implements the TCL keylset command:
+ *         keylset listvar key value ?key value...?
+ *-----------------------------------------------------------------------------
+ */
+static int
+Tcl_KeylsetObjCmd (clientData, interp, objc, objv)
+    ClientData   clientData;
+    Tcl_Interp  *interp;
+    int          objc;
+    Tcl_Obj     *const objv[];
+{
+    Tcl_Obj *keylVarPtr, *newVarObj;
+    const char *varName, *key;
+    int idx, keyLen;
+
+    if ((objc < 4) || ((objc % 2) != 0)) {
+        return TclX_WrongArgs (interp, objv [0],
+                               "listvar key value ?key value...?");
+    }
+    varName = Tcl_GetStringFromObj (objv [1], NULL);
+
+    /*
+     * Get the variable that we are going to update.  If the var doesn't exist,
+     * create it.  If it is shared by more than being a variable, duplicated
+     * it.
+     */
+    keylVarPtr = Tcl_GetVar2Ex(interp, varName, NULL, TCL_PARSE_PART1);
+    if ((keylVarPtr == NULL) || (Tcl_IsShared (keylVarPtr))) {
+        if (keylVarPtr == NULL) {
+            keylVarPtr = TclX_NewKeyedListObj ();
+        } else {
+            keylVarPtr = Tcl_DuplicateObj (keylVarPtr);
+        }
+        newVarObj = keylVarPtr;
+    } else {
+        newVarObj = NULL;
+    }
+
+    for (idx = 2; idx < objc; idx += 2) {
+        key = Tcl_GetStringFromObj (objv [idx], &keyLen);
+        if (ValidateKey (interp, key, keyLen, TRUE) == TCL_ERROR) {
+            goto errorExit;
+        }
+        if (TclX_KeyedListSet (interp, keylVarPtr, key, objv [idx+1]) != TCL_OK) {
+            goto errorExit;
+        }
+    }
+
+    if (Tcl_SetVar2Ex(interp, varName, NULL, keylVarPtr,
+                      TCL_PARSE_PART1|TCL_LEAVE_ERR_MSG) == NULL) {
+        goto errorExit;
+    }
+
+    return TCL_OK;
+
+  errorExit:
+    if (newVarObj != NULL) {
+        Tcl_DecrRefCount (newVarObj);
+    }
+    return TCL_ERROR;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * Tcl_KeyldelObjCmd --
+ *     Implements the TCL keyldel command:
+ *         keyldel listvar key ?key ...?
+ *----------------------------------------------------------------------------
+ */
+static int
+Tcl_KeyldelObjCmd (clientData, interp, objc, objv)
+    ClientData   clientData;
+    Tcl_Interp  *interp;
+    int          objc;
+    Tcl_Obj     *const objv[];
+{
+    Tcl_Obj *keylVarPtr, *keylPtr;
+    const char *varName, *key;
+    int idx, keyLen, status;
+
+    if (objc < 3) {
+        return TclX_WrongArgs (interp, objv [0], "listvar key ?key ...?");
+    }
+    varName = Tcl_GetStringFromObj (objv [1], NULL);
+
+    /*
+     * Get the variable that we are going to update.  If it is shared by more
+     * than being a variable, duplicated it.
+     */
+    keylVarPtr = Tcl_GetVar2Ex(interp, varName, NULL, 
+                               TCL_PARSE_PART1|TCL_LEAVE_ERR_MSG);
+    if (keylVarPtr == NULL) {
+        return TCL_ERROR;
+    }
+    if (Tcl_IsShared (keylVarPtr)) {
+        keylPtr = Tcl_DuplicateObj (keylVarPtr);
+        keylVarPtr = Tcl_SetVar2Ex(interp, varName, NULL, keylPtr,
+                                   TCL_PARSE_PART1|TCL_LEAVE_ERR_MSG);
+        if (keylVarPtr == NULL) {
+            Tcl_DecrRefCount (keylPtr);
+            return TCL_ERROR;
+        }
+        if (keylVarPtr != keylPtr) {
+            Tcl_DecrRefCount (keylPtr);
+        }
+    }
+    keylPtr = keylVarPtr;
+
+    for (idx = 2; idx < objc; idx++) {
+        key = Tcl_GetStringFromObj (objv [idx], &keyLen);
+        if (ValidateKey (interp, key, keyLen, TRUE) == TCL_ERROR) {
+            return TCL_ERROR;
+        }
+
+        status = TclX_KeyedListDelete (interp, keylPtr, key);
+        switch (status) {
+          case TCL_BREAK:
+            TclX_AppendObjResult (interp, "key not found: \"",
+                                  key, "\"", (char *) NULL);
+            return TCL_ERROR;
+          case TCL_ERROR:
+            return TCL_ERROR;
+        }
+    }
+
+    return TCL_OK;
+}
+\f
+/*-----------------------------------------------------------------------------
+ * Tcl_KeylkeysObjCmd --
+ *     Implements the TCL keylkeys command:
+ *         keylkeys listvar ?key?
+ *-----------------------------------------------------------------------------
+ */
+static int
+Tcl_KeylkeysObjCmd (clientData, interp, objc, objv)
+    ClientData   clientData;
+    Tcl_Interp  *interp;
+    int          objc;
+    Tcl_Obj     *const objv[];
+{
+    Tcl_Obj *keylPtr, *listObjPtr;
+    const char *varName, *key;
+    int keyLen, status;
+
+    if ((objc < 2) || (objc > 3)) {
+        return TclX_WrongArgs (interp, objv [0], "listvar ?key?");
+    }
+    varName = Tcl_GetStringFromObj (objv [1], NULL);
+
+    keylPtr = Tcl_GetVar2Ex(interp, varName, NULL, 
+                            TCL_PARSE_PART1|TCL_LEAVE_ERR_MSG);
+    if (keylPtr == NULL) {
+        return TCL_ERROR;
+    }
+
+    /*
+     * If key argument is not specified, then objv [2] is NULL or empty,
+     * meaning get top level keys.
+     */
+    if (objc < 3) {
+        key = NULL;
+    } else {
+        key = Tcl_GetStringFromObj (objv [2], &keyLen);
+        if (ValidateKey (interp, key, keyLen, TRUE) == TCL_ERROR) {
+            return TCL_ERROR;
+        }
+    }
+
+    status = TclX_KeyedListGetKeys (interp, keylPtr, key, &listObjPtr);
+    switch (status) {
+      case TCL_BREAK:
+        TclX_AppendObjResult (interp, "key not found: \"", key, "\"",
+                              (char *) NULL);
+        return TCL_ERROR;
+      case TCL_ERROR:
+        return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult (interp, listObjPtr);
+
+    return TCL_OK;
+}
+
+/*-----------------------------------------------------------------------------
+ * TclX_KeyedListInit --
+ *   Initialize the keyed list commands for this interpreter.
+ *
+ * Parameters:
+ *   o interp - Interpreter to add commands to.
+ *-----------------------------------------------------------------------------
+ */
+void
+TclX_KeyedListInit (interp)
+    Tcl_Interp *interp;
+{
+    Tcl_RegisterObjType (&keyedListType);
+
+    listType = Tcl_GetObjType("list");
+    stringType = Tcl_GetObjType("string");
+
+    if (0) {
+    Tcl_CreateObjCommand (interp, 
+                          "keylget",
+                          Tcl_KeylgetObjCmd,
+                          (ClientData) NULL,
+                          (Tcl_CmdDeleteProc*) NULL);
+
+    Tcl_CreateObjCommand (interp, 
+                          "keylset",
+                          Tcl_KeylsetObjCmd,
+                          (ClientData) NULL,
+                          (Tcl_CmdDeleteProc*) NULL);
+
+    Tcl_CreateObjCommand (interp,
+                          "keyldel",
+                          Tcl_KeyldelObjCmd,
+                          (ClientData) NULL,
+                          (Tcl_CmdDeleteProc*) NULL);
+
+    Tcl_CreateObjCommand (interp, 
+                          "keylkeys",
+                          Tcl_KeylkeysObjCmd,
+                          (ClientData) NULL,
+                          (Tcl_CmdDeleteProc*) NULL);
+    }
+}
+
+
diff --git a/8.x/thread/generic/tclXkeylist.h b/8.x/thread/generic/tclXkeylist.h
new file mode 100644 (file)
index 0000000..9c44a7b
--- /dev/null
@@ -0,0 +1,53 @@
+/* 
+ * tclXkeylist.h --
+ *
+ * Extended Tcl keyed list commands and interfaces.
+ *-----------------------------------------------------------------------------
+ * Copyright 1991-1999 Karl Lehenbauer and Mark Diekhans.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies.  Karl Lehenbauer and
+ * Mark Diekhans make no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ *-----------------------------------------------------------------------------
+ *
+ * Rcsid: @(#)$Id: tclXkeylist.h,v 1.2 2009/07/22 11:25:34 nijtmans Exp $
+ *-----------------------------------------------------------------------------
+ */
+
+#ifndef _KEYLIST_H_
+#define _KEYLIST_H_
+
+/* 
+ * Keyed list object interface commands
+ */
+
+Tcl_Obj* TclX_NewKeyedListObj();
+
+void TclX_KeyedListInit(Tcl_Interp*);
+int  TclX_KeyedListGet(Tcl_Interp*, Tcl_Obj*, const char*, Tcl_Obj**);
+int  TclX_KeyedListSet(Tcl_Interp*, Tcl_Obj*, const char*, Tcl_Obj*);
+int  TclX_KeyedListDelete(Tcl_Interp*, Tcl_Obj*, const char*);
+int  TclX_KeyedListGetKeys(Tcl_Interp*, Tcl_Obj*, const char*, Tcl_Obj**);
+
+/*
+ * Exported for usage in Sv_DuplicateObj. This is slightly
+ * modified version of the DupKeyedListInternalRep() function.
+ * It does a proper deep-copy of the keyed list object.
+ */
+
+void DupKeyedListInternalRepShared(Tcl_Obj*, Tcl_Obj*);
+
+#endif /* _KEYLIST_H_ */
+
+/* EOF $RCSfile: tclXkeylist.h,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
diff --git a/8.x/thread/generic/threadCmd.c b/8.x/thread/generic/threadCmd.c
new file mode 100644 (file)
index 0000000..e202f93
--- /dev/null
@@ -0,0 +1,3592 @@
+/* 
+ * threadCmd.c --
+ *
+ * This file implements the Tcl thread commands that allow script
+ * level access to threading. It will not load into a core that was
+ * not compiled for thread support.
+ *
+ * See http://www.tcl.tk/doc/howto/thread_model.html
+ *
+ * Some of this code is based on work done by Richard Hipp on behalf of
+ * Conservation Through Innovation, Limited, with their permission.
+ *
+ * Copyright (c) 1998 by Sun Microsystems, Inc.
+ * Copyright (c) 1999,2000 by Scriptics Corporation.
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: threadCmd.c,v 1.106 2010/04/02 16:49:58 vasiljevic Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#include "tclThread.h"
+
+#ifdef NS_AOLSERVER
+# include "aolstub.cpp"
+#endif
+
+/* 
+ * Access to the list of threads and to the thread send results
+ * (defined below) is guarded by this mutex. 
+ */
+
+TCL_DECLARE_MUTEX(threadMutex)
+
+/*
+ * Each thread has an single instance of the following structure. There
+ * is one instance of this structure per thread even if that thread contains
+ * multiple interpreters. The interpreter identified by this structure is
+ * the main interpreter for the thread. The main interpreter is the one that
+ * will process any messages received by a thread. Any interpreter can send
+ * messages but only the main interpreter can receive them, unless you're 
+ * not doing asynchronous script backfiring. In such cases the caller might
+ * signal the thread to which interpreter the result should be delivered.
+ */
+
+typedef struct ThreadSpecificData {
+    Tcl_ThreadId threadId;                /* The real ID of this thread */
+    Tcl_Interp *interp;                   /* Main interp for this thread */
+    Tcl_Condition doOneEvent;             /* Signalled just before running 
+                                             an event from the event loop */
+    int flags;                            /* One of the ThreadFlags below */
+    int refCount;                         /* Used for thread reservation */
+    int eventsPending;                    /* # of unprocessed events */
+    int maxEventsCount;                   /* Maximum # of pending events */
+    struct ThreadEventResult  *result;
+    struct ThreadSpecificData *nextPtr;
+    struct ThreadSpecificData *prevPtr;
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+#define THREAD_FLAGS_NONE          0      /* None */
+#define THREAD_FLAGS_STOPPED       1      /* Thread is being stopped */
+#define THREAD_FLAGS_INERROR       2      /* Thread is in error */
+#define THREAD_FLAGS_UNWINDONERROR 4      /* Thread unwinds on script error */
+
+#define THREAD_RESERVE             1      /* Reserves the thread */
+#define THREAD_RELEASE             2      /* Releases the thread */
+
+/*
+ * Length of storage for building the Tcl handle for the thread.
+ */
+
+#define THREAD_HNDLPREFIX  "tid"
+#define THREAD_HNDLMAXLEN  32
+
+/*
+ * This list is used to list all threads that have interpreters.
+ */
+
+static struct ThreadSpecificData *threadList = NULL;
+
+/*
+ * Used to represent the empty result.
+ */
+
+static char *threadEmptyResult = (char *)"";
+
+/*
+ * An instance of the following structure contains all information that is
+ * passed into a new thread when the thread is created using either the
+ * "thread create" Tcl command or the ThreadCreate() C function.
+ */
+
+typedef struct ThreadCtrl {
+    char *script;                         /* Script to execute */
+    int flags;                            /* Initial value of the "flags" 
+                                           * field in ThreadSpecificData */
+    Tcl_Condition condWait;               /* Condition variable used to
+                                           * sync parent and child threads */
+    ClientData cd;                        /* Opaque ptr to pass to thread */
+} ThreadCtrl;
+
+/*
+ * Structure holding result of the command executed in target thread.
+ */
+
+typedef struct ThreadEventResult {
+    Tcl_Condition done;                   /* Set when the script completes */
+    int code;                             /* Return value of the function */
+    char *result;                         /* Result from the function */
+    char *errorInfo;                      /* Copy of errorInfo variable */
+    char *errorCode;                      /* Copy of errorCode variable */
+    Tcl_ThreadId srcThreadId;             /* Id of sender, if it dies */
+    Tcl_ThreadId dstThreadId;             /* Id of target, if it dies */
+    struct ThreadEvent *eventPtr;         /* Back pointer */
+    struct ThreadEventResult *nextPtr;    /* List for cleanup */
+    struct ThreadEventResult *prevPtr;
+} ThreadEventResult;
+
+/*
+ * This list links all active ThreadEventResult structures. This way
+ * an exiting thread can inform all threads waiting on jobs posted to
+ * his event queue that it is dying, so they might stop waiting.
+ */
+
+static ThreadEventResult *resultList;
+
+/*
+ * This is the event used to send commands to other threads.
+ */
+
+typedef struct ThreadEvent {
+    Tcl_Event event;                      /* Must be first */
+    struct ThreadSendData *sendData;      /* See below */
+    struct ThreadClbkData *clbkData;      /* See below */
+    struct ThreadEventResult *resultPtr;  /* To communicate the result back.
+                                           * NULL if we don't care about it */
+} ThreadEvent;
+
+typedef int  (ThreadSendProc) _ANSI_ARGS_((Tcl_Interp*, ClientData));
+typedef void (ThreadSendFree) _ANSI_ARGS_((ClientData));
+
+static ThreadSendProc ThreadSendEval;     /* Does a regular Tcl_Eval */
+static ThreadSendProc ThreadClbkSetVar;   /* Sets the named variable */
+
+/*
+ * These structures are used to communicate commands between source and target
+ * threads. The ThreadSendData is used for source->target command passing,
+ * while the ThreadClbkData is used for doing asynchronous callbacks.
+ *
+ * Important: structures below must have first three elements indentical!
+ */
+
+typedef struct ThreadSendData {
+    ThreadSendProc *execProc;             /* Func to exec in remote thread */
+    ClientData clientData;                /* Ptr to pass to send function */
+    ThreadSendFree *freeProc;             /* Function to free client data */
+     /* ---- */
+    Tcl_Interp *interp;                   /* Interp to run the command */
+} ThreadSendData;
+
+typedef struct ThreadClbkData {
+    ThreadSendProc *execProc;             /* The callback function */
+    ClientData clientData;                /* Ptr to pass to clbk function */
+    ThreadSendFree *freeProc;             /* Function to free client data */
+    /* ---- */
+    Tcl_Interp *interp;                   /* Interp to run the command */
+    Tcl_ThreadId threadId;                /* Thread where to post callback */
+    ThreadEventResult result;             /* Returns result asynchronously */
+} ThreadClbkData;
+
+/*
+ * Event used to transfer a channel between threads.
+ */
+typedef struct TransferEvent {
+    Tcl_Event event;                      /* Must be first */
+    Tcl_Channel chan;                     /* The channel to transfer */
+    struct TransferResult *resultPtr;     /* To communicate the result */
+} TransferEvent;
+
+typedef struct TransferResult {
+    Tcl_Condition done;                   /* Set when transfer is done */
+    int resultCode;                       /* Set to TCL_OK or TCL_ERROR when
+                                             the transfer is done. Def = -1 */
+    char *resultMsg;                      /* Initialized to NULL. Set to a
+                                             allocated string by the targer
+                                             thread in case of an error  */
+    Tcl_ThreadId srcThreadId;             /* Id of src thread, if it dies */
+    Tcl_ThreadId dstThreadId;             /* Id of tgt thread, if it dies */
+    struct TransferEvent *eventPtr;       /* Back pointer */
+    struct TransferResult *nextPtr;       /* Next in the linked list */
+    struct TransferResult *prevPtr;       /* Previous in the linked list */
+} TransferResult;
+
+static TransferResult *transferList;
+
+/*
+ * This is for simple error handling when a thread script exits badly.
+ */
+
+static Tcl_ThreadId errorThreadId; /* Id of thread to post error message */
+static char *errorProcString;      /* Tcl script to run when reporting error */
+
+/*
+ * Definition of flags for ThreadSend. 
+ */
+
+#define THREAD_SEND_WAIT 1<<1
+#define THREAD_SEND_HEAD 1<<2
+
+#ifdef BUILD_thread
+# undef  TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLEXPORT
+#endif
+
+/*
+ * Miscelaneous functions used within this file
+ */
+
+static Tcl_EventDeleteProc ThreadDeleteEvent;
+
+static Tcl_ThreadCreateType 
+NewThread         _ANSI_ARGS_((ClientData clientData));
+
+static ThreadSpecificData* 
+ThreadExistsInner _ANSI_ARGS_((Tcl_ThreadId id));
+
+static int 
+ThreadInit        _ANSI_ARGS_((Tcl_Interp *interp));
+
+static int  
+ThreadCreate      _ANSI_ARGS_((Tcl_Interp *interp,
+                               const char *script,
+                               int stacksize,
+                               int flags,
+                               int preserve));
+static int  
+ThreadSend        _ANSI_ARGS_((Tcl_Interp *interp, 
+                               Tcl_ThreadId id, 
+                               ThreadSendData *sendPtr,
+                               ThreadClbkData *clbkPtr,
+                               int flags));
+static void 
+ThreadSetResult   _ANSI_ARGS_((Tcl_Interp *interp,
+                               int code,
+                               ThreadEventResult *resultPtr));
+static int  
+ThreadGetOption   _ANSI_ARGS_((Tcl_Interp *interp,
+                               Tcl_ThreadId id,
+                               char *option, 
+                               Tcl_DString *ds));
+static int  
+ThreadSetOption   _ANSI_ARGS_((Tcl_Interp *interp,
+                               Tcl_ThreadId id,
+                               char *option,
+                               char *value));
+static int  
+ThreadReserve     _ANSI_ARGS_((Tcl_Interp *interp, 
+                               Tcl_ThreadId id, 
+                               int operation,
+                               int wait));
+static int  
+ThreadEventProc   _ANSI_ARGS_((Tcl_Event *evPtr, 
+                               int mask));
+static int  
+ThreadWait        _ANSI_ARGS_((void));
+
+static int  
+ThreadExists      _ANSI_ARGS_((Tcl_ThreadId id));
+
+static int  
+ThreadList        _ANSI_ARGS_((Tcl_Interp *interp,
+                               Tcl_ThreadId **thrIdArray));
+static void 
+ThreadErrorProc   _ANSI_ARGS_((Tcl_Interp *interp));
+
+static void 
+ThreadFreeProc    _ANSI_ARGS_((ClientData clientData));
+
+static void 
+ThreadIdleProc    _ANSI_ARGS_((ClientData clientData));
+
+static void 
+ThreadExitProc    _ANSI_ARGS_((ClientData clientData));
+
+static void
+ListRemove        _ANSI_ARGS_((ThreadSpecificData *tsdPtr));
+
+static void 
+ListRemoveInner   _ANSI_ARGS_((ThreadSpecificData *tsdPtr));
+
+static void 
+ListUpdate        _ANSI_ARGS_((ThreadSpecificData *tsdPtr));
+
+static void 
+ListUpdateInner   _ANSI_ARGS_((ThreadSpecificData *tsdPtr));
+
+static int 
+ThreadJoin        _ANSI_ARGS_((Tcl_Interp *interp,
+                               Tcl_ThreadId id));
+static int 
+ThreadTransfer    _ANSI_ARGS_((Tcl_Interp *interp, 
+                               Tcl_ThreadId id,
+                               Tcl_Channel chan));
+static int 
+ThreadDetach      _ANSI_ARGS_((Tcl_Interp *interp,
+                               Tcl_Channel chan));
+static int 
+ThreadAttach      _ANSI_ARGS_((Tcl_Interp *interp,
+                               char *chanName));
+static int 
+TransferEventProc _ANSI_ARGS_((Tcl_Event *evPtr, 
+                               int mask));
+
+static void
+ThreadGetHandle   _ANSI_ARGS_((Tcl_ThreadId,
+                               char *handlePtr));
+
+static int
+ThreadGetId       _ANSI_ARGS_((Tcl_Interp *interp,
+                               Tcl_Obj *handleObj,
+                               Tcl_ThreadId *thrIdPtr));
+static void
+ErrorNoSuchThread _ANSI_ARGS_((Tcl_Interp *interp,
+                               Tcl_ThreadId thrId));
+static void
+ThreadCutChannel  _ANSI_ARGS_((Tcl_Interp *interp,
+                               Tcl_Channel channel));
+
+/*
+ * Functions implementing Tcl commands
+ */
+
+static Tcl_ObjCmdProc ThreadCreateObjCmd;
+static Tcl_ObjCmdProc ThreadReserveObjCmd;
+static Tcl_ObjCmdProc ThreadReleaseObjCmd;
+static Tcl_ObjCmdProc ThreadSendObjCmd;
+static Tcl_ObjCmdProc ThreadBroadcastObjCmd;
+static Tcl_ObjCmdProc ThreadUnwindObjCmd;
+static Tcl_ObjCmdProc ThreadExitObjCmd;
+static Tcl_ObjCmdProc ThreadIdObjCmd;
+static Tcl_ObjCmdProc ThreadNamesObjCmd;
+static Tcl_ObjCmdProc ThreadWaitObjCmd;
+static Tcl_ObjCmdProc ThreadExistsObjCmd;
+static Tcl_ObjCmdProc ThreadConfigureObjCmd;
+static Tcl_ObjCmdProc ThreadErrorProcObjCmd;
+static Tcl_ObjCmdProc ThreadJoinObjCmd;
+static Tcl_ObjCmdProc ThreadTransferObjCmd;
+static Tcl_ObjCmdProc ThreadDetachObjCmd;
+static Tcl_ObjCmdProc ThreadAttachObjCmd;
+
+static int
+ThreadInit(interp)
+    Tcl_Interp *interp; /* The current Tcl interpreter */
+{
+    Tcl_Obj *boolObjPtr;
+    const char *msg;
+    int boolVar;
+
+    if (Tcl_InitStubs(interp, "8.4", 0) == NULL) {
+        return TCL_ERROR;
+    }
+
+    boolObjPtr = Tcl_GetVar2Ex(interp, "::tcl_platform", "threaded", 0);
+
+    if (boolObjPtr == NULL
+            || Tcl_GetBooleanFromObj(interp, boolObjPtr, &boolVar) != TCL_OK
+            || boolVar == 0) {
+        msg = "Tcl core wasn't compiled for threading.";
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
+        return TCL_ERROR;
+    }
+
+    /*
+     * We seem to have a Tcl core compiled with threads enabled.
+     */
+
+    TCL_CMD(interp, THREAD_CMD_PREFIX"create",    ThreadCreateObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"send",      ThreadSendObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"broadcast", ThreadBroadcastObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"exit",      ThreadExitObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"unwind",    ThreadUnwindObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"id",        ThreadIdObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"names",     ThreadNamesObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"exists",    ThreadExistsObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"wait",      ThreadWaitObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"configure", ThreadConfigureObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"errorproc", ThreadErrorProcObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"preserve",  ThreadReserveObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"release",   ThreadReleaseObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"join",      ThreadJoinObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"transfer",  ThreadTransferObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"detach",    ThreadDetachObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"attach",    ThreadAttachObjCmd);
+
+    /*
+     * Add shared variable commands
+     */
+    
+    Sv_Init(interp);
+    
+    /*
+     * Add commands to access thread
+     * synchronization primitives.
+     */
+    
+    Sp_Init(interp);
+
+    /*
+     * Add threadpool commands.
+     */
+    
+    Tpool_Init(interp);
+
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Thread_Init --
+ *
+ *  Initialize the thread commands.
+ *
+ * Results:
+ *  TCL_OK if the package was properly initialized.
+ *
+ * Side effects:
+ *  Adds package commands to the current interp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+EXTERN int
+Thread_Init(interp)
+    Tcl_Interp *interp; /* The current Tcl interpreter */
+{
+    int status = ThreadInit(interp);
+
+    if (status != TCL_OK) {
+        return status;
+    }
+
+    return Tcl_PkgProvide(interp, "Thread", PACKAGE_VERSION);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Thread_SafeInit --
+ *
+ *  This function is called from within initialization of the safe
+ *  Tcl interpreter.
+ *
+ * Results:
+ *  Standard Tcl result
+ *
+ * Side effects:
+ *  Commands added to the current interpreter,
+ *
+ *----------------------------------------------------------------------
+ */
+
+EXTERN int
+Thread_SafeInit(interp)
+    Tcl_Interp *interp;
+{
+    return Thread_Init(interp);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Init --
+ *
+ *  Make sure internal list of threads references the current thread.
+ *
+ * Results:
+ *  None
+ *
+ * Side effects:
+ *  The list of threads is initialized to include the current thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+Init(interp)
+    Tcl_Interp *interp;         /* Current interpreter. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->interp == (Tcl_Interp*)NULL) {
+        memset(tsdPtr, 0, sizeof(ThreadSpecificData));
+        tsdPtr->interp = interp;
+        ListUpdate(tsdPtr);
+        Tcl_CreateThreadExitHandler(ThreadExitProc,
+                                    (ClientData)threadEmptyResult);
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadCreateObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::create" Tcl
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadCreateObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int argc, rsrv = 0;
+    const char *arg, *script;
+    int flags = TCL_THREAD_NOFLAGS;
+
+    Init(interp);
+
+    /* 
+     * Syntax: thread::create ?-joinable? ?-preserved? ?script?
+     */
+
+    script = THREAD_CMD_PREFIX"wait";
+
+    for (argc = 1; argc < objc; argc++) {
+        arg = Tcl_GetStringFromObj(objv[argc], NULL);
+        if (OPT_CMP(arg, "--")) {
+            argc++;
+            if ((argc + 1) == objc) {
+                script = Tcl_GetStringFromObj(objv[argc], NULL);
+            } else {
+                goto usage;
+            }
+            break;
+        } else if (OPT_CMP(arg, "-joinable")) {
+            flags |= TCL_THREAD_JOINABLE;
+        } else if (OPT_CMP(arg, "-preserved")) {
+            rsrv = 1;
+        } else if ((argc + 1) == objc) {
+            script = Tcl_GetStringFromObj(objv[argc], NULL);
+        } else {
+            goto usage;
+        }
+    }
+
+    return ThreadCreate(interp, script, TCL_THREAD_STACK_DEFAULT, flags, rsrv);
+
+ usage:
+    Tcl_WrongNumArgs(interp, 1, objv, "?-joinable? ?script?");
+    return TCL_ERROR;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadReserveObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::preserve" and
+ *  "thread::release" Tcl commands, depending on the flag passed by
+ *  the ClientData argument. See the user documentation for details 
+ *  on what those command do.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadReserveObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    Tcl_ThreadId thrId = (Tcl_ThreadId)0;
+
+    Init(interp);
+
+    if (objc > 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "?threadId?");
+        return TCL_ERROR;
+    }
+    if (objc == 2) {
+        if (ThreadGetId(interp, objv[1], &thrId) != TCL_OK) {
+            return TCL_ERROR;
+        }
+    }
+
+    return ThreadReserve(interp, thrId, THREAD_RESERVE, 0);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadReleaseObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::release" Tcl 
+ *  command. See the user documentation for details on what this
+ *  command does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadReleaseObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;           /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int wait = 0;
+    Tcl_ThreadId thrId = (Tcl_ThreadId)0;
+
+    Init(interp);
+
+    if (objc > 3) {
+        Tcl_WrongNumArgs(interp, 1, objv, "?-wait? ?threadId?");
+        return TCL_ERROR; 
+    }
+    if (objc > 1) {
+        if (OPT_CMP(Tcl_GetString(objv[1]), "-wait")) {
+            wait = 1;
+            if (ThreadGetId(interp, objv[2], &thrId) != TCL_OK) {
+                return TCL_ERROR;
+            }
+        } else if (ThreadGetId(interp, objv[1], &thrId) != TCL_OK) {
+            return TCL_ERROR;
+        }
+    }
+
+    return ThreadReserve(interp, thrId, THREAD_RELEASE, wait);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadUnwindObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::unwind" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadUnwindObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    Init(interp);
+
+    if (objc > 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+
+    return ThreadReserve(interp, 0, THREAD_RELEASE, 0);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadExitObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::exit" Tcl 
+ *  command.  This causes an unconditional close of the thread
+ *  and is GUARENTEED to cause memory leaks.  Use this with caution.
+ *
+ * Results:
+ *  Doesn't actually return.
+ *
+ * Side effects:
+ *  Lots.  improper clean up of resources.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadExitObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+
+    Init(interp);
+    ListRemove(NULL);
+
+    Tcl_ExitThread(666);
+
+    return TCL_OK; /* NOT REACHED */
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadIdObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::id" Tcl command.
+ *  This returns the ID of the current thread.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadIdObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    char thrHandle[THREAD_HNDLMAXLEN];
+
+    Init(interp);
+
+    if (objc > 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+
+    ThreadGetHandle(Tcl_GetCurrentThread(), thrHandle);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(thrHandle, -1));
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadNamesObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::names" Tcl 
+ *  command. This returns a list of all known thread IDs.  
+ *  These are only threads created via this module (e.g., not 
+ *  driver threads or the notifier).
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadNamesObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ii, length;
+    char *result, thrHandle[THREAD_HNDLMAXLEN];
+    Tcl_ThreadId *thrIdArray;
+    Tcl_DString threadNames;
+
+    Init(interp);
+
+    if (objc > 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+
+    length = ThreadList(interp, &thrIdArray);
+
+    if (length == 0) {
+        return TCL_OK;
+    }
+
+    Tcl_DStringInit(&threadNames);
+
+    for (ii = 0; ii < length; ii++) {
+        ThreadGetHandle(thrIdArray[ii], thrHandle);
+        Tcl_DStringAppendElement(&threadNames, thrHandle);
+    }
+
+    length = Tcl_DStringLength(&threadNames);
+    result = Tcl_DStringValue(&threadNames);
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(result, length));
+
+    Tcl_DStringFree(&threadNames);
+    Tcl_Free((char*)thrIdArray);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadSendObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::send" Tcl 
+ *  command. This sends a script to another thread for execution.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadSendObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ret, len, vlen = 0, ii = 0, flags = 0;
+    Tcl_ThreadId thrId;
+    const char *script, *arg, *var = NULL;
+
+    ThreadClbkData *clbkPtr = NULL;
+    ThreadSendData *sendPtr = NULL;
+
+    Init(interp);
+
+    /*
+     * Syntax: thread::send ?-async? ?-head? threadId script ?varName?
+     */
+
+    if (objc < 3 || objc > 6) {
+        goto usage;
+    }
+
+    flags = THREAD_SEND_WAIT;
+
+    for (ii = 1; ii < objc; ii++) {
+        arg = Tcl_GetStringFromObj(objv[ii], NULL);
+        if (OPT_CMP(arg, "-async")) {
+            flags &= ~THREAD_SEND_WAIT;
+        } else if (OPT_CMP(arg, "-head")) {
+            flags |= THREAD_SEND_HEAD;
+        } else {
+            break;
+        }
+    }
+    if (ii >= objc) {
+        goto usage;
+    }
+    if (ThreadGetId(interp, objv[ii], &thrId) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (++ii >= objc) {
+        goto usage;
+    }
+
+    script = Tcl_GetStringFromObj(objv[ii], &len);
+    if (++ii < objc) {
+        var = Tcl_GetStringFromObj(objv[ii], &vlen);
+    }
+    if (var && (flags & THREAD_SEND_WAIT) == 0) {
+        if (thrId == Tcl_GetCurrentThread()) {
+            /*
+             * FIXME: Do something for callbacks to self
+             */
+            Tcl_SetResult(interp, "can't notify self", TCL_STATIC);
+            return TCL_ERROR;
+        }
+
+        /*
+         * Prepare record for the callback. This is asynchronously
+         * posted back to us when the target thread finishes processing.
+         * We should do a vwait on the "var" to get notified.
+         */
+        
+        clbkPtr = (ThreadClbkData*)Tcl_Alloc(sizeof(ThreadClbkData));
+        clbkPtr->execProc   = ThreadClbkSetVar;
+        clbkPtr->freeProc   = (ThreadSendFree*)Tcl_Free;
+        clbkPtr->interp     = interp;
+        clbkPtr->threadId   = Tcl_GetCurrentThread();
+        clbkPtr->clientData = (ClientData)strcpy(Tcl_Alloc(1+vlen), var);
+    }
+
+    /*
+     * Prepare job record for the target thread
+     */
+
+    sendPtr = (ThreadSendData*)Tcl_Alloc(sizeof(ThreadSendData));
+    sendPtr->interp     = NULL; /* Signal to use thread main interp */
+    sendPtr->execProc   = ThreadSendEval;
+    sendPtr->freeProc   = (ThreadSendFree*)Tcl_Free;
+    sendPtr->clientData = (ClientData)strcpy(Tcl_Alloc(1+len), script);
+
+    ret = ThreadSend(interp, thrId, sendPtr, clbkPtr, flags);
+
+    if (var && (flags & THREAD_SEND_WAIT)) {
+        
+        /*
+         * Leave job's result in passed variable
+         * and return the code, like "catch" does.
+         */
+        
+        Tcl_Obj *resultObj = Tcl_GetObjResult(interp);
+        if (!Tcl_SetVar2Ex(interp, var, NULL, resultObj, TCL_LEAVE_ERR_MSG)) {
+            return TCL_ERROR;
+        }
+        Tcl_SetObjResult(interp, Tcl_NewIntObj(ret));
+        return TCL_OK;
+    }
+
+    return ret;
+
+usage:
+    Tcl_WrongNumArgs(interp,1,objv,"?-async? ?-head? id script ?varName?");
+    return TCL_ERROR;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadBroadcastObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::broadcast" Tcl
+ *  command. This asynchronously sends a script to all known threads.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  Script is sent to all known threads except the caller thread. 
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadBroadcastObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ii, len, nthreads;
+    const char *script;
+    Tcl_ThreadId *thrIdArray;
+    ThreadSendData *sendPtr, job;
+
+    Init(interp);
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "script");
+        return TCL_ERROR;
+    }
+
+    script = Tcl_GetStringFromObj(objv[1], &len);
+
+    /*
+     * Get the list of known threads. Note that this one may
+     * actually change (thread may exit or otherwise cease to
+     * exist) while we circle in the loop below. We really do
+     * not care about that here since we don't return any 
+     * script results to the caller.
+     */
+
+    nthreads = ThreadList(interp, &thrIdArray);
+
+    if (nthreads == 0) {
+        return TCL_OK;
+    }
+
+    /* 
+     * Prepare the structure with the job description
+     * to be sent asynchronously to each known thread.
+     */
+
+    job.interp     = NULL; /* Signal to use thread's main interp */
+    job.execProc   = ThreadSendEval;
+    job.freeProc   = (ThreadSendFree*)Tcl_Free;
+    job.clientData = NULL;
+
+    /*
+     * Now, circle this list and send each thread the script.
+     * This is sent asynchronously, since we do not care what
+     * are they going to do with it. Also, the event is queued
+     * to the head of the event queue (as out-of-band message).
+     */
+
+    for (ii = 0; ii < nthreads; ii++) {
+        if (thrIdArray[ii] == Tcl_GetCurrentThread()) {
+            continue; /* Do not broadcast self */
+        }
+        sendPtr  = (ThreadSendData*)Tcl_Alloc(sizeof(ThreadSendData));
+        *sendPtr = job;
+        sendPtr->clientData = (ClientData)strcpy(Tcl_Alloc(1+len), script);
+        ThreadSend(interp, thrIdArray[ii], sendPtr, NULL, THREAD_SEND_HEAD);
+    }
+
+    Tcl_Free((char*)thrIdArray);
+    Tcl_ResetResult(interp);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadWaitObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::wait" Tcl 
+ *  command. This enters the event loop.
+ *
+ * Results:
+ *  Standard Tcl result.
+ *
+ * Side effects:
+ *  Enters the event loop.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadWaitObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    Init(interp);
+
+    if (objc > 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+
+    return ThreadWait();
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadErrorProcObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::errorproc" 
+ *  command. This registers a procedure to handle thread errors.
+ *  Empty string as the name of the procedure will reset the 
+ *  default behaviour, which is writing to standard error channel.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  Registers an errorproc.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadErrorProcObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int len;
+    char *proc;
+
+    Init(interp);
+
+    if (objc > 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "?proc?");
+        return TCL_ERROR;
+    }
+    Tcl_MutexLock(&threadMutex);
+    if (objc == 1) {
+        if (errorProcString) {
+            Tcl_SetResult(interp, errorProcString, TCL_VOLATILE);
+        }
+    } else {
+        errorThreadId = Tcl_GetCurrentThread();
+        if (errorProcString) {
+            Tcl_Free(errorProcString);
+        }
+        proc = Tcl_GetStringFromObj(objv[1], &len);
+        if (len == 0) {
+            errorProcString = NULL;
+        } else {
+            errorProcString = Tcl_Alloc(1+strlen(proc));
+            strcpy(errorProcString, proc);
+        }
+    }
+    Tcl_MutexUnlock(&threadMutex);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadJoinObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::join" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadJoinObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    Tcl_ThreadId thrId;
+    
+    Init(interp);
+
+    /*
+     * Syntax of 'join': id
+     */
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "id");
+        return TCL_ERROR;
+    }
+
+    if (ThreadGetId(interp, objv[1], &thrId) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    return ThreadJoin(interp, thrId);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadTransferObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::transfer" Tcl
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadTransferObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+
+    Tcl_ThreadId thrId;
+    Tcl_Channel chan;
+
+    Init(interp);
+
+    /*
+     * Syntax of 'transfer': id channel
+     */
+
+    if (objc != 3) {
+        Tcl_WrongNumArgs(interp, 1, objv, "id channel");
+        return TCL_ERROR;
+    }
+    if (ThreadGetId(interp, objv[1], &thrId) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    chan = Tcl_GetChannel(interp, Tcl_GetString(objv[2]), NULL);
+    if (chan == (Tcl_Channel)NULL) {
+        return TCL_ERROR;
+    }
+    
+    return ThreadTransfer(interp, thrId, Tcl_GetTopChannel(chan));
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadDetachObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::detach" Tcl
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadDetachObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    Tcl_Channel chan;
+
+    Init(interp);
+
+    /*
+     * Syntax: thread::detach channel
+     */
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "channel");
+        return TCL_ERROR;
+    }
+
+    chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), NULL);
+    if (chan == (Tcl_Channel)NULL) {
+        return TCL_ERROR;
+    }
+    
+    return ThreadDetach(interp, Tcl_GetTopChannel(chan));
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadAttachObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::attach" Tcl
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadAttachObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    char *chanName;
+
+    Init(interp);
+
+    /*
+     * Syntax: thread::attach channel
+     */
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "channel");
+        return TCL_ERROR;
+    }
+
+    chanName = Tcl_GetString(objv[1]);
+    if (Tcl_IsChannelExisting(chanName)) {
+        return TCL_OK;
+    }
+
+    return ThreadAttach(interp, chanName);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadExistsObjCmd --
+ *
+ *  This procedure is invoked to process the "thread::exists" Tcl
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadExistsObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    Tcl_ThreadId thrId;
+
+    Init(interp);
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "id");
+        return TCL_ERROR;
+    }
+
+    if (ThreadGetId(interp, objv[1], &thrId) != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), ThreadExists(thrId));
+    
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadConfigureObjCmd --
+ *
+ *     This procedure is invoked to process the Tcl "thread::configure"
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *     A standard Tcl result.
+ *
+ * Side effects:
+ *     None.
+ *----------------------------------------------------------------------
+ */
+static int
+ThreadConfigureObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    char *option, *value;
+    Tcl_ThreadId thrId;         /* Id of the thread to configure */ 
+    int i;                      /* Iterate over arg-value pairs. */
+    Tcl_DString ds;                        /* DString to hold result of
+                                 * calling GetThreadOption. */
+
+    if (objc < 2 || (objc % 2 == 1 && objc != 3)) {
+        Tcl_WrongNumArgs(interp, 1, objv, "threadlId ?optionName? "
+                         "?value? ?optionName value?...");
+        return TCL_ERROR;
+    }
+
+    Init(interp);
+
+    if (ThreadGetId(interp, objv[1], &thrId) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (objc == 2) {
+        Tcl_DStringInit(&ds);
+        if (ThreadGetOption(interp, thrId, NULL, &ds) != TCL_OK) {
+            Tcl_DStringFree(&ds);
+            return TCL_ERROR;
+        }
+        Tcl_DStringResult(interp, &ds);
+        return TCL_OK;
+    }
+    if (objc == 3) {
+        Tcl_DStringInit(&ds);
+        option = Tcl_GetString(objv[2]);
+        if (ThreadGetOption(interp, thrId, option, &ds) != TCL_OK) {
+            Tcl_DStringFree(&ds);
+            return TCL_ERROR;
+        }
+        Tcl_DStringResult(interp, &ds);
+        return TCL_OK;
+    }
+    for (i = 3; i < objc; i += 2) {
+        option = Tcl_GetString(objv[i-1]);
+        value  = Tcl_GetString(objv[i]);
+        if (ThreadSetOption(interp, thrId, option, value) != TCL_OK) {
+            return TCL_ERROR;
+        }
+    }
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadSendEval --
+ *
+ *  Evaluates Tcl script passed from source to target thread.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int 
+ThreadSendEval(interp, clientData)
+    Tcl_Interp *interp;
+    ClientData clientData;
+{
+    ThreadSendData *sendPtr = (ThreadSendData*)clientData;
+    char *script = (char*)sendPtr->clientData;
+
+    return Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadClbkSetVar --
+ *
+ *  Sets the Tcl variable in the source thread, as the result
+ *  of the asynchronous callback.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  New Tcl variable may be created
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int 
+ThreadClbkSetVar(interp, clientData)
+    Tcl_Interp *interp;
+    ClientData clientData;
+{
+    ThreadClbkData *clbkPtr = (ThreadClbkData*)clientData;
+    const char *var = (const char *)clbkPtr->clientData;
+    Tcl_Obj *valObj;
+    ThreadEventResult *resultPtr = &clbkPtr->result;
+
+    /*
+     * Get the result of the posted command.
+     * We will use it to fill-in the result variable.
+     */
+
+    valObj = Tcl_NewStringObj(resultPtr->result, -1);
+    if (resultPtr->result != threadEmptyResult) {
+        Tcl_Free(resultPtr->result);
+    }
+
+    /*
+     * Set the result variable
+     */
+
+    if (Tcl_SetVar2Ex(interp, var, NULL, valObj, 
+                      TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) == NULL) {
+        return TCL_ERROR;
+    }
+
+    /*
+     * In case of error, trigger the bgerror mechansim
+     */
+
+    if (resultPtr->code == TCL_ERROR) {
+        if (resultPtr->errorCode) {
+            var = "errorCode";
+            Tcl_SetVar(interp, var, resultPtr->errorCode, TCL_GLOBAL_ONLY);
+            Tcl_Free((char*)resultPtr->errorCode);
+        }
+        if (resultPtr->errorInfo) {
+            var = "errorInfo";
+            Tcl_SetVar(interp, var, resultPtr->errorInfo, TCL_GLOBAL_ONLY);
+            Tcl_Free((char*)resultPtr->errorInfo);
+        }
+        Tcl_SetObjResult(interp, valObj);
+        Tcl_BackgroundError(interp);
+    }
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadCreate --
+ *
+ *  This procedure is invoked to create a thread containing an 
+ *  interp to run a script. This returns after the thread has
+ *  started executing.
+ *
+ * Results:
+ *  A standard Tcl result, which is the thread ID.
+ *
+ * Side effects:
+ *  Create a thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadCreate(interp, script, stacksize, flags, preserve)
+    Tcl_Interp *interp;         /* Current interpreter. */
+    const char *script;         /* Script to evaluate */
+    int         stacksize;      /* Zero for default size */
+    int         flags;          /* Zero for no flags */
+    int         preserve;       /* If true, reserve the thread */
+{
+    char thrHandle[THREAD_HNDLMAXLEN];
+    ThreadCtrl ctrl;
+    Tcl_ThreadId thrId;
+
+#ifdef NS_AOLSERVER
+    ctrl.cd = Tcl_GetAssocData(interp, "thread:nsd", NULL);
+#endif
+    ctrl.script   = (char *)script;
+    ctrl.condWait = NULL;
+    ctrl.flags    = 0;
+
+    Tcl_MutexLock(&threadMutex);
+    if (Tcl_CreateThread(&thrId, NewThread, (ClientData)&ctrl,
+            stacksize, flags) != TCL_OK) {
+        Tcl_MutexUnlock(&threadMutex);
+        Tcl_SetResult(interp, "can't create a new thread", TCL_STATIC);
+        return TCL_ERROR;
+    }
+
+    /*
+     * Wait for the thread to start because it is using
+     * the ThreadCtrl argument which is on our stack.
+     */
+
+    while (ctrl.script != NULL) {
+        Tcl_ConditionWait(&ctrl.condWait, &threadMutex, NULL);
+    }
+    if (preserve) {
+        ThreadSpecificData *tsdPtr = ThreadExistsInner(thrId);
+        if (tsdPtr == (ThreadSpecificData*)NULL) {
+            Tcl_MutexUnlock(&threadMutex);
+            Tcl_ConditionFinalize(&ctrl.condWait);
+            ErrorNoSuchThread(interp, thrId);
+            return TCL_ERROR;
+        }
+        tsdPtr->refCount++;
+    }
+
+    Tcl_MutexUnlock(&threadMutex);
+    Tcl_ConditionFinalize(&ctrl.condWait);
+    
+    ThreadGetHandle(thrId, thrHandle);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(thrHandle, -1));
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * NewThread --
+ *
+ *    This routine is the "main()" for a new thread whose task is to
+ *    execute a single TCL script. The argument to this function is
+ *    a pointer to a structure that contains the text of the Tcl script
+ *    to be executed, plus some synchronization primitives. Those are
+ *    used so the caller gets signalized when the new thread has 
+ *    done its initialization.
+ *
+ *    Space to hold the ThreadControl structure itself is reserved on
+ *    the stack of the calling function. The two condition variables
+ *    in the ThreadControl structure are destroyed by the calling 
+ *    function as well. The calling function will destroy the
+ *    ThreadControl structure and the condition variable as soon as
+ *    ctrlPtr->condWait is signaled, so this routine must make copies
+ *    of any data it might need after that point.
+ *
+ * Results:
+ *    none
+ *
+ * Side effects:
+ *    A Tcl script is executed in a new thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_ThreadCreateType
+NewThread(clientData)
+    ClientData clientData;
+{
+    ThreadCtrl *ctrlPtr = (ThreadCtrl *)clientData;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    Tcl_Interp *interp;
+    int result = TCL_OK, scriptLen;
+    char *evalScript;
+
+    /*
+     * Initialize the interpreter. The bad thing here is that we
+     * assume that initialization of the Tcl interp will be 
+     * error free, which it may not. In the future we must recover
+     * from this and exit gracefully (this is not that easy as
+     * it seems on the first glance...)
+     */
+
+#ifdef NS_AOLSERVER
+    struct mydata *md = (struct mydata*)ctrlPtr->cd;
+    Ns_ThreadSetName("-tclthread-");
+    interp = (Tcl_Interp*)Ns_TclAllocateInterp(md ? md->server : NULL);
+#else
+    interp = Tcl_CreateInterp();
+    result = Tcl_Init(interp);
+#endif
+
+#if !defined(NS_AOLSERVER) || (defined(NS_MAJOR_VERSION) && NS_MAJOR_VERSION >= 4)
+    result = Thread_Init(interp);
+#endif
+
+    tsdPtr->interp = interp;
+
+    Tcl_MutexLock(&threadMutex);
+
+    /*
+     * Update the list of threads.
+     */
+
+    ListUpdateInner(tsdPtr);
+
+    /*
+     * We need to keep a pointer to the alloc'ed mem of the script
+     * we are eval'ing, for the case that we exit during evaluation
+     */
+
+    scriptLen = strlen(ctrlPtr->script);
+    evalScript = strcpy((char*)Tcl_Alloc(scriptLen+1), ctrlPtr->script);
+    Tcl_CreateThreadExitHandler(ThreadExitProc,(ClientData)evalScript);
+
+    /*
+     * Notify the parent we are alive.
+     */
+
+    ctrlPtr->script = NULL;
+    Tcl_ConditionNotify(&ctrlPtr->condWait);
+
+    Tcl_MutexUnlock(&threadMutex);
+
+    /*
+     * Run the script.
+     */
+
+    Tcl_Preserve((ClientData)tsdPtr->interp);
+    result = Tcl_EvalEx(tsdPtr->interp, evalScript,scriptLen,TCL_EVAL_GLOBAL);
+    if (result != TCL_OK) {
+        ThreadErrorProc(tsdPtr->interp);
+    }
+
+    /*
+     * Clean up. Note: add something like TlistRemove for the transfer list.
+     */
+
+    if (tsdPtr->doOneEvent) {
+        Tcl_ConditionFinalize(&tsdPtr->doOneEvent);
+    }
+
+    ListRemove(tsdPtr);
+
+    /*
+     * It is up to all other extensions, including Tk, to be responsible
+     * for their own events when they receive their Tcl_CallWhenDeleted
+     * notice when we delete this interp.
+     */
+
+#ifdef NS_AOLSERVER
+    Ns_TclMarkForDelete(tsdPtr->interp);
+    Ns_TclDeAllocateInterp(tsdPtr->interp);
+#else
+    Tcl_DeleteInterp(tsdPtr->interp);
+#endif
+    Tcl_Release((ClientData)tsdPtr->interp);
+
+    /*
+     * Tcl_ExitThread calls Tcl_FinalizeThread() indirectly which calls
+     * ThreadExitHandlers and cleans the notifier as well as other sub-
+     * systems that save thread state data.
+     */
+
+    Tcl_ExitThread(result);
+
+    TCL_THREAD_CREATE_RETURN;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadErrorProc --
+ *
+ *  Send a message to the thread willing to hear about errors.
+ *
+ * Results:
+ *  None
+ *
+ * Side effects:
+ *  Send an event.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ThreadErrorProc(interp)
+    Tcl_Interp *interp;         /* Interp that failed */
+{
+    ThreadSendData *sendPtr;
+    const char *argv[3];
+    char buf[THREAD_HNDLMAXLEN];
+    const char *errorInfo;
+
+    errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
+    if (errorInfo == NULL) {
+        errorInfo = "";
+    }
+
+    if (errorProcString == NULL) {
+#ifdef NS_AOLSERVER
+        Ns_Log(Error, "%s\n%s", Tcl_GetStringResult(interp), errorInfo);
+#else
+        Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
+        if (errChannel == NULL) {
+            /* Fixes the [#634845] bug; credits to
+             * Wojciech Kocjan <wojciech@kocjan.org> */
+            return;
+        }
+        ThreadGetHandle(Tcl_GetCurrentThread(), buf);
+        Tcl_WriteChars(errChannel, "Error from thread ", -1);
+        Tcl_WriteChars(errChannel, buf, -1);
+        Tcl_WriteChars(errChannel, "\n", 1);
+        Tcl_WriteChars(errChannel, errorInfo, -1);
+        Tcl_WriteChars(errChannel, "\n", 1);
+#endif
+    } else {
+        ThreadGetHandle(Tcl_GetCurrentThread(), buf);
+        argv[0] = errorProcString;
+        argv[1] = buf;
+        argv[2] = errorInfo;
+
+        sendPtr = (ThreadSendData*)Tcl_Alloc(sizeof(ThreadSendData));
+        sendPtr->execProc   = ThreadSendEval;
+        sendPtr->freeProc   = (ThreadSendFree*)Tcl_Free;
+        sendPtr->clientData = (ClientData) Tcl_Merge(3, argv);
+        sendPtr->interp     = NULL;
+
+        ThreadSend(interp, errorThreadId, sendPtr, NULL, 0);
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ListUpdate --
+ *
+ *  Add the thread local storage to the list. This grabs the
+ *  mutex to protect the list.
+ *
+ * Results:
+ *  None
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ListUpdate(tsdPtr)
+    ThreadSpecificData *tsdPtr;
+{
+    if (tsdPtr == NULL) {
+        tsdPtr = TCL_TSD_INIT(&dataKey);
+    }
+
+    Tcl_MutexLock(&threadMutex);
+    ListUpdateInner(tsdPtr);
+    Tcl_MutexUnlock(&threadMutex);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ListUpdateInner --
+ *
+ *  Add the thread local storage to the list. This assumes the caller
+ *  has obtained the threadMutex.
+ *
+ * Results:
+ *  None
+ *
+ * Side effects:
+ *  Add the thread local storage to its list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ListUpdateInner(tsdPtr)
+    ThreadSpecificData *tsdPtr;
+{
+    if (threadList) {
+        threadList->prevPtr = tsdPtr;
+    }
+
+    tsdPtr->nextPtr  = threadList;
+    tsdPtr->prevPtr  = NULL;
+    tsdPtr->threadId = Tcl_GetCurrentThread();
+
+    threadList = tsdPtr;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ListRemove --
+ *
+ *  Remove the thread local storage from its list. This grabs the
+ *  mutex to protect the list.
+ *
+ * Results:
+ *  None
+ *
+ * Side effects:
+ *  Remove the thread local storage from its list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ListRemove(tsdPtr)
+    ThreadSpecificData *tsdPtr;
+{
+    if (tsdPtr == NULL) {
+        tsdPtr = TCL_TSD_INIT(&dataKey);
+    }
+
+    Tcl_MutexLock(&threadMutex);
+    ListRemoveInner(tsdPtr);
+    Tcl_MutexUnlock(&threadMutex);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ListRemoveInner --
+ *
+ *  Remove the thread local storage from its list.
+ *
+ * Results:
+ *  None
+ *
+ * Side effects:
+ *  Remove the thread local storage from its list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ListRemoveInner(tsdPtr)
+    ThreadSpecificData *tsdPtr;
+{
+    if (tsdPtr->prevPtr || tsdPtr->nextPtr) {
+        if (tsdPtr->prevPtr) {
+            tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
+        } else {
+            threadList = tsdPtr->nextPtr;
+        }
+        if (tsdPtr->nextPtr) {
+            tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
+        }
+        tsdPtr->nextPtr = NULL;
+        tsdPtr->prevPtr = NULL;
+    } else if (tsdPtr == threadList) {
+        threadList = NULL;
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadList --
+ *
+ *  Return a list of threads running Tcl interpreters.
+ *
+ * Results:
+ *  Number of threads.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadList(interp, thrIdArray)
+    Tcl_Interp *interp;
+    Tcl_ThreadId **thrIdArray;
+{
+    int ii, count = 0;
+    ThreadSpecificData *tsdPtr;
+
+    Tcl_MutexLock(&threadMutex);
+    
+    /*
+     * First walk; find out how many threads are registered.
+     * We may avoid this and gain some speed by maintaining
+     * the counter of allocated structs in the threadList.
+     */
+
+    for (tsdPtr = threadList; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+        count++;
+    }
+    
+    if (count == 0) {
+        return 0;
+    }
+
+    /*
+     * Allocate storage for passing thread id's to caller
+     */
+
+    *thrIdArray = (Tcl_ThreadId*)Tcl_Alloc(count * sizeof(Tcl_ThreadId));
+
+    /*
+     * Second walk; fill-in the array with thread ID's
+     */
+
+    for (tsdPtr = threadList, ii = 0; tsdPtr; tsdPtr = tsdPtr->nextPtr, ii++) {
+        (*thrIdArray)[ii] = tsdPtr->threadId;
+    }
+
+    Tcl_MutexUnlock(&threadMutex);
+
+    return count;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadExists --
+ *
+ *  Test wether a thread given by it's id is known to us.
+ *
+ * Results:
+ *  Pointer to thread specific data structure or
+ *  NULL if no thread with given ID found
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadExists(thrId)
+     Tcl_ThreadId thrId;
+{
+    ThreadSpecificData *tsdPtr;
+    
+    Tcl_MutexLock(&threadMutex);
+    tsdPtr = ThreadExistsInner(thrId);
+    Tcl_MutexUnlock(&threadMutex);
+    
+    return tsdPtr != NULL;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadExistsInner --
+ *
+ *  Test wether a thread given by it's id is known to us. Assumes 
+ *  caller holds the thread mutex.
+ *
+ * Results:
+ *  Pointer to thread specific data structure or
+ *  NULL if no thread with given ID found
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ThreadSpecificData *
+ThreadExistsInner(thrId)
+    Tcl_ThreadId thrId;              /* Thread id to look for. */
+{
+    ThreadSpecificData *tsdPtr;
+    
+    for (tsdPtr = threadList; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+        if (tsdPtr->threadId == thrId) {
+            return tsdPtr;
+        }
+    }
+
+    return NULL;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadJoin --
+ *
+ *  Wait for the exit of a different thread.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  The status of the exiting thread is left in the interp result 
+ *  area, but only in the case of success.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadJoin(interp, thrId)
+    Tcl_Interp  *interp;        /* The current interpreter. */
+    Tcl_ThreadId thrId;         /* Thread ID of other interpreter. */
+{
+    int ret, state;
+
+    ret = Tcl_JoinThread(thrId, &state);
+
+    if (ret == TCL_OK) {
+        Tcl_SetIntObj(Tcl_GetObjResult (interp), state);
+    } else {
+        char thrHandle[THREAD_HNDLMAXLEN]; 
+        ThreadGetHandle(thrId, thrHandle);
+        Tcl_AppendResult(interp, "cannot join thread ", thrHandle, NULL);
+    }
+
+    return ret;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadTransfer --
+ *
+ *  Transfers the specified channel which must not be shared and has
+ *  to be registered in the given interp from that location to the
+ *  main interp of the specified thread.
+ *
+ *  Thanks to Anreas Kupries for the initial implementation.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  The thread-global lists of all known channels of both threads
+ *  involved (specified and current) are modified. The channel is
+ *  moved, all event handling for the channel is killed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadTransfer(interp, thrId, chan)
+    Tcl_Interp *interp;         /* The current interpreter. */
+    Tcl_ThreadId thrId;         /* Thread Id of other interpreter. */
+    Tcl_Channel  chan;          /* The channel to transfer */
+{
+    /* Steps to perform for the transfer:
+     *
+     * i.   Sanity checks: chan has to registered in interp, must not be
+     *      shared. This automatically excludes the special channels for
+     *      stdin, stdout and stderr!
+     * ii.  Clear event handling.
+     * iii. Bump reference counter up to prevent destruction during the
+     *      following unregister, then unregister the channel from the
+     *      interp. Remove it from the thread-global list of all channels
+     *      too.
+     * iv.  Wrap the channel into an event and send that to the other
+     *      thread, then wait for the other thread to process our message.
+     * v.   The event procedure called by the other thread is
+     *      'TransferEventProc'. It links the channel into the
+     *      thread-global list of channels for that thread, registers it
+     *      in the main interp of the other thread, removes the artificial
+     *      reference, at last notifies this thread of the sucessful
+     *      transfer. This allows this thread then to proceed.
+     */
+
+    TransferEvent *evPtr;
+    TransferResult *resultPtr;
+
+    if (!Tcl_IsChannelRegistered(interp, chan)) {
+        Tcl_SetResult(interp, "channel is not registered here", TCL_STATIC);
+    }
+    if (Tcl_IsChannelShared(chan)) {
+        Tcl_SetResult(interp, "channel is shared", TCL_STATIC);
+        return TCL_ERROR;
+    }
+
+    /*
+     * Short circut transfers to ourself.  Nothing to do.
+     */
+
+    if (thrId == Tcl_GetCurrentThread()) {
+        return TCL_OK;
+    }
+
+    Tcl_MutexLock(&threadMutex);
+
+    /* 
+     * Verify the thread exists.
+     */
+
+    if (ThreadExistsInner(thrId) == NULL) {
+        Tcl_MutexUnlock(&threadMutex);
+        ErrorNoSuchThread(interp, thrId);
+        return TCL_ERROR;
+    }
+
+    /*
+     * Cut the channel out of the interp/thread
+     */
+
+    ThreadCutChannel(interp, chan);
+
+    /*
+     * Wrap it into an event.
+     */
+
+    resultPtr = (TransferResult*)Tcl_Alloc(sizeof(TransferResult));
+    evPtr     = (TransferEvent *)Tcl_Alloc(sizeof(TransferEvent));
+
+    evPtr->chan       = chan;
+    evPtr->event.proc = TransferEventProc;
+    evPtr->resultPtr  = resultPtr;
+
+    /*
+     * Initialize the result fields.
+     */
+
+    resultPtr->done       = (Tcl_Condition) NULL;
+    resultPtr->resultCode = -1;
+    resultPtr->resultMsg  = (char *) NULL;
+
+    /* 
+     * Maintain the cleanup list.
+     */
+
+    resultPtr->srcThreadId = Tcl_GetCurrentThread();
+    resultPtr->dstThreadId = thrId;
+    resultPtr->eventPtr    = evPtr;
+
+    SpliceIn(resultPtr, transferList);
+
+    /*
+     * Queue the event and poke the other thread's notifier.
+     */
+
+    Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)evPtr, TCL_QUEUE_TAIL);
+    Tcl_ThreadAlert(thrId);
+
+    /*
+     * (*) Block until the other thread has either processed the transfer
+     * or rejected it.
+     */
+
+    while (resultPtr->resultCode < 0) {
+        Tcl_ConditionWait(&resultPtr->done, &threadMutex, NULL);
+    }
+
+    /*
+     * Unlink result from the result list.
+     */
+
+    SpliceOut(resultPtr, transferList);
+
+    resultPtr->eventPtr = NULL;
+    resultPtr->nextPtr  = NULL;
+    resultPtr->prevPtr  = NULL;
+    
+    Tcl_MutexUnlock(&threadMutex);
+
+    Tcl_ConditionFinalize(&resultPtr->done);
+
+    /*
+     * Process the result now.
+     */
+
+    if (resultPtr->resultCode != TCL_OK) {
+
+        /*
+         * Transfer failed, restore old state of channel with respect
+         * to current thread and specified interp.
+         */
+
+        Tcl_SpliceChannel(chan);
+        Tcl_RegisterChannel(interp, chan);
+        Tcl_UnregisterChannel((Tcl_Interp *) NULL, chan);
+        Tcl_AppendResult(interp, "transfer failed: ", NULL);
+
+        if (resultPtr->resultMsg) {
+            Tcl_AppendResult(interp, resultPtr->resultMsg, NULL);
+            Tcl_Free(resultPtr->resultMsg);
+        } else {
+            Tcl_AppendResult(interp, "for reasons unknown", NULL);
+        }
+
+        return TCL_ERROR;
+    }
+
+    if (resultPtr->resultMsg) {
+        Tcl_Free(resultPtr->resultMsg);
+    }
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadDetach --
+ *
+ *  Detaches the specified channel which must not be shared and has
+ *  to be registered in the given interp. The detached channel is
+ *  left in the transfer list until some other thread attaches it
+ +  by calling the "thread::attach" command.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  The thread-global lists of all known channels (transferList)
+ *  is modified. All event handling for the channel is killed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadDetach(interp, chan)
+    Tcl_Interp *interp;         /* The current interpreter. */
+    Tcl_Channel chan;           /* The channel to detach */
+{
+    TransferEvent *evPtr;
+    TransferResult *resultPtr;
+
+    if (!Tcl_IsChannelRegistered(interp, chan)) {
+        Tcl_SetResult(interp, "channel is not registered here", TCL_STATIC);
+    }
+    if (Tcl_IsChannelShared(chan)) {
+        Tcl_SetResult(interp, "channel is shared", TCL_STATIC);
+        return TCL_ERROR;
+    }
+    
+    /*
+     * Cut the channel out of the interp/thread
+     */
+
+    ThreadCutChannel(interp, chan);
+
+    /*
+     * Wrap it into the list of transfered channels. We generate no
+     * events associated with the detached channel, thus really not
+     * needing the transfer event structure allocated here. This 
+     * is done purely to avoid having yet another wrapper.
+     */
+
+    resultPtr = (TransferResult*)Tcl_Alloc(sizeof(TransferResult));
+    evPtr     = (TransferEvent*)Tcl_Alloc(sizeof(TransferEvent));
+
+    evPtr->chan       = chan;
+    evPtr->event.proc = NULL;
+    evPtr->resultPtr  = resultPtr;
+
+    /*
+     * Initialize the result fields. This is not used.
+     */
+
+    resultPtr->done       = (Tcl_Condition)NULL;
+    resultPtr->resultCode = -1;
+    resultPtr->resultMsg  = (char*)NULL;
+
+    /* 
+     * Maintain the cleanup list. By setting the dst/srcThreadId
+     * to zero we signal the code in ThreadAttach that this is the 
+     * detached channel. Therefore it should not be mistaken for 
+     * some regular TransferChannel operation underway. Also, this
+     * will prevent the code in ThreadExitProc to splice out this
+     * record from the list when the threads are exiting.
+     * A side effect of this is that we may have entries in this
+     * list which may never be removed (i.e. nobody attaches the
+     * channel later on). This will result in both Tcl channel and
+     * memory leak.
+     */
+
+    resultPtr->srcThreadId = (Tcl_ThreadId)0;
+    resultPtr->dstThreadId = (Tcl_ThreadId)0;
+    resultPtr->eventPtr    = evPtr;
+
+    Tcl_MutexLock(&threadMutex);
+    SpliceIn(resultPtr, transferList);
+    Tcl_MutexUnlock(&threadMutex);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadAttach --
+ *
+ *  Attaches the previously detached channel into the current
+ *  interpreter. 
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  The thread-global lists of all known channels (transferList)
+ *  is modified.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadAttach(interp, chanName)
+    Tcl_Interp *interp;         /* The current interpreter. */
+    char *chanName;             /* The name of the channel to detach */
+{
+    int found = 0;
+    Tcl_Channel chan = NULL;
+    TransferResult *resPtr;
+
+    /*
+     * Locate the channel to attach by looking up its name in 
+     * the list of transfered channels. Watch that we don't
+     * hit the regular channel transfer event.
+     */
+    
+    Tcl_MutexLock(&threadMutex);
+    for (resPtr = transferList; resPtr; resPtr = resPtr->nextPtr) {
+        chan = resPtr->eventPtr->chan;
+        if (!strcmp(Tcl_GetChannelName(chan),chanName)
+                && !resPtr->dstThreadId) {
+            if (Tcl_IsChannelExisting(chanName)) {
+                Tcl_MutexUnlock(&threadMutex);
+                Tcl_AppendResult(interp, "channel already exists", NULL);
+                return TCL_ERROR;
+            }
+            SpliceOut(resPtr, transferList);
+            Tcl_Free((char*)resPtr->eventPtr);
+            Tcl_Free((char*)resPtr);
+            found = 1;
+            break;
+        }
+    }
+    Tcl_MutexUnlock(&threadMutex);
+
+    if (found == 0) {
+        Tcl_AppendResult(interp, "channel not detached", NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     * Splice channel into the current interpreter
+     */
+    
+    Tcl_SpliceChannel(chan);
+    Tcl_RegisterChannel(interp, chan);
+    Tcl_UnregisterChannel((Tcl_Interp *)NULL, chan);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadSend --
+ *
+ *  Run the procedure in other thread.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadSend(interp, thrId, send, clbk, flags)
+    Tcl_Interp     *interp;      /* The current interpreter. */
+    Tcl_ThreadId    thrId;       /* Thread Id of other thread. */
+    ThreadSendData *send;        /* Pointer to structure with work to do */
+    ThreadClbkData *clbk;        /* Opt. callback structure (may be NULL) */
+    int             flags;       /* Wait or queue to tail */
+{
+    ThreadSpecificData *tsdPtr = NULL; /* ... of the target thread */
+
+    int code;
+    ThreadEvent *eventPtr;
+    ThreadEventResult *resultPtr;
+
+    /* 
+     * Verify the thread exists and is not in the error state.
+     * The thread is in the error state only if we've configured
+     * it to unwind on script evaluation error and last script
+     * evaluation resulted in error actually.
+     */
+
+    Tcl_MutexLock(&threadMutex);
+
+    tsdPtr = ThreadExistsInner(thrId);
+
+    if (tsdPtr == (ThreadSpecificData*)NULL
+            || (tsdPtr->flags & THREAD_FLAGS_INERROR)) {
+        int inerror = tsdPtr && (tsdPtr->flags & THREAD_FLAGS_INERROR);
+        Tcl_MutexUnlock(&threadMutex);
+        ThreadFreeProc((ClientData)send);
+        if (clbk) {
+            ThreadFreeProc((ClientData)clbk);
+        }
+        if (inerror) {
+            Tcl_SetResult(interp, "thread is in error", TCL_STATIC);
+        } else {
+            ErrorNoSuchThread(interp, thrId);
+        }
+        return TCL_ERROR;
+    }
+
+    /*
+     * Short circut sends to ourself.
+     */
+
+    if (thrId == Tcl_GetCurrentThread()) {
+        Tcl_MutexUnlock(&threadMutex);
+        if ((flags & THREAD_SEND_WAIT)) {
+            return (*send->execProc)(interp, (ClientData)send);
+        } else {
+            send->interp = interp;
+            Tcl_Preserve((ClientData)send->interp);
+            Tcl_DoWhenIdle((Tcl_IdleProc*)ThreadIdleProc, (ClientData)send);
+            return TCL_OK;
+        }
+    }
+    
+    /* 
+     * Create the event for target thread event queue.
+     */
+
+    eventPtr = (ThreadEvent*)Tcl_Alloc(sizeof(ThreadEvent));
+    eventPtr->sendData = send;
+    eventPtr->clbkData = clbk;
+
+    /*
+     * Target thread about to service 
+     * another event
+     */
+
+    if (tsdPtr->maxEventsCount) {
+        tsdPtr->eventsPending++;
+    }
+
+    /*
+     * Caller wants to be notified, so we must take care
+     * it's interpreter stays alive until we've finished.
+     */
+
+    if (eventPtr->clbkData) {
+        Tcl_Preserve((ClientData)eventPtr->clbkData->interp);
+    }
+    if ((flags & THREAD_SEND_WAIT) == 0) {
+        resultPtr              = NULL;
+        eventPtr->resultPtr    = NULL;
+    } else {
+        resultPtr = (ThreadEventResult*)Tcl_Alloc(sizeof(ThreadEventResult));
+        resultPtr->done        = (Tcl_Condition)NULL;
+        resultPtr->result      = NULL;
+        resultPtr->errorCode   = NULL;
+        resultPtr->errorInfo   = NULL;
+        resultPtr->dstThreadId = thrId;
+        resultPtr->srcThreadId = Tcl_GetCurrentThread();
+        resultPtr->eventPtr    = eventPtr;
+
+        eventPtr->resultPtr    = resultPtr;
+
+        SpliceIn(resultPtr, resultList);
+    }
+
+    /*
+     * Queue the event and poke the other thread's notifier.
+     */
+
+    eventPtr->event.proc = ThreadEventProc;
+    if ((flags & THREAD_SEND_HEAD)) {
+        Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_HEAD);
+    } else {
+        Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_TAIL);
+    }
+    Tcl_ThreadAlert(thrId);
+
+    if ((flags & THREAD_SEND_WAIT) == 0) {
+        /*
+         * Might potentially spend some time here, until the
+         * worker thread clean's up it's queue a little bit.
+         */ 
+        while (tsdPtr->maxEventsCount &&
+               tsdPtr->eventsPending > tsdPtr->maxEventsCount) {
+            Tcl_ConditionWait(&tsdPtr->doOneEvent, &threadMutex, NULL);
+        }
+        Tcl_MutexUnlock(&threadMutex);
+        return TCL_OK;
+    }
+    
+    /* 
+     * Block on the result indefinitely.
+     */
+
+    Tcl_ResetResult(interp);
+
+    while (resultPtr->result == NULL) {
+        Tcl_ConditionWait(&resultPtr->done, &threadMutex, NULL);
+    }
+
+    SpliceOut(resultPtr, resultList);
+
+    Tcl_MutexUnlock(&threadMutex);
+
+    /*
+     * Return result to caller
+     */
+
+    if (resultPtr->code == TCL_ERROR) {
+        if (resultPtr->errorCode) {
+            Tcl_SetErrorCode(interp, resultPtr->errorCode, NULL);
+            Tcl_Free(resultPtr->errorCode);
+        }
+        if (resultPtr->errorInfo) {
+            Tcl_AddErrorInfo(interp, resultPtr->errorInfo);
+            Tcl_Free(resultPtr->errorInfo);
+        }
+    }
+
+    code = resultPtr->code;
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(resultPtr->result, -1));
+
+    /*
+     * Cleanup
+     */
+
+    Tcl_ConditionFinalize(&resultPtr->done);
+    if (resultPtr->result != threadEmptyResult) {
+        Tcl_Free(resultPtr->result);
+    }
+    Tcl_Free((char*)resultPtr);
+
+    return code;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadWait --
+ *
+ *  Waits for events and process them as they come, until signaled
+ *  to stop.
+ *
+ * Results:
+ *  TCL_OK always
+ *
+ * Side effects:
+ *  Deletes any thread::send or thread::transfer events that are
+ *  pending.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ThreadWait()
+{
+    int canrun = 1;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    /*
+     * Process events until signaled to stop.
+     */
+
+    while (canrun) {
+
+        /*
+         * About to service another event.
+         * Wake-up eventual sleepers.
+         */
+
+        if (tsdPtr->maxEventsCount) {
+            Tcl_MutexLock(&threadMutex);
+            tsdPtr->eventsPending--;
+            Tcl_ConditionNotify(&tsdPtr->doOneEvent);
+            Tcl_MutexUnlock(&threadMutex);
+        }
+        Tcl_DoOneEvent(TCL_ALL_EVENTS);
+        
+        /*
+         * Test stop condition under mutex since
+         * some other thread may flip our flags.
+         */
+
+        Tcl_MutexLock(&threadMutex);
+        canrun = (tsdPtr->flags & THREAD_FLAGS_STOPPED) == 0;
+        Tcl_MutexUnlock(&threadMutex);
+    }
+
+    /*
+     * Remove from the list of active threads, so nobody can post 
+     * work to this thread, since it is just about to terminate.
+     */
+    
+    ListRemove(tsdPtr);
+
+    /*
+     * Now that the event processor for this thread is closing,
+     * delete all pending thread::send and thread::transfer events.
+     * These events are owned by us.  We don't delete anyone else's
+     * events, but ours.
+     */
+
+    Tcl_DeleteEvents((Tcl_EventDeleteProc*)ThreadDeleteEvent, NULL);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadReserve --
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadReserve(interp, thrId, operation, wait)
+    Tcl_Interp *interp;                 /* Current interpreter */
+    Tcl_ThreadId thrId;                 /* Target thread ID */
+    int operation;                      /* THREAD_RESERVE | THREAD_RELEASE */
+    int wait;                           /* Wait for thread to exit */
+{
+    int users, dowait = 0;
+    ThreadEvent *evPtr;
+    ThreadSpecificData *tsdPtr;
+
+    Tcl_MutexLock(&threadMutex);
+
+    /*
+     * Check the given thread
+     */
+
+    if (thrId == (Tcl_ThreadId)0) {
+        tsdPtr = TCL_TSD_INIT(&dataKey);
+    } else {
+        tsdPtr = ThreadExistsInner(thrId);
+        if (tsdPtr == (ThreadSpecificData*)NULL) {
+            Tcl_MutexUnlock(&threadMutex);
+            ErrorNoSuchThread(interp, thrId);
+            return TCL_ERROR;
+        }
+    }
+
+    switch (operation) {
+    case THREAD_RESERVE: ++tsdPtr->refCount;                break;
+    case THREAD_RELEASE: --tsdPtr->refCount; dowait = wait; break;
+    }
+
+    users = tsdPtr->refCount;
+
+    if (users <= 0) {
+        
+        /*
+         * We're last attached user, so tear down the *target* thread
+         */
+        
+        tsdPtr->flags |= THREAD_FLAGS_STOPPED;
+        
+        if (thrId /* Not current! */) {
+            ThreadEventResult *resultPtr = NULL;
+
+            /*
+             * Remove from the list of active threads, so nobody can post 
+             * work to this thread, since it is just about to terminate.
+             */
+            
+            ListRemoveInner(tsdPtr);
+            
+            /*
+             * Send an dummy event, just to wake-up target thread.
+             * It should immediately exit thereafter. We might get
+             * stuck here for long time if user really wants to 
+             * be absolutely sure that the thread has exited.
+             */
+            
+            if (dowait) {
+                resultPtr = (ThreadEventResult*)
+                    Tcl_Alloc(sizeof(ThreadEventResult));
+                resultPtr->done        = (Tcl_Condition)NULL;
+                resultPtr->result      = NULL;
+                resultPtr->code        = TCL_OK;
+                resultPtr->errorCode   = NULL;
+                resultPtr->errorInfo   = NULL;
+                resultPtr->dstThreadId = thrId;
+                resultPtr->srcThreadId = Tcl_GetCurrentThread();
+                SpliceIn(resultPtr, resultList);
+            }
+
+            evPtr = (ThreadEvent*)Tcl_Alloc(sizeof(ThreadEvent));
+            evPtr->event.proc = ThreadEventProc;
+            evPtr->sendData   = NULL;
+            evPtr->clbkData   = NULL;
+            evPtr->resultPtr  = resultPtr;
+
+            Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)evPtr, TCL_QUEUE_TAIL);
+            Tcl_ThreadAlert(thrId);
+
+            if (dowait) {
+                while (resultPtr->result == NULL) {
+                    Tcl_ConditionWait(&resultPtr->done, &threadMutex, NULL);
+                }
+                SpliceOut(resultPtr, resultList);
+                Tcl_ConditionFinalize(&resultPtr->done);
+                if (resultPtr->result != threadEmptyResult) {
+                    Tcl_Free(resultPtr->result); /* Will be ignored anyway */
+                }
+                Tcl_Free((char*)resultPtr);
+            }
+        }
+    }
+
+    Tcl_MutexUnlock(&threadMutex);
+    Tcl_SetIntObj(Tcl_GetObjResult(interp), (users > 0) ? users : 0);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadEventProc --
+ *
+ *  Handle the event in the target thread.
+ *
+ * Results:
+ *  Returns 1 to indicate that the event was processed.
+ *
+ * Side effects:
+ *  Fills out the ThreadEventResult struct.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ThreadEventProc(evPtr, mask)
+    Tcl_Event *evPtr;           /* Really ThreadEvent */
+    int mask;
+{
+    ThreadSpecificData* tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    Tcl_Interp         *interp   = NULL;
+    Tcl_ThreadId           thrId = Tcl_GetCurrentThread();
+    ThreadEvent        *eventPtr = (ThreadEvent*)evPtr;
+    ThreadSendData      *sendPtr = eventPtr->sendData;
+    ThreadClbkData      *clbkPtr = eventPtr->clbkData;
+    ThreadEventResult* resultPtr = eventPtr->resultPtr;
+
+    int code = TCL_ERROR; /* Pessimistic assumption */
+
+    /*
+     * See wether user has any preferences about which interpreter
+     * to use for running this job. The job structure might indentify
+     * one. If not, just use the thread's main interpreter which is
+     * stored in the thread specific data structure.
+     * Note that later on we might discover that we're running the
+     * aync callback script. In this case, interpreter will be 
+     * changed to one given in the callback.
+     */
+
+    interp = (sendPtr && sendPtr->interp) ? sendPtr->interp : tsdPtr->interp;
+
+    if (interp != NULL) {
+        if (clbkPtr && clbkPtr->threadId == thrId) {
+            /* Watch: this thread evaluates it's own callback. */
+            interp = clbkPtr->interp;
+        } else {
+            Tcl_Preserve((ClientData)interp);
+        }
+
+        Tcl_ResetResult(interp);
+
+        if (sendPtr) {
+            Tcl_CreateThreadExitHandler(ThreadFreeProc, (ClientData)sendPtr);
+            if (clbkPtr) {
+                Tcl_CreateThreadExitHandler(ThreadFreeProc,
+                                            (ClientData)clbkPtr);
+            }   
+            code = (*sendPtr->execProc)(interp, (ClientData)sendPtr);
+            Tcl_DeleteThreadExitHandler(ThreadFreeProc, (ClientData)sendPtr);
+            if (clbkPtr) {
+                Tcl_DeleteThreadExitHandler(ThreadFreeProc,
+                                            (ClientData)clbkPtr);
+            }
+        } else {
+            code = TCL_OK;
+        }
+    }
+
+    ThreadFreeProc((ClientData)sendPtr);
+
+    if (resultPtr) {
+
+        /*
+         * Report job result synchronously to waiting caller
+         */
+
+        Tcl_MutexLock(&threadMutex);
+        ThreadSetResult(interp, code, resultPtr);
+        Tcl_ConditionNotify(&resultPtr->done);
+        Tcl_MutexUnlock(&threadMutex);
+
+    } else if (clbkPtr && clbkPtr->threadId != thrId) {
+
+        ThreadSendData *tmpPtr = (ThreadSendData*)clbkPtr;
+        
+        /*
+         * Route the callback back to it's originator.
+         * Do not wait for the result.
+         */
+
+        if (code == TCL_ERROR) {
+            ThreadErrorProc(interp);
+        }
+
+        ThreadSetResult(interp, code, &clbkPtr->result);
+        ThreadSend(interp, clbkPtr->threadId, tmpPtr, NULL, 0);
+
+    } else if (code == TCL_ERROR) {
+        /*
+         * Only pass errors onto the registered error handler 
+         * when we don't have a result target for this event.
+         */
+        ThreadErrorProc(interp);
+    }
+
+    if (interp != NULL) {
+        Tcl_Release((ClientData)interp);
+    }
+
+    /*
+     * Mark unwind scenario for this thread if the script resulted
+     * in error condition and thread has been marked to unwind.
+     * This will cause thread to disappear from the list of active
+     * threads, clean-up its event queue and exit.
+     */
+
+    if (code != TCL_OK) {
+        Tcl_MutexLock(&threadMutex);
+        if (tsdPtr->flags & THREAD_FLAGS_UNWINDONERROR) {
+            tsdPtr->flags |= THREAD_FLAGS_INERROR;
+            if (tsdPtr->refCount == 0) {
+                tsdPtr->flags |= THREAD_FLAGS_STOPPED;
+            }
+        }
+        Tcl_MutexUnlock(&threadMutex);
+    }
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadSetResult --
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ThreadSetResult(interp, code, resultPtr)
+    Tcl_Interp *interp;
+    int code;
+    ThreadEventResult *resultPtr;
+{
+    int reslen;
+    const char *errorCode, *errorInfo, *result;
+
+    if (interp == NULL) {
+        code      = TCL_ERROR;
+        errorInfo = "";
+        errorCode = "THREAD";
+        result    = "no target interp!";
+        reslen    = strlen(result);
+        resultPtr->result = (reslen) ?
+            strcpy(Tcl_Alloc(1+reslen), result) : threadEmptyResult;
+    } else {
+        result = Tcl_GetStringResult(interp);
+        reslen = strlen(result);
+        resultPtr->result = (reslen) ?
+            strcpy(Tcl_Alloc(1+reslen), result) : threadEmptyResult;
+        if (code == TCL_ERROR) {
+            errorCode = Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);
+            errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
+        } else {
+            errorCode = NULL;
+            errorInfo = NULL;
+        }
+    }
+    
+    resultPtr->code = code;
+
+    if (errorCode != NULL) {
+        resultPtr->errorCode = Tcl_Alloc(1+strlen(errorCode));
+        strcpy(resultPtr->errorCode, errorCode);
+    } else {
+        resultPtr->errorCode = NULL;
+    }
+    if (errorInfo != NULL) {
+        resultPtr->errorInfo = Tcl_Alloc(1+strlen(errorInfo));
+        strcpy(resultPtr->errorInfo, errorInfo);
+    } else {
+        resultPtr->errorInfo = NULL;
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadGetOption --
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadGetOption(interp, thrId, option, dsPtr)
+    Tcl_Interp *interp;
+    Tcl_ThreadId thrId;
+    char *option;
+    Tcl_DString *dsPtr;
+{
+    int len;
+    ThreadSpecificData *tsdPtr = NULL;
+
+    /*
+     * If the optionName is NULL it means that we want
+     * a list of all options and values.
+     */
+    
+    len = (option == NULL) ? 0 : strlen(option);
+
+    Tcl_MutexLock(&threadMutex);
+
+    tsdPtr = ThreadExistsInner(thrId);
+
+    if (tsdPtr == (ThreadSpecificData*)NULL) {
+        Tcl_MutexUnlock(&threadMutex);
+        ErrorNoSuchThread(interp, thrId);
+        return TCL_ERROR;
+    }
+
+    if (len == 0 || (len > 3 && option[1] == 'e' && option[2] == 'v'
+                     && !strncmp(option,"-eventmark", len))) {
+        char buf[16];
+        if (len == 0) {
+            Tcl_DStringAppendElement(dsPtr, "-eventmark");
+        }
+        sprintf(buf, "%d", tsdPtr->maxEventsCount);
+        Tcl_DStringAppendElement(dsPtr, buf);
+        if (len != 0) {
+            Tcl_MutexUnlock(&threadMutex);
+            return TCL_OK;
+        }
+    }
+    
+    if (len == 0 || (len > 2 && option[1] == 'u' 
+                     && !strncmp(option,"-unwindonerror", len))) {
+        int flag = tsdPtr->flags & THREAD_FLAGS_UNWINDONERROR;
+        if (len == 0) {
+            Tcl_DStringAppendElement(dsPtr, "-unwindonerror");
+        }
+        Tcl_DStringAppendElement(dsPtr, flag ? "1" : "0");
+        if (len != 0) {
+            Tcl_MutexUnlock(&threadMutex);
+            return TCL_OK;
+        }
+    }
+    
+    if (len == 0 || (len > 3 && option[1] == 'e' && option[2] == 'r'
+                     && !strncmp(option,"-errorstate", len))) {
+        int flag = tsdPtr->flags & THREAD_FLAGS_INERROR;
+        if (len == 0) {
+            Tcl_DStringAppendElement(dsPtr, "-errorstate");
+        }
+        Tcl_DStringAppendElement(dsPtr, flag ? "1" : "0");
+        if (len != 0) {
+            Tcl_MutexUnlock(&threadMutex);
+            return TCL_OK;
+        }
+    }
+
+    if (len != 0) {
+        Tcl_AppendResult(interp, "bad option \"", option,
+                         "\", should be one of -eventmark, "
+                         "-unwindonerror or -errorstate", NULL);
+        Tcl_MutexUnlock(&threadMutex);
+        return TCL_ERROR;
+    }
+
+    Tcl_MutexUnlock(&threadMutex);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadSetOption --
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadSetOption(interp, thrId, option, value)
+    Tcl_Interp *interp;
+    Tcl_ThreadId thrId;
+    char *option;
+    char *value;
+{
+    int len = strlen(option);
+    ThreadSpecificData *tsdPtr = NULL;
+
+    Tcl_MutexLock(&threadMutex);
+
+    tsdPtr = ThreadExistsInner(thrId);
+
+    if (tsdPtr == (ThreadSpecificData*)NULL) {
+        Tcl_MutexUnlock(&threadMutex);
+        ErrorNoSuchThread(interp, thrId);
+        return TCL_ERROR;
+    }
+    if (len > 3 && option[1] == 'e' && option[2] == 'v'
+        && !strncmp(option,"-eventmark", len)) {
+        if (sscanf(value, "%d", &tsdPtr->maxEventsCount) != 1) {
+            Tcl_AppendResult(interp, "expected integer but got \"",
+                             value, "\"", NULL);
+            Tcl_MutexUnlock(&threadMutex);
+            return TCL_ERROR;
+        }
+    } else if (len > 2 && option[1] == 'u' 
+               && !strncmp(option,"-unwindonerror", len)) {
+        int flag = 0;
+        if (Tcl_GetBoolean(interp, value, &flag) != TCL_OK) {
+            Tcl_MutexUnlock(&threadMutex);
+            return TCL_ERROR;
+        }
+        if (flag) {
+            tsdPtr->flags |=  THREAD_FLAGS_UNWINDONERROR;
+        } else {
+            tsdPtr->flags &= ~THREAD_FLAGS_UNWINDONERROR;
+        }
+    } else if (len > 3 && option[1] == 'e' && option[2] == 'r'
+               && !strncmp(option,"-errorstate", len)) {
+        int flag = 0;
+        if (Tcl_GetBoolean(interp, value, &flag) != TCL_OK) {
+            Tcl_MutexUnlock(&threadMutex);
+            return TCL_ERROR;
+        }
+        if (flag) {
+            tsdPtr->flags |=  THREAD_FLAGS_INERROR;
+        } else {
+            tsdPtr->flags &= ~THREAD_FLAGS_INERROR;
+        }
+    }
+        
+    Tcl_MutexUnlock(&threadMutex);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadIdleProc --
+ *
+ * Results:
+ *
+ * Side effects.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ThreadIdleProc(clientData)
+    ClientData clientData;
+{
+    int ret;
+    ThreadSendData *sendPtr = (ThreadSendData*)clientData;
+
+    ret = (*sendPtr->execProc)(sendPtr->interp, (ClientData)sendPtr);
+    if (ret != TCL_OK) {
+        ThreadErrorProc(sendPtr->interp);
+    }
+
+    Tcl_Release((ClientData)sendPtr->interp);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransferEventProc --
+ *
+ *  Handle a transfer event in the target thread.
+ *
+ * Results:
+ *  Returns 1 to indicate that the event was processed.
+ *
+ * Side effects:
+ *  Fills out the TransferResult struct.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransferEventProc(evPtr, mask)
+    Tcl_Event *evPtr;           /* Really ThreadEvent */
+    int mask;
+{
+    ThreadSpecificData    *tsdPtr = TCL_TSD_INIT(&dataKey);
+    TransferEvent       *eventPtr = (TransferEvent *)evPtr;
+    TransferResult     *resultPtr = eventPtr->resultPtr;
+    Tcl_Interp            *interp = tsdPtr->interp;
+    int code;
+    const char* msg = NULL;
+
+    if (interp == NULL) {
+        /*
+         * Reject transfer in case of a missing target.
+         */
+        code = TCL_ERROR;
+        msg  = "target interp missing";
+    } else {
+        /*
+         * Add channel to current thread and interp.
+         * See ThreadTransfer for more explanations.
+         */
+        if (Tcl_IsChannelExisting(Tcl_GetChannelName(eventPtr->chan))) {
+            /*
+             * Reject transfer. Channel of same name already exists in target.
+             */
+            code = TCL_ERROR;
+            msg  = "channel already exists in target";
+        } else {
+            Tcl_SpliceChannel(eventPtr->chan);
+            Tcl_RegisterChannel(interp, eventPtr->chan);
+            Tcl_UnregisterChannel((Tcl_Interp *) NULL, eventPtr->chan);
+            code = TCL_OK; /* Return success. */
+        }
+    }
+    if (resultPtr) {
+        Tcl_MutexLock(&threadMutex);
+        resultPtr->resultCode = code;
+        if (msg != NULL) {
+            resultPtr->resultMsg = (char*)Tcl_Alloc(1+strlen (msg));
+            strcpy (resultPtr->resultMsg, msg);
+        }    
+        Tcl_ConditionNotify(&resultPtr->done);
+        Tcl_MutexUnlock(&threadMutex);
+    }
+    
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadFreeProc --
+ *
+ *  Called when we are exiting and memory needs to be freed.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  Clears up mem specified in ClientData
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+ThreadFreeProc(clientData)
+    ClientData clientData;
+{
+    /*
+     * This will free send and/or callback structures
+     * since both are the same in the beginning.
+     */
+
+    ThreadSendData *anyPtr = (ThreadSendData*)clientData;
+
+    if (anyPtr) {
+        if (anyPtr->clientData) {
+            (*anyPtr->freeProc)(anyPtr->clientData);
+        }
+        Tcl_Free((char*)anyPtr);
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadDeleteEvent --
+ *
+ *  This is called from the ThreadExitProc to delete memory related
+ *  to events that we put on the queue.
+ *
+ * Results:
+ *  1 it was our event and we want it removed, 0 otherwise.
+ *
+ * Side effects:
+ *  It cleans up our events in the event queue for this thread.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ThreadDeleteEvent(eventPtr, clientData)
+    Tcl_Event *eventPtr;        /* Really ThreadEvent */
+    ClientData clientData;      /* dummy */
+{
+    if (eventPtr->proc == ThreadEventProc) {
+        /*
+         * Regular script event. Just dispose memory
+         */
+        ThreadEvent *evPtr = (ThreadEvent*)eventPtr;
+        if (evPtr->sendData) {
+            ThreadFreeProc((ClientData)evPtr->sendData);
+        }
+        if (evPtr->clbkData) {
+            ThreadFreeProc((ClientData)evPtr->clbkData);
+        }
+        return 1;
+    }
+    if ((eventPtr->proc == TransferEventProc)) {
+        /* 
+         * A channel is in flight toward the thread just exiting.
+         * Pass it back to the originator, if possible.
+         * Else kill it.
+         */
+        TransferEvent* evPtr = (TransferEvent *) eventPtr;
+        
+        if (evPtr->resultPtr == (TransferResult *) NULL) {
+            /* No thread to pass the channel back to. Kill it.
+             * This requires to splice it temporarily into our channel
+             * list and then forcing the ref.counter down to the real
+             * value of zero. This destroys the channel.
+             */
+            
+            Tcl_SpliceChannel(evPtr->chan);
+            Tcl_UnregisterChannel((Tcl_Interp *) NULL, evPtr->chan);
+            return 1;
+        }
+        
+        /* Our caller (ThreadExitProc) will pass the channel back.
+         */
+        
+        return 1;
+    }
+
+    /*
+     * If it was NULL, we were in the middle of servicing the event
+     * and it should be removed
+     */
+
+    return (eventPtr->proc == NULL);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadExitProc --
+ *
+ *  This is called when the thread exits.  
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  It unblocks anyone that is waiting on a send to this thread.
+ *  It cleans up any events in the event queue for this thread.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+ThreadExitProc(clientData)
+    ClientData clientData;
+{
+    char *threadEvalScript = (char*)clientData;
+    const char *diemsg = "target thread died";
+    ThreadEventResult *resultPtr, *nextPtr;
+    Tcl_ThreadId self = Tcl_GetCurrentThread();
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    TransferResult *tResultPtr, *tNextPtr;
+
+    if (threadEvalScript && threadEvalScript != threadEmptyResult) {
+        Tcl_Free((char*)threadEvalScript);
+    }
+    
+    Tcl_MutexLock(&threadMutex);
+
+    /*
+     * AOLserver and threadpool threads get started/stopped
+     * out of the control of this interface so this is
+     * the first chance to split them out of the thread list.
+     */
+
+    ListRemoveInner(tsdPtr);
+
+    /* 
+     * Delete events posted to our queue while we were running.
+     * For threads exiting from the thread::wait command, this 
+     * has already been done in ThreadWait() function.
+     * For one-shot threads, having something here is a very 
+     * strange condition. It *may* happen if somebody posts us
+     * an event while we were in the middle of processing some
+     * lengthly user script. It is unlikely to happen, though.
+     */ 
+
+    Tcl_DeleteEvents((Tcl_EventDeleteProc*)ThreadDeleteEvent, NULL);
+
+    /*
+     * Walk the list of threads waiting for result from us 
+     * and inform them that we're about to exit.
+     */
+
+    for (resultPtr = resultList; resultPtr; resultPtr = nextPtr) {
+        nextPtr = resultPtr->nextPtr;
+        if (resultPtr->srcThreadId == self) {
+            
+            /*
+             * We are going away. By freeing up the result we signal
+             * to the other thread we don't care about the result.
+             */
+            
+            SpliceOut(resultPtr, resultList);
+            Tcl_Free((char*)resultPtr);
+
+        } else if (resultPtr->dstThreadId == self) {
+            
+            /*
+             * Dang. The target is going away. Unblock the caller.
+             * The result string must be dynamically allocated
+             * because the main thread is going to call free on it.
+             */
+
+            resultPtr->result = strcpy(Tcl_Alloc(1+strlen(diemsg)), diemsg);
+            resultPtr->code = TCL_ERROR;
+            resultPtr->errorCode = resultPtr->errorInfo = NULL;
+            Tcl_ConditionNotify(&resultPtr->done);
+        }
+    }
+    for (tResultPtr = transferList; tResultPtr; tResultPtr = tNextPtr) {
+        tNextPtr = tResultPtr->nextPtr;
+        if (tResultPtr->srcThreadId == self) {
+            /*
+             * We are going away. By freeing up the result we signal
+             * to the other thread we don't care about the result.
+             *
+             * This should not happen, as this thread should be in
+             * ThreadTransfer at location (*).
+             */
+            
+            SpliceOut(tResultPtr, transferList);
+            Tcl_Free((char*)tResultPtr);
+            
+        } else if (tResultPtr->dstThreadId == self) {
+            /*
+             * Dang. The target is going away. Unblock the caller.
+             * The result string must be dynamically allocated 
+             * because the main thread is going to call free on it.
+             */
+            
+            tResultPtr->resultMsg = strcpy(Tcl_Alloc(1+strlen(diemsg)),
+                                           diemsg);
+            tResultPtr->resultCode = TCL_ERROR;
+            Tcl_ConditionNotify(&tResultPtr->done);
+        }
+    }
+    Tcl_MutexUnlock(&threadMutex);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadGetHandle --
+ *
+ *  Construct the handle of the thread which is suitable 
+ *  to pass to Tcl.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ThreadGetHandle(thrId, handlePtr)
+    Tcl_ThreadId thrId;
+    char *handlePtr;
+{
+    sprintf(handlePtr, THREAD_HNDLPREFIX"%p", thrId);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadGetId --
+ *
+ *  Returns the ID of thread given it's Tcl handle.
+ *
+ * Results:
+ *  Thread ID.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadGetId(interp, handleObj, thrIdPtr)
+     Tcl_Interp *interp;
+     Tcl_Obj *handleObj;
+     Tcl_ThreadId *thrIdPtr;
+{
+    const char *thrHandle = Tcl_GetStringFromObj(handleObj, NULL);
+
+    if (sscanf(thrHandle, THREAD_HNDLPREFIX"%p", thrIdPtr) == 1) {
+        return TCL_OK;
+    }
+
+    Tcl_AppendResult(interp, "invalid thread handle \"", 
+                     thrHandle, "\"", NULL);
+    return TCL_ERROR;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ *  ErrorNoSuchThread --
+ *
+ *  Convenience function to set interpreter result when the thread 
+ *  given by it's ID cannot be found.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ErrorNoSuchThread(interp, thrId)
+    Tcl_Interp *interp;
+    Tcl_ThreadId thrId;
+{
+    char thrHandle[THREAD_HNDLMAXLEN];
+
+    ThreadGetHandle(thrId, thrHandle);
+    Tcl_AppendResult(interp, "thread \"", thrHandle, 
+                     "\" does not exist", NULL);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ *  ThreadCutChannel --
+ *
+ *  Dissociate a Tcl channel from the current thread/interp. 
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  Events still pending in the thread event queue and ready to fire
+ *  are not processed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ThreadCutChannel(interp, chan)
+    Tcl_Interp *interp;
+    Tcl_Channel chan;
+{
+    const Tcl_ChannelType *chanTypePtr;
+    Tcl_DriverWatchProc *watchProc;
+
+    Tcl_ClearChannelHandlers(chan);
+
+    chanTypePtr = Tcl_GetChannelType(chan);
+    watchProc   = Tcl_ChannelWatchProc(chanTypePtr);
+
+    /*
+     * This effectively disables processing of pending
+     * events which are ready to fire for the given 
+     * channel. If we do not do this, events will hit
+     * the detached channel which is potentially being
+     * owned by some other thread. This will wreck havoc
+     * on our memory and eventually badly hurt us...
+     */
+
+    if (watchProc) {
+        (*watchProc)(Tcl_GetChannelInstanceData(chan), 0);
+    }
+
+    /*
+     * Artificially bump the channel reference count
+     * which protects us from channel being closed
+     * during the Tcl_UnregisterChannel().
+     */
+
+    Tcl_RegisterChannel((Tcl_Interp *) NULL, chan);
+    Tcl_UnregisterChannel(interp, chan);
+
+    Tcl_CutChannel(chan);
+}
+
+/* EOF $RCSfile: threadCmd.c,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
diff --git a/8.x/thread/generic/threadPoolCmd.c b/8.x/thread/generic/threadPoolCmd.c
new file mode 100644 (file)
index 0000000..335f78e
--- /dev/null
@@ -0,0 +1,1926 @@
+/* 
+ * threadPoolCmd.c --
+ *
+ * This file implements the Tcl thread pools.
+ *
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: threadPoolCmd.c,v 1.43 2010/03/31 08:50:24 vasiljevic Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#include "tclThread.h"
+
+/*
+ * Structure to maintain idle poster threads
+ */
+
+typedef struct TpoolWaiter {
+    Tcl_ThreadId threadId;         /* Thread id of the current thread */
+    struct TpoolWaiter *nextPtr;   /* Next structure in the list */
+    struct TpoolWaiter *prevPtr;   /* Previous structure in the list */
+} TpoolWaiter;
+
+/*
+ * Structure describing an instance of a thread pool.
+ */
+
+typedef struct ThreadPool {
+    unsigned int jobId;             /* Job counter */
+    int idleTime;                   /* Time in secs a worker thread idles */
+    int tearDown;                   /* Set to 1 to tear down the pool */
+    int suspend;                    /* Set to 1 to suspend pool processing */
+    char *initScript;               /* Script to initialize worker thread */
+    char *exitScript;               /* Script to cleanup the worker */
+    int minWorkers;                 /* Minimum number or worker threads */
+    int maxWorkers;                 /* Maximum number of worker threads */
+    int numWorkers;                 /* Current number of worker threads */
+    int idleWorkers;                /* Number of idle workers */
+    int refCount;                   /* Reference counter for reserve/release */
+    Tcl_Mutex mutex;                /* Pool mutex */
+    Tcl_Condition cond;             /* Pool condition variable */
+    Tcl_HashTable jobsDone;         /* Stores processed job results */
+    struct TpoolResult *workTail;   /* Tail of the list with jobs pending*/
+    struct TpoolResult *workHead;   /* Head of the list with jobs pending*/
+    struct TpoolWaiter *waitTail;   /* Tail of the thread waiters list */
+    struct TpoolWaiter *waitHead;   /* Head of the thread waiters list */
+    struct ThreadPool *nextPtr;     /* Next structure in the threadpool list */
+    struct ThreadPool *prevPtr;     /* Previous structure in threadpool list */
+} ThreadPool;
+
+#define TPOOL_HNDLPREFIX  "tpool"   /* Prefix to generate Tcl pool handles */
+#define TPOOL_MINWORKERS  0         /* Default minimum # of worker threads */
+#define TPOOL_MAXWORKERS  4         /* Default maximum # of worker threads */
+#define TPOOL_IDLETIMER   0         /* Default worker thread idle timer */
+
+/*
+ * Structure for passing evaluation results
+ */
+
+typedef struct TpoolResult {
+    int detached;                   /* Result is to be ignored */
+    unsigned int jobId;             /* The job id of the current job */
+    char *script;                   /* Script to evaluate in worker thread */
+    int scriptLen;                  /* Length of the script */    
+    int retcode;                    /* Tcl return code of the current job */
+    char *result;                   /* Tcl result of the current job */
+    char *errorCode;                /* On error: content of the errorCode */
+    char *errorInfo;                /* On error: content of the errorInfo */
+    Tcl_ThreadId threadId;          /* Originating thread id */
+    ThreadPool *tpoolPtr;           /* Current thread pool */
+    struct TpoolResult *nextPtr;
+    struct TpoolResult *prevPtr;
+} TpoolResult;
+
+/*
+ * Private structure for each worker/poster thread.
+ */
+
+typedef struct ThreadSpecificData {
+    int stop;                       /* Set stop event; exit from event loop */
+    TpoolWaiter *waitPtr;           /* Threads private idle structure */
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * This global list maintains thread pools.
+ */
+
+static ThreadPool *tpoolList;
+static Tcl_Mutex listMutex;
+static Tcl_Mutex startMutex;
+
+/*
+ * Used to represent the empty result.
+ */
+
+static char *threadEmptyResult = (char *)"";
+
+/*
+ * Functions implementing Tcl commands
+ */
+
+static Tcl_ObjCmdProc TpoolCreateObjCmd;
+static Tcl_ObjCmdProc TpoolPostObjCmd;
+static Tcl_ObjCmdProc TpoolWaitObjCmd;
+static Tcl_ObjCmdProc TpoolCancelObjCmd;
+static Tcl_ObjCmdProc TpoolGetObjCmd;
+static Tcl_ObjCmdProc TpoolReserveObjCmd;
+static Tcl_ObjCmdProc TpoolReleaseObjCmd;
+static Tcl_ObjCmdProc TpoolSuspendObjCmd;
+static Tcl_ObjCmdProc TpoolResumeObjCmd;
+static Tcl_ObjCmdProc TpoolNamesObjCmd;
+
+/*
+ * Miscelaneous functions used within this file
+ */
+
+static int
+CreateWorker   _ANSI_ARGS_((Tcl_Interp *interp, ThreadPool *tpoolPtr));
+
+static Tcl_ThreadCreateType
+TpoolWorker    _ANSI_ARGS_((ClientData clientData));
+
+static int
+RunStopEvent   _ANSI_ARGS_((Tcl_Event *evPtr, int mask));
+
+static void
+PushWork       _ANSI_ARGS_((TpoolResult *rPtr, ThreadPool *tpoolPtr));
+
+static TpoolResult*
+PopWork        _ANSI_ARGS_((ThreadPool *tpoolPtr));
+
+static void
+PushWaiter     _ANSI_ARGS_((ThreadPool *tpoolPtr));
+
+static TpoolWaiter*
+PopWaiter      _ANSI_ARGS_((ThreadPool *tpoolPtr));
+
+static void
+SignalWaiter   _ANSI_ARGS_((ThreadPool *tpoolPtr));
+
+static int
+TpoolEval      _ANSI_ARGS_((Tcl_Interp *interp, char *script, int scriptLen,
+                            TpoolResult *rPtr));
+static void
+SetResult      _ANSI_ARGS_((Tcl_Interp *interp, TpoolResult *rPtr));
+
+static ThreadPool* 
+GetTpool       _ANSI_ARGS_((const char *tpoolName));
+
+static ThreadPool* 
+GetTpoolUnl    _ANSI_ARGS_((const char *tpoolName));
+
+static void
+ThrExitHandler _ANSI_ARGS_((ClientData clientData));
+
+static void
+AppExitHandler _ANSI_ARGS_((ClientData clientData));
+
+static int
+TpoolReserve   _ANSI_ARGS_((ThreadPool *tpoolPtr));
+
+static int
+TpoolRelease   _ANSI_ARGS_((ThreadPool *tpoolPtr));
+
+static void
+TpoolSuspend   _ANSI_ARGS_((ThreadPool *tpoolPtr));
+
+static void
+TpoolResume   _ANSI_ARGS_((ThreadPool *tpoolPtr));
+
+static void
+InitWaiter     _ANSI_ARGS_((void));
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolCreateObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::create" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TpoolCreateObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ii, minw, maxw, idle, len;
+    char buf[64], *exs = NULL, *cmd = NULL;
+    ThreadPool *tpoolPtr;
+
+    /* 
+     * Syntax:  tpool::create ?-minworkers count?
+     *                        ?-maxworkers count?
+     *                        ?-initcmd script?
+     *                        ?-exitcmd script?
+     *                        ?-idletime seconds?
+     */
+
+    if (((objc-1) % 2)) {
+        goto usage;
+    }
+
+    minw = TPOOL_MINWORKERS;
+    maxw = TPOOL_MAXWORKERS;
+    idle = TPOOL_IDLETIMER;
+
+    /*
+     * Parse the optional arguments
+     */
+
+    for (ii = 1; ii < objc; ii += 2) {
+        char *opt = Tcl_GetString(objv[ii]);
+        if (OPT_CMP(opt, "-minworkers")) {
+            if (Tcl_GetIntFromObj(interp, objv[ii+1], &minw) != TCL_OK) {
+                return TCL_ERROR;
+            }
+        } else if (OPT_CMP(opt, "-maxworkers")) {
+            if (Tcl_GetIntFromObj(interp, objv[ii+1], &maxw) != TCL_OK) {
+                return TCL_ERROR;
+            }
+        } else if (OPT_CMP(opt, "-idletime")) {
+            if (Tcl_GetIntFromObj(interp, objv[ii+1], &idle) != TCL_OK) {
+                return TCL_ERROR;
+            }
+        } else if (OPT_CMP(opt, "-initcmd")) {
+            const char *val = Tcl_GetStringFromObj(objv[ii+1], &len);
+            cmd  = strcpy(Tcl_Alloc(len+1), val);
+        } else if (OPT_CMP(opt, "-exitcmd")) {
+            const char *val = Tcl_GetStringFromObj(objv[ii+1], &len);
+            exs  = strcpy(Tcl_Alloc(len+1), val);
+        } else {
+            goto usage;
+        }
+    }
+
+    /*
+     * Do some consistency checking
+     */
+
+    if (minw < 0) {
+        minw = 0;
+    }
+    if (maxw < 0) {
+        maxw = TPOOL_MAXWORKERS;
+    }
+    if (minw > maxw) {
+        maxw = minw;
+    }
+
+    /*
+     * Allocate and initialize thread pool structure
+     */
+
+    tpoolPtr = (ThreadPool*)Tcl_Alloc(sizeof(ThreadPool));
+    memset(tpoolPtr, 0, sizeof(ThreadPool));
+
+    tpoolPtr->minWorkers  = minw;
+    tpoolPtr->maxWorkers  = maxw;
+    tpoolPtr->idleTime    = idle;
+    tpoolPtr->initScript  = cmd;
+    tpoolPtr->exitScript  = exs;
+    Tcl_InitHashTable(&tpoolPtr->jobsDone, TCL_ONE_WORD_KEYS);
+
+    Tcl_MutexLock(&listMutex);
+    SpliceIn(tpoolPtr, tpoolList);
+    Tcl_MutexUnlock(&listMutex);
+
+    /*
+     * Start the required number of worker threads.
+     * On failure to start any of them, tear-down
+     * partially initialized pool.
+     */
+
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    for (ii = 0; ii < tpoolPtr->minWorkers; ii++) {
+        if (CreateWorker(interp, tpoolPtr) != TCL_OK) {
+            Tcl_MutexUnlock(&tpoolPtr->mutex);
+            Tcl_MutexLock(&listMutex);
+            TpoolRelease(tpoolPtr);
+            Tcl_MutexUnlock(&listMutex);
+            return TCL_ERROR;
+        }
+    }
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+
+    sprintf(buf, "%s%p", TPOOL_HNDLPREFIX, tpoolPtr);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
+
+    return TCL_OK;
+
+ usage:
+    Tcl_WrongNumArgs(interp, 1, objv,
+                     "?-minworkers count? ?-maxworkers count? "
+                     "?-initcmd script? ?-exitcmd script? "
+                     "?-idletime seconds?");
+    return TCL_ERROR;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolPostObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::post" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TpoolPostObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    unsigned int jobId = 0;
+    int ii, detached = 0, nowait = 0, len;
+    const char *tpoolName, *script;
+    TpoolResult *rPtr;
+    ThreadPool *tpoolPtr;
+
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    /* 
+     * Syntax: tpool::post ?-detached? ?-nowait? tpoolId script
+     */
+
+    if (objc < 3 || objc > 5) {
+        goto usage;
+    }
+    for (ii = 1; ii < objc; ii++) {
+        char *opt = Tcl_GetString(objv[ii]);
+        if (*opt != '-') {
+            break;
+        } else if (OPT_CMP(opt, "-detached")) {
+            detached  = 1;
+        } else if (OPT_CMP(opt, "-nowait")) {
+            nowait = 1;
+        } else {
+            goto usage;
+        }
+    }
+
+    tpoolName = Tcl_GetString(objv[ii]);
+    script    = Tcl_GetStringFromObj(objv[ii+1], &len);
+    tpoolPtr  = GetTpool(tpoolName);
+    if (tpoolPtr == NULL) {
+        Tcl_AppendResult(interp, "can not find threadpool \"", tpoolName, 
+                         "\"", NULL);
+        return TCL_ERROR;
+    }
+    
+    /*
+     * Initialize per-thread private data for this caller
+     */
+    
+    InitWaiter();
+
+    /*
+     * See if any worker available to run the job.
+     */
+
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    if (nowait && tpoolPtr->numWorkers == 0) {
+
+        /*
+         * Do not wait for an idle thread but assure
+         * there is at least one worker started.
+         */
+
+        PushWaiter(tpoolPtr);
+        if (CreateWorker(interp, tpoolPtr) != TCL_OK) {
+            Tcl_MutexUnlock(&tpoolPtr->mutex);
+            return TCL_ERROR;
+        }
+        /* Wait for worker to start and service the event loop */
+        Tcl_MutexUnlock(&tpoolPtr->mutex);
+        tsdPtr->stop = -1;
+        while(tsdPtr->stop == -1) {
+            Tcl_DoOneEvent(TCL_ALL_EVENTS);
+        }
+        Tcl_MutexLock(&tpoolPtr->mutex);
+    } else {
+
+        /*
+         * If there are no idle worker threads, start some new
+         * unless we are already running max number of workers.
+         * In that case wait for the next one to become idle.
+         */
+
+        while (tpoolPtr->idleWorkers == 0) {
+            PushWaiter(tpoolPtr);
+            if (tpoolPtr->numWorkers < tpoolPtr->maxWorkers) {
+                /* No more free workers; start new one */
+                if (CreateWorker(interp, tpoolPtr) != TCL_OK) {
+                    Tcl_MutexUnlock(&tpoolPtr->mutex);
+                    return TCL_ERROR;
+                }
+            }
+            /* Wait for any idle worker and service the event loop */
+            Tcl_MutexUnlock(&tpoolPtr->mutex);
+            tsdPtr->stop = -1;
+            while(tsdPtr->stop == -1) {
+                Tcl_DoOneEvent(TCL_ALL_EVENTS);
+            }
+            Tcl_MutexLock(&tpoolPtr->mutex);
+        }
+    }
+
+    /*
+     * Create new job ticket and put it on the list.
+     */
+
+    rPtr = (TpoolResult*)Tcl_Alloc(sizeof(TpoolResult));
+    memset(rPtr, 0, sizeof(TpoolResult));
+
+    if (detached == 0) {
+        jobId = ++tpoolPtr->jobId;
+        rPtr->jobId = jobId;
+    }
+
+    rPtr->script    = strcpy(Tcl_Alloc(len+1), script);
+    rPtr->scriptLen = len;
+    rPtr->detached  = detached;
+    rPtr->threadId  = Tcl_GetCurrentThread();
+
+    PushWork(rPtr, tpoolPtr);
+    Tcl_ConditionNotify(&tpoolPtr->cond);
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+
+    if (detached == 0) {
+        Tcl_SetObjResult(interp, Tcl_NewIntObj(jobId));
+    }
+    
+    return TCL_OK;
+
+  usage:
+    Tcl_WrongNumArgs(interp, 1, objv, "?-detached? ?-nowait? tpoolId script");
+    return TCL_ERROR;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolWaitObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::wait" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+TpoolWaitObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ii, done, wObjc;
+    unsigned int jobId;
+    char *tpoolName, *listVar = NULL;
+    Tcl_Obj *waitList, *doneList, **wObjv;
+    ThreadPool *tpoolPtr;
+    TpoolResult *rPtr;
+    Tcl_HashEntry *hPtr;
+
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    /* 
+     * Syntax: tpool::wait tpoolId jobIdList ?listVar?
+     */
+
+    if (objc < 3 || objc > 4) {
+        Tcl_WrongNumArgs(interp, 1, objv, "tpoolId jobIdList ?listVar");
+        return TCL_ERROR;
+    }
+    if (objc == 4) {
+        listVar = Tcl_GetString(objv[3]);
+    }
+    if (Tcl_ListObjGetElements(interp, objv[2], &wObjc, &wObjv) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    tpoolName = Tcl_GetString(objv[1]);
+    tpoolPtr  = GetTpool(tpoolName);
+    if (tpoolPtr == NULL) {
+        Tcl_AppendResult(interp, "can not find threadpool \"", tpoolName,
+                         "\"", NULL);
+        return TCL_ERROR;
+    }
+
+    InitWaiter();
+    done = 0; /* Number of elements in the done list */
+    doneList = Tcl_NewListObj(0, NULL);
+
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    while (1) {
+        waitList = Tcl_NewListObj(0, NULL);
+        for (ii = 0; ii < wObjc; ii++) {
+            if (Tcl_GetIntFromObj(interp, wObjv[ii], (int *)&jobId) != TCL_OK) {
+                Tcl_MutexUnlock(&tpoolPtr->mutex);
+                return TCL_ERROR;
+            }
+            hPtr = Tcl_FindHashEntry(&tpoolPtr->jobsDone, (char*)jobId);
+            if (hPtr) {
+                rPtr = (TpoolResult*)Tcl_GetHashValue(hPtr);
+            } else {
+                for (rPtr = tpoolPtr->workHead; rPtr; rPtr = rPtr->nextPtr) {
+                    if (rPtr->jobId == jobId) {
+                        break;
+                    }
+                }
+                if (rPtr == NULL) {
+                    continue; /* Bogus job id; ignore */
+                }
+            }
+            if (rPtr->detached) {
+                continue; /* A detached job */
+            }
+            if (rPtr->result) {
+                done++; /* Job has been processed */
+                Tcl_ListObjAppendElement(interp, doneList, wObjv[ii]);
+            } else if (listVar) {
+                Tcl_ListObjAppendElement(interp, waitList, wObjv[ii]);
+            }
+        }
+        if (done) {
+            break;
+        }
+
+        /*
+         * None of the jobs done, wait for completion
+         * of the next job and try again.
+         */
+
+        Tcl_DecrRefCount(waitList); 
+        PushWaiter(tpoolPtr);
+
+        Tcl_MutexUnlock(&tpoolPtr->mutex);
+        tsdPtr->stop = -1;
+        while (tsdPtr->stop == -1) {
+            Tcl_DoOneEvent(TCL_ALL_EVENTS);
+        }
+        Tcl_MutexLock(&tpoolPtr->mutex);
+    }
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+
+    if (listVar) {
+        Tcl_SetVar2Ex(interp, listVar, NULL, waitList, 0);
+    }
+
+    Tcl_SetObjResult(interp, doneList);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolCancelObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::cancel" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+TpoolCancelObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ii, wObjc, jobId;
+    char *tpoolName, *listVar = NULL;
+    Tcl_Obj *doneList, *waitList, **wObjv;
+    ThreadPool *tpoolPtr;
+    TpoolResult *rPtr;
+
+    /* 
+     * Syntax: tpool::wait tpoolId jobIdList ?listVar?
+     */
+
+    if (objc < 3 || objc > 4) {
+        Tcl_WrongNumArgs(interp, 1, objv, "tpoolId jobIdList ?listVar");
+        return TCL_ERROR;
+    }
+    if (objc == 4) {
+        listVar = Tcl_GetString(objv[3]);
+    }
+    if (Tcl_ListObjGetElements(interp, objv[2], &wObjc, &wObjv) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    tpoolName = Tcl_GetString(objv[1]);
+    tpoolPtr  = GetTpool(tpoolName);
+    if (tpoolPtr == NULL) {
+        Tcl_AppendResult(interp, "can not find threadpool \"", tpoolName,
+                         "\"", NULL);
+        return TCL_ERROR;
+    }
+    InitWaiter();
+    doneList = Tcl_NewListObj(0, NULL);
+    waitList = Tcl_NewListObj(0, NULL);
+
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    for (ii = 0; ii < wObjc; ii++) {
+        if (Tcl_GetIntFromObj(interp, wObjv[ii], &jobId) != TCL_OK) {
+            return TCL_ERROR;
+        }
+        for (rPtr = tpoolPtr->workHead; rPtr; rPtr = rPtr->nextPtr) {
+            if (rPtr->jobId == (unsigned int)jobId) {
+                if (rPtr->prevPtr != NULL) {
+                    rPtr->prevPtr->nextPtr = rPtr->nextPtr;
+                } else {
+                    tpoolPtr->workHead = rPtr->nextPtr;
+                }
+                if (rPtr->nextPtr != NULL) {
+                    rPtr->nextPtr->prevPtr = rPtr->prevPtr;
+                } else {
+                    tpoolPtr->workTail = rPtr->prevPtr;
+                }
+                SetResult(NULL, rPtr); /* Just to free the result */
+                Tcl_Free(rPtr->script);
+                Tcl_Free((char*)rPtr);
+                Tcl_ListObjAppendElement(interp, doneList, wObjv[ii]);
+                break;
+            }
+        }
+        if (rPtr == NULL && listVar) {
+            Tcl_ListObjAppendElement(interp, waitList, wObjv[ii]);
+        }
+    }
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+
+    if (listVar) {
+        Tcl_SetVar2Ex(interp, listVar, NULL, waitList, 0);
+    }
+
+    Tcl_SetObjResult(interp, doneList);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolGetObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::get" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+TpoolGetObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ret, jobId;
+    char *tpoolName, *resVar = NULL;
+    ThreadPool *tpoolPtr;
+    TpoolResult *rPtr;
+    Tcl_HashEntry *hPtr;
+
+    /* 
+     * Syntax: tpool::get tpoolId jobId ?result?
+     */
+
+    if (objc < 3 || objc > 4) {
+        Tcl_WrongNumArgs(interp, 1, objv, "tpoolId jobId ?result?");
+        return TCL_ERROR;
+    }
+    if (Tcl_GetIntFromObj(interp, objv[2], &jobId) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if (objc == 4) {
+        resVar = Tcl_GetString(objv[3]);
+    }
+
+    /*
+     * Locate the threadpool
+     */
+
+    tpoolName = Tcl_GetString(objv[1]);
+    tpoolPtr  = GetTpool(tpoolName);
+    if (tpoolPtr == NULL) {
+        Tcl_AppendResult(interp, "can not find threadpool \"", tpoolName, 
+                         "\"", NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     * Locate the job in question. It is an error to
+     * do a "get" on bogus job handle or on the job
+     * which did not complete yet.
+     */
+
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    hPtr = Tcl_FindHashEntry(&tpoolPtr->jobsDone, (char*)jobId);
+    if (hPtr == NULL) {
+        Tcl_MutexUnlock(&tpoolPtr->mutex);
+        Tcl_AppendResult(interp, "no such job", NULL);
+        return TCL_ERROR;
+    }
+    rPtr = (TpoolResult*)Tcl_GetHashValue(hPtr);
+    if (rPtr->result == NULL) {
+        Tcl_MutexUnlock(&tpoolPtr->mutex);
+        Tcl_AppendResult(interp, "job not completed", NULL);
+        return TCL_ERROR;
+    }
+
+    Tcl_DeleteHashEntry(hPtr);
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+
+    ret = rPtr->retcode;
+    SetResult(interp, rPtr);
+    Tcl_Free((char*)rPtr);
+
+    if (resVar) {
+        Tcl_SetVar2Ex(interp, resVar, NULL, Tcl_GetObjResult(interp), 0);
+        Tcl_SetObjResult(interp, Tcl_NewIntObj(ret));
+        ret = TCL_OK; 
+    }
+
+    return ret;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolReserveObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::preserve" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TpoolReserveObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ret;
+    char *tpoolName;
+    ThreadPool *tpoolPtr;
+
+    /*
+     * Syntax: tpool::preserve tpoolId
+     */
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "tpoolId");
+        return TCL_ERROR;
+    }
+
+    tpoolName = Tcl_GetString(objv[1]);
+
+    Tcl_MutexLock(&listMutex);
+    tpoolPtr  = GetTpoolUnl(tpoolName);
+    if (tpoolPtr == NULL) {
+        Tcl_MutexUnlock(&listMutex);
+        Tcl_AppendResult(interp, "can not find threadpool \"", tpoolName, 
+                         "\"", NULL);
+        return TCL_ERROR;
+    }
+
+    ret = TpoolReserve(tpoolPtr); 
+    Tcl_MutexUnlock(&listMutex);
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(ret));
+
+    return TCL_OK; 
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolReleaseObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::release" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TpoolReleaseObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    int ret;
+    char *tpoolName;
+    ThreadPool *tpoolPtr;
+
+    /*
+     * Syntax: tpool::release tpoolId
+     */
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "tpoolId");
+        return TCL_ERROR;
+    }
+
+    tpoolName = Tcl_GetString(objv[1]);
+
+    Tcl_MutexLock(&listMutex);
+    tpoolPtr  = GetTpoolUnl(tpoolName);
+    if (tpoolPtr == NULL) {
+        Tcl_MutexUnlock(&listMutex);
+        Tcl_AppendResult(interp, "can not find threadpool \"", tpoolName,
+                         "\"", NULL);
+        return TCL_ERROR;
+    }
+
+    ret = TpoolRelease(tpoolPtr); 
+    Tcl_MutexUnlock(&listMutex);
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(ret));
+
+    return TCL_OK; 
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolSuspendObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::suspend" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TpoolSuspendObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    char *tpoolName;
+    ThreadPool *tpoolPtr;
+
+    /*
+     * Syntax: tpool::suspend tpoolId
+     */
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "tpoolId");
+        return TCL_ERROR;
+    }
+
+    tpoolName = Tcl_GetString(objv[1]);
+    tpoolPtr  = GetTpool(tpoolName);
+
+    if (tpoolPtr == NULL) {
+        Tcl_AppendResult(interp, "can not find threadpool \"", tpoolName, 
+                         "\"", NULL);
+        return TCL_ERROR;
+    }
+
+    TpoolSuspend(tpoolPtr); 
+
+    return TCL_OK; 
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolResumeObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::resume" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TpoolResumeObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    char *tpoolName;
+    ThreadPool *tpoolPtr;
+
+    /*
+     * Syntax: tpool::resume tpoolId
+     */
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "tpoolId");
+        return TCL_ERROR;
+    }
+
+    tpoolName = Tcl_GetString(objv[1]);
+    tpoolPtr  = GetTpool(tpoolName);
+
+    if (tpoolPtr == NULL) {
+        Tcl_AppendResult(interp, "can not find threadpool \"", tpoolName, 
+                         "\"", NULL);
+        return TCL_ERROR;
+    }
+
+    TpoolResume(tpoolPtr); 
+
+    return TCL_OK; 
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolNamesObjCmd --
+ *
+ *  This procedure is invoked to process the "tpool::names" Tcl 
+ *  command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TpoolNamesObjCmd(dummy, interp, objc, objv)
+    ClientData  dummy;          /* Not used. */
+    Tcl_Interp *interp;         /* Current interpreter. */
+    int         objc;           /* Number of arguments. */
+    Tcl_Obj    *const objv[];   /* Argument objects. */
+{
+    ThreadPool *tpoolPtr;
+    Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
+    
+    Tcl_MutexLock(&listMutex);
+    for (tpoolPtr = tpoolList; tpoolPtr; tpoolPtr = tpoolPtr->nextPtr) {
+        char buf[32];
+        sprintf(buf, "%s%p", TPOOL_HNDLPREFIX, tpoolPtr);
+        Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(buf,-1));
+    }
+    Tcl_MutexUnlock(&listMutex);
+    Tcl_SetObjResult(interp, listObj);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * CreateWorker --
+ *
+ *  Creates new worker thread for the given pool. Assumes the caller
+ *  holds the pool mutex.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  Informs waiter thread (if any) about the new worker thread.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+CreateWorker(interp, tpoolPtr)
+    Tcl_Interp *interp;
+    ThreadPool *tpoolPtr;
+{
+    Tcl_ThreadId id;
+    TpoolResult result;
+
+    /*
+     * Initialize the result structure to be
+     * passed to the new thread. This is used
+     * as communication to and from the thread.
+     */
+
+    memset(&result, 0, sizeof(TpoolResult));
+    result.retcode  = -1;
+    result.tpoolPtr = tpoolPtr;
+
+    /*
+     * Create new worker thread here. Wait for the thread to start 
+     * because it's using the ThreadResult arg which is on our stack.
+     */
+
+    Tcl_MutexLock(&startMutex);
+    if (Tcl_CreateThread(&id, TpoolWorker, (ClientData)&result,
+                         TCL_THREAD_STACK_DEFAULT, 0) != TCL_OK) {
+        Tcl_SetResult(interp, "can't create a new thread", TCL_STATIC);
+        Tcl_MutexUnlock(&startMutex);
+        return TCL_ERROR;
+    }
+    while(result.retcode == -1) {
+        Tcl_ConditionWait(&tpoolPtr->cond, &startMutex, NULL);
+    }
+    Tcl_MutexUnlock(&startMutex);
+
+    /*
+     * Set error-related information if the thread
+     * failed to initialize correctly.
+     */
+    
+    if (result.retcode == 1) {
+        result.retcode = TCL_ERROR;
+        SetResult(interp, &result);
+        return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolWorker --
+ *
+ *  This is the main function of each of the threads in the pool.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_ThreadCreateType
+TpoolWorker(clientData)
+    ClientData clientData;
+{    
+    TpoolResult          *rPtr = (TpoolResult*)clientData;
+    ThreadPool       *tpoolPtr = rPtr->tpoolPtr;
+
+    int tout = 0;
+    Tcl_Interp *interp;
+    Tcl_Time waitTime, *idlePtr;
+    char *errMsg;
+
+    Tcl_MutexLock(&startMutex);
+
+    /*
+     * Initialize the Tcl interpreter
+     */
+
+#ifdef NS_AOLSERVER
+    interp = (Tcl_Interp*)Ns_TclAllocateInterp(NULL);
+    rPtr->retcode = 0;
+#else
+    interp = Tcl_CreateInterp();
+    if (Tcl_Init(interp) != TCL_OK) {
+        rPtr->retcode = 1;
+    } else if (Thread_Init(interp) != TCL_OK) {
+        rPtr->retcode = 1;
+    } else {
+        rPtr->retcode = 0;
+    }
+#endif
+    
+    if (rPtr->retcode == 1) {
+        errMsg = (char*)Tcl_GetStringResult(interp);
+        rPtr->result = strcpy(Tcl_Alloc(strlen(errMsg)+1), errMsg);
+        Tcl_ConditionNotify(&tpoolPtr->cond);
+        Tcl_MutexUnlock(&startMutex);
+        goto out;
+    }
+
+    /*
+     * Initialize the interpreter
+     */
+
+    if (tpoolPtr->initScript) {
+        TpoolEval(interp, tpoolPtr->initScript, -1, rPtr);
+        if (rPtr->retcode != TCL_OK) {
+            rPtr->retcode = 1;
+            errMsg = (char*)Tcl_GetStringResult(interp);
+            rPtr->result  = strcpy(Tcl_Alloc(strlen(errMsg)+1), errMsg);
+            Tcl_ConditionNotify(&tpoolPtr->cond);
+            Tcl_MutexUnlock(&startMutex);
+            goto out;
+        }
+    }
+
+    /*
+     * Setup idle timer
+     */
+
+    if (tpoolPtr->idleTime == 0) {
+        idlePtr = NULL;
+    } else {
+        waitTime.sec  = tpoolPtr->idleTime;
+        waitTime.usec = 0;
+        idlePtr = &waitTime;
+    }
+
+    /*
+     * Tell caller we've started
+     */
+
+    tpoolPtr->numWorkers++; 
+    Tcl_ConditionNotify(&tpoolPtr->cond);
+    Tcl_MutexUnlock(&startMutex);
+
+    /*
+     * Wait for jobs to arrive. Note the handcrafted time test.
+     * Tcl API misses the return value of the Tcl_ConditionWait().
+     * Hence, we do not know why the call returned. Was it someone
+     * signalled the variable or has the idle timer expired?
+     */
+
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    while (!tpoolPtr->tearDown) {
+        SignalWaiter(tpoolPtr);
+        tpoolPtr->idleWorkers++;
+        rPtr = NULL;
+        tout = 0;
+        while (tpoolPtr->suspend
+               || (!tpoolPtr->tearDown && !tout
+                   && (rPtr = PopWork(tpoolPtr)) == NULL)) {
+            if (tpoolPtr->suspend && rPtr == NULL) {
+                Tcl_ConditionWait(&tpoolPtr->cond, &tpoolPtr->mutex, NULL);
+            } else if (rPtr == NULL) {
+                Tcl_Time t1, t2;
+                Tcl_GetTime(&t1);
+                Tcl_ConditionWait(&tpoolPtr->cond, &tpoolPtr->mutex, idlePtr);
+                Tcl_GetTime(&t2);
+                if (tpoolPtr->idleTime > 0) {
+                    tout = (t2.sec - t1.sec) >= tpoolPtr->idleTime;
+                }
+            }
+        }
+        tpoolPtr->idleWorkers--;
+        if (rPtr == NULL) {
+            if (tpoolPtr->numWorkers > tpoolPtr->minWorkers) {
+                break; /* Enough workers, can safely kill this one */
+            } else {
+                continue; /* Worker count at min, leave this one alive */
+            }
+        } else if (tpoolPtr->tearDown) {
+            PushWork(rPtr, tpoolPtr);
+            break; /* Kill worker because pool is going down */
+        }
+        Tcl_MutexUnlock(&tpoolPtr->mutex);
+        TpoolEval(interp, rPtr->script, rPtr->scriptLen, rPtr);
+        Tcl_MutexLock(&tpoolPtr->mutex);
+        Tcl_Free(rPtr->script);
+        if (!rPtr->detached) {
+            int new;
+            Tcl_SetHashValue(Tcl_CreateHashEntry(&tpoolPtr->jobsDone, 
+                                                 (char*)rPtr->jobId, &new), 
+                             (ClientData)rPtr);
+        } else {
+            Tcl_Free((char*)rPtr);
+        }
+    }
+
+    /*
+     * Tear down the worker
+     */
+
+    if (tpoolPtr->exitScript) {
+        TpoolEval(interp, tpoolPtr->exitScript, -1, NULL);
+    }
+
+    tpoolPtr->numWorkers--;
+    SignalWaiter(tpoolPtr);
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+
+ out:
+
+#ifdef NS_AOLSERVER
+    Ns_TclMarkForDelete(interp);
+    Ns_TclDeAllocateInterp(interp);
+#else
+    Tcl_DeleteInterp(interp);
+#endif
+    Tcl_ExitThread(0);
+
+    TCL_THREAD_CREATE_RETURN;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * RunStopEvent --
+ *
+ *  Signalizes the waiter thread to stop waiting.
+ *
+ * Results:
+ *  1 (always)
+ *
+ * Side effects:
+ *  None. 
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+RunStopEvent(eventPtr, mask)
+    Tcl_Event *eventPtr; 
+    int mask;
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    tsdPtr->stop = 1;
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * PushWork --
+ *
+ *  Adds a worker thread to the end of the workers list.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PushWork(rPtr, tpoolPtr)
+    TpoolResult *rPtr;
+    ThreadPool *tpoolPtr;
+{
+    SpliceIn(rPtr, tpoolPtr->workHead);
+    if (tpoolPtr->workTail == NULL) {
+        tpoolPtr->workTail = rPtr;
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * PopWork --
+ *
+ *  Pops the work ticket from the list
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static TpoolResult *
+PopWork(tpoolPtr)
+    ThreadPool *tpoolPtr;
+{   
+    TpoolResult *rPtr = tpoolPtr->workTail;
+
+    if (rPtr == NULL) {
+        return NULL;
+    }
+
+    tpoolPtr->workTail = rPtr->prevPtr;
+    SpliceOut(rPtr, tpoolPtr->workHead);
+
+    rPtr->nextPtr = rPtr->prevPtr = NULL;
+
+    return rPtr;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * PushWaiter --
+ *
+ *  Adds a waiter thread to the end of the waiters list.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PushWaiter(tpoolPtr)
+    ThreadPool *tpoolPtr;
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    SpliceIn(tsdPtr->waitPtr, tpoolPtr->waitHead);
+    if (tpoolPtr->waitTail == NULL) {
+        tpoolPtr->waitTail = tsdPtr->waitPtr;
+    }
+} 
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * PopWaiter --
+ *
+ *  Pops the first waiter from the head of the waiters list.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static TpoolWaiter*
+PopWaiter(tpoolPtr)
+    ThreadPool *tpoolPtr;
+{
+    TpoolWaiter *waitPtr =  tpoolPtr->waitTail;
+
+    if (waitPtr == NULL) {
+        return NULL;
+    }
+
+    tpoolPtr->waitTail = waitPtr->prevPtr;
+    SpliceOut(waitPtr, tpoolPtr->waitHead);
+
+    waitPtr->prevPtr = waitPtr->nextPtr = NULL;
+
+    return waitPtr;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetTpool 
+ *
+ *  Parses the Tcl threadpool handle and locates the
+ *  corresponding threadpool maintenance structure. 
+ *
+ * Results:
+ *  Pointer to the threadpool struct or NULL if none found, 
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+static ThreadPool* 
+GetTpool(tpoolName) 
+    const char *tpoolName;
+{
+    ThreadPool *tpoolPtr; 
+
+    Tcl_MutexLock(&listMutex);
+    tpoolPtr = GetTpoolUnl(tpoolName);
+    Tcl_MutexUnlock(&listMutex);
+
+    return tpoolPtr;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetTpoolUnl 
+ *
+ *  Parses the threadpool handle and locates the
+ *  corresponding threadpool maintenance structure. 
+ *  Assumes caller holds the listMutex,
+ *
+ * Results:
+ *  Pointer to the threadpool struct or NULL if none found, 
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ThreadPool* 
+GetTpoolUnl (tpoolName) 
+    const char *tpoolName;
+{
+    ThreadPool *tpool;
+    ThreadPool *tpoolPtr = NULL;
+
+    if (sscanf(tpoolName, TPOOL_HNDLPREFIX"%p", &tpool) != 1) {
+        return NULL;
+    }
+    for (tpoolPtr = tpoolList; tpoolPtr; tpoolPtr = tpoolPtr->nextPtr) {
+        if (tpoolPtr == tpool) {
+            break;
+        }
+    }
+
+    return tpoolPtr;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolEval 
+ *
+ *  Evaluates the script and fills in the result structure. 
+ *
+ * Results:
+ *  Standard Tcl result, 
+ *
+ * Side effects:
+ *  Many, depending on the script.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+TpoolEval(interp, script, scriptLen, rPtr)
+    Tcl_Interp *interp;
+    char *script;
+    int scriptLen;
+    TpoolResult *rPtr;
+{
+    int ret, reslen;
+    char *result, *errorCode, *errorInfo;
+    
+    ret = Tcl_EvalEx(interp, script, scriptLen, TCL_EVAL_GLOBAL);
+    if (rPtr == NULL || rPtr->detached) {
+        return ret;
+    }
+    rPtr->retcode = ret;
+    if (ret == TCL_ERROR) {
+        errorCode = (char*)Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);
+        errorInfo = (char*)Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
+        if (errorCode != NULL) {
+            rPtr->errorCode = Tcl_Alloc(1 + strlen(errorCode));
+            strcpy(rPtr->errorCode, errorCode);
+        }
+        if (errorInfo != NULL) {
+            rPtr->errorInfo = Tcl_Alloc(1 + strlen(errorInfo));
+            strcpy(rPtr->errorInfo, errorInfo);
+        }
+    }
+    
+    result = (char*)Tcl_GetStringResult(interp);
+    reslen = strlen(result);
+    
+    if (reslen == 0) {
+        rPtr->result = threadEmptyResult;
+    } else {
+        rPtr->result = strcpy(Tcl_Alloc(1 + reslen), result);
+    }
+
+    return ret;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetResult
+ *
+ *  Sets the result in current interpreter.
+ *
+ * Results:
+ *  Standard Tcl result, 
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+SetResult(interp, rPtr)
+    Tcl_Interp *interp;
+    TpoolResult *rPtr;
+{
+    if (rPtr->result) {
+        if (rPtr->result == threadEmptyResult) {
+            if (interp) {
+                Tcl_ResetResult(interp);
+            }
+        } else {
+            if (interp) {
+                Tcl_SetObjResult(interp, Tcl_NewStringObj(rPtr->result,-1));
+            }
+            Tcl_Free(rPtr->result);
+            rPtr->result = NULL;
+        }
+    }
+    if (rPtr->retcode == TCL_ERROR) {
+        if (rPtr->errorCode) {
+            if (interp) {
+                Tcl_SetObjErrorCode(interp,Tcl_NewStringObj(rPtr->errorCode,-1));
+            }
+            Tcl_Free(rPtr->errorCode);
+            rPtr->errorCode = NULL;
+        }
+        if (rPtr->errorInfo) {
+            if (interp) {
+                Tcl_AddObjErrorInfo(interp, rPtr->errorInfo, -1);
+            }
+            Tcl_Free(rPtr->errorInfo);
+            rPtr->errorInfo = NULL;
+        }
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolReserve --
+ *
+ *  Does the pool preserve and/or release. Assumes caller holds 
+ *  the listMutex.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  May tear-down the threadpool if refcount drops to 0 or below.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+TpoolReserve(tpoolPtr)
+    ThreadPool *tpoolPtr;
+{
+    return ++tpoolPtr->refCount;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolRelease --
+ *
+ *  Does the pool preserve and/or release. Assumes caller holds 
+ *  the listMutex.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  May tear-down the threadpool if refcount drops to 0 or below.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+TpoolRelease(tpoolPtr)
+    ThreadPool *tpoolPtr;
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    TpoolResult *rPtr;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+
+    if (--tpoolPtr->refCount > 0) { 
+        return tpoolPtr->refCount;
+    }
+
+    /*
+     * Pool is going away; remove from the list of pools,
+     */ 
+    
+    SpliceOut(tpoolPtr, tpoolList);
+    InitWaiter();
+    
+    /*
+     * Signal and wait for all workers to die.
+     */
+    
+    tpoolPtr->tearDown = 1;
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    while (tpoolPtr->numWorkers > 0) {
+        PushWaiter(tpoolPtr);
+        Tcl_ConditionNotify(&tpoolPtr->cond);
+        Tcl_MutexUnlock(&tpoolPtr->mutex);
+        tsdPtr->stop = -1;
+        while(tsdPtr->stop == -1) {
+            Tcl_DoOneEvent(TCL_ALL_EVENTS);
+        }
+        Tcl_MutexLock(&tpoolPtr->mutex);
+    }
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+    
+    /*
+     * Tear down the pool structure
+     */
+    
+    if (tpoolPtr->initScript) {
+        Tcl_Free(tpoolPtr->initScript);
+    }
+    if (tpoolPtr->exitScript) {
+        Tcl_Free(tpoolPtr->exitScript);
+    }
+
+    /*
+     * Cleanup completed but not collected jobs
+     */
+
+    hPtr = Tcl_FirstHashEntry(&tpoolPtr->jobsDone, &search);
+    while (hPtr != NULL) {
+        rPtr = (TpoolResult*)Tcl_GetHashValue(hPtr);
+        if (rPtr->result && rPtr->result != threadEmptyResult) {
+            Tcl_Free(rPtr->result);
+        }
+        if (rPtr->retcode == TCL_ERROR) {
+            if (rPtr->errorInfo) {
+                Tcl_Free(rPtr->errorInfo);
+            }
+            if (rPtr->errorCode) {
+                Tcl_Free(rPtr->errorCode);
+            }
+        }
+        Tcl_Free((char*)rPtr);
+        Tcl_DeleteHashEntry(hPtr);
+        hPtr = Tcl_NextHashEntry(&search);
+    }
+    Tcl_DeleteHashTable(&tpoolPtr->jobsDone);
+
+    /*
+     * Cleanup jobs posted but never completed.
+     */
+
+    for (rPtr = tpoolPtr->workHead; rPtr; rPtr = rPtr->nextPtr) {
+        Tcl_Free(rPtr->script);
+        Tcl_Free((char*)rPtr);
+    }
+    Tcl_MutexFinalize(&tpoolPtr->mutex);
+    Tcl_ConditionFinalize(&tpoolPtr->cond);
+    Tcl_Free((char*)tpoolPtr);
+
+    return 0;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolSuspend --
+ *
+ *  Marks the pool as suspended. This prevents pool workers to drain
+ *  the pool work queue. 
+ *
+ * Results:
+ *  Value of the suspend flag (1 always).
+ *
+ * Side effects:
+ *  During the suspended state, pool worker threads wlll not timeout
+ *  even if the worker inactivity timer has been configured. 
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+TpoolSuspend(tpoolPtr)
+    ThreadPool *tpoolPtr;
+{
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    tpoolPtr->suspend = 1;
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TpoolResume --
+ *
+ *  Clears the pool suspended state. This allows pool workers to drain
+ *  the pool work queue again. 
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  Pool workers may be started or awaken.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+TpoolResume(tpoolPtr)
+    ThreadPool *tpoolPtr;
+{
+    Tcl_MutexLock(&tpoolPtr->mutex);
+    tpoolPtr->suspend = 0;
+    Tcl_ConditionNotify(&tpoolPtr->cond);
+    Tcl_MutexUnlock(&tpoolPtr->mutex);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SignalWaiter --
+ *
+ *  Signals the waiter thread.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  The waiter thread will exit from the event loop.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+SignalWaiter(tpoolPtr)
+    ThreadPool *tpoolPtr;
+{
+    TpoolWaiter *waitPtr;
+    Tcl_Event *evPtr;
+
+    waitPtr = PopWaiter(tpoolPtr);
+    if (waitPtr == NULL) {
+        return;
+    }
+
+    evPtr = (Tcl_Event*)Tcl_Alloc(sizeof(Tcl_Event));
+    evPtr->proc = RunStopEvent;
+
+    Tcl_ThreadQueueEvent(waitPtr->threadId,(Tcl_Event*)evPtr,TCL_QUEUE_TAIL);
+    Tcl_ThreadAlert(waitPtr->threadId);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitWaiter --
+ *
+ *  Setup poster thread to be able to wait in the event loop.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+InitWaiter ()
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->waitPtr == NULL) {
+        tsdPtr->waitPtr = (TpoolWaiter*)Tcl_Alloc(sizeof(TpoolWaiter));
+        tsdPtr->waitPtr->prevPtr  = NULL;
+        tsdPtr->waitPtr->nextPtr  = NULL;
+        tsdPtr->waitPtr->threadId = Tcl_GetCurrentThread();
+        Tcl_CreateThreadExitHandler(ThrExitHandler, (ClientData)tsdPtr);
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThrExitHandler --
+ *
+ *  Performs cleanup when a caller (poster) thread exits.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+ThrExitHandler(clientData)
+    ClientData clientData;
+{
+    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)clientData;
+
+    Tcl_Free((char*)tsdPtr->waitPtr);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * AppExitHandler 
+ *
+ *  Deletes all threadpools on application exit.
+ *
+ * Results:
+ *  None. 
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+AppExitHandler(clientData)
+    ClientData clientData;
+{
+    ThreadPool *tpoolPtr;
+
+    Tcl_MutexLock(&listMutex);
+    /*
+     * Restart with head of list each time until empty. [Bug 1427570]
+     */
+    for (tpoolPtr = tpoolList; tpoolPtr; tpoolPtr = tpoolList) {
+        TpoolRelease(tpoolPtr);
+    }
+    Tcl_MutexUnlock(&listMutex);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tpool_Init --
+ *
+ *  Create commands in current interpreter.
+ *
+ * Results:
+ *  None.
+ *
+ * Side effects:
+ *  On first load, creates application exit handler to clean up
+ *  any threadpools left.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int 
+Tpool_Init (interp)
+    Tcl_Interp *interp;                 /* Interp where to create cmds */
+{
+    static int initialized;
+
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"create",   TpoolCreateObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"names",    TpoolNamesObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"post",     TpoolPostObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"wait",     TpoolWaitObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"cancel",   TpoolCancelObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"get",      TpoolGetObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"preserve", TpoolReserveObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"release",  TpoolReleaseObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"suspend",  TpoolSuspendObjCmd);
+    TCL_CMD(interp, TPOOL_CMD_PREFIX"resume",   TpoolResumeObjCmd);
+
+    if (initialized == 0) {
+        Tcl_MutexLock(&listMutex);
+        if (initialized == 0) {
+            Tcl_CreateExitHandler(AppExitHandler, (ClientData)-1);
+            initialized = 1;
+        }
+        Tcl_MutexUnlock(&listMutex);
+    }
+    return TCL_OK;
+}
+
+/* EOF $RCSfile: threadPoolCmd.c,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
diff --git a/8.x/thread/generic/threadSpCmd.c b/8.x/thread/generic/threadSpCmd.c
new file mode 100644 (file)
index 0000000..0681379
--- /dev/null
@@ -0,0 +1,1930 @@
+/* 
+ * threadSpCmd.c --
+ *
+ * This file implements commands for script-level access to thread 
+ * synchronization primitives. Currently, the exclusive mutex, the
+ * recursive mutex. the reader/writer mutex and condition variable 
+ * objects are exposed to the script programmer.
+ *
+ * Additionaly, a locked eval is also implemented. This is a practical
+ * convenience function which relieves the programmer from the need
+ * to take care about unlocking some mutex after evaluating a protected
+ * part of code. The locked eval is recursive-savvy since it used the
+ * recursive mutex for internal locking. 
+ *
+ * The Tcl interface to the locking and synchronization primitives 
+ * attempts to catch some very common problems in thread programming
+ * like attempting to lock an exclusive mutex twice from the same
+ * thread (deadlock), waiting on the condition variable without 
+ * locking the mutex, destroying primitives while being used, etc...
+ * This all comes with some additional internal locking costs but
+ * the benefits outweight the costs, especially considering overall
+ * performance (or lack of it) of an interpreted laguage like Tcl is.
+ *
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: threadSpCmd.c,v 1.33 2010/05/26 20:10:10 andreas_kupries Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#include "tclThread.h"
+#include "threadSpCmd.h"
+
+/*
+ * Types of synchronization variables we support.
+ */
+
+#define EMUTEXID  'm' /* First letter of the exclusive mutex name */
+#define RMUTEXID  'r' /* First letter of the recursive mutex name */
+#define WMUTEXID  'w' /* First letter of the read/write mutex name */
+#define CONDVID   'c' /* First letter of the condition variable name */
+
+#define SP_MUTEX   1  /* Any kind of mutex */
+#define SP_CONDV   2  /* The condition variable sync type */
+
+/*
+ * Handle hiding of errorLine in 8.6
+ */
+#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
+#define ERRORLINE(interp) ((interp)->errorLine)
+#else
+#define ERRORLINE(interp) (Tcl_GetErrorLine(interp))
+#endif
+
+/* 
+ * Structure representing one sync primitive (mutex, condition variable). 
+ * We use buckets to manage Tcl names of sync primitives. Each bucket
+ * is associated with a mutex. Each time we process the Tcl name of an
+ * sync primitive, we compute it's (trivial) hash and use this hash to
+ * address one of pre-allocated buckets.
+ * The bucket internally utilzes a hash-table to store item pointers.
+ * Item pointers are identified by a simple xid1, xid2... counting
+ * handle. This format is chosen to simplify distribution of handles
+ * across buckets (natural distribution vs. hash-one as in shared vars).
+ */
+
+typedef struct _SpItem {
+    int refcnt;            /* Number of threads operating on the item */
+    SpBucket *bucket;      /* Bucket where this item is stored */
+    Tcl_HashEntry *hentry; /* Hash table entry where this item is stored */
+} SpItem;
+
+/*
+ * Structure representing a mutex.
+ */
+
+typedef struct _SpMutex {
+    int refcnt;            /* Number of threads operating on the mutex */
+    SpBucket *bucket;      /* Bucket where mutex is stored */
+    Tcl_HashEntry *hentry; /* Hash table entry where mutex is stored */
+    /* --- */
+    char type;             /* Type of the mutex */
+    Sp_AnyMutex *lock;     /* Exclusive, recursive or read/write mutex */
+} SpMutex;
+
+/*
+ * Structure representing a condition variable. 
+ */
+
+typedef struct _SpCondv {
+    int refcnt;            /* Number of threads operating on the variable */
+    SpBucket *bucket;      /* Bucket where this variable is stored */
+    Tcl_HashEntry *hentry; /* Hash table entry where variable is stored */
+    /* --- */
+    SpMutex *mutex;        /* Set when waiting on the variable  */
+    Tcl_Condition cond;    /* The condition variable itself */
+} SpCondv;
+
+/*
+ * This global data is used to map opaque Tcl-level names 
+ * to pointers of their corresponding synchronization objects.
+ */
+
+static int        initOnce;    /* Flag for initializing tables below */
+static Tcl_Mutex  initMutex;   /* Controls initialization of primitives */
+static SpBucket*  muxBuckets;  /* Maps mutex names/handles */
+static SpBucket*  varBuckets;  /* Maps condition variable names/handles */
+
+/*
+ * Functions implementing Tcl commands
+ */
+
+static Tcl_ObjCmdProc ThreadMutexObjCmd;
+static Tcl_ObjCmdProc ThreadRWMutexObjCmd;
+static Tcl_ObjCmdProc ThreadCondObjCmd;
+static Tcl_ObjCmdProc ThreadEvalObjCmd;
+
+/*
+ * Forward declaration of functions used only within this file
+ */
+
+static int       SpMutexLock       (SpMutex *);
+static int       SpMutexUnlock     (SpMutex *);
+static int       SpMutexFinalize   (SpMutex *);
+
+static int       SpCondvWait       (SpCondv *, SpMutex *, int);
+static void      SpCondvNotify     (SpCondv *);
+static int       SpCondvFinalize   (SpCondv *);
+
+static void      AddAnyItem        (int, const char *, int, SpItem *);
+static SpItem*   GetAnyItem        (int, const char *, int);
+static void      PutAnyItem        (SpItem *);
+static SpItem *  RemoveAnyItem     (int, const char*, int);
+
+static int       RemoveMutex       (const char *, int);
+static int       RemoveCondv       (const char *, int);
+
+static Tcl_Obj*  GetName           (int, void *);
+static SpBucket* GetBucket         (int, const char *, int);
+
+static int       AnyMutexIsLocked  (Sp_AnyMutex *mPtr, Tcl_ThreadId);
+
+/*
+ * Function-like macros for some frequently used calls
+ */
+
+#define AddMutex(a,b,c)  AddAnyItem(SP_MUTEX, (a), (b), (SpItem*)(c))
+#define GetMutex(a,b)    (SpMutex*)GetAnyItem(SP_MUTEX, (a), (b))
+#define PutMutex(a)      PutAnyItem((SpItem*)(a))
+
+#define AddCondv(a,b,c)  AddAnyItem(SP_CONDV, (a), (b), (SpItem*)(c))
+#define GetCondv(a,b)    (SpCondv*)GetAnyItem(SP_CONDV, (a), (b))
+#define PutCondv(a)      PutAnyItem((SpItem*)(a))
+
+#define IsExclusive(a)   ((a)->type == EMUTEXID)
+#define IsRecursive(a)   ((a)->type == RMUTEXID)
+#define IsReadWrite(a)   ((a)->type == WMUTEXID)
+
+/* 
+ * This macro produces a hash-value for table-lookups given a handle
+ * and its length. It is implemented as macro just for speed.
+ * It is actually a trivial thing because the handles are simple
+ * counting values with a small three-letter prefix.
+ */
+
+#define GetHash(a,b) (atoi((a)+((b) < 4 ? 0 : 3)) % NUMSPBUCKETS)
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadMutexObjCmd --
+ *
+ *    This procedure is invoked to process "thread::mutex" Tcl command.
+ *    See the user documentation for details on what it does.
+ *
+ * Results:
+ *    A standard Tcl result.
+ *
+ * Side effects:
+ *    See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadMutexObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;                   /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int opt, ret, nameLen;
+    const char *mutexName;
+    char type;
+    SpMutex *mutexPtr;
+
+    static const char *cmdOpts[] = {
+        "create", "destroy", "lock", "unlock", NULL
+    };
+    enum options {
+        m_CREATE, m_DESTROY, m_LOCK, m_UNLOCK
+    };
+    
+    /* 
+     * Syntax:
+     *
+     *     thread::mutex create ?-recursive?
+     *     thread::mutex destroy <mutexHandle>
+     *     thread::mutex lock <mutexHandle>
+     *     thread::mutex unlock <mutexHandle>
+     */
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
+        return TCL_ERROR;
+    }
+    ret = Tcl_GetIndexFromObj(interp, objv[1], cmdOpts, "option", 0, &opt);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     * Cover the "create" option first. It needs no existing handle.
+     */
+
+    if (opt == (int)m_CREATE) {
+        Tcl_Obj *nameObj;
+        const char *arg;
+        
+        /*
+         * Parse out which type of mutex to create
+         */
+
+        if (objc == 2) {
+            type = EMUTEXID;
+        } else if (objc > 3) {
+            Tcl_WrongNumArgs(interp, 2, objv, "?-recursive?");
+            return TCL_ERROR;
+        } else {
+            arg = Tcl_GetStringFromObj(objv[2], NULL);
+            if (OPT_CMP(arg, "-recursive")) {
+                type = RMUTEXID;
+            } else {
+                Tcl_WrongNumArgs(interp, 2, objv, "?-recursive?");
+                return TCL_ERROR;
+            }
+        }
+
+        /*
+         * Create the requested mutex
+         */
+
+        mutexPtr = (SpMutex*)Tcl_Alloc(sizeof(SpMutex));
+        mutexPtr->type   = type;
+        mutexPtr->bucket = NULL;
+        mutexPtr->hentry = NULL;
+        mutexPtr->lock   = NULL; /* Will be auto-initialized */
+
+        /*
+         * Generate Tcl name for this mutex
+         */
+
+        nameObj = GetName(mutexPtr->type, (void*)mutexPtr);
+        mutexName = Tcl_GetStringFromObj(nameObj, &nameLen);
+        AddMutex(mutexName, nameLen, mutexPtr);
+        Tcl_SetObjResult(interp, nameObj);
+        return TCL_OK;
+    }
+
+    /*
+     * All other options require a valid name.
+     */
+
+    if (objc != 3) {
+        Tcl_WrongNumArgs(interp, 2, objv, "mutexHandle");
+        return TCL_ERROR;
+    }
+
+    mutexName = Tcl_GetStringFromObj(objv[2], &nameLen);
+
+    /*
+     * Try mutex destroy
+     */
+
+    if (opt == (int)m_DESTROY) {
+        ret = RemoveMutex(mutexName, nameLen);
+        if (ret <= 0) {
+            if (ret == -1) {
+            notfound:
+                Tcl_AppendResult(interp, "no such mutex \"", mutexName,
+                                 "\"", NULL);
+                return TCL_ERROR;
+            } else {
+                Tcl_AppendResult(interp, "mutex is in use", NULL);
+                return TCL_ERROR;
+            }
+        }
+        return TCL_OK;
+    }
+
+    /*
+     * Try all other options
+     */
+
+    mutexPtr = GetMutex(mutexName, nameLen);
+    if (mutexPtr == NULL) {
+        goto notfound;
+    }
+    if (!IsExclusive(mutexPtr) && !IsRecursive(mutexPtr)) {
+        PutMutex(mutexPtr);
+        Tcl_AppendResult(interp, "wrong mutex type, must be either"
+                         " exclusive or recursive", NULL);
+        return TCL_ERROR;
+    }
+
+    switch ((enum options)opt) {
+    case m_LOCK:
+        if (!SpMutexLock(mutexPtr)) {
+            PutMutex(mutexPtr);
+            Tcl_AppendResult(interp, "locking the same exclusive mutex "
+                             "twice from the same thread", NULL);
+            return TCL_ERROR;
+        }
+        break;
+    case m_UNLOCK:
+        if (!SpMutexUnlock(mutexPtr)) {
+            PutMutex(mutexPtr);
+            Tcl_AppendResult(interp, "mutex is not locked", NULL);
+            return TCL_ERROR;
+        }
+        break;
+    default:
+        break;
+    }
+
+    PutMutex(mutexPtr);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadRwMutexObjCmd --
+ *
+ *    This procedure is invoked to process "thread::rwmutex" Tcl command.
+ *    See the user documentation for details on what it does.
+ *
+ * Results:
+ *    A standard Tcl result.
+ *
+ * Side effects:
+ *    See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadRWMutexObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;                   /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int opt, ret, nameLen;
+    const char *mutexName;
+    SpMutex *mutexPtr;
+    Sp_ReadWriteMutex *rwPtr;
+    Sp_AnyMutex **lockPtr;
+
+    static const char *cmdOpts[] = {
+        "create", "destroy", "rlock", "wlock", "unlock", NULL
+    };
+    enum options {
+        w_CREATE, w_DESTROY, w_RLOCK, w_WLOCK, w_UNLOCK
+    };
+    
+    /* 
+     * Syntax:
+     *
+     *     thread::rwmutex create
+     *     thread::rwmutex destroy <mutexHandle>
+     *     thread::rwmutex rlock <mutexHandle>
+     *     thread::rwmutex wlock <mutexHandle>
+     *     thread::rwmutex unlock <mutexHandle>
+     */
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
+        return TCL_ERROR;
+    }
+    ret = Tcl_GetIndexFromObj(interp, objv[1], cmdOpts, "option", 0, &opt);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     * Cover the "create" option first, since it needs no existing name.
+     */
+
+    if (opt == (int)w_CREATE) {
+        Tcl_Obj *nameObj;
+        if (objc > 2) {
+            Tcl_WrongNumArgs(interp, 1, objv, "create");
+            return TCL_ERROR;
+        }
+        mutexPtr = (SpMutex*)Tcl_Alloc(sizeof(SpMutex));
+        mutexPtr->type   = WMUTEXID;
+        mutexPtr->refcnt = 0;
+        mutexPtr->bucket = NULL;
+        mutexPtr->hentry = NULL;
+        mutexPtr->lock   = NULL; /* Will be auto-initialized */
+
+        nameObj = GetName(mutexPtr->type, (void*)mutexPtr);
+        mutexName = Tcl_GetStringFromObj(nameObj, &nameLen);
+        AddMutex(mutexName, nameLen, mutexPtr);
+        Tcl_SetObjResult(interp, nameObj);
+        return TCL_OK;
+    }
+
+    /*
+     * All other options require a valid name.
+     */
+
+    if (objc != 3) {
+        Tcl_WrongNumArgs(interp, 2, objv, "mutexHandle");
+        return TCL_ERROR;
+    }
+
+    mutexName = Tcl_GetStringFromObj(objv[2], &nameLen);
+
+    /*
+     * Try mutex destroy
+     */
+
+    if (opt == (int)w_DESTROY) {
+        ret = RemoveMutex(mutexName, nameLen);
+        if (ret <= 0) {
+            if (ret == -1) {
+            notfound:
+                Tcl_AppendResult(interp, "no such mutex \"", mutexName,
+                                 "\"", NULL);
+                return TCL_ERROR;
+            } else {
+                Tcl_AppendResult(interp, "mutex is in use", NULL);
+                return TCL_ERROR;
+            }
+        }
+        return TCL_OK;
+    }
+
+    /*
+     * Try all other options
+     */
+
+    mutexPtr = GetMutex(mutexName, nameLen);
+    if (mutexPtr == NULL) {
+        goto notfound;
+    }
+    if (!IsReadWrite(mutexPtr)) {
+        PutMutex(mutexPtr);
+        Tcl_AppendResult(interp, "wrong mutex type, must be readwrite", NULL);
+        return TCL_ERROR;
+    }
+
+    lockPtr = &mutexPtr->lock;
+    rwPtr = (Sp_ReadWriteMutex*) lockPtr;
+    
+    switch ((enum options)opt) {
+    case w_RLOCK:
+        if (!Sp_ReadWriteMutexRLock(rwPtr)) {
+            PutMutex(mutexPtr);
+            Tcl_AppendResult(interp, "read-locking already write-locked mutex ",
+                             "from the same thread", NULL);
+            return TCL_ERROR;
+        }
+        break;
+    case w_WLOCK:
+        if (!Sp_ReadWriteMutexWLock(rwPtr)) {
+            PutMutex(mutexPtr);
+            Tcl_AppendResult(interp, "write-locking the same read-write "
+                             "mutex twice from the same thread", NULL);
+            return TCL_ERROR;
+        }
+        break;
+    case w_UNLOCK:
+        if (!Sp_ReadWriteMutexUnlock(rwPtr)) {
+            PutMutex(mutexPtr);
+            Tcl_AppendResult(interp, "mutex is not locked", NULL);
+            return TCL_ERROR;
+        }
+        break;
+    default:
+        break;
+    }
+
+    PutMutex(mutexPtr);
+
+    return TCL_OK;
+}
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadCondObjCmd --
+ *
+ *    This procedure is invoked to process "thread::cond" Tcl command.
+ *    See the user documentation for details on what it does.
+ *
+ * Results:
+ *    A standard Tcl result.
+ *
+ * Side effects:
+ *    See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadCondObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;                   /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int opt, ret, nameLen, timeMsec = 0;
+    const char *condvName, *mutexName;
+    SpMutex *mutexPtr;
+    SpCondv *condvPtr;
+
+    static const char *cmdOpts[] = {
+        "create", "destroy", "notify", "wait", NULL
+    };
+    enum options {
+        c_CREATE, c_DESTROY, c_NOTIFY, c_WAIT
+    };
+
+    /* 
+     * Syntax:
+     *
+     *    thread::cond create
+     *    thread::cond destroy <condHandle>
+     *    thread::cond notify <condHandle>
+     *    thread::cond wait <condHandle> <mutexHandle> ?timeout?
+     */
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
+        return TCL_ERROR;
+    }
+    ret = Tcl_GetIndexFromObj(interp, objv[1], cmdOpts, "option", 0, &opt);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    /*
+     * Cover the "create" option since it needs no existing name.
+     */
+
+    if (opt == (int)c_CREATE) {
+        Tcl_Obj *nameObj;
+        if (objc > 2) {
+            Tcl_WrongNumArgs(interp, 1, objv, "create");
+            return TCL_ERROR;
+        }
+        condvPtr = (SpCondv*)Tcl_Alloc(sizeof(SpCondv));
+        condvPtr->refcnt = 0;
+        condvPtr->bucket = NULL;
+        condvPtr->hentry = NULL;
+        condvPtr->mutex  = NULL;
+        condvPtr->cond   = NULL; /* Will be auto-initialized */
+
+        nameObj = GetName(CONDVID, (void*)condvPtr);
+        condvName = Tcl_GetStringFromObj(nameObj, &nameLen);
+        AddCondv(condvName, nameLen, condvPtr);
+        Tcl_SetObjResult(interp, nameObj);
+        return TCL_OK;
+    }
+
+    /*
+     * All others require at least a valid handle. 
+     */
+
+    if (objc < 3) {
+        Tcl_WrongNumArgs(interp, 2, objv, "condHandle ?args?");
+        return TCL_ERROR;
+    }
+
+    condvName = Tcl_GetStringFromObj(objv[2], &nameLen);
+
+    /*
+     * Try variable destroy.
+     */
+
+    if (opt == (int)c_DESTROY) {
+        ret = RemoveCondv(condvName, nameLen);
+        if (ret <= 0) {
+            if (ret == -1) {
+            notfound:
+                Tcl_AppendResult(interp, "no such condition variable \"",
+                                 condvName, "\"", NULL);
+                return TCL_ERROR;
+            } else {
+                Tcl_AppendResult(interp, "condition variable is in use", NULL);
+                return TCL_ERROR;
+            }
+        }
+        return TCL_OK;
+    }
+
+    /*
+     * Try all other options
+     */
+
+    condvPtr = GetCondv(condvName, nameLen);
+    if (condvPtr == NULL) {
+        goto notfound;
+    }
+
+    switch ((enum options)opt) {
+    case c_WAIT:
+
+        /*
+         * May improve the Tcl_ConditionWait() to report timeouts so we can
+         * inform script programmer about this interesting fact. I think 
+         * there is still a place for something like Tcl_ConditionWaitEx()
+         * or similar in the core.
+         */
+
+        if (objc < 4 || objc > 5) {
+            PutCondv(condvPtr);
+            Tcl_WrongNumArgs(interp, 2, objv, "condHandle mutexHandle ?timeout?");
+            return TCL_ERROR;
+        }
+        if (objc == 5) {
+            if (Tcl_GetIntFromObj(interp, objv[4], &timeMsec) != TCL_OK) {
+                PutCondv(condvPtr);
+                return TCL_ERROR;
+            }
+        }
+        mutexName = Tcl_GetStringFromObj(objv[3], &nameLen);
+        mutexPtr  = GetMutex(mutexName, nameLen);
+        if (mutexPtr == NULL) {
+            PutCondv(condvPtr);
+            Tcl_AppendResult(interp, "no such mutex \"",mutexName,"\"", NULL);
+            return TCL_ERROR;
+        }
+        if (!IsExclusive(mutexPtr)  
+            || SpCondvWait(condvPtr, mutexPtr, timeMsec) == 0) {
+            PutCondv(condvPtr);
+            PutMutex(mutexPtr);
+            Tcl_AppendResult(interp, "mutex not locked or wrong type", NULL);
+            return TCL_ERROR;
+        }
+        PutMutex(mutexPtr);
+        break;
+    case c_NOTIFY:
+        SpCondvNotify(condvPtr);
+        break;
+    default:
+        break;
+    }
+
+    PutCondv(condvPtr);
+
+    return TCL_OK;
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadEvalObjCmd --
+ *
+ *    This procedure is invoked to process "thread::eval" Tcl command.
+ *    See the user documentation for details on what it does.
+ *
+ * Results:
+ *    A standard Tcl result.
+ *
+ * Side effects:
+ *    See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ThreadEvalObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;                   /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int ret, optx, internal, nameLen;
+    const char *mutexName;
+    Tcl_Obj *scriptObj;
+    SpMutex *mutexPtr = NULL;
+    static Sp_RecursiveMutex evalMutex;
+
+    /* 
+     * Syntax:
+     *
+     *     thread::eval ?-lock <mutexHandle>? arg ?arg ...?
+     */
+
+    if (objc < 2) {
+      syntax:
+        Tcl_AppendResult(interp, "wrong # args: should be \"",
+                         Tcl_GetString(objv[0]),
+                         " ?-lock <mutexHandle>? arg ?arg...?\"", NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     * Find out wether to use the internal (recursive) mutex
+     * or external mutex given on the command line, and lock
+     * the corresponding mutex immediately.
+     * 
+     * We are using recursive internal mutex so we can easily
+     * support the recursion w/o danger of deadlocking. If 
+     * however, user gives us an exclusive mutex, we will 
+     * throw error on attempt to recursively call us.
+     */
+
+    if (OPT_CMP(Tcl_GetString(objv[1]), "-lock") == 0) {
+        internal = 1;
+        optx = 1;
+        Sp_RecursiveMutexLock(&evalMutex);
+    } else {
+        internal = 0;
+        optx = 3;
+        if ((objc - optx) < 1) {
+            goto syntax;
+        }
+        mutexName = Tcl_GetStringFromObj(objv[2], &nameLen);
+        mutexPtr  = GetMutex(mutexName, nameLen);
+        if (mutexPtr == NULL) {
+            Tcl_AppendResult(interp, "no such mutex \"",mutexName,"\"", NULL);
+            return TCL_ERROR;
+        }
+        if (IsReadWrite(mutexPtr)) {
+            Tcl_AppendResult(interp, "wrong mutex type, must be exclusive "
+                             "or recursive", NULL);
+            return TCL_ERROR;
+        }
+        if (!SpMutexLock(mutexPtr)) {
+            Tcl_AppendResult(interp, "locking the same exclusive mutex "
+                             "twice from the same thread", NULL);
+            return TCL_ERROR;
+        }
+    }
+
+    objc -= optx;
+
+    /*
+     * Evaluate passed arguments as Tcl script. Note that
+     * Tcl_EvalObjEx throws away the passed object by 
+     * doing an decrement reference count on it. This also
+     * means we need not build object bytecode rep.
+     */
+    
+    if (objc == 1) {
+        scriptObj = Tcl_DuplicateObj(objv[optx]);
+    } else {
+        scriptObj = Tcl_ConcatObj(objc, objv + optx);
+    }
+
+    Tcl_IncrRefCount(scriptObj);
+    ret = Tcl_EvalObjEx(interp, scriptObj, TCL_EVAL_DIRECT);
+    Tcl_DecrRefCount(scriptObj);
+
+    if (ret == TCL_ERROR) {
+        char msg[32 + TCL_INTEGER_SPACE];
+        sprintf(msg, "\n    (\"eval\" body line %d)", ERRORLINE(interp));
+        Tcl_AddObjErrorInfo(interp, msg, -1);
+    }
+
+    /*
+     * Unlock the mutex.
+     */
+
+    if (internal) {
+        Sp_RecursiveMutexUnlock(&evalMutex);
+    } else {
+        SpMutexUnlock(mutexPtr);
+    }
+
+    return ret;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetName --
+ *
+ *      Construct a Tcl name for the given sync primitive.
+ *      The name is in the simple counted form: XidN
+ *      where "X" designates the type of the primitive
+ *      and "N" is a increasing integer.
+ *
+ * Results:
+ *      Tcl string object with the constructed name.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj*
+GetName(int type, void *addrPtr)
+{
+    char name[32];
+    unsigned int id;
+    static unsigned int idcounter;
+
+    Tcl_MutexLock(&initMutex);
+    id = idcounter++;
+    Tcl_MutexUnlock(&initMutex);
+        
+    sprintf(name, "%cid%d", type, id);
+
+    return Tcl_NewStringObj(name, -1);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetBucket --
+ *
+ *      Returns the bucket for the given name.
+ *
+ * Results:
+ *      Pointer to the bucket.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static SpBucket*
+GetBucket(int type, const char *name, int len)
+{
+    switch (type) {
+    case SP_MUTEX: return &muxBuckets[GetHash(name, len)];
+    case SP_CONDV: return &varBuckets[GetHash(name, len)];
+    }
+
+    return NULL; /* Never reached */
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetAnyItem --
+ *
+ *      Retrieves the item structure from it's corresponding bucket.
+ *
+ * Results:
+ *      Item pointer or NULL
+ *
+ * Side effects:
+ *      Increment the item's ref count preventing it's deletion.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static SpItem*
+GetAnyItem(int type, const char *name, int len)
+{
+    SpItem *itemPtr = NULL;
+    SpBucket *bucketPtr = GetBucket(type, name, len);
+    Tcl_HashEntry *hashEntryPtr = NULL;
+
+    Tcl_MutexLock(&bucketPtr->lock);
+    hashEntryPtr = Tcl_FindHashEntry(&bucketPtr->handles, name);
+    if (hashEntryPtr != (Tcl_HashEntry*)NULL) {
+        itemPtr = (SpItem*)Tcl_GetHashValue(hashEntryPtr);
+        itemPtr->refcnt++;
+    }
+    Tcl_MutexUnlock(&bucketPtr->lock);
+
+    return itemPtr;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * PutAnyItem --
+ *
+ *      Current thread detaches from the item.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Decrement item's ref count allowing for it's deletion
+ *      and signalize any threads waiting to delete the item.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PutAnyItem(SpItem *itemPtr)
+{
+    Tcl_MutexLock(&itemPtr->bucket->lock);
+    itemPtr->refcnt--;
+    Tcl_ConditionNotify(&itemPtr->bucket->cond);
+    Tcl_MutexUnlock(&itemPtr->bucket->lock);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * AddAnyItem --
+ *
+ *      Puts any item in the corresponding bucket.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AddAnyItem(int type, const char *handle, int len, SpItem *itemPtr)
+{
+    int new;
+    SpBucket *bucketPtr = GetBucket(type, handle, len);
+    Tcl_HashEntry *hashEntryPtr;
+
+    Tcl_MutexLock(&bucketPtr->lock);
+
+    hashEntryPtr = Tcl_CreateHashEntry(&bucketPtr->handles, handle, &new);
+    Tcl_SetHashValue(hashEntryPtr, (ClientData)itemPtr);
+
+    itemPtr->refcnt = 0;
+    itemPtr->bucket = bucketPtr;
+    itemPtr->hentry = hashEntryPtr;
+
+    Tcl_MutexUnlock(&bucketPtr->lock);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * RemoveAnyItem --
+ *
+ *      Removes the item from it's bucket.
+ *
+ * Results:
+ *      Item's pointer or NULL if none found.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static SpItem *
+RemoveAnyItem(int type, const char *name, int len)
+{
+    SpItem *itemPtr = NULL;
+    SpBucket *bucketPtr = GetBucket(type, name, len);
+    Tcl_HashEntry *hashEntryPtr = NULL;
+
+    Tcl_MutexLock(&bucketPtr->lock);
+    hashEntryPtr = Tcl_FindHashEntry(&bucketPtr->handles, name);
+    if (hashEntryPtr == (Tcl_HashEntry*)NULL) {
+        Tcl_MutexUnlock(&bucketPtr->lock);
+        return NULL;
+    }
+    itemPtr = (SpItem*)Tcl_GetHashValue(hashEntryPtr);
+    Tcl_DeleteHashEntry(hashEntryPtr);
+    while (itemPtr->refcnt > 0) {
+        Tcl_ConditionWait(&bucketPtr->cond, &bucketPtr->lock, NULL);
+    }
+    Tcl_MutexUnlock(&bucketPtr->lock);
+
+    return itemPtr;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * RemoveMutex --
+ *
+ *      Removes the mutex from it's bucket and finalizes it.
+ *
+ * Results:
+ *      1 - mutex is finalized and removed
+ *      0 - mutex is not finalized
+ +     -1 - mutex is not found
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+RemoveMutex(const char *name, int len)
+{
+    SpMutex *mutexPtr = GetMutex(name, len);
+    if (mutexPtr == NULL) {
+        return -1;
+    }
+    if (!SpMutexFinalize(mutexPtr)) {
+        PutMutex(mutexPtr);
+        return 0;
+    }
+    PutMutex(mutexPtr);
+    RemoveAnyItem(SP_MUTEX, name, len);
+    Tcl_Free((char*)mutexPtr);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * RemoveCondv --
+ *
+ *      Removes the cond variable from it's bucket and finalizes it.
+ *
+ * Results:
+ *      1 - variable is finalized and removed
+ *      0 - variable is not finalized
+ +     -1 - variable is not found
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+RemoveCondv(const char *name, int len)
+{
+    SpCondv *condvPtr = GetCondv(name, len);
+    if (condvPtr == NULL) {
+        return -1;
+    }
+    if (!SpCondvFinalize(condvPtr)) {
+        PutCondv(condvPtr);
+        return 0;
+    }
+    PutCondv(condvPtr);
+    RemoveAnyItem(SP_CONDV, name, len);
+    Tcl_Free((char*)condvPtr);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_Init --
+ *
+ *      Create commands in current interpreter.
+ *
+ * Results:
+ *      Standard Tcl result.
+ *
+ * Side effects:
+ *      Initializes shared hash table for storing sync primitive 
+ *      handles and pointers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_Init (interp)
+    Tcl_Interp *interp;                 /* Interp where to create cmds */
+{
+    SpBucket *bucketPtr;
+
+    if (!initOnce) {
+        Tcl_MutexLock(&initMutex);
+        if (!initOnce) {
+            int ii, buflen = sizeof(SpBucket) * (NUMSPBUCKETS);
+            char *buf  = Tcl_Alloc(2 * buflen);
+            muxBuckets = (SpBucket*)(buf);
+            varBuckets = (SpBucket*)(buf + buflen);
+            for (ii = 0; ii < 2 * (NUMSPBUCKETS); ii++) {
+                bucketPtr = &muxBuckets[ii];
+                memset(bucketPtr, 0, sizeof(SpBucket));
+                Tcl_InitHashTable(&bucketPtr->handles, TCL_STRING_KEYS);
+            }
+            initOnce = 1;
+        }
+        Tcl_MutexUnlock(&initMutex);
+    }
+
+    TCL_CMD(interp, THREAD_CMD_PREFIX"::mutex",   ThreadMutexObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"::rwmutex", ThreadRWMutexObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"::cond",    ThreadCondObjCmd);
+    TCL_CMD(interp, THREAD_CMD_PREFIX"::eval",    ThreadEvalObjCmd);
+
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SpMutexLock --
+ *
+ *      Locks the typed mutex.
+ *
+ * Results:
+ *      1 - mutex is locked
+ *      0 - mutex is not locked (pending deadlock?)
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int 
+SpMutexLock(SpMutex *mutexPtr)
+{
+    Sp_AnyMutex **lockPtr = &mutexPtr->lock;
+
+    switch (mutexPtr->type) {
+    case EMUTEXID:
+        return Sp_ExclusiveMutexLock((Sp_ExclusiveMutex*)lockPtr);
+        break;
+    case RMUTEXID: 
+        return Sp_RecursiveMutexLock((Sp_RecursiveMutex*)lockPtr);
+        break;
+    }
+
+    return 0;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SpMutexUnlock --
+ *
+ *      Unlocks the typed mutex.
+ *
+ * Results:
+ *      1 - mutex is unlocked
+ *      0 - mutex was not locked
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SpMutexUnlock(SpMutex *mutexPtr)
+{
+    Sp_AnyMutex **lockPtr = &mutexPtr->lock;
+
+    switch (mutexPtr->type) {
+    case EMUTEXID:
+        return Sp_ExclusiveMutexUnlock((Sp_ExclusiveMutex*)lockPtr);
+        break;
+    case RMUTEXID:
+        return Sp_RecursiveMutexUnlock((Sp_RecursiveMutex*)lockPtr);
+        break;
+    }
+
+    return 0;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SpMutexFinalize --
+ *
+ *      Finalizes the typed mutex. This should never be called without
+ *      some external mutex protection.
+ *
+ * Results:
+ *      1 - mutex is finalized
+ *      0 - mutex is still in use
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SpMutexFinalize(SpMutex *mutexPtr)
+{
+    Sp_AnyMutex **lockPtr = &mutexPtr->lock;
+
+    if (AnyMutexIsLocked((Sp_AnyMutex*)mutexPtr->lock, (Tcl_ThreadId)0)) {
+        return 0;
+    }
+    
+    /*
+     * At this point, the mutex could be locked again, hence it
+     * is important never to call this function unprotected.
+     */
+
+    switch (mutexPtr->type) {
+    case EMUTEXID:
+        Sp_ExclusiveMutexFinalize((Sp_ExclusiveMutex*)lockPtr);
+        break;
+    case RMUTEXID:
+        Sp_RecursiveMutexFinalize((Sp_RecursiveMutex*)lockPtr);
+        break;
+    case WMUTEXID:
+        Sp_ReadWriteMutexFinalize((Sp_ReadWriteMutex*)lockPtr);
+        break;
+    default:
+        break;
+    }
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SpCondvWait --
+ *
+ *      Waits on the condition variable.
+ *
+ * Results:
+ *      1 - wait ok
+ *      0 - not waited as mutex is not locked in the same thread
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SpCondvWait(SpCondv *condvPtr, SpMutex *mutexPtr, int msec)
+{
+       Sp_AnyMutex **lock = &mutexPtr->lock;
+    Sp_ExclusiveMutex_ *emPtr = *(Sp_ExclusiveMutex_**)lock;
+    Tcl_Time waitTime, *wt = NULL;
+    Tcl_ThreadId threadId = Tcl_GetCurrentThread();
+
+    if (msec > 0) {
+        wt = &waitTime;
+        wt->sec  = (msec/1000);
+        wt->usec = (msec%1000) * 1000;
+    }
+    if (!AnyMutexIsLocked((Sp_AnyMutex*)mutexPtr->lock, threadId)) {
+        return 0; /* Mutex not locked by the current thread */
+    }
+
+    /*
+     * It is safe to operate on mutex struct because caller
+     * is holding the emPtr->mutex locked before we enter
+     * the Tcl_ConditionWait and after we return out of it.
+     */
+
+    condvPtr->mutex = mutexPtr;
+
+    emPtr->owner = (Tcl_ThreadId)0;
+    emPtr->lockcount = 0;
+
+    Tcl_ConditionWait(&condvPtr->cond, &emPtr->mutex, wt);
+
+    emPtr->owner = threadId;
+    emPtr->lockcount = 1;
+
+    condvPtr->mutex = NULL;
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SpCondvNotify --
+ *
+ *      Signalizes the condition variable.
+ *
+ * Results:
+ *      None. 
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void 
+SpCondvNotify(SpCondv *condvPtr)
+{
+    if (condvPtr->cond) {
+        Tcl_ConditionNotify(&condvPtr->cond);
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SpCondvFinalize --
+ *
+ *      Finalizes the condition variable.
+ *
+ * Results:
+ *      1 - variable is finalized
+ *      0 - variable is in use
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int 
+SpCondvFinalize(SpCondv *condvPtr)
+{
+    if (condvPtr->mutex != NULL) {
+        return 0; /* Somebody is waiting on the variable */
+    }
+
+    if (condvPtr->cond) {
+        Tcl_ConditionFinalize(&condvPtr->cond);
+    }
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ExclusiveMutexLock --
+ *
+ *      Locks the exclusive mutex.
+ *
+ * Results:
+ *      1 - mutex is locked
+ *      0 - mutex is not locked; same thread tries to locks twice
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_ExclusiveMutexLock(Sp_ExclusiveMutex *muxPtr)
+{
+    Sp_ExclusiveMutex_ *emPtr;
+    Tcl_ThreadId thisThread = Tcl_GetCurrentThread();
+
+    /*
+     * Allocate the mutex structure on first access
+     */
+
+    if (*muxPtr == (Sp_ExclusiveMutex_*)0) {
+        Tcl_MutexLock(&initMutex);
+        if (*muxPtr == (Sp_ExclusiveMutex_*)0) {
+            *muxPtr = (Sp_ExclusiveMutex_*)
+                Tcl_Alloc(sizeof(Sp_ExclusiveMutex_));
+            memset(*muxPtr, 0, sizeof(Sp_ExclusiveMutex_));
+        }
+        Tcl_MutexUnlock(&initMutex);
+    }
+
+    /*
+     * Try locking if not currently locked by anybody.
+     */
+
+    emPtr = *(Sp_ExclusiveMutex_**)muxPtr;
+    Tcl_MutexLock(&emPtr->lock);
+    if (emPtr->lockcount && emPtr->owner == thisThread) {
+        Tcl_MutexUnlock(&emPtr->lock);
+        return 0; /* Already locked by the same thread */
+    }
+    Tcl_MutexUnlock(&emPtr->lock);
+
+    /*
+     * Many threads can come to this point.
+     * Only one will succeed locking the 
+     * mutex. Others will block...
+     */
+
+    Tcl_MutexLock(&emPtr->mutex);
+
+    Tcl_MutexLock(&emPtr->lock);
+    emPtr->owner = thisThread;
+    emPtr->lockcount = 1;
+    Tcl_MutexUnlock(&emPtr->lock);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ExclusiveMutexIsLocked --
+ *
+ *      Checks wether the mutex is locked or not.
+ *
+ * Results:
+ *      1 - mutex is locked
+ *      0 - mutex is not locked
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_ExclusiveMutexIsLocked(Sp_ExclusiveMutex *muxPtr)
+{
+    return AnyMutexIsLocked((Sp_AnyMutex*)*muxPtr, (Tcl_ThreadId)0);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ExclusiveMutexUnlock --
+ *
+ *      Unlock the exclusive mutex.
+ *
+ * Results:
+ *      1 - mutex is unlocked
+ ?      0 - mutex was never locked
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_ExclusiveMutexUnlock(Sp_ExclusiveMutex *muxPtr)
+{
+    Sp_ExclusiveMutex_ *emPtr;
+
+    if (*muxPtr == (Sp_ExclusiveMutex_*)0) {
+        return 0; /* Never locked before */
+    }
+
+    emPtr = *(Sp_ExclusiveMutex_**)muxPtr;
+
+    Tcl_MutexLock(&emPtr->lock);
+    if (emPtr->lockcount == 0) {
+        Tcl_MutexUnlock(&emPtr->lock);
+        return 0; /* Not locked */
+    }
+    emPtr->owner = (Tcl_ThreadId)0;
+    emPtr->lockcount = 0;
+    Tcl_MutexUnlock(&emPtr->lock);
+
+    /*
+     * Only one thread should be able
+     * to come to this point and unlock...
+     */
+
+    Tcl_MutexUnlock(&emPtr->mutex);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ExclusiveMutexFinalize --
+ *
+ *      Finalize the exclusive mutex. It is not safe for two or
+ *      more threads to finalize the mutex at the same time.
+ *
+ * Results:
+ *      None. 
+ *
+ * Side effects:
+ *      Mutex is destroyed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Sp_ExclusiveMutexFinalize(Sp_ExclusiveMutex *muxPtr)
+{
+    if (*muxPtr != (Sp_ExclusiveMutex_*)0) {
+        Sp_ExclusiveMutex_ *emPtr = *(Sp_ExclusiveMutex_**)muxPtr;
+        if (emPtr->lock) {
+            Tcl_MutexFinalize(&emPtr->lock);
+        }
+        if (emPtr->mutex) {
+            Tcl_MutexFinalize(&emPtr->mutex);
+        }
+        Tcl_Free((char*)*muxPtr);
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_RecursiveMutexLock --
+ *
+ *      Locks the recursive mutex.
+ *
+ * Results:
+ *      1 - mutex is locked (as it always should be)
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_RecursiveMutexLock(Sp_RecursiveMutex *muxPtr)
+{
+    Sp_RecursiveMutex_ *rmPtr;
+    Tcl_ThreadId thisThread = Tcl_GetCurrentThread();
+
+    /*
+     * Allocate the mutex structure on first access
+     */
+
+    if (*muxPtr == (Sp_RecursiveMutex_*)0) {
+        Tcl_MutexLock(&initMutex);
+        if (*muxPtr == (Sp_RecursiveMutex_*)0) {
+            *muxPtr = (Sp_RecursiveMutex_*)
+                Tcl_Alloc(sizeof(Sp_RecursiveMutex_));
+            memset(*muxPtr, 0, sizeof(Sp_RecursiveMutex_));
+        }
+        Tcl_MutexUnlock(&initMutex);
+    }
+
+    rmPtr = *(Sp_RecursiveMutex_**)muxPtr;
+    Tcl_MutexLock(&rmPtr->lock);
+    
+    if (rmPtr->owner == thisThread) {
+        /*
+         * We are already holding the mutex
+         * so just count one more lock.
+         */
+       rmPtr->lockcount++;
+    } else {
+       if (rmPtr->owner == (Tcl_ThreadId)0) {
+            /*
+             * Nobody holds the mutex, we do now.
+             */
+               rmPtr->owner = thisThread;
+               rmPtr->lockcount = 1;
+       } else {
+            /*
+             * Somebody else holds the mutex; wait.
+             */
+               while (1) {
+                Tcl_ConditionWait(&rmPtr->cond, &rmPtr->lock, NULL);
+                       if (rmPtr->owner == (Tcl_ThreadId)0) {
+                               rmPtr->owner = thisThread;
+                               rmPtr->lockcount = 1;
+                               break;
+                       }
+               }
+       }
+    }
+
+    Tcl_MutexUnlock(&rmPtr->lock);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_RecursiveMutexIsLocked --
+ *
+ *      Checks wether the mutex is locked or not.
+ *
+ * Results:
+ *      1 - mutex is locked
+ *      0 - mutex is not locked
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_RecursiveMutexIsLocked(Sp_RecursiveMutex *muxPtr)
+{
+    return AnyMutexIsLocked((Sp_AnyMutex*)*muxPtr, (Tcl_ThreadId)0);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_RecursiveMutexUnlock --
+ *
+ *      Unlock the recursive mutex.
+ *
+ * Results:
+ *      1 - mutex unlocked
+ *      0 - mutex never locked
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_RecursiveMutexUnlock(Sp_RecursiveMutex *muxPtr)
+{
+    Sp_RecursiveMutex_ *rmPtr;
+
+    if (*muxPtr == (Sp_RecursiveMutex_*)0) {
+        return 0; /* Never locked before */
+    }
+
+    rmPtr = *(Sp_RecursiveMutex_**)muxPtr;
+    Tcl_MutexLock(&rmPtr->lock);
+    if (rmPtr->lockcount == 0) {
+        Tcl_MutexUnlock(&rmPtr->lock);
+        return 0; /* Not locked now */
+    }
+    if (--rmPtr->lockcount <= 0) {
+        rmPtr->lockcount = 0;
+        rmPtr->owner = (Tcl_ThreadId)0;
+        if (rmPtr->cond) {
+            Tcl_ConditionNotify(&rmPtr->cond);
+        }
+    }
+    Tcl_MutexUnlock(&rmPtr->lock);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_RecursiveMutexFinalize --
+ *
+ *      Finalize the recursive mutex. It is not safe for two or
+ *      more threads to finalize the mutex at the same time.
+ *
+ * Results:
+ *      None. 
+ *
+ * Side effects:
+ *      Mutex is destroyed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Sp_RecursiveMutexFinalize(Sp_RecursiveMutex *muxPtr)
+{
+    if (*muxPtr != (Sp_RecursiveMutex_*)0) {
+        Sp_RecursiveMutex_ *rmPtr = *(Sp_RecursiveMutex_**)muxPtr;
+        if (rmPtr->lock) {
+            Tcl_MutexFinalize(&rmPtr->lock);
+        }
+        if (rmPtr->cond) {
+            Tcl_ConditionFinalize(&rmPtr->cond);
+        }
+        Tcl_Free((char*)*muxPtr);
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ReadWriteMutexRLock --
+ *
+ *      Read-locks the reader/writer mutex.
+ *
+ * Results:
+ *      1 - mutex is locked
+ *      0 - mutex is not locked as we already hold the write lock
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_ReadWriteMutexRLock(Sp_ReadWriteMutex *muxPtr)
+{
+    Sp_ReadWriteMutex_ *rwPtr;
+    Tcl_ThreadId thisThread = Tcl_GetCurrentThread();
+
+    /*
+     * Allocate the mutex structure on first access
+     */
+
+    if (*muxPtr == (Sp_ReadWriteMutex_*)0) {
+        Tcl_MutexLock(&initMutex);
+        if (*muxPtr == (Sp_ReadWriteMutex_*)0) {
+            *muxPtr = (Sp_ReadWriteMutex_*)
+                Tcl_Alloc(sizeof(Sp_ReadWriteMutex_));
+            memset(*muxPtr, 0, sizeof(Sp_ReadWriteMutex_));
+        }
+        Tcl_MutexUnlock(&initMutex);
+    }
+
+    rwPtr = *(Sp_ReadWriteMutex_**)muxPtr;
+    Tcl_MutexLock(&rwPtr->lock);
+    if (rwPtr->lockcount == -1 && rwPtr->owner == thisThread) {
+        Tcl_MutexUnlock(&rwPtr->lock);
+        return 0; /* We already hold the write lock */
+    }
+    while (rwPtr->lockcount < 0) {
+        rwPtr->numrd++;
+        Tcl_ConditionWait(&rwPtr->rcond, &rwPtr->lock, NULL);
+        rwPtr->numrd--;
+    }
+    rwPtr->lockcount++;
+    rwPtr->owner = (Tcl_ThreadId)0; /* Many threads can read-lock */
+    Tcl_MutexUnlock(&rwPtr->lock);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ReadWriteMutexWLock --
+ *
+ *      Write-locks the reader/writer mutex.
+ *
+ * Results:
+ *      1 - mutex is locked
+ *      0 - same thread attempts to write-lock the mutex twice
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_ReadWriteMutexWLock(Sp_ReadWriteMutex *muxPtr)
+{
+    Sp_ReadWriteMutex_ *rwPtr;
+    Tcl_ThreadId thisThread = Tcl_GetCurrentThread();
+
+    /*
+     * Allocate the mutex structure on first access
+     */
+
+    if (*muxPtr == (Sp_ReadWriteMutex_*)0) {
+        Tcl_MutexLock(&initMutex);
+        if (*muxPtr == (Sp_ReadWriteMutex_*)0) {
+            *muxPtr = (Sp_ReadWriteMutex_*)
+                Tcl_Alloc(sizeof(Sp_ReadWriteMutex_));
+            memset(*muxPtr, 0, sizeof(Sp_ReadWriteMutex_));
+        }
+        Tcl_MutexUnlock(&initMutex);
+    }
+
+    rwPtr = *(Sp_ReadWriteMutex_**)muxPtr;
+    Tcl_MutexLock(&rwPtr->lock);
+    if (rwPtr->owner == thisThread && rwPtr->lockcount == -1) {
+        Tcl_MutexUnlock(&rwPtr->lock);
+        return 0; /* The same thread attempts to write-lock again */
+    }
+    while (rwPtr->lockcount != 0) {
+        rwPtr->numwr++;
+        Tcl_ConditionWait(&rwPtr->wcond, &rwPtr->lock, NULL);
+        rwPtr->numwr--;
+    }
+    rwPtr->lockcount = -1;     /* This designates the sole writer */
+    rwPtr->owner = thisThread; /* which is our current thread     */
+    Tcl_MutexUnlock(&rwPtr->lock);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ReadWriteMutexIsLocked --
+ *
+ *      Checks wether the mutex is locked or not.
+ *
+ * Results:
+ *      1 - mutex is locked
+ *      0 - mutex is not locked
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_ReadWriteMutexIsLocked(Sp_ReadWriteMutex *muxPtr)
+{
+    return AnyMutexIsLocked((Sp_AnyMutex*)*muxPtr, (Tcl_ThreadId)0);
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ReadWriteMutexUnlock --
+ *
+ *      Unlock the reader/writer mutex.
+ *
+ * Results:
+ *      None. 
+ *
+ * Side effects:
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Sp_ReadWriteMutexUnlock(Sp_ReadWriteMutex *muxPtr)
+{
+    Sp_ReadWriteMutex_ *rwPtr;
+
+    if (*muxPtr == (Sp_ReadWriteMutex_*)0) {
+        return 0; /* Never locked before */
+    }
+    
+    rwPtr = *(Sp_ReadWriteMutex_**)muxPtr;
+    Tcl_MutexLock(&rwPtr->lock);
+    if (rwPtr->lockcount == 0) {
+        Tcl_MutexUnlock(&rwPtr->lock);
+        return 0; /* Not locked now */
+    }
+    if (--rwPtr->lockcount <= 0) {
+        rwPtr->lockcount = 0;
+        rwPtr->owner = (Tcl_ThreadId)0;
+    }
+    if (rwPtr->numwr) {
+        Tcl_ConditionNotify(&rwPtr->wcond);
+    } else if (rwPtr->numrd) {
+        Tcl_ConditionNotify(&rwPtr->rcond);
+    }
+
+    Tcl_MutexUnlock(&rwPtr->lock);
+
+    return 1;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * Sp_ReadWriteMutexFinalize --
+ *
+ *      Finalize the reader/writer mutex. It is not safe for two or
+ *      more threads to finalize the mutex at the same time.
+ *
+ * Results:
+ *      None. 
+ *
+ * Side effects:
+ *      Mutex is destroyed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Sp_ReadWriteMutexFinalize(Sp_ReadWriteMutex *muxPtr)
+{
+    if (*muxPtr != (Sp_ReadWriteMutex_*)0) {
+        Sp_ReadWriteMutex_ *rwPtr = *(Sp_ReadWriteMutex_**)muxPtr;
+        if (rwPtr->lock) {
+            Tcl_MutexFinalize(&rwPtr->lock);
+        }
+        if (rwPtr->rcond) {
+            Tcl_ConditionFinalize(&rwPtr->rcond);
+        }
+        if (rwPtr->wcond) {
+            Tcl_ConditionFinalize(&rwPtr->wcond);
+        }
+        Tcl_Free((char*)*muxPtr);
+    }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * AnyMutexIsLocked --
+ *
+ *      Checks wether the mutex is locked. If optional threadId
+ *      is given (i.e. != 0) it checks if the given thread also
+ *      holds the lock.
+ *
+ * Results:
+ *      1 - mutex is locked (optionally by the given thread)
+ *      0 - mutex is not locked (optionally by the given thread)
+ *
+ * Side effects:
+ *      None.  
+ *
+ *----------------------------------------------------------------------
+ */
+static int 
+AnyMutexIsLocked(Sp_AnyMutex *mPtr, Tcl_ThreadId threadId)
+{
+    int locked = 0;
+
+    if (mPtr != NULL) {
+        Tcl_MutexLock(&mPtr->lock);
+        locked = mPtr->lockcount != 0;
+        if (locked && threadId != (Tcl_ThreadId)0) {
+            locked = mPtr->owner == threadId;
+        }
+        Tcl_MutexUnlock(&mPtr->lock);
+    }
+
+    return locked;
+}
+
+
+/* EOF $RCSfile: threadSpCmd.c,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
diff --git a/8.x/thread/generic/threadSpCmd.h b/8.x/thread/generic/threadSpCmd.h
new file mode 100644 (file)
index 0000000..7e75b0d
--- /dev/null
@@ -0,0 +1,132 @@
+/* 
+ * This is the header file for the module that implements some missing
+ * synchronization priomitives from the Tcl API.
+ *
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.txt" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Rcsid: @(#)$Id: threadSpCmd.h,v 1.4 2008/05/22 16:19:40 vasiljevic Exp $
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _SP_H_
+#define _SP_H_
+
+#include <tcl.h>
+
+/*
+ * The following structure defines a locking bucket. A locking
+ * bucket is associated with a mutex and protects access to 
+ * objects stored in bucket hash table.
+ */
+
+typedef struct SpBucket {
+    Tcl_Mutex lock;            /* For locking the bucket */
+    Tcl_Condition cond;        /* For waiting on threads to release items */
+    Tcl_ThreadId lockt;        /* Thread holding the lock */
+    Tcl_HashTable handles;     /* Hash table of given-out handles in bucket */
+    struct Container *freeCt;  /* List of free Tcl-object containers */
+} SpBucket;
+
+#define NUMSPBUCKETS 32
+
+/*
+ * All types of mutexes share this common part.
+ */
+
+typedef struct Sp_AnyMutex_ {
+    int lockcount;              /* If !=0 mutex is locked */
+    int numlocks;               /* Number of times the mutex got locked */
+    Tcl_Mutex lock;             /* Regular mutex */
+    Tcl_ThreadId owner;         /* Current lock owner thread (-1 = any) */
+} Sp_AnyMutex;
+
+/*
+ * Implementation of the exclusive mutex.
+ */
+
+typedef struct Sp_ExclusiveMutex_ {
+    int lockcount;              /* Flag: 1-locked, 0-not locked */
+    int numlocks;               /* Number of times the mutex got locked */
+    Tcl_Mutex lock;             /* Regular mutex */
+    Tcl_ThreadId owner;         /* Current lock owner thread */
+    /* --- */
+    Tcl_Mutex mutex;            /* Mutex being locked */
+} Sp_ExclusiveMutex_;
+
+typedef Sp_ExclusiveMutex_* Sp_ExclusiveMutex;
+
+/*
+ * Implementation of the recursive mutex.
+ */
+
+typedef struct Sp_RecursiveMutex_ {
+    int lockcount;              /* # of times this mutex is locked */
+    int numlocks;               /* Number of time the mutex got locked */
+    Tcl_Mutex lock;             /* Regular mutex */
+    Tcl_ThreadId owner;         /* Current lock owner thread */
+    /* --- */
+    Tcl_Condition cond;         /* Wait to be allowed to lock the mutex */
+} Sp_RecursiveMutex_;
+
+typedef Sp_RecursiveMutex_* Sp_RecursiveMutex;
+
+/*
+ * Implementation of the read/writer mutex.
+ */
+
+typedef struct Sp_ReadWriteMutex_ {
+    int lockcount;              /* >0: # of readers, -1: sole writer */
+    int numlocks;               /* Number of time the mutex got locked */
+    Tcl_Mutex lock;             /* Regular mutex */
+    Tcl_ThreadId owner;         /* Current lock owner thread */
+    /* --- */
+    unsigned int numrd;                /* # of readers waiting for lock */
+    unsigned int numwr;         /* # of writers waiting for lock */
+    Tcl_Condition rcond;        /* Reader lockers wait here */
+    Tcl_Condition wcond;        /* Writer lockers wait here */
+} Sp_ReadWriteMutex_;
+
+typedef Sp_ReadWriteMutex_* Sp_ReadWriteMutex;
+
+
+/*
+ * API for exclusive mutexes.
+ */
+
+int  Sp_ExclusiveMutexLock(Sp_ExclusiveMutex *mutexPtr);
+int  Sp_ExclusiveMutexIsLocked(Sp_ExclusiveMutex *mutexPtr);
+int  Sp_ExclusiveMutexUnlock(Sp_ExclusiveMutex *mutexPtr);
+void Sp_ExclusiveMutexFinalize(Sp_ExclusiveMutex *mutexPtr);
+
+/*
+ * API for recursive mutexes.
+ */
+
+int  Sp_RecursiveMutexLock(Sp_RecursiveMutex *mutexPtr);
+int  Sp_RecursiveMutexIsLocked(Sp_RecursiveMutex *mutexPtr);
+int  Sp_RecursiveMutexUnlock(Sp_RecursiveMutex *mutexPtr);
+void Sp_RecursiveMutexFinalize(Sp_RecursiveMutex *mutexPtr);
+
+/*
+ * API for reader/writer mutexes.
+ */
+
+int  Sp_ReadWriteMutexRLock(Sp_ReadWriteMutex *mutexPtr);
+int  Sp_ReadWriteMutexWLock(Sp_ReadWriteMutex *mutexPtr);
+int  Sp_ReadWriteMutexIsLocked(Sp_ReadWriteMutex *mutexPtr);
+int  Sp_ReadWriteMutexUnlock(Sp_ReadWriteMutex *mutexPtr);
+void Sp_ReadWriteMutexFinalize(Sp_ReadWriteMutex *mutexPtr);
+
+#endif /* _SP_H_ */
+
+/* EOF $RCSfile: threadSpCmd.h,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
diff --git a/8.x/thread/generic/threadSvCmd.c b/8.x/thread/generic/threadSvCmd.c
new file mode 100644 (file)
index 0000000..bd7806f
--- /dev/null
@@ -0,0 +1,2332 @@
+/*
+ * This file implements a family of commands for sharing variables
+ * between threads.
+ *
+ * Initial code is taken from nsd/tclvar.c found in AOLserver 3.+
+ * distribution and modified to support Tcl 8.0+ command object interface
+ * and internal storage in private shared Tcl objects.
+ *
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: threadSvCmd.c,v 1.50 2010/03/31 08:50:24 vasiljevic Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#include "threadSvCmd.h"
+
+#include "threadSvListCmd.h"    /* Shared variants of list commands */
+#include "threadSvKeylistCmd.h" /* Shared variants of list commands */
+#include "psGdbm.h"             /* The gdbm persistent store implementation */
+
+#ifdef NS_AOLSERVER
+# define HIDE_DOTNAMES       /* tsv::names cmd does not list .<name> arrays */
+#endif
+
+/*
+ * Number of buckets to spread shared arrays into. Each bucket is 
+ * associated with one mutex so locking a bucket locks all arrays
+ * in that bucket as well. The number of buckets should be a prime.
+ */
+
+#define NUMBUCKETS 31
+
+/*
+ * Number of object containers
+ * to allocate in one shot.
+ */
+
+#define OBJS_TO_ALLOC_EACH_TIME 100
+
+/*
+ * Handle hiding of errorLine in 8.6
+ */
+#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
+#define ERRORLINE(interp) ((interp)->errorLine)
+#else
+#define ERRORLINE(interp) (Tcl_GetErrorLine(interp))
+#endif
+
+/*
+ * Reference to Tcl object types used in object-copy code.
+ * Those are referenced read-only, thus no mutex protection.
+ */
+
+static const Tcl_ObjType* booleanObjTypePtr;
+static const Tcl_ObjType* byteArrayObjTypePtr;
+static const Tcl_ObjType* doubleObjTypePtr;
+static const Tcl_ObjType* intObjTypePtr;
+static const Tcl_ObjType* stringObjTypePtr;
+
+/*
+ * In order to be fully stub enabled, a small
+ * hack is needed to query the tclEmptyStringRep
+ * global symbol defined by Tcl. See Sv_Init.
+ */
+
+char *Sv_tclEmptyStringRep = NULL;
+
+/*
+ * Global variables used within this file.
+ */
+
+static Bucket*    buckets;      /* Array of buckets. */
+static Tcl_Mutex  bucketsMutex; /* Protects the array of buckets */
+
+static SvCmdInfo* svCmdInfo;    /* Linked list of registered commands */
+static RegType*   regType;      /* Linked list of registered obj types */
+static PsStore*   psStore;      /* Linked list of registered pers. stores */
+
+static Tcl_Mutex  svMutex;      /* Protects inserts into above lists */
+static Tcl_Mutex  initMutex;    /* Serializes initialization issues */
+
+/*
+ * The standard commands found in AOLserver nsv_* interface. 
+ * For sharp-eye readers: the implementaion of the "lappend" command
+ * is moved to new list-command package, since it realy belongs there.
+ */
+
+static Tcl_ObjCmdProc SvObjObjCmd;
+static Tcl_ObjCmdProc SvAppendObjCmd;
+static Tcl_ObjCmdProc SvIncrObjCmd;
+static Tcl_ObjCmdProc SvSetObjCmd;
+static Tcl_ObjCmdProc SvExistsObjCmd;
+static Tcl_ObjCmdProc SvGetObjCmd;
+static Tcl_ObjCmdProc SvArrayObjCmd;
+static Tcl_ObjCmdProc SvUnsetObjCmd;
+static Tcl_ObjCmdProc SvNamesObjCmd;
+
+/*
+ * New commands added to 
+ * standard set of nsv_*
+ */
+
+static Tcl_ObjCmdProc SvPopObjCmd;
+static Tcl_ObjCmdProc SvMoveObjCmd;
+static Tcl_ObjCmdProc SvLockObjCmd;
+
+/*
+ * Forward declarations for functions to
+ * manage buckets, arrays and shared objects.
+ */
+
+static Container* CreateContainer(Array*, Tcl_HashEntry*, Tcl_Obj*);
+static Container* AcquireContainer(Array*, const char*, int);
+
+static Array* CreateArray(Bucket*, const char*);
+static Array* LockArray(Tcl_Interp*, const char*, int);
+
+static int ReleaseContainer(Tcl_Interp*, Container*, int);
+static int DeleteContainer(Container*);
+static int FlushArray(Array*);
+static int DeleteArray(Array*);
+
+static void SvAllocateContainers(Bucket*);
+static void SvRegisterStdCommands(void);
+
+#ifdef SV_FINALIZE
+static void SvFinalizeContainers(Bucket*);
+static void SvFinalize(ClientData);
+#endif /* SV_FINALIZE */
+
+static PsStore* GetPsStore(char *handle);
+
+static int SvObjDispatchObjCmd _ANSI_ARGS_ ((ClientData arg,
+            Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]));
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_RegisterCommand --
+ *
+ *      Utility to register commands to be loaded at module start.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects;
+ *      New command will be added to a linked list of registered commands.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+Sv_RegisterCommand(cmdName, objProc, delProc, clientData)
+    const char *cmdName;                /* Name of command to register */
+    Tcl_ObjCmdProc *objProc;            /* Object-based command procedure */
+    Tcl_CmdDeleteProc *delProc;         /* Command delete procedure */
+    ClientData clientData;              /* Private data ptr to pass to cmd */
+{
+    int len = strlen(cmdName) + strlen(TSV_CMD_PREFIX);
+    SvCmdInfo *newCmd = (SvCmdInfo*)Tcl_Alloc(sizeof(SvCmdInfo) + len + 1);
+
+    /*
+     * Setup new command structure
+     */
+
+    newCmd->cmdName = (char*)((char*)newCmd + sizeof(SvCmdInfo));
+
+    newCmd->objProcPtr = objProc;
+    newCmd->delProcPtr = delProc;
+    newCmd->clientData = clientData;
+
+    /*
+     * Rewrite command name. This is needed so we can
+     * easily turn-on the compatiblity with AOLserver
+     * command names.
+     */
+
+    strcpy(newCmd->cmdName, TSV_CMD_PREFIX);
+    strcat(newCmd->cmdName, cmdName);
+    newCmd->name = newCmd->cmdName + strlen(TSV_CMD_PREFIX);
+
+    /*
+     * Plug-in in shared list of commands.
+     */
+
+    Tcl_MutexLock(&svMutex);
+    if (svCmdInfo == NULL) {
+        svCmdInfo = newCmd;
+        newCmd->nextPtr = NULL;
+    } else {
+        newCmd->nextPtr = svCmdInfo;
+        svCmdInfo = newCmd;
+    }
+    Tcl_MutexUnlock(&svMutex);
+
+    return;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_RegisterObjType --
+ *
+ *      Registers custom object duplicator function for a specific
+ *      object type. Registered function will be called by the
+ *      private object creation routine every time an object is
+ *      plugged out or in the shared array. This way we assure that
+ *      Tcl objects do not get shared per-reference between threads.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects;
+ *      Memory gets allocated.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+Sv_RegisterObjType(typePtr, dupProc)
+    const Tcl_ObjType *typePtr;               /* Type of object to register */
+    Tcl_DupInternalRepProc *dupProc;    /* Custom object duplicator */
+{
+    RegType *newType = (RegType*)Tcl_Alloc(sizeof(RegType));
+
+    /*
+     * Setup new type structure
+     */
+
+    newType->typePtr = typePtr;
+    newType->dupIntRepProc = dupProc;
+
+    /*
+     * Plug-in in shared list
+     */
+
+    Tcl_MutexLock(&svMutex);
+    newType->nextPtr = regType;
+    regType = newType;
+    Tcl_MutexUnlock(&svMutex);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_RegisterPsStore --
+ *
+ *      Registers a handler to the persistent storage.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects;
+ *      Memory gets allocated.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+Sv_RegisterPsStore(psStorePtr)
+     PsStore *psStorePtr;
+{
+    
+    PsStore *psPtr = (PsStore*)Tcl_Alloc(sizeof(PsStore));
+
+    *psPtr = *psStorePtr;
+
+    /*
+     * Plug-in in shared list
+     */
+
+    Tcl_MutexLock(&svMutex);
+    if (psStore == NULL) {
+        psStore = psPtr;
+        psStore->nextPtr = NULL;
+    } else {
+        psPtr->nextPtr = psStore;
+        psStore = psPtr;
+    }
+    Tcl_MutexUnlock(&svMutex);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_GetContainer --
+ *
+ *      This is the workhorse of the module. It returns the container
+ *      with the shared Tcl object. It also locks the container, so 
+ *      when finished with operation on the Tcl object, one has to 
+ *      unlock the container by calling the Sv_PutContainer().
+ *      If instructed, this command might also create new container 
+ *      with empty Tcl object.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      New container might be created.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+int
+Sv_GetContainer(interp, objc, objv, retObj, offset, flags)
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+    Container **retObj;                 /* OUT: shared object container */
+    int *offset;                        /* Shift in argument list */
+    int flags;                          /* Options for locking shared array */
+{
+    const char *array, *key;
+
+    if (*retObj == NULL) {
+        Array *arrayPtr = NULL;
+
+        /*
+         * Parse mandatory arguments: <cmd> array key
+         */
+
+        if (objc < 3) {
+            Tcl_WrongNumArgs(interp, 1, objv, "array key ?args?");
+            return TCL_ERROR;
+        }
+
+        array = Tcl_GetString(objv[1]);
+        key   = Tcl_GetString(objv[2]);
+
+        *offset = 3; /* Consumed three arguments: cmd, array, key */
+
+        /*
+         * Lock the shared array and locate the shared object
+         */
+
+        arrayPtr = LockArray(interp, array, flags);
+        if (arrayPtr == NULL) {
+            return TCL_BREAK;
+        }
+        *retObj = AcquireContainer(arrayPtr, Tcl_GetString(objv[2]), flags);
+        if (*retObj == NULL) {
+            UnlockArray(arrayPtr);
+            Tcl_AppendResult(interp, "no key ", array, "(", key, ")", NULL);
+            return TCL_BREAK;
+        }
+    } else {
+        Tcl_HashTable *handles = &((*retObj)->bucketPtr->handles);
+        LOCK_CONTAINER(*retObj);
+        if (Tcl_FindHashEntry(handles, (char*)(*retObj)) == NULL) {
+            UNLOCK_CONTAINER(*retObj);
+            Tcl_SetResult(interp, "key has been deleted", TCL_STATIC);
+            return TCL_BREAK;
+        }
+        *offset = 2; /* Consumed two arguments: object, cmd */
+    }
+
+    return TCL_OK;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_PutContainer --
+ *
+ *      Releases the container obtained by the Sv_GetContainer. 
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      For bound arrays, update the underlying persistent storage.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+int
+Sv_PutContainer(interp, svObj, mode)
+    Tcl_Interp *interp;               /* For error reporting; might be NULL */
+    Container *svObj;                 /* Shared object container */
+    int mode;                         /* One of SV_XXX modes */
+{
+    int ret;
+
+    ret = ReleaseContainer(interp, svObj, mode);
+    UnlockArray(svObj->arrayPtr);
+
+    return ret;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * GetPsStore --
+ *
+ *      Performs a lookup in the list of registered persistent storage
+ *      handlers. If the match is found, duplicates the persistent
+ *      storage record and passes the copy to the caller.
+ *
+ * Results:
+ *      Pointer to the newly allocated persistent storage handler. Caller
+ *      must free this block when done with it. If none found, returns NULL,
+ *
+ * Side effects;
+ *      Memory gets allocated. Caller should free the return value of this
+ *      function using Tcl_Free(). 
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static PsStore*
+GetPsStore(char *handle)
+{
+    int i;
+    char *type = handle, *addr, *delimiter = strchr(handle, ':');
+    PsStore *tmpPtr, *psPtr = NULL;
+
+    /*
+     * Expect the handle in the following format: <type>:<address>
+     * where "type" must match one of the registered presistent store
+     * types (gdbm, tcl, whatever) and <address> is what is passed to
+     * the open procedure of the registered store.
+     *
+     * Example: gdbm:/path/to/gdbm/file
+     */
+
+    /*
+     * Try to see wether some array is already bound to the
+     * same persistent storage address. 
+     */
+
+    for (i = 0; i < NUMBUCKETS; i++) {
+        Tcl_HashSearch search;
+        Tcl_HashEntry *hPtr;
+        Bucket *bucketPtr = &buckets[i];
+        LOCK_BUCKET(bucketPtr);
+        hPtr = Tcl_FirstHashEntry(&bucketPtr->arrays, &search);
+        while (hPtr) {
+            Array *arrayPtr = (Array*)Tcl_GetHashValue(hPtr);
+            if (arrayPtr->bindAddr && arrayPtr->psPtr) {
+                if (strcmp(arrayPtr->bindAddr, handle) == 0) {
+                    UNLOCK_BUCKET(bucketPtr);
+                    return NULL; /* Array already bound */
+                }
+            }
+            hPtr = Tcl_NextHashEntry(&search);
+        }
+        UNLOCK_BUCKET(bucketPtr);
+    }
+
+    /*
+     * Split the address and storage handler
+     */
+
+    if (delimiter == NULL) {
+        addr = NULL;
+    } else {
+        *delimiter = 0;
+        addr = delimiter + 1;
+    }
+
+    /*
+     * No array was bound to the same persistent storage.
+     * Lookup the persistent storage to bind to.
+     */
+
+    Tcl_MutexLock(&svMutex);
+    for (tmpPtr = psStore; tmpPtr; tmpPtr = tmpPtr->nextPtr) {
+        if (strcmp(tmpPtr->type, type) == 0) {
+            tmpPtr->psHandle = (*tmpPtr->psOpen)(addr);
+            if (tmpPtr->psHandle) {
+                psPtr = (PsStore*)Tcl_Alloc(sizeof(PsStore));
+                *psPtr = *tmpPtr;
+                psPtr->nextPtr = NULL;
+            }
+            break;
+        }
+    }
+    Tcl_MutexUnlock(&svMutex);
+    
+    if (delimiter) {
+        *delimiter = ':';
+    }
+
+    return psPtr;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * AcquireContainer --
+ *
+ *      Finds a variable within an array and returns it's container.
+ *
+ * Results:
+ *      Pointer to variable object.
+ *
+ * Side effects;
+ *      New variable may be created. For bound arrays, try to locate
+ *      the key in the persistent storage as well.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static Container *
+AcquireContainer(arrayPtr, key, flags)
+    Array *arrayPtr;
+    const char *key;
+    int flags;
+{
+    int new;
+    Tcl_Obj *tclObj = NULL;
+    Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&arrayPtr->vars, key);
+
+    if (hPtr == NULL) {
+        PsStore *psPtr = arrayPtr->psPtr;
+        if (psPtr) {
+            char *val = NULL;
+            int len = 0;
+            if ((*psPtr->psGet)(psPtr->psHandle, key, &val, &len) == 0) {
+                tclObj = Tcl_NewStringObj(val, len);
+                (*psPtr->psFree)(val);
+            }
+        }
+        if (!(flags & FLAGS_CREATEVAR) && tclObj == NULL) {
+            return NULL;
+        }
+        if (tclObj == NULL) {
+            tclObj = Tcl_NewObj();
+        }
+        hPtr = Tcl_CreateHashEntry(&arrayPtr->vars, key, &new);
+        Tcl_SetHashValue(hPtr, CreateContainer(arrayPtr, hPtr, tclObj));
+    }
+
+    return (Container*)Tcl_GetHashValue(hPtr);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ReleaseContainer --
+ *
+ *      Does some post-processing on the used container. This is mostly
+ *      needed when the container has been modified and needs to be
+ *      saved in the bound persistent storage. 
+ *
+ * Results:
+ *      A standard Tcl result
+ *
+ * Side effects:
+ *      Persistent storage, if bound, might be modified.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+ReleaseContainer(interp, svObj, mode)
+    Tcl_Interp *interp;
+    Container *svObj;
+    int mode;
+{
+    PsStore *psPtr = svObj->arrayPtr->psPtr;
+    int len;
+    char *key, *val;
+
+    switch (mode) {
+    case SV_UNCHANGED: return TCL_OK;
+    case SV_ERROR:     return TCL_ERROR;
+    case SV_CHANGED:
+        if (psPtr) {
+            key = Tcl_GetHashKey(&svObj->arrayPtr->vars, svObj->entryPtr);
+            val = Tcl_GetStringFromObj(svObj->tclObj, &len);
+            if ((*psPtr->psPut)(psPtr->psHandle, key, val, len) == -1) {
+                const char *err = (*psPtr->psError)(psPtr->psHandle);
+                Tcl_SetObjResult(interp, Tcl_NewStringObj(err, -1));
+                return TCL_ERROR;
+            }
+        }
+        return TCL_OK;
+    }
+
+    return TCL_ERROR; /* Should never be reached */
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CreateContainer --
+ *
+ *      Creates new shared container holding Tcl object to be stored
+ *      in the shared array
+ *
+ * Results:
+ *      The container pointer.
+ *
+ * Side effects:
+ *      Memory gets allocated.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static Container *
+CreateContainer(arrayPtr, entryPtr, tclObj)
+    Array *arrayPtr;
+    Tcl_HashEntry *entryPtr;
+    Tcl_Obj *tclObj;
+{
+    Container *svObj;
+
+    if (arrayPtr->bucketPtr->freeCt == NULL) {
+        SvAllocateContainers(arrayPtr->bucketPtr);
+    }
+
+    svObj = arrayPtr->bucketPtr->freeCt;
+    arrayPtr->bucketPtr->freeCt = svObj->nextPtr;
+
+    svObj->arrayPtr  = arrayPtr;
+    svObj->bucketPtr = arrayPtr->bucketPtr;
+    svObj->tclObj    = tclObj;
+    svObj->entryPtr  = entryPtr;
+    svObj->handlePtr = NULL;
+
+    if (svObj->tclObj) {
+        Tcl_IncrRefCount(svObj->tclObj);
+    }
+
+    return svObj;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DeleteContainer --
+ *
+ *      Destroys the container and the Tcl object within it. For bound
+ *      shared arrays, the underlying persistent store is updated as well.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Memory gets reclaimed. If the shared array was bound to persistent
+ *      storage, it removes the corresponding record.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int 
+DeleteContainer(svObj)
+    Container *svObj;
+{
+    if (svObj->tclObj) {
+        Tcl_DecrRefCount(svObj->tclObj);
+    }
+    if (svObj->handlePtr) {
+        Tcl_DeleteHashEntry(svObj->handlePtr);
+    }
+    if (svObj->entryPtr) {
+        PsStore *psPtr = svObj->arrayPtr->psPtr;
+        if (psPtr) {
+            char *key = Tcl_GetHashKey(&svObj->arrayPtr->vars,svObj->entryPtr);
+            if ((*psPtr->psDelete)(psPtr->psHandle, key) == -1) {
+                return TCL_ERROR;
+            }
+        } 
+        Tcl_DeleteHashEntry(svObj->entryPtr);
+    }
+
+    svObj->arrayPtr  = NULL;
+    svObj->entryPtr  = NULL;
+    svObj->handlePtr = NULL;
+    svObj->tclObj    = NULL;
+
+    svObj->nextPtr = svObj->bucketPtr->freeCt;
+    svObj->bucketPtr->freeCt = svObj;
+
+    return TCL_OK;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * LockArray --
+ *
+ *      Find (or create) the array structure for shared array and lock it.
+ *      Array structure must be later unlocked with UnlockArray.
+ *
+ * Results:
+ *      TCL_OK or TCL_ERROR if no such array.
+ *
+ * Side effects:
+ *      Sets *arrayPtrPtr with Array pointer or leave error in given interp.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static Array *
+LockArray(interp, array, flags)
+    Tcl_Interp *interp;                 /* Interpreter to leave result. */
+    const char *array;                  /* Name of array to lock */
+    int flags;                          /* FLAGS_CREATEARRAY/FLAGS_NOERRMSG*/
+{
+    register const char *p;
+    register unsigned int result;
+    register int i;
+    Bucket *bucketPtr;
+    Array *arrayPtr;
+
+    /*
+     * Compute a hash to map an array to a bucket.
+     */
+
+    p = array;
+    result = 0;
+    while (*p++) {
+        i = *p;
+        result += (result << 3) + i;
+    }
+    i = result % NUMBUCKETS;
+    bucketPtr = &buckets[i];
+
+    /*
+     * Lock the bucket and find the array, or create a new one.
+     * The bucket will be left locked on success.
+     */
+
+    LOCK_BUCKET(bucketPtr); /* Note: no matching unlock below ! */
+    if (flags & FLAGS_CREATEARRAY) {
+        arrayPtr = CreateArray(bucketPtr, array);
+    } else {
+        Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&bucketPtr->arrays, array);
+        if (hPtr == NULL) {
+            UNLOCK_BUCKET(bucketPtr);
+            if (!(flags & FLAGS_NOERRMSG)) {
+                Tcl_AppendResult(interp, "\"", array,
+                                 "\" is not a thread shared array", NULL);
+            }
+            return NULL;
+        }
+        arrayPtr = (Array*)Tcl_GetHashValue(hPtr);
+    }
+
+    return arrayPtr;
+}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * FlushArray --
+ *
+ *      Unset all keys in an array.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Array is cleaned but it's variable hash-hable still lives.
+ *      For bound arrays, the persistent store is updated accordingly.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int 
+FlushArray(arrayPtr)
+    Array *arrayPtr;                    /* Name of array to flush */
+{
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+    
+    for (hPtr = Tcl_FirstHashEntry(&arrayPtr->vars, &search); hPtr;
+         hPtr = Tcl_NextHashEntry(&search)) {
+        if (DeleteContainer((Container*)Tcl_GetHashValue(hPtr)) != TCL_OK) {
+            return TCL_ERROR;
+        }
+    }
+
+    return TCL_OK;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CreateArray --
+ *
+ *      Creates new shared array instance.
+ *
+ * Results:
+ *      Pointer to the newly created array
+ *
+ * Side effects:
+ *      Memory gets allocated
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static Array *
+CreateArray(bucketPtr, arrayName)
+    Bucket *bucketPtr;
+    const char *arrayName;
+{
+    int new;
+    Array *arrayPtr;
+    Tcl_HashEntry *hPtr;
+
+    hPtr = Tcl_CreateHashEntry(&bucketPtr->arrays, arrayName, &new);
+    if (!new) {
+        return (Array*)Tcl_GetHashValue(hPtr);
+    }
+
+    arrayPtr = (Array*)Tcl_Alloc(sizeof(Array));
+    arrayPtr->bucketPtr = bucketPtr;
+    arrayPtr->entryPtr  = hPtr;
+    arrayPtr->psPtr     = NULL;
+    arrayPtr->bindAddr  = NULL;
+
+    Tcl_InitHashTable(&arrayPtr->vars, TCL_STRING_KEYS);
+    Tcl_SetHashValue(hPtr, arrayPtr);
+
+    return arrayPtr;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DeleteArray --
+ *
+ *      Deletes the shared array.
+ *
+ * Results:
+ *      A standard Tcl result. 
+ *
+ * Side effects:
+ *      Memory gets reclaimed.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int  
+DeleteArray(arrayPtr)
+    Array *arrayPtr;
+{
+    if (FlushArray(arrayPtr) == -1) {
+        return TCL_ERROR;
+    }
+    if (arrayPtr->psPtr) {
+        PsStore *psPtr = arrayPtr->psPtr;
+        if ((*psPtr->psClose)(psPtr->psHandle) == -1) {
+            return TCL_ERROR;
+        }
+        Tcl_Free((char*)arrayPtr->psPtr), arrayPtr->psPtr = NULL;
+    }
+    if (arrayPtr->bindAddr) {
+        Tcl_Free(arrayPtr->bindAddr);
+    }
+    if (arrayPtr->entryPtr) {
+        Tcl_DeleteHashEntry(arrayPtr->entryPtr);
+    }
+
+    Tcl_DeleteHashTable(&arrayPtr->vars);
+    Tcl_Free((char*)arrayPtr);
+
+    return TCL_OK;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvAllocateContainers --
+ *
+ *      Any similarity with the Tcl AllocateFreeObj function is purely
+ *      coincidental... Just joking; this is (almost) 100% copy of it! :-)
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Allocates memory for many containers at the same time
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+SvAllocateContainers(bucketPtr)
+    Bucket *bucketPtr;
+{
+    Container tmp[2];
+    size_t objSizePlusPadding = (size_t)(((char*)(tmp+1))-(char*)tmp);
+    size_t bytesToAlloc = (OBJS_TO_ALLOC_EACH_TIME * objSizePlusPadding);
+    char *basePtr;
+    register Container *prevPtr = NULL, *objPtr = NULL;
+    register int i;
+
+    basePtr = (char*)Tcl_Alloc(bytesToAlloc);
+    memset(basePtr, 0, bytesToAlloc);
+
+    objPtr = (Container*)basePtr;
+    objPtr->chunkAddr = basePtr; /* Mark chunk address for reclaim */
+
+    for (i = 0; i < OBJS_TO_ALLOC_EACH_TIME; i++) {
+        objPtr->nextPtr = prevPtr;
+        prevPtr = objPtr;
+        objPtr = (Container*)(((char*)objPtr) + objSizePlusPadding);
+    }
+    bucketPtr->freeCt = prevPtr;
+}
+\f
+#ifdef SV_FINALIZE
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvFinalizeContainers --
+ *
+ *    Reclaim memory for free object containers per bucket.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    Memory gets reclaimed
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+SvFinalizeContainers(bucketPtr)
+    Bucket *bucketPtr;
+{
+   Container *tmpPtr, *objPtr = bucketPtr->freeCt;
+
+    while (objPtr) {
+        if (objPtr->chunkAddr == (char*)objPtr) {
+            tmpPtr = objPtr->nextPtr;
+            Tcl_Free((char*)objPtr);
+            objPtr = tmpPtr;
+        } else {
+            objPtr = objPtr->nextPtr;
+        }
+    }
+}
+#endif /* SV_FINALIZE */
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_DuplicateObj --
+ *
+ *  Create and return a new object that is (mostly) a duplicate of the
+ *  argument object. We take care that the duplicate object is either
+ *  a proper object copy, i.e. w/o hidden references to original object
+ *  elements or a plain string object, i.e one w/o internal representation.
+ *
+ *  Decision about wether to produce a real duplicate or a string object
+ *  is done as follows:
+ *
+ *     1) Scalar Tcl object types are properly copied by default;
+ *        these include: boolean, int double, string and byteArray types.
+ *     2) Object registered with Sv_RegisterObjType are duplicated
+ *        using custom duplicator function which is guaranteed to
+ *        produce a proper deep copy of the object in question.
+ *     3) All other object types are stringified; these include
+ *        miscelaneous Tcl objects (cmdName, nsName, bytecode, etc, etc)
+ *        and all user-defined objects.
+ *
+ * Results:
+ *      The return value is a pointer to a newly created Tcl_Obj. This
+ *      object has reference count 0 and the same type, if any, as the
+ *      source object objPtr. Also:
+ *
+ *        1) If the source object has a valid string rep, we copy it;
+ *           otherwise, the new string rep is marked invalid.
+ *        2) If the source object has an internal representation (i.e. its
+ *           typePtr is non-NULL), the new object's internal rep is set to
+ *           a copy; otherwise the new internal rep is marked invalid.
+ *
+ * Side effects:
+ *  Some object may, when copied, loose their type, i.e. will become
+ *  just plain string objects.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Sv_DuplicateObj(objPtr)
+    register Tcl_Obj *objPtr;        /* The object to duplicate. */
+{
+    register Tcl_Obj *dupPtr = Tcl_NewObj();
+
+    /*
+     * Handle the internal rep
+     */
+
+    if (objPtr->typePtr != NULL) {
+        if (objPtr->typePtr->dupIntRepProc == NULL) {
+            dupPtr->internalRep = objPtr->internalRep;
+            dupPtr->typePtr = objPtr->typePtr;
+            Tcl_InvalidateStringRep(dupPtr);
+        } else {
+            if (   objPtr->typePtr == booleanObjTypePtr    \
+                || objPtr->typePtr == byteArrayObjTypePtr  \
+                || objPtr->typePtr == doubleObjTypePtr     \
+                || objPtr->typePtr == intObjTypePtr        \
+                || objPtr->typePtr == stringObjTypePtr) {
+               /*
+                * Cover all "safe" obj types (see header comment)
+                */
+              (*objPtr->typePtr->dupIntRepProc)(objPtr, dupPtr);
+              Tcl_InvalidateStringRep(dupPtr);
+            } else {
+                int found = 0;
+                register RegType *regPtr;
+               /*
+                * Cover special registered types. Assume not
+                * very many of those, so this sequential walk
+                * should be fast enough.
+                */
+                for (regPtr = regType; regPtr; regPtr = regPtr->nextPtr) {
+                    if (objPtr->typePtr == regPtr->typePtr) {
+                        (*regPtr->dupIntRepProc)(objPtr, dupPtr);
+                        Tcl_InvalidateStringRep(dupPtr);
+                        found = 1;
+                        break;
+                    }
+                }
+               /*
+                * Assure at least string rep of the source 
+                * is present, which will be copied below. 
+                */  
+                if (found == 0 && objPtr->bytes == NULL 
+                    && objPtr->typePtr->updateStringProc != NULL) {
+                    (*objPtr->typePtr->updateStringProc)(objPtr);
+                }
+            }
+        }
+    }
+
+    /*
+     * Handle the string rep
+     */
+
+    if (objPtr->bytes == NULL) {
+        dupPtr->bytes = NULL;
+    } else if (objPtr->bytes != Sv_tclEmptyStringRep) {
+        /* A copy of TclInitStringRep macro */
+        dupPtr->bytes = (char*)Tcl_Alloc((unsigned)objPtr->length + 1);
+        if (objPtr->length > 0) {
+            memcpy((void*)dupPtr->bytes,(void*)objPtr->bytes,
+                   (unsigned)objPtr->length);
+        }
+        dupPtr->length = objPtr->length;
+        dupPtr->bytes[objPtr->length] = '\0';        
+    }
+
+    return dupPtr;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvObjDispatchObjCmd --
+ *
+ *      The method command for dispatching sub-commands of the shared
+ *      object.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      Depends on the dispatched command
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvObjDispatchObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Just passed to the command. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    const char *cmdName;
+    SvCmdInfo *cmdPtr;
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "args");
+        return TCL_ERROR;
+    }
+
+    cmdName = Tcl_GetString(objv[1]);
+
+    /*
+     * Do simple linear search. We may later replace this list
+     * with the hash table to gain speed. Currently, the list
+     * of registered commands is so small, so this will work
+     * fast enough.
+     */
+
+    for (cmdPtr = svCmdInfo; cmdPtr; cmdPtr = cmdPtr->nextPtr) {
+        if (!strcmp(cmdPtr->name, cmdName)) {
+            return (*cmdPtr->objProcPtr)(arg, interp, objc, objv);
+        }
+    }
+
+    Tcl_AppendResult(interp, "invalid command name \"", cmdName, "\"", NULL);
+    return TCL_ERROR;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvObjObjCmd --
+ *
+ *      Creates the object command for a shared array.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      New Tcl command gets created.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvObjObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;                   /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int new, off, ret, flg;
+    char buf[128];
+    Tcl_Obj *val = NULL;
+    Container *svObj = NULL;
+
+    /*
+     * Syntax: sv::object array key ?var?
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    switch (ret) {
+    case TCL_BREAK: /* Shared array was not found */
+        if ((objc - off)) {
+            val = objv[off];
+        }
+        Tcl_ResetResult(interp);
+        flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+        ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+        if (ret != TCL_OK) {
+            return TCL_ERROR;
+        }
+        Tcl_DecrRefCount(svObj->tclObj);
+        svObj->tclObj = Sv_DuplicateObj(val ? val : Tcl_NewObj());
+        Tcl_IncrRefCount(svObj->tclObj);
+        break;
+    case TCL_ERROR:
+        return TCL_ERROR;
+    }
+
+    if (svObj->handlePtr == NULL) {
+        Tcl_HashTable *handles = &svObj->arrayPtr->bucketPtr->handles;
+        svObj->handlePtr = Tcl_CreateHashEntry(handles, (char*)svObj, &new);
+    }
+
+    /*
+     * Format the command name
+     */
+
+    sprintf(buf, "::%p", (int*)svObj);
+    Tcl_CreateObjCommand(interp, buf, SvObjDispatchObjCmd, (int*)svObj, NULL);
+    Tcl_ResetResult(interp);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
+
+    return Sv_PutContainer(interp, svObj, SV_UNCHANGED);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvArrayObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::array" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvArrayObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Pointer to object container. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int i, argx = 0, lobjc = 0, index, ret = TCL_OK;
+    const char *arrayName = NULL;
+    Array *arrayPtr = NULL;
+    Tcl_Obj **lobjv = NULL;
+    Container *svObj, *elObj = NULL;
+
+    static const char *opts[] = {
+        "set",  "reset", "get", "names", "size", "exists", "isbound", 
+        "bind", "unbind", NULL
+    };
+    enum options {
+        ASET,   ARESET,  AGET,  ANAMES,  ASIZE,  AEXISTS, AISBOUND,
+        ABIND,  AUNBIND
+    };
+
+    svObj = (Container*)arg;
+
+    if (objc < 3) {
+        Tcl_WrongNumArgs(interp, 1, objv, "option array");
+        return TCL_ERROR;
+    }
+
+    arrayName = Tcl_GetString(objv[2]);
+    arrayPtr  = LockArray(interp, arrayName, FLAGS_NOERRMSG);
+
+    if (objc > 3) {
+        argx = 3;
+    }
+
+    Tcl_ResetResult(interp);
+
+    if (Tcl_GetIndexFromObj(interp,objv[1],opts,"option",0,&index) != TCL_OK) {
+        ret = TCL_ERROR;
+
+    } else if (index == AEXISTS) {
+        Tcl_SetBooleanObj(Tcl_GetObjResult(interp), arrayPtr ? 1 : 0);
+
+    } else if (index == AISBOUND) {
+        if (arrayPtr == NULL) {
+            Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0);
+        } else {
+            Tcl_SetBooleanObj(Tcl_GetObjResult(interp), arrayPtr->psPtr ? 1:0);
+        }        
+
+    } else if (index == ASIZE) {
+        if (arrayPtr == NULL) {
+            Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
+        } else {
+            Tcl_SetLongObj(Tcl_GetObjResult(interp),arrayPtr->vars.numEntries);
+        }
+
+    } else if (index == ASET || index == ARESET) {
+        if (argx == (objc - 1)) {
+            if (argx && Tcl_ListObjGetElements(interp, objv[argx], &lobjc,
+                    &lobjv) != TCL_OK) {
+                ret = TCL_ERROR;
+                goto cmdExit;
+            }
+        } else {
+            lobjc = objc - 3;
+            lobjv = (Tcl_Obj**)objv + 3;
+        }
+        if (lobjc & 1) {
+            Tcl_AppendResult(interp, "list must have an even number"
+                    " of elements", NULL);
+            ret = TCL_ERROR;
+            goto cmdExit;
+        }
+        if (arrayPtr == NULL) {
+            arrayPtr = LockArray(interp, arrayName, FLAGS_CREATEARRAY);
+        }
+        if (index == ARESET) {
+            ret = FlushArray(arrayPtr);
+            if (ret != TCL_OK) {
+                if (arrayPtr->psPtr) {
+                    PsStore *psPtr = arrayPtr->psPtr;
+                    char *err = (*psPtr->psError)(psPtr->psHandle);
+                    Tcl_SetObjResult(interp, Tcl_NewStringObj(err, -1));
+                }
+                goto cmdExit;
+            }
+        }
+        for (i = 0; i < lobjc; i += 2) {
+            const char *key = Tcl_GetString(lobjv[i]);
+            elObj = AcquireContainer(arrayPtr, key, FLAGS_CREATEVAR);
+            Tcl_DecrRefCount(elObj->tclObj);
+            elObj->tclObj = Sv_DuplicateObj(lobjv[i+1]);
+            Tcl_IncrRefCount(elObj->tclObj);
+            if (ReleaseContainer(interp, elObj, SV_CHANGED) != TCL_OK) {
+                ret = TCL_ERROR;
+                goto cmdExit;
+            }
+        }
+
+    } else if (index == AGET || index == ANAMES) {
+        if (arrayPtr) {
+            Tcl_HashSearch search;
+            Tcl_Obj *resObj = Tcl_NewListObj(0, NULL);
+            const char *pattern = (argx == 0) ? NULL : Tcl_GetString(objv[argx]);
+            Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&arrayPtr->vars,&search);
+            while (hPtr) {
+                char *key = Tcl_GetHashKey(&arrayPtr->vars, hPtr);
+                if (pattern == NULL || Tcl_StringMatch(key, pattern)) {
+                    Tcl_ListObjAppendElement(interp, resObj,
+                            Tcl_NewStringObj(key, -1));
+                    if (index == AGET) {
+                        elObj = (Container*)Tcl_GetHashValue(hPtr);
+                        Tcl_ListObjAppendElement(interp, resObj,
+                                Sv_DuplicateObj(elObj->tclObj));
+                    }
+                }
+                hPtr = Tcl_NextHashEntry(&search);
+            }
+            Tcl_SetObjResult(interp, resObj);
+        }
+
+    } else if (index == ABIND) {
+
+        /*
+         * This is more complex operation, requiring some clarification.
+         *
+         * When binding an already existing array, we walk the array
+         * first and store all key/value pairs found there in the 
+         * persistent storage. Then we proceed with the below.
+         *
+         * When binding an non-existent array, we open the persistent
+         * storage and cache all key/value pairs found there into tne
+         * newly created shared array.
+         */
+        
+        PsStore *psPtr;
+        int len;
+        char *psurl, *key = NULL, *val = NULL;
+
+        if (objc < 4) {
+            Tcl_WrongNumArgs(interp, 2, objv, "array handle");
+            ret = TCL_ERROR;
+            goto cmdExit;
+        }
+        
+        if (arrayPtr && arrayPtr->psPtr) {
+            Tcl_AppendResult(interp, "array is already bound", NULL);
+            ret = TCL_ERROR;
+            goto cmdExit;
+        }
+
+        psurl = Tcl_GetStringFromObj(objv[3], &len);
+        psPtr = GetPsStore(psurl);
+
+        if (psPtr == NULL) {
+            Tcl_AppendResult(interp, "can't open persistent storage on \"", 
+                             psurl, "\"", NULL);
+            ret = TCL_ERROR;
+            goto cmdExit;
+        }
+        if (arrayPtr) {
+            Tcl_HashSearch search;
+            Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&arrayPtr->vars,&search);
+            arrayPtr->psPtr = psPtr;
+            arrayPtr->bindAddr = strcpy(Tcl_Alloc(len+1), psurl);
+            while (hPtr) {
+                svObj = Tcl_GetHashValue(hPtr);
+                if (ReleaseContainer(interp, svObj, SV_CHANGED) != TCL_OK) {
+                    ret = TCL_ERROR;
+                    goto cmdExit;
+                }
+                hPtr = Tcl_NextHashEntry(&search);
+            }
+        } else {
+            arrayPtr = LockArray(interp, arrayName, FLAGS_CREATEARRAY);
+            arrayPtr->psPtr = psPtr;
+            arrayPtr->bindAddr = strcpy(Tcl_Alloc(len+1), psurl);
+        }
+        if (!(*psPtr->psFirst)(psPtr->psHandle, &key, &val, &len)) {
+            do {
+                (*psPtr->psFree)(val); /* What a waste! */
+                AcquireContainer(arrayPtr, key, FLAGS_CREATEVAR);
+            } while (!(*psPtr->psNext)(psPtr->psHandle, &key, &val, &len));
+        }
+
+    } else if (index == AUNBIND) {
+        if (arrayPtr && arrayPtr->psPtr) {
+            PsStore *psPtr = arrayPtr->psPtr;
+            if ((*psPtr->psClose)(psPtr->psHandle) == -1) {
+                char *err = (*psPtr->psError)(psPtr->psHandle);
+                Tcl_SetObjResult(interp, Tcl_NewStringObj(err, -1));
+                ret = TCL_ERROR;
+                goto cmdExit;
+            }
+            Tcl_Free((char*)arrayPtr->psPtr), arrayPtr->psPtr = NULL;
+        } else {
+            Tcl_AppendResult(interp, "shared variable is not bound", NULL);
+            ret = TCL_ERROR;
+            goto cmdExit;
+        }
+    }
+
+ cmdExit:
+    if (arrayPtr) {
+        UnlockArray(arrayPtr);
+    }
+
+    return ret;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvUnsetObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::unset" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvUnsetObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;                   /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int ii;
+    const char *arrayName;
+    Array *arrayPtr;
+
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "array ?key ...?");
+        return TCL_ERROR;
+    }
+
+    arrayName = Tcl_GetString(objv[1]);
+    arrayPtr  = LockArray(interp, arrayName, 0);
+
+    if (arrayPtr == NULL) {
+        return TCL_ERROR;
+    }
+    if (objc == 2) {
+        UnlockArray(arrayPtr);
+        if (DeleteArray(arrayPtr) != TCL_OK) {
+            return TCL_ERROR;
+        }
+    } else {
+        for (ii = 2; ii < objc; ii++) {
+            const char *key = Tcl_GetString(objv[ii]);
+            Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&arrayPtr->vars, key);
+            if (hPtr) {
+                if (DeleteContainer((Container*)Tcl_GetHashValue(hPtr))
+                    != TCL_OK) {
+                    UnlockArray(arrayPtr);
+                    return TCL_ERROR;
+                }
+            } else {
+                UnlockArray(arrayPtr);
+                Tcl_AppendResult(interp,"no key ",arrayName,"(",key,")",NULL);
+                return TCL_ERROR;
+            }
+        }
+        UnlockArray(arrayPtr);
+    }
+
+    return TCL_OK;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvNamesObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::names" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvNamesObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;                   /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int i, len;
+    const char *pattern = NULL;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+    Tcl_Obj *resObj;
+
+    if (objc > 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+        return TCL_ERROR;
+    }
+    if (objc == 2) {
+        pattern = Tcl_GetStringFromObj(objv[1], &len);
+    }
+
+    resObj = Tcl_NewListObj(0, NULL);
+
+    for (i = 0; i < NUMBUCKETS; i++) {
+        Bucket *bucketPtr = &buckets[i];
+        LOCK_BUCKET(bucketPtr);
+        hPtr = Tcl_FirstHashEntry(&bucketPtr->arrays, &search);
+        while (hPtr) {
+            char *key = Tcl_GetHashKey(&bucketPtr->arrays, hPtr);
+#ifdef HIDE_DOTNAMES
+            if (*key != '.' /* Hide .<name> arrays */ &&
+#else
+            if (1 &&
+#endif
+                (pattern == NULL || Tcl_StringMatch(key, pattern))) {
+                Tcl_ListObjAppendElement(interp, resObj,
+                        Tcl_NewStringObj(key, -1));
+            }
+            hPtr = Tcl_NextHashEntry(&search);
+        }
+        UNLOCK_BUCKET(bucketPtr);
+    }
+
+    Tcl_SetObjResult(interp, resObj);
+
+    return TCL_OK;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvGetObjCmd --
+ *
+ *      This procedure is invoked to process "tsv::get" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvGetObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Pointer to object container. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int off, ret;
+    Tcl_Obj *res;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::get array key ?var?
+     *          $object get ?var?
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    switch (ret) {
+    case TCL_BREAK:
+        if ((objc - off) == 0) {
+            return TCL_ERROR;
+        } else {
+            Tcl_ResetResult(interp);
+            Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
+            return TCL_OK;
+        }
+    case TCL_ERROR:
+        return TCL_ERROR;
+    }
+
+    res = Sv_DuplicateObj(svObj->tclObj);
+
+    if ((objc - off) == 0) {
+        Tcl_SetObjResult(interp, res);
+    } else {
+        if (Tcl_ObjSetVar2(interp, objv[off], NULL, res, 0) == NULL) {
+            Tcl_DecrRefCount(res);
+            goto cmd_err;
+        }
+        Tcl_ResetResult(interp);
+        Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
+    }
+
+    return Sv_PutContainer(interp, svObj, SV_UNCHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvExistsObjCmd --
+ *
+ *      This procedure is invoked to process "tsv::exists" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvExistsObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Pointer to object container. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int off, ret;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::exists array key
+     *          $object exists
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    switch (ret) {
+    case TCL_BREAK: /* Array/key not found */
+        Tcl_ResetResult(interp);
+        Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); 
+        return TCL_OK;
+    case TCL_ERROR:
+        return TCL_ERROR;
+    }
+
+    Tcl_ResetResult(interp);
+    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1);
+
+    return Sv_PutContainer(interp, svObj, SV_UNCHANGED);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvSetObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::set" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvSetObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Pointer to object container */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int ret, off, flg, mode;
+    Tcl_Obj *val;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::set array key ?value?
+     *          $object set ?value?
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    switch (ret) {
+    case TCL_BREAK:
+        if ((objc - off) == 0) {
+            return TCL_ERROR;
+        } else {
+            Tcl_ResetResult(interp);
+            flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+            ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+            if (ret != TCL_OK) {
+                return TCL_ERROR;
+            }
+        }
+        break;
+    case TCL_ERROR:
+        return TCL_ERROR;
+    }
+    if ((objc - off)) {
+        val = objv[off];
+        Tcl_DecrRefCount(svObj->tclObj);
+        svObj->tclObj = Sv_DuplicateObj(val);
+        Tcl_IncrRefCount(svObj->tclObj);
+        mode = SV_CHANGED;
+    } else {
+        val = Sv_DuplicateObj(svObj->tclObj);
+        mode = SV_UNCHANGED;
+    }
+
+    Tcl_SetObjResult(interp, val);
+
+    return Sv_PutContainer(interp, svObj, mode);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvIncrObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::incr" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvIncrObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Pointer to object container */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int off, ret, flg, new = 0;
+    long incrValue = 1, currValue = 0;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::incr array key ?increment?
+     *          $object incr ?increment?
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        if (ret != TCL_BREAK) {
+            return TCL_ERROR;
+        }
+        flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+        Tcl_ResetResult(interp);
+        ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+        if (ret != TCL_OK) {
+            return TCL_ERROR;
+        }
+        new = 1;
+    }
+    if ((objc - off)) {
+        ret = Tcl_GetLongFromObj(interp, objv[off], &incrValue);
+        if (ret != TCL_OK) {
+            goto cmd_err;
+        }
+    }
+    if (new) {
+        currValue = 0;
+    } else {
+        ret = Tcl_GetLongFromObj(interp, svObj->tclObj, &currValue);
+        if (ret != TCL_OK) {
+            goto cmd_err;
+        }
+    }
+
+    incrValue += currValue;
+    Tcl_SetLongObj(svObj->tclObj, incrValue);
+    Tcl_ResetResult(interp);
+    Tcl_SetLongObj(Tcl_GetObjResult(interp), incrValue);
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvAppendObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::append" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvAppendObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Pointer to object container */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int i, off, flg, ret;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::append array key value ?value ...?
+     *          $object append value ?value ...?
+     */
+
+    flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) < 1) {
+        Tcl_WrongNumArgs(interp, off, objv, "value ?value ...?");
+        goto cmd_err;
+    }
+    for (i = off; i < objc; ++i) {
+        Tcl_AppendObjToObj(svObj->tclObj, Sv_DuplicateObj(objv[i]));
+    }
+
+    Tcl_SetObjResult(interp, Sv_DuplicateObj(svObj->tclObj));
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvPopObjCmd --
+ *
+ *      This procedure is invoked to process "tsv::pop" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvPopObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Pointer to object container */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int ret, off;
+    Tcl_Obj *retObj;
+    Array *arrayPtr = NULL;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::pop array key ?var?
+     *          $object pop ?var?
+     *
+     * Note: the object command will run into error next time !
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    switch (ret) {
+    case TCL_BREAK:
+        if ((objc - off) == 0) {
+            return TCL_ERROR;
+        } else {
+            Tcl_ResetResult(interp);
+            Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
+            return TCL_OK;
+        }
+    case TCL_ERROR:
+        return TCL_ERROR;
+    }
+
+    arrayPtr = svObj->arrayPtr;
+
+    retObj = svObj->tclObj;
+    svObj->tclObj = NULL;
+
+    if (DeleteContainer(svObj) != TCL_OK) {
+        if (svObj->arrayPtr->psPtr) {
+            PsStore *psPtr = svObj->arrayPtr->psPtr;
+            char *err = (*psPtr->psError)(psPtr->psHandle);
+            Tcl_SetObjResult(interp, Tcl_NewStringObj(err,-1));
+        }
+        ret = TCL_ERROR;
+        goto cmd_exit;
+    }
+
+    if ((objc - off) == 0) {
+        Tcl_SetObjResult(interp, retObj);
+    } else {
+        if (Tcl_ObjSetVar2(interp, objv[off], NULL, retObj, 0) == NULL) {
+            ret = TCL_ERROR;
+            goto cmd_exit;
+        }
+        Tcl_ResetResult(interp);
+        Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
+    }
+
+  cmd_exit:
+    Tcl_DecrRefCount(retObj);
+    UnlockArray(arrayPtr);
+
+    return ret;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvMoveObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::move" command.
+ *      See the user documentation for details on what it does.
+ *
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvMoveObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Pointer to object container. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int ret, off, new;
+    const char *toKey;
+    Tcl_HashEntry *hPtr;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::move array key to
+     *          $object move to
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    toKey = Tcl_GetString(objv[off]);
+    hPtr = Tcl_CreateHashEntry(&svObj->arrayPtr->vars, toKey, &new);
+
+    if (!new) {
+        Tcl_AppendResult(interp, "key \"", toKey, "\" exists", NULL);
+        goto cmd_err;
+    }
+    if (svObj->entryPtr) {
+        char *key = Tcl_GetHashKey(&svObj->arrayPtr->vars, svObj->entryPtr);
+        if (svObj->arrayPtr->psPtr) {
+            PsStore *psPtr = svObj->arrayPtr->psPtr;
+            if ((*psPtr->psDelete)(psPtr->psHandle, key) == -1) {
+                char *err = (*psPtr->psError)(psPtr->psHandle);
+                Tcl_SetObjResult(interp, Tcl_NewStringObj(err, -1));
+                return TCL_ERROR;
+            }
+        }
+        Tcl_DeleteHashEntry(svObj->entryPtr);
+    }
+
+    svObj->entryPtr = hPtr;
+    Tcl_SetHashValue(hPtr, svObj);
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SvLockObjCmd --
+ *
+ *    This procedure is invoked to process "tsv::lock" Tcl command.
+ *    See the user documentation for details on what it does.
+ *
+ * Results:
+ *    A standard Tcl result.
+ *
+ * Side effects:
+ *    See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SvLockObjCmd(dummy, interp, objc, objv)
+    ClientData dummy;                   /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int ret;
+    Tcl_Obj *scriptObj;
+    Bucket *bucketPtr;
+    Array *arrayPtr = NULL;
+
+    /* 
+     * Syntax:
+     *
+     *     tsv::lock array arg ?arg ...?
+     */
+
+    if (objc < 3) {
+        Tcl_AppendResult(interp, "wrong # args: should be \"",
+                         Tcl_GetString(objv[0]), "array arg ?arg...?\"", NULL);
+        return TCL_ERROR;
+    }
+
+    arrayPtr  = LockArray(interp, Tcl_GetString(objv[1]), FLAGS_CREATEARRAY);
+    bucketPtr = arrayPtr->bucketPtr;
+
+    /*
+     * Evaluate passed arguments as Tcl script. Note that
+     * Tcl_EvalObjEx throws away the passed object by 
+     * doing an decrement reference count on it. This also
+     * means we need not build object bytecode rep.
+     */
+    
+    if (objc == 3) {
+        scriptObj = Tcl_DuplicateObj(objv[2]);
+    } else {
+        scriptObj = Tcl_ConcatObj(objc-2, objv + 2);
+    }
+    
+    Tcl_AllowExceptions(interp);
+    ret = Tcl_EvalObjEx(interp, scriptObj, TCL_EVAL_DIRECT);
+
+    if (ret == TCL_ERROR) {
+        char msg[32 + TCL_INTEGER_SPACE];
+        sprintf(msg, "\n    (\"eval\" body line %d)", ERRORLINE(interp));
+        Tcl_AddObjErrorInfo(interp, msg, -1);
+    }
+
+    /*
+     * We unlock the bucket directly, w/o going to Sv_Unlock()
+     * since it needs the array which may be unset by the script.
+     */
+
+    UNLOCK_BUCKET(bucketPtr);
+
+    return ret;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_RegisterStdCommands --
+ *
+ *      Register standard shared variable commands
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      Memory gets allocated
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+SvRegisterStdCommands(void)
+{
+    static int initialized = 0;
+    
+    if (initialized == 0) {
+        Tcl_MutexLock(&initMutex);
+        if (initialized == 0) {
+            Sv_RegisterCommand("var",    SvObjObjCmd,    NULL, NULL);
+            Sv_RegisterCommand("object", SvObjObjCmd,    NULL, NULL);
+            Sv_RegisterCommand("set",    SvSetObjCmd,    NULL, NULL);
+            Sv_RegisterCommand("unset",  SvUnsetObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("get",    SvGetObjCmd,    NULL, NULL);
+            Sv_RegisterCommand("incr",   SvIncrObjCmd,   NULL, NULL);
+            Sv_RegisterCommand("exists", SvExistsObjCmd, NULL, NULL);
+            Sv_RegisterCommand("append", SvAppendObjCmd, NULL, NULL);
+            Sv_RegisterCommand("array",  SvArrayObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("names",  SvNamesObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("pop",    SvPopObjCmd,    NULL, NULL);
+            Sv_RegisterCommand("move",   SvMoveObjCmd,   NULL, NULL);
+            Sv_RegisterCommand("lock",   SvLockObjCmd,   NULL, NULL);
+            initialized = 1;
+        }
+        Tcl_MutexUnlock(&initMutex);
+    }
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_Init --
+ *
+ *    Creates commands in current interpreter.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects
+ *    Many new command created in current interpreter. Global data
+ *    structures used by them initialized as well.
+ *
+ *-----------------------------------------------------------------------------
+ */
+int
+Sv_Init (interp)
+    Tcl_Interp *interp;
+{
+    register int i;
+    Bucket *bucketPtr;
+    SvCmdInfo *cmdPtr;
+
+    /*
+     * Add keyed-list datatype
+     */
+
+    TclX_KeyedListInit(interp);
+    Sv_RegisterKeylistCommands();
+
+    /*
+     * Register standard (nsv_* compatible) and our 
+     * own extensive set of list manipulating commands
+     */
+
+    SvRegisterStdCommands();
+    Sv_RegisterListCommands();
+
+    /*
+     * Get Tcl object types. These are used
+     * in custom object duplicator function.
+     */
+
+    booleanObjTypePtr   = Tcl_GetObjType("boolean");
+    byteArrayObjTypePtr = Tcl_GetObjType("bytearray");
+    doubleObjTypePtr    = Tcl_GetObjType("double");
+    intObjTypePtr       = Tcl_GetObjType("int");
+    stringObjTypePtr    = Tcl_GetObjType("string");
+
+    /*
+     * Plug-in registered commands in current interpreter
+     */
+
+    for (cmdPtr = svCmdInfo; cmdPtr; cmdPtr = cmdPtr->nextPtr) {
+        Tcl_CreateObjCommand(interp, cmdPtr->cmdName, cmdPtr->objProcPtr,
+                (ClientData)cmdPtr->clientData, (Tcl_CmdDeleteProc*)0);
+    }
+
+    /*
+     * Create array of buckets and initialize each bucket
+     */
+
+    if (buckets == NULL) {
+        Tcl_MutexLock(&bucketsMutex);
+        if (buckets == NULL) {
+            buckets = (Bucket *)Tcl_Alloc(sizeof(Bucket) * NUMBUCKETS);
+            for (i = 0; i < NUMBUCKETS; ++i) {
+                bucketPtr = &buckets[i];
+                memset(bucketPtr, 0, sizeof(Bucket));
+                Tcl_InitHashTable(&bucketPtr->arrays, TCL_STRING_KEYS);
+                Tcl_InitHashTable(&bucketPtr->handles, TCL_ONE_WORD_KEYS);
+            }
+
+            /*
+             * There is no other way to get Sv_tclEmptyStringRep
+             * pointer value w/o this trick.
+             */
+
+            {
+                Tcl_Obj *dummy = Tcl_NewObj();
+                Sv_tclEmptyStringRep = dummy->bytes;
+                Tcl_DecrRefCount(dummy);
+            }
+
+#ifdef HAVE_GDBM
+            /*
+             * Register persistent store handlers
+             */
+            Sv_RegisterGdbmStore();
+#endif
+        }
+        Tcl_MutexUnlock(&bucketsMutex);
+    }
+
+    return TCL_OK;
+}
+\f
+int Sv_SafeInit (interp)
+    Tcl_Interp *interp;
+{
+    return (Sv_Init(interp));
+}
+
+\f
+#ifdef SV_FINALIZE
+/* 
+ * Left for reference, but unused since multithreaded finalization is
+ * unsolvable in the general case. Brave souls can revive this by
+ * installing a late exit handler on Thread's behalf, bringing the
+ * function back onto the Tcl_Finalize (but not Tcl_Exit) path.
+ */
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvFinalize --
+ *
+ *    Unset all arrays and reclaim all buckets.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects
+ *    Memory gets reclaimed.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+SvFinalize (clientData)
+    ClientData clientData;
+{
+    register int i;
+    SvCmdInfo *cmdPtr;
+    RegType *regPtr;
+
+    Tcl_HashEntry *hashPtr;
+    Tcl_HashSearch search;
+
+    /*
+     * Reclaim memory for shared arrays
+     */
+
+    if (buckets != NULL) {
+        Tcl_MutexLock(&bucketsMutex);
+        if (buckets != NULL) {
+            for (i = 0; i < NUMBUCKETS; ++i) {
+                Bucket *bucketPtr = &buckets[i];
+                hashPtr = Tcl_FirstHashEntry(&bucketPtr->arrays, &search);
+                while (hashPtr != NULL) {
+                    Array *arrayPtr = (Array*)Tcl_GetHashValue(hashPtr); 
+                    UnlockArray(arrayPtr);
+                    DeleteArray(arrayPtr);
+                    hashPtr = Tcl_NextHashEntry(&search);
+                }
+                if (bucketPtr->lock) {
+                    Sp_RecursiveMutexFinalize(&bucketPtr->lock);
+                }
+                SvFinalizeContainers(bucketPtr);
+                Tcl_DeleteHashTable(&bucketPtr->handles);
+                Tcl_DeleteHashTable(&bucketPtr->arrays);
+            }
+            Tcl_Free((char *)buckets), buckets = NULL;
+        }
+        buckets = NULL;
+        Tcl_MutexUnlock(&bucketsMutex);
+    }
+
+    Tcl_MutexLock(&svMutex);
+
+    /*
+     * Reclaim memory for registered commands
+     */
+
+    if (svCmdInfo != NULL) {
+        cmdPtr = svCmdInfo;
+        while (cmdPtr) {
+            SvCmdInfo *tmpPtr = cmdPtr->nextPtr;
+            Tcl_Free((char*)cmdPtr);
+            cmdPtr = tmpPtr;
+        }
+        svCmdInfo = NULL;
+    }
+
+    /*
+     * Reclaim memory for registered object types
+     */
+
+    if (regType != NULL) {
+        regPtr = regType;
+        while (regPtr) {
+            RegType *tmpPtr = regPtr->nextPtr;
+            Tcl_Free((char*)regPtr);
+            regPtr = tmpPtr;
+        }
+        regType = NULL;
+    }
+
+    Tcl_MutexUnlock(&svMutex);
+}
+#endif /* SV_FINALIZE */
+
+/* EOF $RCSfile: threadSvCmd.c,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
diff --git a/8.x/thread/generic/threadSvCmd.h b/8.x/thread/generic/threadSvCmd.h
new file mode 100644 (file)
index 0000000..9bfbcb2
--- /dev/null
@@ -0,0 +1,232 @@
+/* 
+ * This is the header file for the module that implements shared variables.
+ * for protected multithreaded access.
+ *
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.txt" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Rcsid: @(#)$Id: threadSvCmd.h,v 1.17 2010/03/31 08:50:24 vasiljevic Exp $
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _SV_H_
+#define _SV_H_
+
+#include <tcl.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "threadSpCmd.h" /* For recursive locks */
+
+/*
+ * Uncomment following line to get command-line
+ * compatibility with AOLserver nsv_* commands
+ */
+
+/* #define NSV_COMPAT 1 */
+
+/*
+ * Uncomment following line to force command-line
+ * compatibility with older thread::sv_ commands
+ * If you leave it commented-out, the older style
+ * command is going to be included in addition to
+ * the new tsv::* style.
+ */
+
+/* #define OLD_COMPAT 1 */
+
+#ifdef NS_AOLSERVER
+# ifdef NSV_COMPAT
+#  define TSV_CMD_PREFIX "nsv_"  /* Compatiblity prefix for AOLserver */
+# else
+#  define TSV_CMD_PREFIX "sv_"   /* Regular command prefix for AOLserver */
+# endif
+#else
+# ifdef OLD_COMPAT
+#  define TSV_CMD_PREFIX "thread::sv_" /* Old command prefix for Tcl */
+# else
+#  define TSV_CMD_PREFIX "tsv::" /* Regular command prefix for Tcl */
+# endif
+#endif
+
+/*
+ * Used when creating arrays/variables
+ */
+
+#define FLAGS_CREATEARRAY  1   /* Create the array in bucket if none found */
+#define FLAGS_NOERRMSG     2   /* Do not format error message */
+#define FLAGS_CREATEVAR    4   /* Create the array variable if none found */
+
+/*
+ * Macros for handling locking and unlocking
+ */
+#define LOCK_BUCKET(a)      Sp_RecursiveMutexLock(&(a)->lock)
+#define UNLOCK_BUCKET(a)    Sp_RecursiveMutexUnlock(&(a)->lock)
+
+#define LOCK_CONTAINER(a)   Sp_RecursiveMutexLock(&(a)->bucketPtr->lock)
+#define UNLOCK_CONTAINER(a) Sp_RecursiveMutexUnlock(&(a)->bucketPtr->lock)
+
+/*
+ * This is named synetrically to LockArray as function
+ * rather than as a macro just to improve readability.
+ */
+
+#define UnlockArray(a) UNLOCK_CONTAINER(a)
+
+/*
+ * Mode for Sv_PutContainer, so it knows what
+ * happened with the embedded shared object.
+ */
+
+#define SV_UNCHANGED       0   /* Object has not been modified */
+#define SV_CHANGED         1   /* Object has been modified */
+#define SV_ERROR          -1   /* Object may be in incosistent state */
+
+/*
+ * Definitions of functions implementing simple key/value 
+ * persistent storage for shared variable arrays.
+ */
+
+typedef ClientData (ps_open_proc)(const char*);
+
+typedef int (ps_get_proc)   (ClientData, const char*, char**, int*);
+typedef int (ps_put_proc)   (ClientData, const char*, char*, int);
+typedef int (ps_first_proc) (ClientData, char**, char**, int*);
+typedef int (ps_next_proc)  (ClientData, char**, char**, int*);
+typedef int (ps_delete_proc)(ClientData, const char*);
+typedef int (ps_close_proc) (ClientData);
+typedef void(ps_free_proc)  (char*);
+
+typedef char* (ps_geterr_proc)(ClientData);
+
+/*
+ * This structure maintains a bunch of pointers to functions implementing
+ * the simple persistence layer for the shared variable arrays. 
+ */
+
+typedef struct PsStore {
+    char *type;                /* Type identifier of the persistent storage */
+    ClientData psHandle;       /* Handle to the opened storage */
+    ps_open_proc   *psOpen;    /* Function to open the persistent key store */
+    ps_get_proc    *psGet;     /* Function to retrieve value bound to key */
+    ps_put_proc    *psPut;     /* Function to store user key and value */
+    ps_first_proc  *psFirst;   /* Function to retrieve the first key/value */
+    ps_next_proc   *psNext;    /* Function to retrieve the next key/value */
+    ps_delete_proc *psDelete;  /* Function to delete user key and value */
+    ps_close_proc  *psClose;   /* Function to close the persistent store */
+    ps_free_proc   *psFree;    /* Fuction to free allocated memory */
+    ps_geterr_proc *psError;   /* Function to return last store error */
+    struct PsStore *nextPtr;   /* For linking into linked lists */
+} PsStore;
+
+/*
+ * The following structure defines a collection of arrays.
+ * Only the arrays within a given bucket share a lock, 
+ * allowing for more concurency.
+ */
+
+typedef struct Bucket {
+    Sp_RecursiveMutex lock;    /* */
+    Tcl_ThreadId lockt;        /* Thread holding the lock */
+    Tcl_HashTable arrays;      /* Hash table of all arrays in bucket */
+    Tcl_HashTable handles;     /* Hash table of given-out handles in bucket */
+    struct Container *freeCt;  /* List of free Tcl-object containers */
+} Bucket;
+
+/*
+ * The following structure maintains the context for each variable array.
+ */
+
+typedef struct Array {
+    char *bindAddr;            /* Array is bound to this address */
+    PsStore *psPtr;            /* Persistent storage functions */
+    Bucket *bucketPtr;         /* Array bucket. */
+    Tcl_HashEntry *entryPtr;   /* Entry in bucket array table. */
+    Tcl_HashEntry *handlePtr;  /* Entry in handles table */
+    Tcl_HashTable vars;        /* Table of variables. */
+} Array;
+
+/*
+ * The object container for Tcl-objects stored within shared arrays.
+ */
+
+typedef struct Container {
+    Bucket *bucketPtr;         /* Bucket holding the array below */
+    Array *arrayPtr;           /* Array with the object container*/
+    Tcl_HashEntry *entryPtr;   /* Entry in array table. */
+    Tcl_HashEntry *handlePtr;  /* Entry in handles table */
+    Tcl_Obj *tclObj;           /* Tcl object to hold shared values */
+    int epoch;                 /* Track object changes */
+    char *chunkAddr;           /* Address of one chunk of object containers */
+    struct Container *nextPtr; /* Next object container in the free list */
+} Container;
+
+/*
+ * Structure for generating command names in Tcl
+ */
+
+typedef struct SvCmdInfo {
+    char *name;                 /* The short name of the command */
+    char *cmdName;              /* Real (rewritten) name of the command */
+    Tcl_ObjCmdProc *objProcPtr; /* The object-based command procedure */
+    Tcl_CmdDeleteProc *delProcPtr; /* Pointer to command delete function */
+    ClientData *clientData;     /* Pointer passed to above command */
+    struct SvCmdInfo *nextPtr;  /* Next in chain of registered commands */
+} SvCmdInfo;
+
+/*
+ * Structure for registering special object duplicator functions.
+ * Reason for this is that even some regular Tcl duplicators
+ * produce shallow instead of proper deep copies of the object.
+ * While this is considered to be ok in single-threaded apps,
+ * a multithreaded app could have problems when accessing objects
+ * which live in (i.e. are accessed from) different interpreters.
+ * So, for each object type which should be stored in shared object
+ * pools, we must assure that the object is copied properly.
+ */
+
+typedef struct RegType {
+    const Tcl_ObjType *typePtr;       /* Type of the registered object */
+    Tcl_DupInternalRepProc *dupIntRepProc; /* Special deep-copy duper */
+    struct RegType *nextPtr;    /* Next in chain of registered types */
+} RegType;
+
+/*
+ * Limited API functions
+ */
+
+void 
+Sv_RegisterCommand(const char*,Tcl_ObjCmdProc*,Tcl_CmdDeleteProc*,ClientData);
+
+void 
+Sv_RegisterObjType(const Tcl_ObjType*, Tcl_DupInternalRepProc*);
+
+void 
+Sv_RegisterPsStore(PsStore*);
+
+int
+Sv_GetContainer(Tcl_Interp*,int,Tcl_Obj*const objv[],Container**,int*,int);
+
+int
+Sv_PutContainer(Tcl_Interp*, Container*, int);
+
+/*
+ * Private version of Tcl_DuplicateObj which takes care about
+ * copying objects when loaded to and retrieved from shared array.
+ */
+
+Tcl_Obj* Sv_DuplicateObj(Tcl_Obj*);
+
+#endif /* _SV_H_ */
+
+/* EOF $RCSfile: threadSvCmd.h,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
diff --git a/8.x/thread/generic/threadSvKeylistCmd.c b/8.x/thread/generic/threadSvKeylistCmd.c
new file mode 100644 (file)
index 0000000..93dd7c5
--- /dev/null
@@ -0,0 +1,364 @@
+/* 
+ * threadSvKeylist.c --
+ *
+ * This file implements keyed-list commands as part of the thread
+ * shared variable implementation.
+ *
+ * Keyed list implementation is borrowed from Mark Diekhans and
+ * Karl Lehenbauer "TclX" (extended Tcl) extension. Please look
+ * into the keylist.c file for more information.
+ *
+ * See the file "license.txt" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Rcsid: @(#)$Id: threadSvKeylistCmd.c,v 1.3 2009/07/22 11:25:34 nijtmans Exp $
+ * ---------------------------------------------------------------------------
+ */
+
+#include "threadSvCmd.h"
+#include "tclXkeylist.h"
+
+/*
+ * This is defined in keylist.c. We need it here
+ * to be able to plug-in our custom keyed-list
+ * object duplicator which produces proper deep
+ * copies of the keyed-list objects. The standard
+ * one produces shallow copies which are not good
+ * for usage in the thread shared variables code.
+ */
+
+extern Tcl_ObjType keyedListType;
+
+/*
+ * Wrapped keyed-list commands
+ */
+
+static Tcl_ObjCmdProc SvKeylsetObjCmd;
+static Tcl_ObjCmdProc SvKeylgetObjCmd;
+static Tcl_ObjCmdProc SvKeyldelObjCmd;
+static Tcl_ObjCmdProc SvKeylkeysObjCmd;
+
+/*
+ * This mutex protects a static variable which tracks
+ * registration of commands and object types.
+ */
+
+static Tcl_Mutex initMutex;
+
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_RegisterKeylistCommands --
+ *
+ *      Register shared variable commands for TclX keyed lists.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      Memory gets allocated
+ *
+ *-----------------------------------------------------------------------------
+ */
+void
+Sv_RegisterKeylistCommands(void)
+{
+    static int initialized;
+
+    if (initialized == 0) {
+        Tcl_MutexLock(&initMutex);
+        if (initialized == 0) {
+            Sv_RegisterCommand("keylset",  SvKeylsetObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("keylget",  SvKeylgetObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("keyldel",  SvKeyldelObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("keylkeys", SvKeylkeysObjCmd, NULL, NULL);
+            Sv_RegisterObjType(&keyedListType, DupKeyedListInternalRepShared);
+            initialized = 1;
+        }
+        Tcl_MutexUnlock(&initMutex);
+    }
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvKeylsetObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::keylset" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvKeylsetObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int i, off, ret, flg;
+    char *key;
+    Tcl_Obj *val;
+    Container *svObj = (Container*)arg;
+    
+    /*
+     * Syntax: 
+     *          sv::keylset array lkey key value ?key value ...?
+     *          $keylist keylset key value ?key value ...?
+     */
+
+    flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) < 2 || ((objc - off) % 2)) {
+        Tcl_WrongNumArgs(interp, off, objv, "key value ?key value ...?");
+        goto cmd_err;   
+    }
+    for (i = off; i < objc; i += 2) {
+        key = Tcl_GetString(objv[i]);
+        val = Sv_DuplicateObj(objv[i+1]);
+        ret = TclX_KeyedListSet(interp, svObj->tclObj, key, val);
+        if (ret != TCL_OK) {
+            goto cmd_err;
+        } 
+    }
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvKeylgetObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::keylget" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvKeylgetObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int ret, flg, off;
+    char *key;
+    Tcl_Obj *varObjPtr = NULL, *valObjPtr = NULL;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax: 
+     *          sv::keylget array lkey ?key? ?var?
+     *          $keylist keylget ?key? ?var?
+     */
+
+    flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) > 2) {
+        Tcl_WrongNumArgs(interp, off, objv, "?key? ?var?");
+        goto cmd_err;   
+    }
+    if ((objc - off) == 0) {
+        if (Sv_PutContainer(interp, svObj, SV_UNCHANGED) != TCL_OK) {
+            return TCL_ERROR;
+        }
+        return SvKeylkeysObjCmd(arg, interp, objc, objv);
+    }
+    if ((objc - off) == 2) {
+        varObjPtr = objv[off+1];
+    } else {
+        varObjPtr = NULL;
+    }
+    
+    key = Tcl_GetString(objv[off]);
+    ret = TclX_KeyedListGet(interp, svObj->tclObj, key, &valObjPtr);
+    if (ret == TCL_ERROR) {
+        goto cmd_err;
+    }
+
+    if (ret == TCL_BREAK) {
+        if (varObjPtr) {
+            Tcl_ResetResult(interp);
+            Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0);
+        } else {
+            Tcl_AppendResult (interp, "key \"", key, "\" not found", NULL);
+            goto cmd_err;
+        }
+    } else {
+        Tcl_Obj *resObjPtr = Sv_DuplicateObj(valObjPtr);
+        if (varObjPtr) {
+            int len;
+            Tcl_ResetResult(interp);
+            Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1);
+            Tcl_GetStringFromObj(varObjPtr, &len);
+            if (len) {
+                Tcl_ObjSetVar2(interp, varObjPtr, NULL, resObjPtr, 0);
+            }
+        } else {
+            Tcl_SetObjResult(interp, resObjPtr);
+        }
+    }
+
+    return Sv_PutContainer(interp, svObj, SV_UNCHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvKeyldelObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::keyldel" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvKeyldelObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int i, off, ret;
+    char *key;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax: 
+     *          sv::keyldel array lkey key ?key ...?
+     *          $keylist keyldel ?key ...?
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) < 1) {
+        Tcl_WrongNumArgs(interp, off, objv, "key ?key ...?");
+        goto cmd_err;
+    }
+    for (i = off; i < objc; i++) {
+        key = Tcl_GetString(objv[i]);
+        ret = TclX_KeyedListDelete(interp, svObj->tclObj, key);
+        if (ret == TCL_BREAK) {
+            Tcl_AppendResult(interp, "key \"", key, "\" not found", NULL);
+        }
+        if (ret == TCL_BREAK || ret == TCL_ERROR) {
+            goto cmd_err;
+        }
+    }
+    
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvKeylkeysObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::keylkeys" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvKeylkeysObjCmd(arg, interp, objc, objv)
+    ClientData arg;                     /* Not used. */
+    Tcl_Interp *interp;                 /* Current interpreter. */
+    int objc;                           /* Number of arguments. */
+    Tcl_Obj *const objv[];              /* Argument objects. */
+{
+    int ret, off;
+    char *key = NULL;
+    Tcl_Obj *listObj = NULL;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax: 
+     *          sv::keylkeys array lkey ?key?
+     *          $keylist keylkeys ?key?
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) > 1) {
+         Tcl_WrongNumArgs(interp, 1, objv, "?lkey?");
+         goto cmd_err;
+    }
+    if ((objc - off) == 1) {
+        key = Tcl_GetString(objv[off]);
+    }
+
+    ret = TclX_KeyedListGetKeys(interp, svObj->tclObj, key, &listObj);
+
+    if (key && ret == TCL_BREAK) {
+        Tcl_AppendResult(interp, "key \"", key, "\" not found", NULL);
+    }
+    if (ret == TCL_BREAK || ret == TCL_ERROR) {
+        goto cmd_err;
+    }
+
+    Tcl_SetObjResult (interp, listObj); /* listObj allocated by API !*/
+    
+    return Sv_PutContainer(interp, svObj, SV_UNCHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+
+/* EOF $RCSfile: threadSvKeylistCmd.c,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
diff --git a/8.x/thread/generic/threadSvKeylistCmd.h b/8.x/thread/generic/threadSvKeylistCmd.h
new file mode 100644 (file)
index 0000000..147312b
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * threadSvKeylistCmd.h --
+ *
+ * See the file "license.txt" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Rcsid: @(#)$Id: threadSvKeylistCmd.h,v 1.2 2004/08/14 20:36:27 vasiljevic Exp $
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _KEYLISTCMDS_H_
+#define _KEYLISTCMDS_H_
+
+void Sv_RegisterKeylistCommands(void);
+void TclX_KeyedListInit(Tcl_Interp *interp);
+
+#endif /* _KEYLISTCMDS_H_ */
+
+/* EOF $RCSfile: threadSvKeylistCmd.h,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
diff --git a/8.x/thread/generic/threadSvListCmd.c b/8.x/thread/generic/threadSvListCmd.c
new file mode 100644 (file)
index 0000000..7294eb1
--- /dev/null
@@ -0,0 +1,1163 @@
+/*
+ * Implementation of most standard Tcl list processing commands
+ * suitable for operation on thread shared (list) variables.
+ *
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: threadSvListCmd.c,v 1.11 2009/07/22 11:25:34 nijtmans Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#include "threadSvCmd.h"
+
+/*
+ * Implementation of list commands for shared variables.
+ * Most of the standard Tcl list commands are implemented.
+ * There are also two new commands: "lpop" and "lpush".
+ * Those are very convenient for simple stack operations.
+ *
+ * Main difference to standard Tcl commands is that our commands
+ * operate on list variable per-reference instead per-value.
+ * This way we avoid frequent object shuffling between shared 
+ * containers and current interpreter, thus increasing speed.
+ */
+
+static Tcl_ObjCmdProc SvLpopObjCmd;      /* lpop        */
+static Tcl_ObjCmdProc SvLpushObjCmd;     /* lpush       */
+static Tcl_ObjCmdProc SvLappendObjCmd;   /* lappend     */
+static Tcl_ObjCmdProc SvLreplaceObjCmd;  /* lreplace    */
+static Tcl_ObjCmdProc SvLlengthObjCmd;   /* llength     */
+static Tcl_ObjCmdProc SvLindexObjCmd;    /* lindex      */
+static Tcl_ObjCmdProc SvLinsertObjCmd;   /* linsert     */
+static Tcl_ObjCmdProc SvLrangeObjCmd;    /* lrange      */
+static Tcl_ObjCmdProc SvLsearchObjCmd;   /* lsearch     */
+static Tcl_ObjCmdProc SvLsetObjCmd;      /* lset        */
+
+/*
+ * These two are copied verbatim from the tclUtil.c
+ * since not found in the public stubs table.
+ * I was just too lazy to rewrite them from scratch.
+ */
+
+static int SvCheckBadOctal(Tcl_Interp*, const char *);
+static int SvGetIntForIndex(Tcl_Interp*,  Tcl_Obj *, int, int*);
+
+/*
+ * Inefficient list duplicator function which,
+ * however, produces deep list copies, unlike
+ * the original, which just makes shallow copies.
+ */
+
+static void DupListObjShared(Tcl_Obj*, Tcl_Obj*);
+
+/*
+ * This mutex protects a static variable which tracks
+ * registration of commands and object types.
+ */
+
+static Tcl_Mutex initMutex;
+
+/*
+ * Functions for implementing the "lset" list command
+ */
+
+static Tcl_Obj*
+SvLsetFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, int indexCount,
+           Tcl_Obj **indexArray, Tcl_Obj *valuePtr);
+
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Sv_RegisterListCommands --
+ *
+ *      Register list commands with shared variable module.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      Memory gets allocated
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+Sv_RegisterListCommands(void)
+{
+    static int initialized = 0;
+
+    if (initialized == 0) {
+        Tcl_MutexLock(&initMutex);
+        if (initialized == 0) {
+            Sv_RegisterCommand("lpop",     SvLpopObjCmd,     NULL, NULL);
+            Sv_RegisterCommand("lpush",    SvLpushObjCmd,    NULL, NULL);
+            Sv_RegisterCommand("lappend",  SvLappendObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("lreplace", SvLreplaceObjCmd, NULL, NULL);
+            Sv_RegisterCommand("linsert",  SvLinsertObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("llength",  SvLlengthObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("lindex",   SvLindexObjCmd,   NULL, NULL);
+            Sv_RegisterCommand("lrange",   SvLrangeObjCmd,   NULL, NULL);
+            Sv_RegisterCommand("lsearch",  SvLsearchObjCmd,  NULL, NULL);
+            Sv_RegisterCommand("lset",     SvLsetObjCmd,     NULL, NULL);
+            Sv_RegisterObjType(Tcl_GetObjType("list"), DupListObjShared);
+            initialized = 1;
+        }
+        Tcl_MutexUnlock(&initMutex);
+    }
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLpopObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::lpop" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLpopObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    int ret, off, llen, index = 0, iarg = 0;
+    Tcl_Obj *elPtr = NULL;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::lpop array key ?index?
+     *          $list lpop ?index?
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) > 1) {
+        Tcl_WrongNumArgs(interp, off, objv, "?index?");
+        goto cmd_err;
+    }
+    if ((objc - off) == 1) {
+        iarg = off;
+    }
+    ret = Tcl_ListObjLength(interp, svObj->tclObj, &llen);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    if (iarg) {
+        ret = SvGetIntForIndex(interp, objv[iarg], llen-1, &index);
+        if (ret != TCL_OK) {
+            goto cmd_err;
+        }
+    }
+    if (index < 0 || index >= llen) {
+        goto cmd_ok; /* Ignore out-of bounds, like Tcl does */
+    }
+    ret = Tcl_ListObjIndex(interp, svObj->tclObj, index, &elPtr);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+
+    Tcl_IncrRefCount(elPtr);
+    ret = Tcl_ListObjReplace(interp, svObj->tclObj, index, 1, 0, NULL);
+    if (ret != TCL_OK) {
+        Tcl_DecrRefCount(elPtr);
+        goto cmd_err;
+    }
+    Tcl_SetObjResult(interp, elPtr);
+    Tcl_DecrRefCount(elPtr);
+
+ cmd_ok:
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLpushObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::lpush" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLpushObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    int off, ret, flg, llen, index = 0;
+    Tcl_Obj *args[1];
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::lpush array key element ?index?
+     *          $list lpush element ?index?
+     */
+
+    flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) < 1) {
+        Tcl_WrongNumArgs(interp, off, objv, "element ?index?");
+        goto cmd_err;
+    }
+    ret = Tcl_ListObjLength(interp, svObj->tclObj, &llen);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    if ((objc - off) == 2) {
+        ret = SvGetIntForIndex(interp, objv[off+1], llen, &index);
+        if (ret != TCL_OK) {
+            goto cmd_err;
+        }
+        if (index < 0) {
+            index = 0;
+        } else if (index > llen) {
+            index = llen;
+        }
+    }
+
+    args[0] = Sv_DuplicateObj(objv[off]);
+    ret = Tcl_ListObjReplace(interp, svObj->tclObj, index, 0, 1, args);
+    if (ret != TCL_OK) {
+        Tcl_DecrRefCount(args[0]);
+        goto cmd_err;
+    }
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLappendObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::lappend" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLappendObjCmd(arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    int i, ret, flg, off;
+    Tcl_Obj *dup;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::lappend array key value ?value ...?
+     *          $list lappend value ?value ...?
+     */
+
+    flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) < 1) {
+        Tcl_WrongNumArgs(interp, off, objv, "value ?value ...?");
+        goto cmd_err;
+    }
+    for (i = off; i < objc; i++) {
+        dup = Sv_DuplicateObj(objv[i]);
+        ret = Tcl_ListObjAppendElement(interp, svObj->tclObj, dup);
+        if (ret != TCL_OK) {
+            Tcl_DecrRefCount(dup);
+            goto cmd_err;
+        }
+    }
+
+    Tcl_SetObjResult(interp, Sv_DuplicateObj(svObj->tclObj));
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLreplaceObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::lreplace" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLreplaceObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    const char *firstArg;
+    int argLen, ret, off, llen, first, last, ndel, nargs, i, j;
+    Tcl_Obj **args = NULL;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::lreplace array key first last ?element ...?
+     *          $list lreplace first last ?element ...?
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) < 2) {
+        Tcl_WrongNumArgs(interp, off, objv, "first last ?element ...?");
+        goto cmd_err;
+    }
+    ret = Tcl_ListObjLength(interp, svObj->tclObj, &llen);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    ret = SvGetIntForIndex(interp, objv[off], llen-1, &first);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    ret = SvGetIntForIndex(interp, objv[off+1], llen-1, &last);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+
+    firstArg = Tcl_GetStringFromObj(objv[off], &argLen);
+    if (first < 0)  {
+        first = 0;
+    }
+    if (llen && first >= llen && strncmp(firstArg, "end", argLen)) {
+        Tcl_AppendResult(interp, "list doesn't have element ", firstArg, NULL);
+        goto cmd_err;
+    }
+    if (last >= llen) {
+        last = llen - 1;
+    }
+    if (first <= last) {
+        ndel = last - first + 1;
+    } else {
+        ndel = 0;
+    }
+
+    nargs = objc - (off + 2);
+    if (nargs) {
+        args = (Tcl_Obj**)Tcl_Alloc(nargs * sizeof(Tcl_Obj*));
+        for(i = off + 2, j = 0; i < objc; i++, j++) {
+            args[j] = Sv_DuplicateObj(objv[i]);
+        }
+    }
+
+    ret = Tcl_ListObjReplace(interp, svObj->tclObj, first, ndel, nargs, args);
+    if (args) {
+        if (ret != TCL_OK) {
+            for(i = off + 2, j = 0; i < objc; i++, j++) {
+                Tcl_DecrRefCount(args[j]);
+            }
+        }
+        Tcl_Free((char*)args);
+    }
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLrangeObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::lrange" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLrangeObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    int ret, off, llen, first, last, nargs, i, j;
+    Tcl_Obj **elPtrs, **args;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::lrange array key first last
+     *          $list lrange first last
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) != 2) {
+        Tcl_WrongNumArgs(interp, off, objv, "first last");
+        goto cmd_err;
+    }
+    ret = Tcl_ListObjGetElements(interp, svObj->tclObj, &llen, &elPtrs);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    ret = SvGetIntForIndex(interp, objv[off], llen-1, &first);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    ret = SvGetIntForIndex(interp, objv[off+1], llen-1, &last);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    if (first < 0)  {
+        first = 0;
+    }
+    if (last >= llen) {
+        last = llen - 1;
+    }
+    if (first > last) {
+        goto cmd_ok;
+    }
+
+    nargs = last - first + 1;
+    args  = (Tcl_Obj**)Tcl_Alloc(nargs * sizeof(Tcl_Obj*));
+    for (i = first, j = 0; i <= last; i++, j++) {
+        args[j] = Sv_DuplicateObj(elPtrs[i]);
+    }
+
+    Tcl_ResetResult(interp);
+    Tcl_SetListObj(Tcl_GetObjResult(interp), nargs, args);
+    Tcl_Free((char*)args);
+
+ cmd_ok:
+    return Sv_PutContainer(interp, svObj, SV_UNCHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLinsertObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::linsert" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLinsertObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    int off, ret, flg, llen, nargs, index = 0, i, j;
+    Tcl_Obj **args;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::linsert array key index element ?element ...?
+     *          $list linsert element ?element ...?
+     */
+
+    flg = FLAGS_CREATEARRAY | FLAGS_CREATEVAR;
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, flg);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) < 2) {
+        Tcl_WrongNumArgs(interp, off, objv, "index element ?element ...?");
+        goto cmd_err;
+    }
+    ret = Tcl_ListObjLength(interp, svObj->tclObj, &llen);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    ret = SvGetIntForIndex(interp, objv[off], llen, &index);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    if (index < 0) {
+        index = 0;
+    } else if (index > llen) {
+        index = llen;
+    }
+
+    nargs = objc - (off + 1);
+    args  = (Tcl_Obj**)Tcl_Alloc(nargs * sizeof(Tcl_Obj*));
+    for (i = off + 1, j = 0; i < objc; i++, j++) {
+         args[j] = Sv_DuplicateObj(objv[i]);
+    }
+    ret = Tcl_ListObjReplace(interp, svObj->tclObj, index, 0, nargs, args);
+    if (ret != TCL_OK) {
+        for (i = off + 1, j = 0; i < objc; i++, j++) {
+            Tcl_DecrRefCount(args[j]);
+        }
+        Tcl_Free((char*)args);
+        goto cmd_err;
+    }
+
+    Tcl_Free((char*)args);
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLlengthObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::llength" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLlengthObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    int llen, off, ret;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::llength array key
+     *          $list llength
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+
+    ret = Tcl_ListObjLength(interp, svObj->tclObj, &llen);
+    if (ret == TCL_OK) {
+        Tcl_ResetResult(interp);
+        Tcl_SetIntObj(Tcl_GetObjResult(interp), llen);
+    }
+    if (Sv_PutContainer(interp, svObj, SV_UNCHANGED) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    
+    return ret;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLsearchObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::lsearch" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLsearchObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    int ret, off, listc, mode, imode, ipatt, length, index, match, i;
+    const char *patBytes;
+    Tcl_Obj **listv;
+    Container *svObj = (Container*)arg;
+
+    static const char *modes[] = {"-exact", "-glob", "-regexp", NULL};
+    enum {LS_EXACT, LS_GLOB, LS_REGEXP};
+
+    mode = LS_GLOB;
+
+    /*
+     * Syntax:
+     *          tsv::lsearch array key ?mode? pattern
+     *          $list lsearch ?mode? pattern
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) == 2) {
+        imode = off;
+        ipatt = off + 1;
+    } else if ((objc - off) == 1) {
+        imode = 0;
+        ipatt = off;
+    } else {
+        Tcl_WrongNumArgs(interp, off, objv, "?mode? pattern");
+        goto cmd_err;
+    }
+    if (imode) {
+        ret = Tcl_GetIndexFromObj(interp, objv[imode], modes, "search mode",
+                0, &mode);
+        if (ret != TCL_OK) {
+            goto cmd_err;
+        }
+    }
+    ret = Tcl_ListObjGetElements(interp, svObj->tclObj, &listc, &listv);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+
+    index = -1;
+    patBytes = Tcl_GetStringFromObj(objv[ipatt], &length);
+
+    for (i = 0; i < listc; i++) {
+        match = 0;
+        switch (mode) {
+        case LS_GLOB:
+            match = Tcl_StringMatch(Tcl_GetString(listv[i]), patBytes);
+            break;
+
+        case LS_EXACT: {
+            int elemLen;
+            const char *bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
+            if (length == elemLen) {
+                match = (memcmp(bytes, patBytes, (size_t)length) == 0);
+            }
+            break;
+        }
+        case LS_REGEXP:
+            match = Tcl_RegExpMatchObj(interp, listv[i], objv[ipatt]);
+            if (match < 0) {
+                goto cmd_err;
+            }
+            break;
+        }
+        if (match) {
+            index = i;
+            break;
+        }
+    }
+
+    Tcl_ResetResult(interp);
+    Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
+
+    return Sv_PutContainer(interp, svObj, SV_UNCHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLindexObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::lindex" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLindexObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    Tcl_Obj **elPtrs;
+    int ret, off, llen, index;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::lindex array key index
+     *          $list lindex index
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) != 1) {
+        Tcl_WrongNumArgs(interp, off, objv, "index");
+        goto cmd_err;
+    }
+    ret = Tcl_ListObjGetElements(interp, svObj->tclObj, &llen, &elPtrs);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    ret = SvGetIntForIndex(interp, objv[off], llen-1, &index);
+    if (ret != TCL_OK) {
+        goto cmd_err;
+    }
+    if (index >= 0 && index < llen) {
+        Tcl_SetObjResult(interp, Sv_DuplicateObj(elPtrs[index]));
+    }
+
+    return Sv_PutContainer(interp, svObj, SV_UNCHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvLsetObjCmd --
+ *
+ *      This procedure is invoked to process the "tsv::lset" command.
+ *      See the user documentation for details on what it does.
+ *
+ * Results:
+ *      A standard Tcl result.
+ *
+ * Side effects:
+ *      See the user documentation.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvLsetObjCmd (arg, interp, objc, objv)
+    ClientData arg;
+    Tcl_Interp *interp;
+    int objc;
+    Tcl_Obj *const objv[];
+{
+    Tcl_Obj *lPtr;
+    int ret, argc, off;
+    Container *svObj = (Container*)arg;
+
+    /*
+     * Syntax:
+     *          tsv::lset array key index ?index ...? value
+     *          $list lset index ?index ...? value
+     */
+
+    ret = Sv_GetContainer(interp, objc, objv, &svObj, &off, 0);
+    if (ret != TCL_OK) {
+        return TCL_ERROR;
+    }
+    if ((objc - off) < 2) {
+        Tcl_WrongNumArgs(interp, off, objv, "index ?index...? value");
+        goto cmd_err;
+    }
+
+    lPtr = svObj->tclObj;
+    argc = objc - off - 1;
+
+    if (!SvLsetFlat(interp, lPtr, argc, (Tcl_Obj**)(objv+off),objv[objc-1])) {
+        return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Sv_DuplicateObj(lPtr));
+
+    return Sv_PutContainer(interp, svObj, SV_CHANGED);
+
+ cmd_err:
+    return Sv_PutContainer(interp, svObj, SV_ERROR);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DupListObjShared --
+ *
+ *      Help function to make a proper deep copy of the list object.
+ *      This is used as the replacement-hook for list object native
+ *      DupInternalRep function. We need it since the native function
+ *      does a shallow list copy, i.e. retains references to list
+ *      element objects from the original list. This gives us trouble
+ *      when making the list object shared between threads.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects;
+ *      This is not a very efficient implementation, but that's all what's
+ *      available to Tcl API programmer. We could include the tclInt.h and
+ *      get the copy more efficient using list internals, but ...
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+DupListObjShared(srcPtr, copyPtr)
+    Tcl_Obj *srcPtr;            /* Object with internal rep to copy. */
+    Tcl_Obj *copyPtr;           /* Object with internal rep to set. */
+{
+    int i, llen;
+    Tcl_Obj *elObj, **newObjList;
+
+    Tcl_ListObjLength(NULL, srcPtr, &llen);
+    if (llen == 0) { 
+        (*srcPtr->typePtr->dupIntRepProc)(srcPtr, copyPtr);
+        copyPtr->refCount = 0;
+        return;
+    }
+
+    newObjList = (Tcl_Obj**)Tcl_Alloc(llen*sizeof(Tcl_Obj*));
+
+    for (i = 0; i < llen; i++) {
+        Tcl_ListObjIndex(NULL, srcPtr, i, &elObj);
+        newObjList[i] = Sv_DuplicateObj(elObj);
+    }
+
+    Tcl_SetListObj(copyPtr, llen, newObjList);
+
+    Tcl_Free((char*)newObjList);
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvCheckBadOctal --
+ *
+ *  Exact copy from the TclCheckBadOctal found in tclUtil.c
+ *  since this is not in the stubs table.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvCheckBadOctal(interp, value)
+    Tcl_Interp *interp;     /* Interpreter to use for error reporting.
+                             * If NULL, then no error message is left
+                             * after errors. */
+    const char *value;      /* String to check. */
+{
+    register const char *p = value;
+
+    /*
+     * A frequent mistake is invalid octal values due to an unwanted
+     * leading zero. Try to generate a meaningful error message.
+     */
+
+    while (isspace((unsigned char)(*p))) { /* INTL: ISO space. */
+        p++;
+    }
+    if (*p == '+' || *p == '-') {
+        p++;
+    }
+    if (*p == '0') {
+        while (isdigit((unsigned char)(*p))) { /* INTL: digit. */
+            p++;
+        }
+        while (isspace((unsigned char)(*p))) { /* INTL: ISO space. */
+            p++;
+        }
+        if (*p == '\0') {
+            /* Reached end of string */
+            if (interp != NULL) {
+                Tcl_AppendResult(interp, " (looks like invalid octal number)",
+                        (char *) NULL);
+            }
+            return 1;
+        }
+    }
+    return 0;
+}
+\f
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SvGetIntForIndex --
+ *
+ *  Exact copy from the TclGetIntForIndex found in tclUtil.c
+ *  since this is not in the stubs table.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+SvGetIntForIndex(interp, objPtr, endValue, indexPtr)
+    Tcl_Interp *interp;     /* Interpreter to use for error reporting.
+                             * If NULL, then no error message is left
+                             * after errors. */
+    Tcl_Obj *objPtr;        /* Points to an object containing either
+                             * "end" or an integer. */
+    int endValue;           /* The value to be stored at "indexPtr" if
+                             * "objPtr" holds "end". */
+    int *indexPtr;          /* Location filled in with an integer
+                             * representing an index. */
+{
+    const char *bytes;
+    int length, offset;
+
+    bytes = Tcl_GetStringFromObj(objPtr, &length);
+
+    if ((*bytes != 'e')
+        || (strncmp(bytes, "end",(size_t)((length > 3) ? 3 : length)) != 0)) {
+        if (Tcl_GetIntFromObj(NULL, objPtr, &offset) != TCL_OK) {
+            goto intforindex_error;
+        }
+        *indexPtr = offset;
+        return TCL_OK;
+    }
+    if (length <= 3) {
+        *indexPtr = endValue;
+    } else if (bytes[3] == '-') {
+        /*
+         * This is our limited string expression evaluator
+         */
+        if (Tcl_GetInt(interp, bytes+3, &offset) != TCL_OK) {
+            return TCL_ERROR;
+        }
+        *indexPtr = endValue + offset;
+    } else {
+  intforindex_error:
+        if (interp != NULL) {
+            Tcl_ResetResult(interp);
+            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "bad index \"",
+                    bytes, "\": must be integer or end?-integer?",(char*)NULL);
+            SvCheckBadOctal(interp, bytes);
+        }
+        return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * SvLsetFlat --
+ *
+ *  Almost exact copy from the TclLsetFlat found in tclListObj.c.
+ *  Simplified in a sense that thread shared objects are guaranteed
+ *  to be non-shared.
+ *
+ *  Actual return value of this procedure is irrelevant to the caller,
+ *  and it should be either NULL or non-NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj*
+SvLsetFlat(interp, listPtr, indexCount, indexArray, valuePtr)
+     Tcl_Interp *interp;     /* Tcl interpreter */
+     Tcl_Obj *listPtr;       /* Pointer to the list being modified */
+     int indexCount;         /* Number of index args */
+     Tcl_Obj **indexArray;
+     Tcl_Obj *valuePtr;      /* Value arg to 'lset' */
+{
+    int elemCount, index, result, i;
+    Tcl_Obj **elemPtrs, *chainPtr, *subListPtr;
+
+    /*
+     * Determine whether the index arg designates a list
+     * or a single index.
+     */
+
+    if (indexCount == 1 &&
+        Tcl_ListObjGetElements(interp, indexArray[0], &indexCount, 
+                               &indexArray) != TCL_OK) {
+        /*
+         * Index arg designates something that is neither an index
+         * nor a well formed list.
+         */
+
+        return NULL;
+    }
+
+    /*
+     * If there are no indices, then simply return the new value,
+     * counting the returned pointer as a reference
+     */
+
+    if (indexCount == 0) {
+        return valuePtr;
+    }
+
+    /*
+     * Anchor the linked list of Tcl_Obj's whose string reps must be
+     * invalidated if the operation succeeds.
+     */
+
+    chainPtr = NULL;
+
+    /*
+     * Handle each index arg by diving into the appropriate sublist
+     */
+
+    for (i = 0; ; ++i) {
+
+        /*
+         * Take the sublist apart.
+         */
+
+        result = Tcl_ListObjGetElements(interp,listPtr,&elemCount,&elemPtrs);
+        if (result != TCL_OK) {
+            break;
+        }
+
+        listPtr->internalRep.twoPtrValue.ptr2 = (VOID*)chainPtr;
+
+        /*
+         * Determine the index of the requested element.
+         */
+
+        result = SvGetIntForIndex(interp, indexArray[i], elemCount-1, &index);
+        if (result != TCL_OK) {
+            break;
+        }
+        
+        /*
+         * Check that the index is in range.
+         */
+        
+        if (index < 0 || index >= elemCount) {
+            Tcl_SetObjResult(interp,
+                             Tcl_NewStringObj("list index out of range", -1));
+            result = TCL_ERROR;
+            break;
+        }
+
+        /*
+         * Break the loop after extracting the innermost sublist
+         */
+
+        if (i >= (indexCount - 1)) {
+            result = TCL_OK;
+            break;
+        }
+    
+        /*
+         * Extract the appropriate sublist and chain it onto the linked
+         * list of Tcl_Obj's whose string reps must be spoilt.
+         */
+
+        subListPtr = elemPtrs[index];
+        chainPtr = listPtr;
+        listPtr = subListPtr;
+    }
+
+    /* Store the result in the list element */
+
+    if (result == TCL_OK) {
+        result = Tcl_ListObjGetElements(interp,listPtr,&elemCount,&elemPtrs);
+        if (result == TCL_OK) {
+            Tcl_DecrRefCount(elemPtrs[index]);
+            elemPtrs[index] = Sv_DuplicateObj(valuePtr);
+            Tcl_IncrRefCount(elemPtrs[index]);
+        }
+    }
+
+    if (result == TCL_OK) {
+        listPtr->internalRep.twoPtrValue.ptr2 = (VOID*)chainPtr;
+        /* Spoil all the string reps */
+        while (listPtr != NULL) {
+            subListPtr = (Tcl_Obj*)listPtr->internalRep.twoPtrValue.ptr2;
+            Tcl_InvalidateStringRep(listPtr);
+            listPtr->internalRep.twoPtrValue.ptr2 = NULL;
+            listPtr = subListPtr;
+        }
+        
+        return valuePtr;
+    }
+    
+    return NULL;
+}
+
+/* EOF $RCSfile: threadSvListCmd.c,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
diff --git a/8.x/thread/generic/threadSvListCmd.h b/8.x/thread/generic/threadSvListCmd.h
new file mode 100644 (file)
index 0000000..70bd942
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2002 by Zoran Vasiljevic.
+ *
+ * See the file "license.txt" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Rcsid: @(#)$Id: threadSvListCmd.h,v 1.2 2002/12/05 15:14:09 vasiljevic Exp $
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _SV_LIST_H_
+#define _SV_LIST_H_
+
+void Sv_RegisterListCommands();
+
+#endif /* _SV_LIST_H_ */
+
+/* EOF $RCSfile: threadSvListCmd.h,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
+
diff --git a/8.x/thread/lib/ttrace.tcl b/8.x/thread/lib/ttrace.tcl
new file mode 100644 (file)
index 0000000..118838b
--- /dev/null
@@ -0,0 +1,939 @@
+#
+# ttrace.tcl --
+#
+# Copyright (C) 2003 Zoran Vasiljevic, Archiware GmbH. All Rights Reserved.
+# 
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Rcsid: @(#)$Id: ttrace.tcl,v 1.13 2010/05/27 16:07:14 andreas_kupries Exp $
+# ----------------------------------------------------------------------------
+#
+# User level commands:
+#
+#   ttrace::eval           top-level wrapper (ttrace-savvy eval)
+#   ttrace::enable         activates registered Tcl command traces
+#   ttrace::disable        terminates tracing of Tcl commands
+#   ttrace::isenabled      returns true if ttrace is enabled
+#   ttrace::cleanup        bring the interp to a pristine state
+#   ttrace::update         update interp to the latest trace epoch
+#   ttrace::config         setup some configuration options
+#   ttrace::getscript      returns a script for initializing interps
+#
+# Commands used for/from trace callbacks:
+#
+#   ttrace::atenable       register callback to be done at trace enable
+#   ttrace::atdisable      register callback to be done at trace disable
+#   ttrace::addtrace       register user-defined tracer callback
+#   ttrace::addscript      register user-defined script generator
+#   ttrace::addresolver    register user-defined command resolver
+#   ttrace::addcleanup     register user-defined cleanup procedures
+#   ttrace::addentry       adds one entry into the named trace store
+#   ttrace::getentry       returns the entry value from the named store
+#   ttrace::delentry       removes the entry from the named store
+#   ttrace::getentries     returns all entries from the named store
+#   ttrace::preload        register procedures to be preloaded always
+#
+#
+# Limitations:
+#
+#   o. [namespace forget] is still not implemented
+#   o. [namespace origin cmd] breaks if cmd is not already defined
+#
+#      I left this deliberately. I didn't want to override the 
+#      [namespace] command in order to avoid potential slowdown.
+#
+
+namespace eval ttrace {
+
+    # Setup some compatibility wrappers
+    if {[info commands nsv_set] != ""} {
+        variable tvers 0
+        variable mutex ns_mutex
+        variable elock [$mutex create traceepochmutex]
+        variable store nsv_
+    } elseif {![catch {package require Thread} version]} {
+        variable tvers $version
+        variable mutex thread::mutex
+        variable elock [$mutex create]
+        variable store tsv::
+    } else {
+        error "requires AOLserver or Tcl threading extension"
+    }
+
+    # Keep in sync with the Thread package
+    package provide Ttrace 2.6.6
+
+    # Package variables
+    variable resolvers ""     ; # List of registered resolvers
+    variable tracers   ""     ; # List of registered cmd tracers
+    variable scripts   ""     ; # List of registered script makers
+    variable enables   ""     ; # List of trace-enable callbacks
+    variable disables  ""     ; # List of trace-disable callbacks
+    variable preloads  ""     ; # List of procedure names to preload
+    variable enabled   0      ; # True if trace is enabled
+    variable config           ; # Array with config options
+
+    variable epoch     -1     ; # The initialization epoch
+    variable cleancnt   0     ; # Counter of registered cleaners
+
+    # Package private namespaces
+    namespace eval resolve "" ; # Commands for resolving commands
+    namespace eval trace   "" ; # Commands registered for tracing
+    namespace eval enable  "" ; # Commands invoked at trace enable
+    namespace eval disable "" ; # Commands invoked at trace disable
+    namespace eval script  "" ; # Commands for generating scripts
+
+    # Exported commands
+    namespace export unknown
+
+    # Initialize ttrace shared state
+    if {[${store}array exists ttrace] == 0} {
+        ${store}set ttrace lastepoch $epoch
+        ${store}set ttrace epochlist ""
+    }
+
+    # Initially, allow creation of epochs
+    set config(-doepochs) 1
+
+    proc eval {cmd args} {
+        enable
+        set code [catch {uplevel 1 [concat $cmd $args]} result]
+        disable
+        if {$code == 0} {
+            if {[info commands ns_ictl] == ""} {
+                thread::broadcast {
+                    package require Ttrace
+                    ttrace::update
+                }
+            } else {
+                ns_ictl save [getscript]
+            }
+        }
+        return -code $code \
+            -errorinfo $::errorInfo -errorcode $::errorCode $result
+    }
+
+    proc config {args} {
+        variable config
+        if {[llength $args] == 0} {
+            array get config
+        } elseif {[llength $args] == 1} {
+            set opt [lindex $args 0]
+            set config($opt)
+        } else {
+            set opt [lindex $args 0]
+            set val [lindex $args 1]
+            set config($opt) $val
+        }
+    }
+
+    proc enable {} {
+        variable config
+        variable tracers
+        variable enables
+        variable enabled
+        incr enabled 1
+        if {$enabled > 1} {
+            return
+        }
+        if {$config(-doepochs) != 0} {
+            variable epoch [_newepoch]
+        }
+        set nsp [namespace current]
+        foreach enabler $enables {
+            enable::_$enabler
+        }
+        foreach trace $tracers {
+            if {[info commands $trace] != ""} {
+                trace add execution $trace leave ${nsp}::trace::_$trace
+            }
+        }
+    }
+
+    proc disable {} {
+        variable enabled
+        variable tracers
+        variable disables
+        incr enabled -1
+        if {$enabled > 0} {
+            return
+        }
+        set nsp [namespace current]
+        foreach disabler $disables {
+            disable::_$disabler
+        }
+        foreach trace $tracers {
+            if {[info commands $trace] != ""} {
+                trace remove execution $trace leave ${nsp}::trace::_$trace
+            }
+        }
+    }
+
+    proc isenabled {} {
+        variable enabled
+        expr {$enabled > 0}
+    }
+
+    proc update {{from -1}} {
+        variable store
+        if {$from == -1} { 
+            variable epoch [${store}set ttrace lastepoch]
+        } else {
+            if {[lsearch [${store}set ttrace epochlist] $from] == -1} {
+                error "no such epoch: $from"
+            }
+            variable epoch $from
+        }
+        uplevel [getscript]
+    } 
+
+    proc getscript {} {
+        variable preloads
+        variable epoch
+        variable scripts
+        append script [_serializensp] \n
+        append script "::namespace eval [namespace current] {" \n
+        append script "::namespace export unknown" \n
+        append script "_useepoch $epoch" \n
+        append script "}" \n
+        foreach cmd $preloads {
+            append script [_serializeproc $cmd] \n
+        }
+        foreach maker $scripts {
+            append script [script::_$maker]
+        }
+        return $script
+    }
+
+    proc cleanup {args} {
+        foreach cmd [info commands resolve::cleaner_*] {
+            uplevel $cmd $args
+        }
+    }
+
+    proc preload {cmd} {
+        variable preloads
+        if {[lsearch $preloads $cmd] == -1} {
+            lappend preloads $cmd
+        }
+    }
+
+    proc atenable {cmd arglist body} {
+        variable enables
+        if {[lsearch $enables $cmd] == -1} {
+            lappend enables $cmd
+            set cmd [namespace current]::enable::_$cmd
+            proc $cmd $arglist $body
+            return $cmd
+        }
+    }
+    
+    proc atdisable {cmd arglist body} {
+        variable disables
+        if {[lsearch $disables $cmd] == -1} {
+            lappend disables $cmd
+            set cmd [namespace current]::disable::_$cmd
+            proc $cmd $arglist $body
+            return $cmd
+        }
+    }
+     
+    proc addtrace {cmd arglist body} {
+        variable tracers
+        if {[lsearch $tracers $cmd] == -1} {
+            lappend tracers $cmd
+            set tracer [namespace current]::trace::_$cmd
+            proc $tracer $arglist $body
+            if {[isenabled]} {
+                trace add execution $cmd leave $tracer
+            }
+            return $tracer
+        }
+    }
+
+    proc addscript {cmd body} {
+        variable scripts
+        if {[lsearch $scripts $cmd] == -1} {
+            lappend scripts $cmd
+            set cmd [namespace current]::script::_$cmd
+            proc $cmd args $body
+            return $cmd
+        }
+    }
+
+    proc addresolver {cmd arglist body} {
+        variable resolvers
+        if {[lsearch $resolvers $cmd] == -1} {
+            lappend resolvers $cmd
+            set cmd [namespace current]::resolve::$cmd
+            proc $cmd $arglist $body
+            return $cmd
+        }
+    }
+
+    proc addcleanup {body} {
+        variable cleancnt
+        set cmd [namespace current]::resolve::cleaner_[incr cleancnt]
+        proc $cmd args $body
+        return $cmd
+    }
+
+    proc addentry {cmd var val} {
+        variable store
+        variable epoch
+        ${store}set ${epoch}-$cmd $var $val
+    }
+
+    proc delentry {cmd var} {
+        variable store
+        variable epoch
+        set ei $::errorInfo
+        set ec $::errorCode
+        catch {${store}unset ${epoch}-$cmd $var}
+        set ::errorInfo $ei
+        set ::errorCode $ec
+    }
+
+    proc getentry {cmd var} {
+        variable store
+        variable epoch
+        set ei $::errorInfo
+        set ec $::errorCode
+        if {[catch {${store}set ${epoch}-$cmd $var} val]} {
+            set ::errorInfo $ei
+            set ::errorCode $ec
+            set val ""
+        }
+        return $val
+    }
+
+    proc getentries {cmd {pattern *}} {
+        variable store
+        variable epoch
+        ${store}array names ${epoch}-$cmd $pattern
+    }
+
+    proc unknown {args} {
+        set cmd [lindex $args 0]
+        if {[uplevel ttrace::_resolve [list $cmd]]} {
+            set c [catch {uplevel $cmd [lrange $args 1 end]} r]
+        } else {
+            set c [catch {::eval ::tcl::unknown $args} r]
+        }
+        return -code $c -errorcode $::errorCode -errorinfo $::errorInfo $r
+    }
+
+    proc _resolve {cmd} {
+        variable resolvers
+        foreach resolver $resolvers {
+            if {[uplevel [info comm resolve::$resolver] [list $cmd]]} {
+                return 1
+            }
+        }
+        return 0
+    }
+
+    proc _getthread {} {
+        if {[info commands ns_thread] == ""} {
+            thread::id
+        } else {
+            ns_thread getid
+        }
+    }
+
+    proc _getthreads {} {
+        if {[info commands ns_thread] == ""} {
+            return [thread::names]
+        } else {
+            foreach entry [ns_info threads] {
+                lappend threads [lindex $entry 2]
+            }
+            return $threads
+        }
+    }
+
+    proc _newepoch {} {
+        variable store
+        variable elock
+        variable mutex
+        $mutex lock $elock
+        set old [${store}set ttrace lastepoch]
+        set new [${store}incr ttrace lastepoch]
+        ${store}lappend ttrace $new [_getthread]
+        if {$old >= 0} {
+            _copyepoch $old $new
+            _delepochs
+        }
+        ${store}lappend ttrace epochlist $new
+        $mutex unlock $elock
+        return $new
+    }
+
+    proc _copyepoch {old new} {
+        variable store
+        foreach var [${store}names $old-*] {
+            set cmd [lindex [split $var -] 1]
+            ${store}array reset $new-$cmd [${store}array get $var]
+        }
+    }
+
+    proc _delepochs {} {
+        variable store
+        set tlist [_getthreads]
+        set elist ""
+        foreach epoch [${store}set ttrace epochlist] {
+            if {[_dropepoch $epoch $tlist] == 0} {
+                lappend elist $epoch
+            } else {
+                ${store}unset ttrace $epoch
+            }
+        }
+        ${store}set ttrace epochlist $elist
+    }
+
+    proc _dropepoch {epoch threads} {
+        variable store
+        set self [_getthread] 
+        foreach tid [${store}set ttrace $epoch] {
+            if {$tid != $self && [lsearch $threads $tid] >= 0} {
+                lappend alive $tid
+            }
+        }
+        if {[info exists alive]} {
+            ${store}set ttrace $epoch $alive
+            return 0
+        } else {
+            foreach var [${store}names $epoch-*] {
+                ${store}unset $var
+            }
+            return 1
+        }
+    }
+
+    proc _useepoch {epoch} {
+        variable store
+        if {$epoch >= 0} {
+            set tid [_getthread]
+            if {[lsearch [${store}set ttrace $epoch] $tid] == -1} {
+                ${store}lappend ttrace $epoch $tid
+            }
+        }
+    }
+
+    proc _serializeproc {cmd} {
+        set dargs [info args $cmd]
+        set pbody [info body $cmd]
+        set pargs ""
+        foreach arg $dargs {
+            if {![info default $cmd $arg def]} {
+                lappend pargs $arg
+            } else {
+                lappend pargs [list $arg $def]
+            }
+        }
+        set nsp [namespace qual $cmd]
+        if {$nsp == ""} {
+            set nsp "::"
+        }
+        append res "::namespace eval $nsp {" \n
+        append res "::proc [namespace tail $cmd] [list $pargs] [list $pbody]" \n
+        append res "}" \n
+    }
+
+    proc _serializensp {{nsp ""} {result _}} {
+        upvar $result res
+        if {$nsp == ""} {
+            set nsp [namespace current]
+        }
+        append res "::namespace eval $nsp {" \n
+        foreach var [info vars ${nsp}::*] {
+            set vname [namespace tail $var]
+            if {[array exists $var] == 0} {
+                append res "::variable $vname {[set $var]}" \n
+            } else {
+                append res "::variable $vname" \n
+                append res "::array set $vname [list [array get $var]]" \n
+            }
+        }
+        foreach cmd [info procs ${nsp}::*] {
+            append res [_serializeproc $cmd] \n
+        }
+        append res "}" \n
+        foreach nn [namespace children $nsp] {
+            _serializensp $nn res
+        }
+        return $res
+    }
+}
+
+#
+# The code below is ment to be run once during the application start. 
+# It provides implementation of tracing callbacks for some Tcl commands.
+# Users can supply their own tracer implementations on-the-fly.
+#
+# The code below will create traces for the following Tcl commands:
+#    "namespace", "variable", "load", "proc" and "rename"
+#
+# Also, the Tcl object extension XOTcl 1.1.0 is handled and all XOTcl
+# related things, like classes and objects are traced (many thanks to
+# Gustaf Neumann from XOTcl for his kind help and support). 
+#
+
+eval {
+
+    #
+    # Register the "load" trace. This will create 
+    # the following key/value pair in the "load" store:
+    #
+    #  --- key ----              --- value ---
+    #  <path_of_loaded_image>    <name_of_the_init_proc>
+    #
+    # We normally need only the name_of_the_init_proc for
+    # being able to load the package in other interpreters,
+    # but we store the path to the image file as well.
+    #
+
+    ttrace::addtrace load {cmdline code args} {
+        if {$code != 0} {
+            return
+        }
+        set image [lindex $cmdline 1]
+        set initp [lindex $cmdline 2]
+        if {$initp == ""} {
+            foreach pkg [info loaded] {
+                if {[lindex $pkg 0] == $image} {
+                    set initp [lindex $pkg 1]
+                }
+            }
+        }
+        ttrace::addentry load $image $initp
+    }
+
+    ttrace::addscript load {
+        append res "\n"
+        foreach entry [ttrace::getentries load] {
+            set initp [ttrace::getentry load $entry]
+            append res "::load {} $initp" \n
+        }
+        return $res
+    }
+
+    #
+    # Register the "namespace" trace. This will create 
+    # the following key/value entry in "namespace" store:
+    #
+    #  --- key ----                   --- value ---
+    #  ::fully::qualified::namespace  1
+    #
+    # It will also fill the "proc" store for procedures
+    # and commands imported in this namespace with following:
+    #
+    #  --- key ----                   --- value ---
+    #  ::fully::qualified::proc       [list <ns>  "" ""]
+    #
+    # The <ns> is the name of the namespace where the 
+    # command or procedure is imported from.
+    #
+
+    ttrace::addtrace namespace {cmdline code args} {
+        if {$code != 0} {
+            return
+        }
+        set nop [lindex $cmdline 1]
+        set cns [uplevel namespace current]
+        if {$cns == "::"} {
+            set cns ""
+        }
+        switch -glob $nop {
+            eva* {
+                set nsp [lindex $cmdline 2]
+                if {![string match "::*" $nsp]} {
+                    set nsp ${cns}::$nsp
+                }
+                ttrace::addentry namespace $nsp 1
+            }
+            imp* {
+                # - parse import arguments (skip opt "-force")
+                set opts [lrange $cmdline 2 end]
+                if {[string match "-fo*" [lindex $opts 0]]} {
+                    set opts [lrange $cmdline 3 end]
+                }
+                # - register all imported procs and commands
+                foreach opt $opts {
+                    if {![string match "::*" [::namespace qual $opt]]} {
+                        set opt ${cns}::$opt
+                    }
+                    # - first import procs
+                    foreach entry [ttrace::getentries proc $opt] {
+                        set cmd ${cns}::[::namespace tail $entry]
+                        set nsp [::namespace qual $entry]
+                        set done($cmd) 1
+                        set entry [list 0 $nsp "" ""]
+                        ttrace::addentry proc $cmd $entry
+                    }
+
+                    # - then import commands
+                    foreach entry [info commands $opt] {
+                        set cmd ${cns}::[::namespace tail $entry]
+                        set nsp [::namespace qual $entry]
+                        if {[info exists done($cmd)] == 0} {
+                            set entry [list 0 $nsp "" ""]
+                            ttrace::addentry proc $cmd $entry
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    ttrace::addscript namespace {
+        append res \n
+        foreach entry [ttrace::getentries namespace] {
+            append res "::namespace eval $entry {}" \n
+        }
+        return $res
+    }
+
+    #
+    # Register the "variable" trace. This will create 
+    # the following key/value entry in the "variable" store:
+    #
+    #  --- key ----                   --- value ---
+    #  ::fully::qualified::variable   1
+    #
+    # The variable value itself is ignored at the time
+    # of trace/collection. Instead, we take the real
+    # value at the time of script generation.
+    #
+
+    ttrace::addtrace variable {cmdline code args} {
+        if {$code != 0} {
+            return
+        }
+        set opts [lrange $cmdline 1 end]
+        if {[llength $opts]} {
+            set cns [uplevel namespace current]
+            if {$cns == "::"} {
+                set cns ""
+            }
+            foreach {var val} $opts {
+                if {![string match "::*" $var]} {
+                    set var ${cns}::$var
+                }
+                ttrace::addentry variable $var 1
+            }
+        }
+    }
+
+    ttrace::addscript variable {
+        append res \n
+        foreach entry [ttrace::getentries variable] {
+            set cns [namespace qual $entry]
+            set var [namespace tail $entry]
+            append res "::namespace eval $cns {" \n
+            append res "::variable $var"
+            if {[array exists $entry]} {
+                append res "\n::array set $var [list [array get $entry]]" \n
+            } elseif {[info exists $entry]} {
+                append res " [list [set $entry]]" \n 
+            } else {
+                append res \n
+            }
+            append res } \n
+        }
+        return $res
+    }
+
+
+    #
+    # Register the "rename" trace. It will create 
+    # the following key/value pair in "rename" store:
+    #
+    #  --- key ----              --- value ---
+    #  ::fully::qualified::old  ::fully::qualified::new
+    #
+    # The "new" value may be empty, for commands that 
+    # have been deleted. In such cases we also remove
+    # any traced procedure definitions.
+    #
+
+    ttrace::addtrace rename {cmdline code args} {
+        if {$code != 0} {
+            return
+        }
+        set cns [uplevel namespace current]
+        if {$cns == "::"} {
+            set cns ""
+        }
+        set old [lindex $cmdline 1]
+        if {![string match "::*" $old]} {
+            set old ${cns}::$old
+        }
+        set new [lindex $cmdline 2]
+        if {$new != ""} {
+            if {![string match "::*" $new]} {
+                set new ${cns}::$new
+            }
+            ttrace::addentry rename $old $new
+        } else {
+            ttrace::delentry proc $old
+        }
+    }
+
+    ttrace::addscript rename {
+        append res \n
+        foreach old [ttrace::getentries rename] {
+            set new [ttrace::getentry rename $old]
+            append res "::rename $old {$new}" \n
+        }
+        return $res
+    }
+
+    #
+    # Register the "proc" trace. This will create 
+    # the following key/value pair in the "proc" store:
+    #
+    #  --- key ----              --- value ---
+    #  ::fully::qualified::proc  [list <epoch> <ns> <arglist> <body>]
+    #
+    # The <epoch> chages anytime one (re)defines a proc. 
+    # The <ns> is the namespace where the command was imported 
+    # from. If empty, the <arglist> and <body> will hold the 
+    # actual procedure definition. See the "namespace" tracer
+    # implementation also.
+    #
+
+    ttrace::addtrace proc {cmdline code args} {
+        if {$code != 0} {
+            return
+        }
+        set cns [uplevel namespace current]
+        if {$cns == "::"} {
+            set cns ""
+        }
+        set cmd [lindex $cmdline 1]
+        if {![string match "::*" $cmd]} {
+            set cmd ${cns}::$cmd
+        }
+        set dargs [info args $cmd]
+        set pbody [info body $cmd]
+        set pargs ""
+        foreach arg $dargs {
+            if {![info default $cmd $arg def]} {
+                lappend pargs $arg
+            } else {
+                lappend pargs [list $arg $def]
+            }
+        }
+        set pdef [ttrace::getentry proc $cmd]
+        if {$pdef == ""} {
+            set epoch -1 ; # never traced before
+        } else {
+            set epoch [lindex $pdef 0]
+        }
+        ttrace::addentry proc $cmd [list [incr epoch] "" $pargs $pbody]
+    }
+
+    ttrace::addscript proc {
+        return {
+            if {[info command ::tcl::unknown] == ""} {
+                rename ::unknown ::tcl::unknown
+                namespace import -force ::ttrace::unknown
+            }
+            if {[info command ::tcl::info] == ""} {
+                rename ::info ::tcl::info
+            }
+            proc ::info args {
+                set cmd [lindex $args 0]
+                set hit [lsearch -glob {commands procs args default body} $cmd*]
+                if {$hit > 1} {
+                    if {[catch {uplevel ::tcl::info $args}]} {
+                        uplevel ttrace::_resolve [list [lindex $args 1]]
+                    }
+                    return [uplevel ::tcl::info $args]
+                }
+                if {$hit == -1} {
+                    return [uplevel ::tcl::info $args]
+                }
+                set cns [uplevel namespace current]
+                if {$cns == "::"} {
+                    set cns ""
+                }
+                set pat [lindex $args 1]
+                if {![string match "::*" $pat]} {
+                    set pat ${cns}::$pat
+                }
+                set fns [ttrace::getentries proc $pat]
+                if {[string match $cmd* commands]} {
+                    set fns [concat $fns [ttrace::getentries xotcl $pat]]
+                }
+                foreach entry $fns {
+                    if {$cns != [namespace qual $entry]} {
+                        set lazy($entry) 1
+                    } else {
+                        set lazy([namespace tail $entry]) 1
+                    }
+                }
+                foreach entry [uplevel ::tcl::info $args] {
+                    set lazy($entry) 1
+                }
+                array names lazy
+            }
+        }
+    }
+
+    #
+    # Register procedure resolver. This will try to
+    # resolve the command in the current namespace
+    # first, and if not found, in global namespace.
+    # It also handles commands imported from other
+    # namespaces.
+    #
+
+    ttrace::addresolver resolveprocs {cmd {export 0}} {
+        set cns [uplevel namespace current]
+        set name [namespace tail $cmd]
+        if {$cns == "::"} {
+            set cns ""
+        }
+        if {![string match "::*" $cmd]} {
+            set ncmd ${cns}::$cmd
+            set gcmd ::$cmd
+        } else {
+            set ncmd $cmd
+            set gcmd $cmd
+        }
+        set pdef [ttrace::getentry proc $ncmd]
+        if {$pdef == ""} {
+            set pdef [ttrace::getentry proc $gcmd]
+            if {$pdef == ""} {
+                return 0
+            }
+            set cmd $gcmd
+        } else {
+            set cmd $ncmd
+        }
+        set epoch [lindex $pdef 0]
+        set pnsp  [lindex $pdef 1]
+        if {$pnsp != ""} {
+            set nsp [namespace qual $cmd]
+            if {$nsp == ""} {
+                set nsp ::
+            }
+            set cmd ${pnsp}::$name
+            if {[resolveprocs $cmd 1] == 0 && [info commands $cmd] == ""} {
+                return 0
+            }
+            namespace eval $nsp "namespace import -force $cmd"
+        } else {
+            uplevel 0 [list ::proc $cmd [lindex $pdef 2] [lindex $pdef 3]]
+            if {$export} {
+                set nsp [namespace qual $cmd]
+                if {$nsp == ""} {
+                    set nsp ::
+                }
+                namespace eval $nsp "namespace export $name"
+            }
+        }
+        variable resolveproc
+        set resolveproc($cmd) $epoch
+        return 1
+    }
+
+    #
+    # For XOTcl, the entire item introspection/tracing
+    # is delegated to XOTcl itself.
+    # The xotcl store is filled with this:
+    #
+    #  --- key ----               --- value ---
+    #  ::fully::qualified::item   <body>
+    #
+    # The <body> is the script used to generate the entire
+    # item (class, object). Note that we do not fill in this
+    # during code tracing. It is done during the script
+    # generation. In this step, only the placeholder is set.
+    #
+    # NOTE: we assume all XOTcl commands are imported in global namespace
+    #
+
+    ttrace::atenable XOTclEnabler {args} {
+        if {[info commands ::xotcl::Class] == ""} {
+            return
+        }
+        if {[info commands ::xotcl::_creator] == ""} {
+            ::xotcl::Class create ::xotcl::_creator -instproc create {args} {
+                set result [next]
+                if {![string match ::xotcl::_* $result]} {
+                    ttrace::addentry xotcl $result ""
+                }
+                return $result
+            }
+        }
+        ::xotcl::Class instmixin ::xotcl::_creator
+    }
+
+    ttrace::atdisable XOTclDisabler {args} {
+        if {   [info commands ::xotcl::Class] == "" 
+            || [info commands ::xotcl::_creator] == ""} {
+            return
+        }
+        ::xotcl::Class instmixin ""
+        ::xotcl::_creator destroy
+    }
+
+    set resolver [ttrace::addresolver resolveclasses {classname} {
+        set cns [uplevel namespace current]
+        set script [ttrace::getentry xotcl $classname]
+        if {$script == ""} {
+            set name [namespace tail $classname]
+            if {$cns == "::"} {
+                set script [ttrace::getentry xotcl ::$name]
+            } else {
+                set script [ttrace::getentry xotcl ${cns}::$name]
+                if {$script == ""} {
+                    set script [ttrace::getentry xotcl ::$name]
+                }
+            }
+            if {$script == ""} {
+                return 0
+            }
+        }
+        uplevel [list namespace eval $cns $script]
+        return 1
+    }]
+
+    ttrace::addscript xotcl [subst -nocommands {
+        if {![catch {Serializer new} ss]} {
+            foreach entry [ttrace::getentries xotcl] {
+                if {[ttrace::getentry xotcl \$entry] == ""} {
+                    ttrace::addentry xotcl \$entry [\$ss serialize \$entry]
+                }
+            }
+            \$ss destroy
+            return {::xotcl::Class proc __unknown name {$resolver \$name}}
+        }
+    }]
+
+    #
+    # Register callback to be called on cleanup.
+    # This will trash lazily loaded procs which
+    # have changed since.
+    # 
+
+    ttrace::addcleanup {
+        variable resolveproc
+        foreach cmd [array names resolveproc] {
+            set def [ttrace::getentry proc $cmd]
+            if {$def != ""} {
+                set new [lindex $def 0]
+                set old $resolveproc($cmd)
+                if {[info command $cmd] != "" && $new != $old} {
+                    catch {rename $cmd ""}
+                }
+            }
+        }
+    }
+}
+
+# EOF
diff --git a/8.x/thread/license.terms b/8.x/thread/license.terms
new file mode 100644 (file)
index 0000000..9df3e60
--- /dev/null
@@ -0,0 +1,39 @@
+This software is copyrighted by the Regents of the University of
+California, Sun Microsystems, Inc., Scriptics Corporation,
+and other parties.  The following terms apply to all files associated
+with the software unless explicitly disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+GOVERNMENT USE: If you are acquiring this software on behalf of the
+U.S. government, the Government shall have only "Restricted Rights"
+in the software and related documentation as defined in the Federal 
+Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
+are acquiring the software on behalf of the Department of Defense, the
+software shall be classified as "Commercial Computer Software" and the
+Government shall have only "Restricted Rights" as defined in Clause
+252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
+authors grant the U.S. Government and others acting in its behalf
+permission to use and distribute the software in accordance with the
+terms specified in this license. 
diff --git a/8.x/thread/pkgIndex.tcl.in b/8.x/thread/pkgIndex.tcl.in
new file mode 100755 (executable)
index 0000000..543bb1e
--- /dev/null
@@ -0,0 +1,46 @@
+# -*- tcl -*-
+# Tcl package index file, version 1.1
+#
+if {[package vsatisfies [package provide Tcl] 8.4]} {
+
+    package ifneeded Thread @PACKAGE_VERSION@ [list load [file join $dir @PKG_LIB_FILE@]]
+
+    if {[llength [info commands apply]]} {
+       # We can use a lambda (anon function).
+
+       package ifneeded Ttrace @PACKAGE_VERSION@ [list ::apply {{dir} {
+           if {[info exists ::env(TCL_THREAD_LIBRARY)] &&
+               [file readable $::env(TCL_THREAD_LIBRARY)/ttrace.tcl]} {
+               source $::env(TCL_THREAD_LIBRARY)/ttrace.tcl
+           } elseif {[file readable [file join $dir .. lib ttrace.tcl]]} {
+               source [file join $dir .. lib ttrace.tcl]
+           } elseif {[file readable [file join $dir ttrace.tcl]]} {
+               source [file join $dir ttrace.tcl]
+           }
+           if {[llength [info commands ttrace::update]]} {
+               ttrace::update
+           }
+       }} $dir]
+    } else {
+       # No anon functions available, go with the necessary evil of a
+       # named procedure, but use package specific prefix and no
+       # hardwired data changing between package versions.
+
+       package ifneeded Ttrace @PACKAGE_VERSION@ [list @PACKAGE_NAME@_source $dir]
+
+       proc @PACKAGE_NAME@_source {dir} {
+           if {[info exists ::env(TCL_THREAD_LIBRARY)] &&
+               [file readable $::env(TCL_THREAD_LIBRARY)/ttrace.tcl]} {
+               source $::env(TCL_THREAD_LIBRARY)/ttrace.tcl
+           } elseif {[file readable [file join $dir .. lib ttrace.tcl]]} {
+               source [file join $dir .. lib ttrace.tcl]
+           } elseif {[file readable [file join $dir ttrace.tcl]]} {
+               source [file join $dir ttrace.tcl]
+           }
+           if {[llength [info commands ttrace::update]]} {
+               ttrace::update
+           }
+           rename @PACKAGE_NAME@_source {}
+       }
+    }
+}
diff --git a/8.x/thread/tcl/README b/8.x/thread/tcl/README
new file mode 100644 (file)
index 0000000..fe1b751
--- /dev/null
@@ -0,0 +1,32 @@
+
+Software here is provided as example of making some interesting
+things and applications using the Tcl threading extension.
+
+Currently, following packages are supplied:
+
+   tpool/    Example Tcl-only implementation of thread pools.
+             The threading extension includes an efficient
+             threadpool implementation in C. This file is 
+             provided as a fully functional example on how this
+             functionality could be implemented in Tcl alone.
+
+   phttpd/   MT-enabled httpd server. It uses threadpool to
+             distribute incoming requests among several worker 
+             threads in the threadpool. This way blocking 
+             requests may be handled much better, w/o halting
+             the event loop of the main responder thread.
+             In this directory you will also find the uhttpd.
+             This is the same web-server but operating in the 
+             event-loop mode alone, no threadpool support. 
+             This is good for comparison purposes.
+
+   cmdsrv/   Socket command-line server. Each new connection 
+             gets new thread, thus allowing multiple outstanding
+             blocking calls without halting the event loop.
+
+To play around with above packages, change to the corresponding 
+directory and source files in the Tcl8.4 (or later) Tcl shell. 
+Be sure to have the latest Tcl threading extension installed in 
+your package path.
+
+- EOF
diff --git a/8.x/thread/tcl/cmdsrv/cmdsrv.tcl b/8.x/thread/tcl/cmdsrv/cmdsrv.tcl
new file mode 100644 (file)
index 0000000..3dd51eb
--- /dev/null
@@ -0,0 +1,313 @@
+#
+# cmdsrv.tcl --
+#
+# Simple socket command server. Supports many simultaneous sessions.
+# Works in thread mode with each new connection receiving a new thread.
+#  
+# Usage:
+#    cmdsrv::create port ?-idletime value? ?-initcmd cmd?
+# 
+#    port         Tcp port where the server listens
+#    -idletime    # of sec to idle before tearing down socket (def: 300 sec)
+#    -initcmd     script to initialize new worker thread (def: empty)
+#
+# Example:
+#
+#    # tclsh8.4
+#    % source cmdsrv.tcl
+#    % cmdsrv::create 5000 -idletime 60
+#    % vwait forever
+#
+#    Starts the server on the port 5000, sets idle timer to 1 minute. 
+#    You can now use "telnet" utility to connect.
+#
+# Copyright (c) 2002 by Zoran Vasiljevic.
+#
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# -----------------------------------------------------------------------------
+# RCS: @(#) $Id: cmdsrv.tcl,v 1.6 2004/12/22 15:31:05 vasiljevic Exp $
+#
+
+package require Tcl    8.4
+package require Thread 2.5
+
+namespace eval cmdsrv {
+    variable data; # Stores global configuration options
+}
+
+#
+# cmdsrv::create --
+#
+#      Start the server on the given Tcp port.
+#
+# Arguments:
+#   port   Port where the server is listening
+#   args   Variable number of arguments
+#
+# Side Effects:
+#      None.
+#
+# Results:
+#      None.
+#
+
+proc cmdsrv::create {port args} {
+
+    variable data
+
+    if {[llength $args] % 2} {
+        error "wrong \# arguments, should be: key1 val1 key2 val2..."
+    }
+
+    #
+    # Setup default pool data.
+    #
+
+    array set data {
+        -idletime 300000
+        -initcmd  {source cmdsrv.tcl}
+    }
+    
+    #
+    # Override with user-supplied data
+    #
+
+    foreach {arg val} $args {
+        switch -- $arg {
+            -idletime {set data($arg) [expr {$val*1000}]}
+            -initcmd  {append data($arg) \n $val}
+            default {
+                error "unsupported pool option \"$arg\""
+            }
+        }
+    }
+
+    #
+    # Start the server on the given port. Note that we wrap
+    # the actual accept with a helper after/idle callback.
+    # This is a workaround for a well-known Tcl bug.
+    #
+    
+    socket -server [namespace current]::_Accept -myaddr 127.0.0.1 $port
+}
+\f
+#
+# cmdsrv::_Accept --
+#
+#      Helper procedure to solve Tcl shared channel bug when responding
+#   to incoming socket connection and transfering the channel to other
+#   thread(s).
+#
+# Arguments:
+#   s      incoming socket
+#   ipaddr IP address of the remote peer
+#   port   Tcp port used for this connection
+#
+# Side Effects:
+#      None.
+#
+# Results:
+#      None.
+#
+
+proc cmdsrv::_Accept {s ipaddr port} {
+    after idle [list [namespace current]::Accept $s $ipaddr $port]
+}
+\f
+#
+# cmdsrv::Accept --
+#
+#      Accepts the incoming socket connection, creates the worker thread.
+#
+# Arguments:
+#   s      incoming socket
+#   ipaddr IP address of the remote peer
+#   port   Tcp port used for this connection
+#
+# Side Effects:
+#      Creates new worker thread.
+#
+# Results:
+#      None.
+#
+
+proc cmdsrv::Accept {s ipaddr port} {
+
+    variable data
+    
+    #
+    # Configure socket for sane operation
+    #
+    
+    fconfigure $s -blocking 0 -buffering none -translation {auto crlf}
+    
+    #
+    # Emit the prompt
+    #
+    
+    puts -nonewline $s "% "
+
+    #
+    # Create worker thread and transfer socket ownership
+    #
+    set tid [thread::create [append data(-initcmd) \n thread::wait]]
+    thread::transfer $tid $s ; # This flushes the socket as well
+
+    #
+    # Start event-loop processing in the remote thread
+    #
+
+    thread::send -async $tid [subst {
+        array set [namespace current]::data {[array get data]}
+        fileevent $s readable {[namespace current]::Read $s}
+        proc exit args {[namespace current]::SockDone $s}
+        [namespace current]::StartIdleTimer $s
+    }]
+}
+\f
+#
+# cmdsrv::Read --
+#
+#      Event loop procedure to read data from socket and collect the 
+#   command to execute. If the command read from socket is complete
+#   it executes the command are prints the result back. 
+#
+# Arguments:
+#   s      incoming socket
+#
+# Side Effects:
+#      None.
+#
+# Results:
+#      None.
+#
+
+proc cmdsrv::Read {s} {
+
+    variable data
+
+    StopIdleTimer $s
+
+    #
+    # Cover client closing connection
+    #
+
+    if {[eof $s] || [catch {read $s} line]} {
+        return [SockDone $s]
+    }
+    if {$line == "\n" || $line == ""} {
+        if {[catch {puts -nonewline $s "% "}]} {
+            return [SockDone $s]
+        }
+        return [StartIdleTimer $s]
+    }
+    
+    #
+    # Construct command line to eval
+    #
+
+    append data(cmd) $line
+    if {[info complete $data(cmd)] == 0} {
+        if {[catch {puts -nonewline $s "> "}]} {
+            return [SockDone $s]
+        }
+        return [StartIdleTimer $s]
+    }
+
+    #
+    # Run the command
+    #
+
+    catch {uplevel \#0 $data(cmd)} ret
+    if {[catch {puts $s $ret}]} {
+        return [SockDone $s]
+    }
+    set data(cmd) ""
+    if {[catch {puts -nonewline $s "% "}]} {
+        return [SockDone $s]
+    }
+    StartIdleTimer $s
+}
+\f
+#
+# cmdsrv::SockDone --
+#
+#      Tears down the thread and closes the socket if the remote peer has
+#   closed his side of the comm channel. 
+#
+# Arguments:
+#   s      incoming socket
+#
+# Side Effects:
+#      Worker thread gets released.
+#
+# Results:
+#      None.
+#
+
+proc cmdsrv::SockDone {s} {
+
+    catch {close $s}
+    thread::release
+}
+\f
+#
+# cmdsrv::StopIdleTimer --
+#
+#      Cancel the connection idle timer. 
+#
+# Arguments:
+#   s      incoming socket
+#
+# Side Effects:
+#      After event gets cancelled.
+#
+# Results:
+#      None.
+#
+
+proc cmdsrv::StopIdleTimer {s} {
+
+    variable data
+
+    if {[info exists data(idleevent)]} {
+        after cancel $data(idleevent)
+        unset data(idleevent)
+    }
+}
+\f
+#
+# cmdsrv::StartIdleTimer --
+#
+#      Initiates the connection idle timer. 
+#
+# Arguments:
+#   s      incoming socket
+#
+# Side Effects:
+#      After event gets posted.
+#
+# Results:
+#      None.
+#
+
+proc cmdsrv::StartIdleTimer {s} {
+
+    variable data
+
+    set data(idleevent) \
+        [after $data(-idletime) [list [namespace current]::SockDone $s]]
+}
+
+# EOF $RCSfile: cmdsrv.tcl,v $
+
+# Emacs Setup Variables
+# Local Variables:
+# mode: Tcl
+# indent-tabs-mode: nil
+# tcl-basic-offset: 4
+# End:
+
diff --git a/8.x/thread/tcl/phttpd/index.htm b/8.x/thread/tcl/phttpd/index.htm
new file mode 100644 (file)
index 0000000..324f1f7
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body>
+<h3>Hallo World</h3>
+</body>
+</html>
diff --git a/8.x/thread/tcl/phttpd/phttpd.tcl b/8.x/thread/tcl/phttpd/phttpd.tcl
new file mode 100644 (file)
index 0000000..8a4b580
--- /dev/null
@@ -0,0 +1,689 @@
+#
+# phttpd.tcl --
+#
+# Simple Sample httpd/1.0 server in 250 lines of Tcl.
+# Stephen Uhler / Brent Welch (c) 1996 Sun Microsystems.
+#
+# Modified to use namespaces, direct url-to-procedure access
+# and thread pool package. Grown little larger since ;)
+#
+# Usage:
+#    phttpd::create port
+# 
+#    port         Tcp port where the server listens
+#
+# Example:
+#
+#    # tclsh8.4
+#    % source phttpd.tcl
+#    % phttpd::create 5000
+#    % vwait forever
+#
+#    Starts the server on the port 5000. Also, look at the Httpd array
+#    definition in the "phttpd" namespace declaration to find out 
+#    about other options you may put on the command line.
+#
+#    You can use: http://localhost:5000/monitor URL to test the
+#    server functionality.
+#
+# Copyright (c) 2002 by Zoran Vasiljevic.
+#
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# -----------------------------------------------------------------------------
+# Rcsid: @(#)$Id: phttpd.tcl,v 1.5 2002/12/13 20:55:07 vasiljevic Exp $
+#
+
+package require Tcl    8.4
+package require Thread 2.5
+
+#
+# Modify the following in order to load the
+# example Tcl implementation of threadpools.
+# Per default, the C-level threadpool is used.
+#
+
+if {0} {
+    eval [set TCL_TPOOL {source ../tpool/tpool.tcl}]
+}
+
+namespace eval phttpd {
+
+    variable Httpd;           # Internal server state and config params
+    variable MimeTypes;       # Cache of file-extension/mime-type
+    variable HttpCodes;       # Portion of well-known http return codes
+    variable ErrorPage;       # Format of error response page in html
+
+    array set Httpd {
+        -name  phttpd
+        -vers  1.0
+        -root  "."
+        -index index.htm
+    }
+    array set HttpCodes {
+        400  "Bad Request"
+        401  "Not Authorized"
+        404  "Not Found"
+        500  "Server error"
+    }
+    array set MimeTypes {
+        {}   "text/plain"
+        .txt "text/plain"
+        .htm "text/html"
+        .htm "text/html"
+        .gif "image/gif"
+        .jpg "image/jpeg"
+        .png "image/png"
+    }
+    set ErrorPage {
+        <title>Error: %1$s %2$s</title>
+        <h1>%3$s</h1>
+        <p>Problem in accessing "%4$s" on this server.</p>
+        <hr>
+        <i>%5$s/%6$s Server at %7$s Port %8$s</i>
+    }
+}
+\f
+#
+# phttpd::create --
+#
+#      Start the server by listening for connections on the desired port.
+#
+# Arguments:
+#   port
+#   args
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::create {port args} {
+
+    variable Httpd
+
+    set arglen [llength $args]
+    if {$arglen} {
+        if {$arglen % 2} {
+            error "wrong \# args, should be: key1 val1 key2 val2..."
+        }
+        set opts [array names Httpd]
+        foreach {arg val} $args {
+            if {[lsearch $opts $arg] == -1} {
+                error "unknown option \"$arg\""
+            }
+            set Httpd($arg) $val
+        }
+    }
+
+    #
+    # Create thread pool with max 8 worker threads.
+    #
+
+    if {[info exists ::TCL_TPOOL] == 0} {
+        #
+        # Using the internal C-based thread pool
+        #
+        set initcmd "source ../phttpd/phttpd.tcl"
+    } else {
+        #
+        # Using the Tcl-level hand-crafted thread pool
+        #
+        append initcmd "source ../phttpd/phttpd.tcl" \n $::TCL_TPOOL
+    }
+
+    set Httpd(tpid) [tpool::create -maxworkers 8 -initcmd $initcmd]
+
+    #
+    # Start the server on the given port. Note that we wrap
+    # the actual accept with a helper after/idle callback.
+    # This is a workaround for a well-known Tcl bug.
+    #
+    
+    socket -server [namespace current]::_Accept $port
+}
+\f
+#
+# phttpd::_Accept --
+#
+#      Helper procedure to solve Tcl shared-channel bug when responding
+#   to incoming connection and transfering the channel to other thread(s).
+#
+# Arguments:
+#   sock   incoming socket
+#   ipaddr IP address of the remote peer
+#   port   Tcp port used for this connection
+#
+# Side Effects:
+#      None.
+#
+# Results:
+#      None.
+#
+
+proc phttpd::_Accept {sock ipaddr port} {
+    after idle [list [namespace current]::Accept $sock $ipaddr $port]
+}
+\f
+#
+# phttpd::Accept --
+#
+#      Accept a new connection from the client.
+#
+# Arguments:
+#   sock
+#   ipaddr
+#   port
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Accept {sock ipaddr port} {
+
+    variable Httpd
+
+    #
+    # Setup the socket for sane operation
+    #
+
+    fconfigure $sock -blocking 0 -translation {auto crlf}
+
+    #
+    # Detach the socket from current interpreter/tnread.
+    # One of the worker threads will attach it again.
+    #
+
+    thread::detach $sock
+
+    #
+    # Send the work ticket to threadpool.
+    # 
+
+    tpool::post -detached $Httpd(tpid) [list [namespace current]::Ticket $sock]
+}
+\f
+#
+# phttpd::Ticket --
+#
+#      Job ticket to run in the thread pool thread.
+#
+# Arguments:
+#   sock
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Ticket {sock} {
+    
+    thread::attach $sock
+    fileevent $sock readable [list [namespace current]::Read $sock]
+    
+    #
+    # End of processing is signalized here.
+    # This will release the worker thread.
+    #
+    
+    vwait [namespace current]::done
+}
+
+\f
+#
+# phttpd::Read --
+#
+#      Read data from client and parse incoming http request.
+#
+# Arguments:
+#   sock
+#
+# Side Effects:
+#      None.
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Read {sock} {
+
+    variable Httpd
+    variable data
+
+    set data(sock) $sock
+
+    while {1} {
+        if {[catch {gets $data(sock) line} readCount] || [eof $data(sock)]} {
+            return [Done]
+        }
+        if {![info exists data(state)]} {
+            set pat {(POST|GET) ([^?]+)\??([^ ]*) HTTP/1\.[0-9]}
+            if {[regexp $pat $line x data(proto) data(url) data(query)]} {
+                set data(state) mime
+                continue
+            } else {
+                Log error "bad request line: (%s)" $line
+                Error 400
+                return [Done]
+            }
+        }
+        
+        # string compare $readCount 0 maps -1 to -1, 0 to 0, and > 0 to 1
+        
+        set state [string compare $readCount 0],$data(state),$data(proto)
+        switch -- $state {
+            "0,mime,GET" - "0,query,POST" {
+                Respond
+                return [Done]
+            }
+            "0,mime,POST" {
+                set data(state) query
+                set data(query) ""
+            }
+            "1,mime,POST" - "1,mime,GET" {
+                if [regexp {([^:]+):[   ]*(.*)}  $line dummy key value] {
+                    set data(mime,[string tolower $key]) $value
+                }
+            }
+            "1,query,POST" {
+                append data(query) $line
+                set clen $data(mime,content-length)
+                if {($clen - [string length $data(query)]) <= 0} {
+                    Respond
+                    return [Done]
+                }
+            }
+            default {
+                if [eof $data(sock)] {
+                    Log error "unexpected eof; client closed connection"
+                    return [Done]
+                } else {
+                    Log error "bad http protocol state: %s" $state
+                    Error 400
+                    return [Done]
+                }
+            }
+        }
+    }
+}
+\f
+#
+# phttpd::Done --
+#
+#      Close the connection socket
+#
+# Arguments:
+#   s
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Done {} {
+
+    variable done
+    variable data
+
+    close $data(sock)
+    
+    if {[info exists data]} {
+        unset data
+    }
+
+    set done 1 ; # Releases the request thread (See Ticket procedure)
+}
+\f
+#
+# phttpd::Respond --
+#
+#      Respond to the query.
+#
+# Arguments:
+#   s
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Respond {} {
+
+    variable data
+
+    if {[info commands $data(url)] == $data(url)} {
+
+        #
+        # Service URL-procedure
+        #
+
+        if {[catch {
+            puts $data(sock) "HTTP/1.0 200 OK"
+            puts $data(sock) "Date: [Date]"
+            puts $data(sock) "Last-Modified: [Date]"
+        } err]} {
+            Log error "client closed connection prematurely: %s" $err
+            return
+        }
+        if {[catch {$data(url) data} err]} {
+            Log error "%s: %s" $data(url) $err
+        }
+
+    } else {
+
+        #
+        # Service regular file path
+        #
+
+        set mypath [Url2File $data(url)]
+        if {![catch {open $mypath} i]} {
+            if {[catch {
+                puts $data(sock) "HTTP/1.0 200 OK"
+                puts $data(sock) "Date: [Date]"
+                puts $data(sock) "Last-Modified: [Date [file mtime $mypath]]"
+                puts $data(sock) "Content-Type: [ContentType $mypath]"
+                puts $data(sock) "Content-Length: [file size $mypath]"
+                puts $data(sock) ""
+                fconfigure $data(sock) -translation binary -blocking 0
+                fconfigure $i          -translation binary
+                fcopy $i $data(sock)
+                close $i
+            } err]} {
+                Log error "client closed connection prematurely: %s" $err
+            }
+        } else {
+            Log error "%s: %s" $data(url) $i
+            Error 404
+        }
+    }
+}
+\f
+#
+# phttpd::ContentType --
+#
+#      Convert the file suffix into a mime type.
+#
+# Arguments:
+#   path
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::ContentType {path} {
+
+    # @c Convert the file suffix into a mime type.
+
+    variable MimeTypes
+
+    set type "text/plain"
+    catch {set type $MimeTypes([file extension $path])}
+    
+    return $type
+}
+\f
+#
+# phttpd::Error --
+#
+#      Emit error page
+#
+# Arguments:
+#   s
+#   code
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Error {code} {
+
+    variable Httpd
+    variable HttpCodes
+    variable ErrorPage
+    variable data
+
+    append data(url) ""
+    set msg \
+        [format $ErrorPage     \
+             $code             \
+             $HttpCodes($code) \
+             $HttpCodes($code) \
+             $data(url)        \
+             $Httpd(-name)     \
+             $Httpd(-vers)     \
+             [info hostname]   \
+             80                \
+            ]
+    if {[catch {
+        puts $data(sock) "HTTP/1.0 $code $HttpCodes($code)"
+        puts $data(sock) "Date: [Date]"
+        puts $data(sock) "Content-Length: [string length $msg]"
+        puts $data(sock) ""
+        puts $data(sock) $msg
+    } err]} {
+        Log error "client closed connection prematurely: %s" $err
+    }
+}
+\f
+#
+# phttpd::Date --
+#
+#      Generate a date string in HTTP format.
+#
+# Arguments:
+#   seconds
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Date {{seconds 0}} {
+
+    # @c Generate a date string in HTTP format.
+
+    if {$seconds == 0} {
+        set seconds [clock seconds]
+    }
+    clock format $seconds -format {%a, %d %b %Y %T %Z} -gmt 1
+}
+\f
+#
+# phttpd::Log --
+#
+#      Log an httpd transaction.
+#
+# Arguments:
+#   reason
+#   format
+#   args
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Log {reason format args} {
+
+    set messg [eval format [list $format] $args]
+    set stamp [clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S"]
+
+    puts stderr "\[$stamp\]\[-thread[thread::id]-\] $reason: $messg"
+}
+\f
+#
+# phttpd::Url2File --
+#
+#      Convert a url into a pathname.
+#
+# Arguments:
+#   url
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::Url2File {url} {
+
+    variable Httpd
+
+    lappend pathlist $Httpd(-root)
+    set level 0
+
+    foreach part [split $url /] {
+        set part [CgiMap $part]
+        if [regexp {[:/]} $part] {
+            return ""
+        }
+        switch -- $part {
+            "." { }
+            ".." {incr level -1}
+            default {incr level}
+        }
+        if {$level <= 0} {
+            return ""
+        }
+        lappend pathlist $part
+    }
+
+    set file [eval file join $pathlist]
+
+    if {[file isdirectory $file]} {
+        return [file join $file $Httpd(-index)]
+    } else {
+        return $file
+    }
+}
+\f
+#
+# phttpd::CgiMap --
+#
+#      Decode url-encoded strings.
+#
+# Arguments:
+#   data
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::CgiMap {data} {
+
+    regsub -all {\+} $data { } data
+    regsub -all {([][$\\])} $data {\\\1} data
+    regsub -all {%([0-9a-fA-F][0-9a-fA-F])} $data {[format %c 0x\1]} data
+
+    return [subst $data]
+}
+\f
+#
+# phttpd::QueryMap --
+#
+#      Decode url-encoded query into key/value pairs.
+#
+# Arguments:
+#   query
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc phttpd::QueryMap {query} {
+    
+    set res [list]
+
+    regsub -all {[&=]} $query { }    query
+    regsub -all {  }   $query { {} } query; # Othewise we lose empty values
+
+    foreach {key val} $query {
+        lappend res [CgiMap $key] [CgiMap $val]
+    }
+    return $res
+}
+\f
+#
+# monitor --
+#
+#      Procedure used to test the phttpd server. It responds on the
+#        http://<hostname>:<port>/monitor
+#
+# Arguments:
+#   array
+#
+# Side Effects:
+#      None..
+#
+# Results:
+#      None.
+#
+
+proc /monitor {array} {
+
+    upvar $array data ; # Holds the socket to remote client
+
+    #
+    # Emit headers
+    #
+
+    puts $data(sock) "HTTP/1.0 200 OK"
+    puts $data(sock) "Date: [phttpd::Date]"
+    puts $data(sock) "Content-Type: text/html"
+    puts $data(sock) ""
+
+    #
+    # Emit body
+    #
+
+    puts $data(sock) [subst {
+        <html>
+        <body>
+        <h3>[clock format [clock seconds]]</h3>
+    }]
+
+    after 1 ; # Simulate blocking call
+
+    puts $data(sock) [subst {
+        </body>
+        </html>
+    }]
+}
+
+# EOF $RCSfile: phttpd.tcl,v $
+# Emacs Setup Variables
+# Local Variables:
+# mode: Tcl
+# indent-tabs-mode: nil
+# tcl-basic-offset: 4
+# End:
+
diff --git a/8.x/thread/tcl/phttpd/uhttpd.tcl b/8.x/thread/tcl/phttpd/uhttpd.tcl
new file mode 100644 (file)
index 0000000..83ba397
--- /dev/null
@@ -0,0 +1,419 @@
+#
+# uhttpd.tcl --
+#
+# Simple Sample httpd/1.0 server in 250 lines of Tcl.
+# Stephen Uhler / Brent Welch (c) 1996 Sun Microsystems.
+#
+# Modified to use namespaces and direct url-to-procedure access (zv).
+# Eh, due to this, and nicer indenting, it's now 150 lines longer :-)
+#
+# Usage:
+#    phttpd::create port
+# 
+#    port         Tcp port where the server listens
+#
+# Example:
+#
+#    # tclsh8.4
+#    % source uhttpd.tcl
+#    % uhttpd::create 5000
+#    % vwait forever
+#
+#    Starts the server on the port 5000. Also, look at the Httpd array
+#    definition in the "uhttpd" namespace declaration to find out 
+#    about other options you may put on the command line.
+#
+#    You can use: http://localhost:5000/monitor URL to test the
+#    server functionality.
+#
+# Copyright (c) Stephen Uhler / Brent Welch (c) 1996 Sun Microsystems.
+# Copyright (c) 2002 by Zoran Vasiljevic.
+#
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# -----------------------------------------------------------------------------
+# Rcsid: @(#)$Id: uhttpd.tcl,v 1.3 2002/12/13 20:55:08 vasiljevic Exp $
+#
+
+namespace eval uhttpd {
+
+    variable Httpd;           # Internal server state and config params
+    variable MimeTypes;       # Cache of file-extension/mime-type
+    variable HttpCodes;       # Portion of well-known http return codes
+    variable ErrorPage;       # Format of error response page in html
+
+    array set Httpd {
+        -name    uhttpd
+        -vers    1.0
+        -root    ""
+        -index   index.htm
+    }
+    array set HttpCodes {
+        400  "Bad Request"
+        401  "Not Authorized"
+        404  "Not Found"
+        500  "Server error"
+    }
+    array set MimeTypes {
+        {}   "text/plain"
+        .txt "text/plain"
+        .htm "text/html"
+        .htm "text/html"
+        .gif "image/gif"
+        .jpg "image/jpeg"
+        .png "image/png"
+    }
+    set ErrorPage {
+        <title>Error: %1$s %2$s</title>
+        <h1>%3$s</h1>
+        <p>Problem in accessing "%4$s" on this server.</p>
+        <hr>
+        <i>%5$s/%6$s Server at %7$s Port %8$s</i>
+    }
+}
+
+proc uhttpd::create {port args} {
+
+    # @c Start the server by listening for connections on the desired port.
+
+    variable Httpd 
+    set arglen [llength $args]
+
+    if {$arglen} {
+        if {$arglen % 2} {
+            error "wrong \# arguments, should be: key1 val1 key2 val2..."
+        }
+        set opts [array names Httpd]
+        foreach {arg val} $args {
+            if {[lsearch $opts $arg] == -1} {
+                error "unknown option \"$arg\""
+            }
+            set Httpd($arg) $val
+        }
+    }
+
+    set Httpd(port) $port
+    set Httpd(host) [info hostname]
+
+    socket -server [namespace current]::Accept $port
+}
+
+proc uhttpd::respond {s status contype data {length 0}} {
+    
+    puts $s "HTTP/1.0 $status"
+    puts $s "Date: [Date]"
+    puts $s "Content-Type: $contype"
+
+    if {$length} {
+        puts $s "Content-Length: $length" 
+    } else {
+        puts $s "Content-Length: [string length $data]"
+    }
+
+    puts $s ""
+    puts $s $data 
+}
+       
+proc uhttpd::Accept {newsock ipaddr port} {
+
+    # @c Accept a new connection from the client.
+
+    variable Httpd
+    upvar \#0 [namespace current]::Httpd$newsock data
+
+    fconfigure $newsock -blocking 0 -translation {auto crlf}
+
+    set data(ipaddr) $ipaddr
+    fileevent $newsock readable [list [namespace current]::Read $newsock]
+}
+
+proc uhttpd::Read {s} {
+
+    # @c Read data from client
+
+    variable Httpd
+    upvar \#0 [namespace current]::Httpd$s data
+
+    if {[catch {gets $s line} readCount] || [eof $s]} {
+        return [Done $s]
+    }
+    if {$readCount == -1} {
+        return ;# Insufficient data on non-blocking socket !
+    }
+    if {![info exists data(state)]} {
+        set pat {(POST|GET) ([^?]+)\??([^ ]*) HTTP/1\.[0-9]}
+        if {[regexp $pat $line x data(proto) data(url) data(query)]} {
+            return [set data(state) mime]
+        } else {
+            Log error "bad request line: %s" $line
+            Error $s 400
+            return [Done $s]
+        }
+    }
+
+    # string compare $readCount 0 maps -1 to -1, 0 to 0, and > 0 to 1
+
+    set state [string compare $readCount 0],$data(state),$data(proto)
+    switch -- $state {
+        "0,mime,GET" - "0,query,POST" {
+            Respond $s
+        }
+        "0,mime,POST" {
+            set data(state) query
+            set data(query) ""
+        }
+        "1,mime,POST" - "1,mime,GET" {
+            if [regexp {([^:]+):[   ]*(.*)}  $line dummy key value] {
+                set data(mime,[string tolower $key]) $value
+            }
+        }
+        "1,query,POST" {
+            append data(query) $line
+            set clen $data(mime,content-length)
+            if {($clen - [string length $data(query)]) <= 0} {
+                Respond $s
+            }
+        }
+        default {
+            if [eof $s] {
+                Log error "unexpected eof; client closed connection"
+                return [Done $s]
+            } else {
+                Log error "bad http protocol state: %s" $state
+                Error $s 400
+                return [Done $s]
+            }
+        }
+    }
+}
+
+proc uhttpd::Done {s} {
+
+    # @c Close the connection socket and discard token
+
+    close $s
+    unset [namespace current]::Httpd$s
+}
+
+proc uhttpd::Respond {s} {
+
+    # @c Respond to the query.
+
+    variable Httpd
+    upvar \#0 [namespace current]::Httpd$s data
+
+    if {[uplevel \#0 info proc $data(url)] == $data(url)} {
+
+        #
+        # Service URL-procedure first
+        #
+
+        if {[catch {
+            puts $s "HTTP/1.0 200 OK"
+            puts $s "Date: [Date]"
+            puts $s "Last-Modified: [Date]"
+        } err]} {
+            Log error "client closed connection prematurely: %s" $err
+            return [Done $s]
+        }
+        set data(sock) $s
+        if {[catch {$data(url) data} err]} {
+            Log error "%s: %s" $data(url) $err
+        }
+
+    } else {
+
+        #
+        # Service regular file path next.
+        #
+
+        set mypath [Url2File $data(url)]
+        if {![catch {open $mypath} i]} {
+            if {[catch {
+                puts $s "HTTP/1.0 200 OK"
+                puts $s "Date: [Date]"
+                puts $s "Last-Modified: [Date [file mtime $mypath]]"
+                puts $s "Content-Type: [ContentType $mypath]"
+                puts $s "Content-Length: [file size $mypath]"
+                puts $s ""
+                fconfigure $s -translation binary -blocking 0
+                fconfigure $i -translation binary
+                fcopy $i $s
+                close $i
+            } err]} {
+                Log error "client closed connection prematurely: %s" $err
+            }
+        } else {
+            Log error "%s: %s" $data(url) $i
+            Error $s 404
+        }
+    }
+
+    Done $s
+}
+
+proc uhttpd::ContentType {path} {
+
+    # @c Convert the file suffix into a mime type.
+
+    variable MimeTypes
+
+    set type "text/plain"
+    catch {set type $MimeTypes([file extension $path])}
+    
+    return $type
+}
+
+proc uhttpd::Error {s code} {
+
+    # @c Emit error page.
+
+    variable Httpd
+    variable HttpCodes
+    variable ErrorPage
+
+    upvar \#0 [namespace current]::Httpd$s data
+
+    append data(url) ""
+    set msg \
+        [format $ErrorPage     \
+             $code             \
+             $HttpCodes($code) \
+             $HttpCodes($code) \
+             $data(url)        \
+             $Httpd(-name)     \
+             $Httpd(-vers)     \
+             $Httpd(host)      \
+             $Httpd(port)      \
+            ]
+    if {[catch {
+        puts $s "HTTP/1.0 $code $HttpCodes($code)"
+        puts $s "Date: [Date]"
+        puts $s "Content-Length: [string length $msg]"
+        puts $s ""
+        puts $s $msg
+    } err]} {
+        Log error "client closed connection prematurely: %s" $err
+    }
+}
+
+proc uhttpd::Date {{seconds 0}} {
+
+    # @c Generate a date string in HTTP format.
+
+    if {$seconds == 0} {
+        set seconds [clock seconds]
+    }
+    clock format $seconds -format {%a, %d %b %Y %T %Z} -gmt 1
+}
+
+proc uhttpd::Log {reason format args} {
+    
+    # @c Log an httpd transaction.
+
+    set messg [eval format [list $format] $args]
+    set stamp [clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S"]
+
+    puts stderr "\[$stamp\] $reason: $messg"
+}
+
+proc uhttpd::Url2File {url} {
+
+    # @c Convert a url into a pathname (this is probably not right)
+
+    variable Httpd
+
+    lappend pathlist $Httpd(-root)
+    set level 0
+
+    foreach part [split $url /] {
+        set part [CgiMap $part]
+        if [regexp {[:/]} $part] {
+            return ""
+        }
+        switch -- $part {
+            "." { }
+            ".." {incr level -1}
+            default {incr level}
+        }
+        if {$level <= 0} {
+            return ""
+        }
+        lappend pathlist $part
+    }
+
+    set file [eval file join $pathlist]
+
+    if {[file isdirectory $file]} {
+        return [file join $file $Httpd(-index)]
+    } else {
+        return $file
+    }
+}
+
+proc uhttpd::CgiMap {data} {
+
+    # @c Decode url-encoded strings
+
+    regsub -all {\+} $data { } data
+    regsub -all {([][$\\])} $data {\\\1} data
+    regsub -all {%([0-9a-fA-F][0-9a-fA-F])} $data {[format %c 0x\1]} data
+
+    return [subst $data]
+}
+
+proc uhttpd::QueryMap {query} {
+
+    # @c Decode url-encoded query into key/value pairs
+    
+    set res [list]
+
+    regsub -all {[&=]} $query { }    query
+    regsub -all {  }   $query { {} } query; # Othewise we lose empty values
+
+    foreach {key val} $query {
+        lappend res [CgiMap $key] [CgiMap $val]
+    }
+    return $res
+}
+
+proc /monitor {array} {
+
+    upvar $array data ; # Holds the socket to remote client
+
+    #
+    # Emit headers
+    #
+
+    puts $data(sock) "HTTP/1.0 200 OK"
+    puts $data(sock) "Date: [uhttpd::Date]"
+    puts $data(sock) "Content-Type: text/html"
+    puts $data(sock) ""
+
+    #
+    # Emit body
+    #
+
+    puts $data(sock) [subst {
+        <html>
+        <body>
+        <h3>[clock format [clock seconds]]</h3>
+    }]
+
+    after 1 ; # Simulate blocking call
+
+    puts $data(sock) [subst {
+        </body>
+        </html>
+    }]
+}
+
+# EOF $RCSfile: uhttpd.tcl,v $
+# Emacs Setup Variables
+# Local Variables:
+# mode: Tcl
+# indent-tabs-mode: nil
+# tcl-basic-offset: 4
+# End:
+
diff --git a/8.x/thread/tcl/tpool/tpool.tcl b/8.x/thread/tcl/tpool/tpool.tcl
new file mode 100644 (file)
index 0000000..f6cb235
--- /dev/null
@@ -0,0 +1,579 @@
+#
+# tpool.tcl --
+#
+# Tcl implementation of a threadpool paradigm in pure Tcl using
+# the Tcl threading extension 2.5 (or higher). 
+#
+# This file is for example purposes only. The efficient C-level
+# threadpool implementation is already a part of the threading
+# extension starting with 2.5 version. Both implementations have
+# the same Tcl API so both can be used interchangeably. Goal of 
+# this implementation is to serve as an example of using the Tcl
+# extension to implement some very common threading paradigms.
+#
+# Beware: with time, as improvements are made to the C-level
+# implementation, this Tcl one might lag behind.
+# Please consider this code as a working example only.
+# 
+# 
+#
+# Copyright (c) 2002 by Zoran Vasiljevic.
+#
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# -----------------------------------------------------------------------------
+# RCS: @(#) $Id: tpool.tcl,v 1.8 2006/10/07 09:05:17 vasiljevic Exp $
+#
+
+package require Thread 2.5
+set thisScript [info script]
+
+namespace eval tpool {
+
+    variable afterevent "" ; # Idle timer event for worker threads
+    variable result        ; # Stores result from the worker thread
+    variable waiter        ; # Waits for an idle worker thread
+    variable jobsdone      ; # Accumulates results from worker threads
+
+    #
+    # Create shared array with a single element.
+    # It is used for automatic pool handles creation.
+    #
+
+    set ns [namespace current]
+    tsv::lock $ns {
+        if {[tsv::exists $ns count] == 0} {
+            tsv::set $ns count 0
+        }
+        tsv::set $ns count -1
+    }
+    variable thisScript [info script]
+}
+\f
+#
+# tpool::create --
+#
+#   Creates instance of a thread pool.
+#
+# Arguments:
+#   args Variable number of key/value arguments, as follows:
+#
+#        -minworkers  minimum # of worker threads (def:0)
+#        -maxworkers  maximum # of worker threads (def:4)
+#        -idletime    # of sec worker is idle before exiting (def:0 = never)
+#        -initcmd     script used to initialize new worker thread
+#        -exitcmd     script run at worker thread exit
+#
+# Side Effects:
+#   Might create many new threads if "-minworkers" option is > 0.
+#
+# Results:
+#   The id of the newly created thread pool. This id must be used 
+#   in all other tpool::* commands.
+#
+
+proc tpool::create {args} {
+
+    variable thisScript
+
+    #
+    # Get next threadpool handle and create the pool array.
+    #
+
+    set usage "wrong \# args: should be \"[lindex [info level 1] 0]\
+               ?-minworkers count? ?-maxworkers count?\
+               ?-initcmd script? ?-exitcmd script?\
+               ?-idletime seconds?\""
+
+    set ns [namespace current]
+    set tpid [namespace tail $ns][tsv::incr $ns count]
+
+    tsv::lock $tpid {
+        tsv::set $tpid name $tpid
+    }
+
+    #
+    # Setup default pool data.
+    #
+
+    tsv::array set $tpid {
+         thrworkers  ""
+         thrwaiters  ""
+         jobcounter  0
+         refcounter  0
+         numworkers  0
+        -minworkers  0
+        -maxworkers  4
+        -idletime    0
+        -initcmd    ""
+        -exitcmd    ""
+    }
+
+    tsv::set $tpid -initcmd  "source $thisScript"
+
+    #
+    # Override with user-supplied data
+    #
+
+    if {[llength $args] % 2} {
+        error $usage
+    }
+
+    foreach {arg val} $args {
+        switch -- $arg {
+            -minworkers -
+            -maxworkers {tsv::set $tpid $arg $val}
+            -idletime   {tsv::set $tpid $arg [expr {$val*1000}]}
+            -initcmd    {tsv::append $tpid $arg \n $val}
+            -exitcmd    {tsv::append $tpid $arg \n $val}
+            default {
+                error $usage
+            }
+        }
+    }
+
+    #
+    # Start initial (minimum) number of worker threads.
+    #
+
+    for {set ii 0} {$ii < [tsv::set $tpid -minworkers]} {incr ii} {
+        Worker $tpid
+    }
+
+    return $tpid
+}
+\f
+#
+# tpool::names --
+#
+#   Returns list of currently created threadpools
+#
+# Arguments:
+#   None.
+#
+# Side Effects:
+#   None.
+#
+# Results
+#   List of active threadpoool identifiers or empty if none found
+#
+#
+
+proc tpool::names {} {
+    tsv::names [namespace tail [namespace current]]*
+}
+\f
+#
+# tpool::post --
+#
+#   Submits the new job to the thread pool. The caller might pass
+#   the job in two modes: synchronous and asynchronous.
+#   For the synchronous mode, the pool implementation will retain
+#   the result of the passed script until the caller collects it 
+#   using the "thread::get" command.
+#   For the asynchronous mode, the result of the script is ignored.
+#
+# Arguments:
+#   args   Variable # of arguments with the following syntax:
+#          tpool::post ?-detached? tpid script
+#
+#          -detached  flag to turn the async operation (ignore result)
+#          tpid       the id of the thread pool 
+#          script     script to pass to the worker thread for execution
+#
+# Side Effects:
+#   Depends on the passed script.
+#
+# Results:
+#   The id of the posted job. This id is used later on to collect
+#   result of the job and set local variables accordingly.
+#   For asynchronously posted jobs, the return result is ignored
+#   and this function returns empty result.
+#
+
+proc tpool::post {args} {
+
+    #
+    # Parse command arguments.
+    #
+    
+    set ns [namespace current]
+    set usage "wrong \# args: should be \"[lindex [info level 1] 0]\
+               ?-detached? tpoolId script\""
+
+    if {[llength $args] == 2} {
+        set detached 0
+        set tpid [lindex $args 0]
+        set cmd  [lindex $args 1]
+    } elseif {[llength $args] == 3} {
+        if {[lindex $args 0] != "-detached"} {
+            error $usage
+        }
+        set detached 1
+        set tpid [lindex $args 1]
+        set cmd  [lindex $args 2]            
+    } else {
+        error $usage
+    }
+
+    #
+    # Find idle (or create new) worker thread. This is relatively
+    # a complex issue, since we must honour the limits about number 
+    # of allowed worker threads imposed to us by the caller.
+    #
+
+    set tid ""
+
+    while {$tid == ""} {
+        tsv::lock $tpid {
+            set tid [tsv::lpop $tpid thrworkers]
+            if {$tid == "" || [catch {thread::preserve $tid}]} {
+                set tid ""
+                tsv::lpush $tpid thrwaiters [thread::id] end
+                if {[tsv::set $tpid numworkers]<[tsv::set $tpid -maxworkers]} {
+                    Worker $tpid
+                }
+            }
+        }
+        if {$tid == ""} {
+            vwait ${ns}::waiter
+        }
+    }
+
+    #
+    # Post the command to the worker thread
+    #
+
+    if {$detached} {
+        set j ""
+        thread::send -async $tid [list ${ns}::Run $tpid 0 $cmd]
+    } else {
+        set j [tsv::incr $tpid jobcounter]
+        thread::send -async $tid [list ${ns}::Run $tpid $j $cmd] ${ns}::result
+    }
+
+    variable jobsdone
+    set jobsdone($j) ""
+
+    return $j
+}
+\f
+#
+# tpool::wait --
+#
+#   Waits for jobs sent with "thread::post" to finish.
+#
+# Arguments:
+#   tpid     Name of the pool shared array.
+#   jobList  List of job id's done.
+#   jobLeft  List of jobs still pending.
+#
+# Side Effects:
+#   Might eventually enter the event loop while waiting
+#   for the job result to arrive from the worker thread.
+#   It ignores bogus job ids.
+#
+# Results:
+#   Result of the job. If the job resulted in error, it sets
+#   the global errorInfo and errorCode variables accordingly.
+#
+
+proc tpool::wait {tpid jobList {jobLeft ""}} {
+
+    variable result
+    variable jobsdone
+
+    if {$jobLeft != ""} {
+        upvar $jobLeft jobleft
+    }
+
+    set retlist ""
+    set jobleft ""
+
+    foreach j $jobList {
+        if {[info exists jobsdone($j)] == 0} {
+            continue ; # Ignore (skip) bogus job ids
+        }
+        if {$jobsdone($j) != ""} {
+            lappend retlist $j
+        } else {
+            lappend jobleft $j
+        }
+    }
+    if {[llength $retlist] == 0 && [llength $jobList]} {
+        #
+        # No jobs found; wait for the first one to get ready.
+        #
+        set jobleft $jobList
+        while {1} {
+            vwait [namespace current]::result
+            set doneid [lindex $result 0]
+            set jobsdone($doneid) $result
+            if {[lsearch $jobList $doneid] >= 0} {
+                lappend retlist $doneid
+                set x [lsearch $jobleft $doneid]
+                set jobleft [lreplace $jobleft $x $x]
+                break
+            }
+        }
+    }
+
+    return $retlist
+}
+\f
+#
+# tpool::get --
+#
+#   Waits for a job sent with "thread::post" to finish.
+#
+# Arguments:
+#   tpid   Name of the pool shared array.
+#   jobid  Id of the previously posted job.
+#
+# Side Effects:
+#   None.
+#
+# Results:
+#   Result of the job. If the job resulted in error, it sets
+#   the global errorInfo and errorCode variables accordingly.
+#
+
+proc tpool::get {tpid jobid} {
+
+    variable jobsdone
+
+    if {[lindex $jobsdone($jobid) 1] != 0} {
+        eval error [lrange $jobsdone($jobid) 2 end]
+    }
+
+    return [lindex $jobsdone($jobid) 2]
+}
+\f
+#
+# tpool::preserve --
+#
+#   Increments the reference counter of the threadpool, reserving it
+#   for the private usage..
+#
+# Arguments:
+#   tpid   Name of the pool shared array.
+#
+# Side Effects:
+#   None.
+#
+# Results:
+#   Current number of threadpool reservations.
+#
+
+proc tpool::preserve {tpid} {
+    tsv::incr $tpid refcounter
+}
+\f
+#
+# tpool::release --
+#
+#   Decrements the reference counter of the threadpool, eventually
+#   tearing the pool down if this was the last reservation.
+#
+# Arguments:
+#   tpid   Name of the pool shared array.
+#
+# Side Effects:
+#   If the number of reservations drops to zero or below
+#   the threadpool is teared down.
+#
+# Results:
+#   Current number of threadpool reservations.
+#
+
+proc tpool::release {tpid} {
+
+    tsv::lock $tpid {
+        if {[tsv::incr $tpid refcounter -1] <= 0} {
+            # Release all workers threads
+            foreach t [tsv::set $tpid thrworkers] {
+                thread::release -wait $t
+            }
+            tsv::unset $tpid ; # This is not an error; it works!
+        }
+    }
+}
+\f
+#
+# Private procedures, not a part of the threadpool API.
+#
+\f
+#
+# tpool::Worker --
+#
+#   Creates new worker thread. This procedure must be executed
+#   under the tsv lock.
+#
+# Arguments:
+#   tpid  Name of the pool shared array.
+#
+# Side Effects:
+#   Depends on the thread initialization script.
+#
+# Results:
+#   None.
+#
+
+proc tpool::Worker {tpid} {
+
+    #
+    # Create new worker thread
+    #
+
+    set tid [thread::create]
+
+    thread::send $tid [tsv::set $tpid -initcmd]
+    thread::preserve $tid
+
+    tsv::incr  $tpid numworkers
+    tsv::lpush $tpid thrworkers $tid
+
+    #
+    # Signalize waiter threads if any
+    #
+
+    set waiter [tsv::lpop $tpid thrwaiters]
+    if {$waiter != ""} {
+        thread::send -async $waiter [subst {
+            set [namespace current]::waiter 1
+        }]
+    }
+}
+\f
+#
+# tpool::Timer --
+#
+#   This procedure should be executed within the worker thread only.
+#   It registers the callback for terminating the idle thread.
+#
+# Arguments:
+#   tpid  Name of the pool shared array.
+#
+# Side Effects:
+#   Thread may eventually exit.
+#
+# Results:
+#   None.
+#
+
+proc tpool::Timer {tpid} {
+
+    tsv::lock $tpid {
+        if {[tsv::set $tpid  numworkers] > [tsv::set $tpid -minworkers]} {
+            
+            #
+            # We have more workers than needed, so kill this one.
+            # We first splice ourselves from the list of active
+            # workers, adjust the number of workers and release 
+            # this thread, which may exit eventually.
+            #
+
+            set x [tsv::lsearch $tpid thrworkers [thread::id]]
+            if {$x >= 0} {
+                tsv::lreplace $tpid thrworkers $x $x
+                tsv::incr $tpid numworkers -1
+                set exitcmd [tsv::set $tpid -exitcmd]
+                if {$exitcmd != ""} {
+                    catch {eval $exitcmd}
+                }
+                thread::release
+            }
+        }
+    }
+}
+\f
+#
+# tpool::Run --
+#
+#   This procedure should be executed within the worker thread only.
+#   It performs the actual command execution in the worker thread.
+#
+# Arguments:
+#   tpid  Name of the pool shared array.
+#   jid   The job id
+#   cmd   The command to execute
+#
+# Side Effects:
+#   Many, depending of the passed command
+#
+# Results:
+#   List for passing the evaluation result and status back.
+#
+
+proc tpool::Run {tpid jid cmd} {
+
+    #
+    # Cancel the idle timer callback, if any.
+    #
+
+    variable afterevent
+    if {$afterevent != ""} {
+        after cancel $afterevent
+    }
+    
+    #
+    # Evaluate passed command and build the result list.
+    #
+
+    set code [catch {uplevel \#0 $cmd} ret]
+    if {$code == 0} {
+        set res [list $jid 0 $ret]
+    } else {
+        set res [list $jid $code $ret $::errorInfo $::errorCode]
+    }
+
+    #
+    # Check to see if any caller is waiting to be serviced.
+    # If yes, kick it out of the waiting state.
+    #
+    
+    set ns [namespace current]
+
+    tsv::lock $tpid {
+        tsv::lpush $tpid thrworkers [thread::id]
+        set waiter [tsv::lpop $tpid thrwaiters]
+        if {$waiter != ""} {
+            thread::send -async $waiter [subst {
+                set ${ns}::waiter 1
+            }]
+        }
+    }
+
+    #
+    # Release the thread. If this turns out to be 
+    # the last refcount held, don't bother to do
+    # any more work, since thread will soon exit.
+    #
+
+    if {[thread::release] <= 0} {
+        return $res
+    }
+
+    #
+    # Register the idle timer again.
+    #
+
+    if {[set idle [tsv::set $tpid -idletime]]} {
+        set afterevent [after $idle [subst {
+            ${ns}::Timer $tpid
+        }]]
+    }
+
+    return $res
+}
+
+# EOF $RCSfile: tpool.tcl,v $
+
+# Emacs Setup Variables
+# Local Variables:
+# mode: Tcl
+# indent-tabs-mode: nil
+# tcl-basic-offset: 4
+# End:
+
diff --git a/8.x/thread/tclconfig/ChangeLog b/8.x/thread/tclconfig/ChangeLog
new file mode 100644 (file)
index 0000000..742b74d
--- /dev/null
@@ -0,0 +1,803 @@
+2010-07-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+       * tcl.m4             [Patch #1055668] removal of exported internals from
+                            tclInt.h (EXTERN macro)
+
+2010-04-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+       * tcl.m4    - Backport a lot of quoting fixes from tcl8.6/unix/tcl.m4
+                   - Fix determination of CYGPATH for CYGWIN
+         With those fixes, itcl and tdbc compile fine with CYGWIN
+
+2010-04-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+       * install-sh         [Bug 2982540] configure and install* script files
+                            should always have LF
+
+2010-02-19  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+       * tcl.m4: Correct compiler/linker flags for threaded builds on
+       OpenBSD.
+
+2010-01-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+       * tcl.m4: Detect CYGWIN variant: win32 or unix
+
+2010-01-03  Donal K. Fellows  <dkf@users.sf.net>
+
+       * unix/tcl.m4 (TEA_CONFIG_CFLAGS): [Tcl Bug 1636685]: Use the
+       configuration for modern FreeBSD suggested by the FreeBSD porter.
+
+2009-10-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+       * tcl.m4: [Tcl Patch #2883533] tcl.m4 support for Haiku OS
+
+2009-04-27  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_CONFIG_CFLAGS): harden the check to add _r to CC on
+       AIX with threads.
+
+2009-04-10  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): check for 64-bit TkAqua.
+
+2009-03-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+       * tclconfig/tcl.m4: Adapt LDFLAGS and LD_SEARCH_FLAGS
+       together with SHLIB_LD definition to unbreak building on HPUX.
+
+2009-03-20  Andreas Kupries  <andreask@activestate.com>
+
+       * tclconfig/tcl.m4: Changed SHLIB_LD definition to unbreak
+       building on HPUX.
+
+2009-03-16  Joe English  <jenglish@users.sourceforge.net>
+       
+       * tcl.m4(TEA_PUBLIC_TK_HEADERS): Look at ${TK_INCLUDE_SPEC}
+       (found in tkConfig.sh) when trying to guess where tk.h might be
+       [Patch 1960628].
+
+2009-03-11  Joe English  <jenglish@users.sourceforge.net>
+
+       * tcl.m4: Allow ${SHLIB_SUFFIX} to be overridden at
+       configure-time [Patch 1960628].  Also fix some comment typos,
+       and an uninitialized variable bug-waiting-to-happen.
+
+2008-12-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+       * tcl.m4: [Bug 2073255] Tcl_GetString(NULL) doesn't crash on HP-UX
+                 (this bug report was for Tcl, but holds for TEA as well.)
+
+2008-12-20  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4: sync with tdbc tcl.m4 changes
+       (SunOS-5.11): Sun cc SHLIB_LD: use LDFLAGS_DEFAULT instead of LDFLAGS
+
+2008-12-02  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       *** Bump to TEA_VERSION 3.7 ***
+
+       * tcl.m4: in private header check, check for <plat>Port.h instead
+       of Int.h to ensure all private headers are available.
+
+2008-11-04  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): sync TEA_PRIVATE_TK_HEADERS handling of
+       Tk.framework PrivateHeaders with TEA_PRIVATE_TCL_HEADERS.
+
+2008-11-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_PATH_TCLCONFIG, TEA_PATH_TKCONFIG): exit with error
+       when tclConfig.sh cannot be found. [Bug #1997760]
+       (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): allow for
+       finding the headers installed in the public areas, e.g. a result of
+       make install-private-headers. [Bug #1631922]
+
+2008-08-12  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): link shlib with current and compatiblity version
+       flags; look for libX11.dylib when searching for X11 libraries.
+
+2008-06-12  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (SunOS-5.11): fix 64bit amd64 support with gcc & Sun cc.
+
+2008-03-27  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (SunOS-5.1x): fix 64bit support for Sun cc. [Bug 1921166]
+
+2008-02-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+       * tcl.m4 (TEA_CONFIG_CFLAGS): Updated to work at least in part with
+       more modern VC versions. Currently just made the linker flags more
+       flexible; more work may be needed.
+
+2007-10-26  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): add support for 64-bit X11.
+
+2007-10-23  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       *** Tagged tea-3-branch to start TEA 4 development on HEAD ***
+
+2007-09-17  Joe English  <jenglish@users.sourceforge.net>
+
+       * tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable'
+       to build shared libraries on current NetBSDs [Bug 1749251].
+
+2007-09-15  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4:       replace all direct references to compiler by ${CC} to
+                       enable CC overriding at configure & make time.
+       (SunOS-5.1x):   replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by
+                       'cc' compiler driver.
+
+2007-08-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: check Ttk dir for Tk private headers (8.5).
+       Add some comments to other bits.
+
+2007-06-25  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): move where / is added.
+
+2007-06-13  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: fix --with-tkinclude alignment. [Bug 1506111]
+
+2007-06-06  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): fix 64bit arch removal in fat 32&64bit builds.
+
+2007-05-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+       * tcl.m4: Added quoting so that paths with spaces cause fewer
+       problems.
+
+2007-03-07  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in -mmacosx-version-min check.
+
+2007-02-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: correct private header check to search in generic subdir
+
+2007-02-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       *** Bump to TEA_VERSION 3.6 ***
+
+       * tcl.m4: correct -d to -f
+       (TEA_CONFIG_CFLAGS): SHLIB_SUFFIX is .so on HP ia64 [Bug 1615058]
+
+2007-02-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): check
+       that the dirs actually have private headers. [Bug 1631922]
+
+2007-02-04  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4: add caching to -pipe check.
+
+2007-01-25  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible and
+       move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS to
+       avoid errors about multiple -isysroot flags from some older gcc builds.
+
+2006-01-19  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861]
+       (Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS when
+       present in CFLAGS to avoid discrepancies between what headers configure
+       sees during preprocessing tests and compiling tests.
+
+2006-12-19  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit -arch flag
+       succeeds before enabling 64bit build.
+
+2006-12-16  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Linux): fix previous change to use makefile variable
+       LDFLAGS_DEFAULT instead of LDFLAGS in SHLIB_LD, to ensure linker
+       flags in sampleextension Makefile are picked up.
+
+2006-11-26  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Linux): --enable-64bit support. [Patch 1597389], [Bug 1230558]
+
+2006-08-18  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
+       universal builds including x86_64 and for use of -mmacosx-version-min
+       instead of MACOSX_DEPLOYMENT_TARGET. For Tk extensions, remove 64-bit
+       arch flags from CFLAGS like in the Tk configure, as neither TkAqua nor
+       TkX11 can be built for 64-bit at present.
+
+2006-03-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: []-quote AC_DEFUN functions.
+       (TEA_PATH_TKCONFIG): Fixed Windows-specific check for tkConfig.sh.
+       (TEA_MAKE_LIB): Prepend 'lib' for Windows-gcc configs.
+
+2006-03-07  Joe English  <jenglish@users.sourceforge.net>
+
+       * tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD,
+       as per the other *BSD variants [Bug 1334613].
+
+2006-01-25  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       *** Bump to TEA version 3.5 ***
+
+       * tcl.m4: keep LD_SEARCH_FLAGS and CC_SEARCH_FLAGS synchronous
+       with core tcl.m4 meaning.
+
+2006-01-24  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): use makefile variable LDFLAGS_DEFAULT instead of
+       LDFLAGS in SHLIB_LD, to ensure linker flags in sampleextension Makefile
+       are picked up. [Bug 1403343]
+
+2006-01-23  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: add C:/Tcl/lib and C:/Progra~1/Tcl/lib dirs to check for
+       *Config.sh on Windows. [Bug 1407544]
+
+2006-01-23  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): for Tk extensions, remove -arch ppc64 from CFLAGS
+       like in the Tk configure, as neither TkAqua nor TkX11 can be built for
+       64bit at present (no 64bit GUI libraries).
+
+2006-01-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: restore system=windows on Windows.
+       Remove error if 'ar' isn't found (it may not be on Windows).
+       Do not add -lxnet or define _XOPEN_SOURCE on HP-UX by default.
+       Ensure the C|LDFLAGS_DEFAULT gets the fully sub'd value at
+       configure time.
+
+2006-01-10  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4: add caching, use AC_CACHE_CHECK instead of AC_CACHE_VAL
+       where possible, consistent message quoting, sync relevant
+       tcl/unix/tcl.m4 HEAD changes and gratuitous formatting differences
+       (notably sunc removal of support for for ancient BSD's, IRIX 4,
+       RISCos and Ultrix by kennykb), Darwin improvements to
+       TEA_LOAD_*CONFIG to make linking work against Tcl/Tk frameworks
+       installed in arbitrary location, change TEA_PROG_* search order
+       (look in *_BIN_DIR parents before *_PREFIX).
+
+2006-01-05  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: add dkf's system config refactor
+
+2006-01-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: remove extraneous ' that causes bash 3.1 to choke
+
+2005-12-19  Joe English  <jenglish@users.sourceforge.net>
+
+       * tcl.m4 (TEA_PATH_TCLCONFIG &c): Look for tclConfig.sh &c
+       in ${libdir}, where they are installed by default [Patch #1377407].
+
+2005-12-05  Don Porter  <dgp@users.sf.net>
+
+       * tcl.m4 (TEA_PUBLIC_*_HEADERS):        Better support for finding
+       header files for uninstalled Tcl and Tk.
+
+2005-12-02  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: correctly bump TEA_VERSION var to 3.4
+
+2005-12-01  Daniel Steffen  <das@users.sourceforge.net>
+
+       * unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset
+
+2005-11-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4:  *** Bump to TEA version 3.4 ***
+       Add Windows x64 build support.
+       Remove TEA_PATH_NOSPACE and handle the problem with ""s where
+       necessary - the macro relied on TCLSH_PROG which didn't work for
+       cross-compiles.
+
+2005-11-27  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): add 64bit support, add CFLAGS to SHLIB_LD to
+       support passing -isysroot in env(CFLAGS) to configure (flag can't
+       be present twice, so can't be in both CFLAGS and LDFLAGS during
+       configure), don't use -prebind when deploying on 10.4.
+       (TEA_ENABLE_LANGINFO, TEA_TIME_HANDLER): add/fix caching.
+
+2005-10-30  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4: fixed two tests for TEA_WINDOWINGSYSTEM = "aqua" that
+       should have been for `uname -s` = "Darwin" instead; added some
+       missing quoting.
+       (TEA_PROG_TCLSH, TEA_PROG_WISH): fix incorrect assumption that
+       install location of tclConfig.sh/tkConfig.sh allows to determine
+       the tclsh/wish install dir via ../bin. Indeed tcl/tk can be
+       configured with arbitrary --libdir and --bindir (independent of
+       prefix) and such a configuration is in fact standard with Darwin
+       framework builds. At least now also check ${TCL_PREFIX}/bin
+       resp. ${TK_PREFIX}/bin for presence of tclsh resp. wish (if tcl/tk
+       have been configured with arbitrary --bindir, this will still not
+       find them, for a general solution *Config.sh would need to contain
+       the values of bindir/libdir/includedir passed to configure).
+
+2005-10-07  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: Fix Solaris 5.10 check and Solaris AMD64 64-bit builds.
+
+2005-10-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_PRIVATE_TCL_HEADERS): add / to finish sed macro
+       (TEA_ENABLE_THREADS): don't check for pthread_attr_setstacksize func
+
+2005-09-13  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: *** Update to TEA version 3.3 ***
+       define TEA_WINDOWINGSYSTEM in TEA_LOAD_TKCONFIG.
+       Make --enable-threads the default (users can --disable-threads).
+       Improve AIX ${CC}_r fix to better check existing ${CC} value.
+       Do the appropriate evals to not require the *TOP_DIR_NATIVE vars
+       be set for extensions that use private headers.
+       Make aqua check for Xlib compat headers the same as win32.
+
+2005-07-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+       * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
+       TEA_PROG_WISH, TEA_BUILD_WISH): Remove
+       TEA_BUILD_TCLSH and TEA_BUILD_WISH because
+       of complaints that it broke the build when
+       only an installed version of Tcl was available
+       at extension build time. The TEA_PROG_TCLSH and
+       TEA_PROG_WISH macros will no longer search the
+       path at all. The build tclsh or installed
+       tclsh shell will now be found by TEA_PROG_TCLSH.
+
+2005-07-24  Mo DeJong  <mdejong@users.sourceforge.net>
+
+       * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
+       TEA_PROG_WISH, TEA_BUILD_WISH):
+       Split confused search for tclsh on PATH and
+       build and install locations into two macros.
+       TEA_PROG_TCLSH and TEA_PROG_WISH search the
+       system PATH for an installed tclsh or wish.
+       The TEA_BUILD_TCLSH and TEA_BUILD_WISH
+       macros determine the name of tclsh or
+       wish in the Tcl or Tk build directory even
+       if tclsh or wish has not yet been built.
+       [Tcl bug 1160114]
+       [Tcl patch 1244153]
+
+2005-06-23  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (TEA_PRIVATE_TK_HEADERS): add ${TK_SRC_DIR}/macosx to
+       TK_INCLUDES when building against TkAqua.
+
+       * tcl.m4 (TEA_PATH_X): fixed missing comma in AC_DEFINE
+
+       * tcl.m4: changes to better support framework builds of Tcl and Tk out
+       of the box: search framework install locations for *Config.sh, and if in
+       presence of a framework build, use the framework's Headers and
+       PrivateHeaders directories for public and private includes. [FR 947735]
+
+2005-06-18  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
+       ensure we can always relocate binaries with install_name_tool.
+
+2005-06-04  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (TEA_PATH_X): for TEA_WINDOWINGSYSTEM == aqua, check if xlib
+       compat headers are available in tkheaders location, otherwise add xlib
+       sourcedir to TK_XINCLUDES.
+
+2005-04-25  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4: added AC_DEFINE* descriptions (from core tcl.m4) to allow
+       use with autoheader.
+       (Darwin): added configure checks for recently added linker flags
+       -single_module and -search_paths_first to allow building with older
+       tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD.
+       (TEA_MISSING_POSIX_HEADERS): added caching of dirent.h check.
+       (TEA_BUGGY_STRTOD): added caching (sync with core tcl.m4).
+
+2005-03-24  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_TCL_64BIT_FLAGS): use Tcl header defaults for wide
+       int type only on Windows when __int64 is detected as valid.
+
+2005-03-24  Don Porter  <dgp@users.sf.net>
+
+       * README.txt:   Update reference to "SC_* macros" to "TEA_* macros".
+       * tcl.m4:       Incorporated recent improvements in SC_PATH_TCLCONFIG
+       and SC_PATH_TKCONFIG into TEA_PATH_TCLCONFIG and TEA_PATH_TKCONFIG.
+       Corrected search path in TEA_PATH_CONFIG and added
+       AC_SUBST($1_BIN_DIR) to TEA_LOAD_CONFIG so that packages that load
+       the configuration of another package can know where they loaded
+       it from.
+
+2005-03-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_CONFIG_CFLAGS): correct 2005-03-17 change to have
+       variant LD_SEARCH_FLAGS for gcc and cc builds.
+
+       * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): correct x-compile check.
+
+2005-03-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: Correct gcc build and HP-UX-11.
+
+2005-02-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_ADD_LIBS): don't touch lib args starting with -.
+       (TEA_CONFIG_CFLAGS): only define _DLL for CE in shared build.
+       (TEA_MAKE_LIB): set RANLIB* to : on Windows (it's not needed).
+
+2005-02-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: redo of 2005-01-27 changes to correctly handle paths
+       with spaces.  Win/CE and Win/64 builds now require a prebuilt
+       tclsh to handle conversion to short pathnames.  This is done in
+       the new TEA_PATH_NOSPACE macro.  For Win/CE|64, make CC just the
+       compiler and move the necessary includes to CFLAGS.
+       (TEA_CONFIG_CFLAGS): Add Solaris 64-bit gcc build support.
+       (TEA_PROG_TCLSH, TEA_PROG_WISH): Allow TCLSH_PROG and WISH_PROG to
+       be set in the env and prevent resetting.
+       (TEA_ADD_LIBS): On Windows using GCC (mingw), convert foo.lib
+       args to -lfoo, for use with mingw.
+               *** POTENTIAL INCOMPATABILITY ***
+       (TEA_CONFIG_CFLAGS): Fix AIX gcc builds to work out-of-box.
+       Bumped TEA to 3.2.
+
+2005-01-27  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: remove cygpath calls to support msys.
+       Update base CE build assumption to "420,ARMV4,ARM,Pocket PC 2003".
+       Make STLIB_LD use $LINKBIN -lib.
+
+2005-01-25  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (Darwin): fixed bug with static build linking to dynamic
+       library in /usr/lib etc instead of linking to static library earlier
+       in search path. [Tcl Bug 956908]
+       Removed obsolete references to Rhapsody.
+
+2004-12-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: Updates for VC7 compatibility, fixing CFLAGS and LDFLAGS
+       options, using better default -O levels. [Bug 1092952, 1091967]
+
+2004-12-29  Joe English  <jenglish@users.sourceforge.net>
+
+       * tcl.m4: Do not use ${DBGX} suffix when building
+       shared libraries [patch #1081595, TIP #34]
+
+2004-09-07  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_CONFIG_CFLAGS): support eVC4 Win/CE builds
+
+2004-08-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_INIT, TEA_PREFIX): update handling of exec_prefix to
+       work around subdir configures since autoconf only propagates the
+       prefix (not exec_prefix).
+
+2004-07-23  Daniel Steffen  <das@users.sourceforge.net>
+
+       * tcl.m4 (TEA_CONFIG_CFLAGS): Darwin section: brought inline with
+       Tcl 8.5 HEAD config, removed core specific & obsolete settings.
+
+2004-07-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_PATH_X): check in TK_DEFS for MAC_OSX_TK to see if
+       we are compiling on Aqua.  Add TEA_WINDOWINGSYSTEM var that
+       reflects 'tk windowingsystem' value.
+
+2004-07-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_ENABLE_THREADS): force a threaded build when
+       building against a threaded core.
+       (CFLAGS_WARNING): Remove -Wconversion for gcc builds
+       (TEA_CONFIG_CFLAGS): Reorder configure.in for better 64-bit build
+       configuration, replacing EXTRA_CFLAGS with CFLAGS.  [Bug #874058]
+       Update to latest Tcl 8.5 head config settings.
+       Call this TEA version 3.1.
+
+2004-04-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_TCL_64BIT_FLAGS): replace AC_TRY_RUN test with
+       AC_TRY_COMPILE for the long vs. long long check. (kenny)
+
+2004-04-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_TCL_64BIT_FLAGS): update against core tcl.m4 to
+       define TCL_WIDE_INT_IS_LONG if 'using long'.
+
+2004-03-19  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: correct Windows builds getting LDFLAGS info in MAKE_LIB
+
+2004-02-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: correct TCL_INCLUDES for private headers on Windows - it
+       doesn't need the eval.
+
+2004-02-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: don't require TK_INCLUDES and TCL_INCLUDES to have the
+       DIR_NATIVE vars defined when using private headers on unix.
+       Allow $... to TEA_ADD_SOURCES for constructs like
+       TEA_ADD_SOURCES([\$(WIN_OBJECTS)]), that allow the developer to
+       place more in the Makefile.in.
+       tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+       CHECK on limits.h
+
+2003-12-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * Makefile.in:      added TEA_ADD_LIBS, TEA_ADD_INCLUDES and
+       * configure:        TEA_ADD_CFLAGS to configurable parameters with
+       * configure.in:     PKG_* equivs in the Makefile.  This allows the
+       * tclconfig/tcl.m4: user to worry less about actual magic VAR names.
+       Corrected Makefile.in to note that TEA_ADD_TCL_SOURCES requires
+       exact file names.
+
+2003-12-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: updated OpenBSD support based on [Patch #775246] (cassoff)
+
+2003-12-05  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure:
+       * configure.in:
+       * Makefile.in (VPATH): readd $(srcdir) to front of VPATH as the
+       first part of VPATH can get chopped off.
+       Change .c.$(OBJEXT) rule to .c.@OBJEXT@ to support more makes.
+       * tclconfig/tcl.m4: add TEA_ADD_STUB_SOURCES to support libstub
+       generation and TEA_ADD_TCL_SOURCES to replace RUNTIME_SOURCES as
+       the way the user specifies library files.
+
+2003-12-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * configure:           Update of TEA spec to (hopefully) simplify
+       * configure.in:        some aspects of TEA by making use of more
+       * Makefile.in:         AC 2.5x features.  Use PACKAGE_NAME (instead
+       * generic/tclsample.c: of PACKAGE) and PACKAGE_VERSION (instead of
+       * tclconfig/tcl.m4:    VERSION) arguments to AC_INIT as the TEA
+       package name and version.
+       Provide a version argument to TEA_INIT - starting with 3.0.
+       Drop all use of interior shell substs that older makefiles didn't
+       like.  Use PKG_* naming convention instead.
+       Move specification of source files and public headers into
+       configure.in with TEA_ADD_SOURCES and TEA_ADD_HEADERS.  These will
+       be munged during ./configure into the right obj file names (no
+       $(SOURCES:.c=.obj) needed).
+       There is almost nothing that should be touched in Makefile.in now
+       for the developer.  May want to add a TEA_ADD_TCL_SOURCES for the
+       RUNTIME_SOURCES that remains.
+       Use SHLID_LD_FLAGS (instead of SHLID_LDFLAGS) as Tcl does.
+       Only specify the user requested LDFLAGS/CFLAGS in the Makefile,
+       don't mention the _OPTIMIZE/_DEBUG variants.
+
+2003-10-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: create a TEA_SETUP_COMPILER_CC the precedes the
+       TEA_SETUP_COMPILER macro.  They are split so the check for CC
+       occurs before any use of CC.  Also add AC_PROG_CPP to the compiler
+       checks.
+
+2003-10-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: Updated for autoconf 2.5x prereq.
+       Where TCL_WIDE_INT_TYPE would be __int64, defer to the code checks
+       in tcl.h, which also handles TCL_LL_MODIFIER* properly.
+
+2003-04-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: correct default setting of ARCH for WinCE builds.
+       Correct \ escaping for CE sed macros.
+
+2003-04-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: replace $(syscal) construct with older `syscall` for
+       systems where sh != bash.
+
+2003-04-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_WITH_CELIB): add --enable-wince and --with-celib
+       options for Windows/CE compilation support.  Requires the
+       Microsoft eMbedded SDK and Keuchel's celib emulation layer.
+
+2003-02-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_ENABLE_THREADS): Make sure -lpthread gets passed on
+       the link line when checking for the pthread_attr_setstacksize
+       symbol. (dejong)
+
+       * tcl.m4 (TEA_SETUP_COMPILER): added default calls to
+       TEA_TCL_EARLY_FLAGS, TEA_TCL_64BIT_FLAGS,
+       TEA_MISSING_POSIX_HEADERS and TEA_BUGGY_STRTOD.
+
+2003-02-14  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: correct HP-UX ia64 --enable-64bit build flags
+
+2003-01-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: check $prefix/lib as well as $exec_prefix/lib when
+       looking for tcl|tkConfig.sh, as this check is done before we would
+       set exec_prefix when the user does not define it.
+
+2003-01-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+       * tcl.m4 (TEA_CONFIG_CFLAGS): Fix build support
+       for mingw, the previous implementation would
+       use VC++ when compiling with mingw gcc. Don't
+       pass -fPIC since gcc always compiles pic code
+       under win32. Change some hard coded cases
+       of gcc to ${CC}.
+
+2002-10-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: move the CFLAGS definition from TEA_ENABLE_SHARED to
+       TEA_MAKE_LIB because setting too early confuses other AC_* macros.
+       Correct the HP-11 SHLIB_LD_LIBS setting.
+
+       * tcl.m4: add the CFLAGS definition into TEA_ENABLE_SHARED and
+       make it pick up the env CFLAGS at configure time.
+
+2002-10-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: add --enable-symbols=mem option to enable TCL_MEM_DEBUG.
+       Improved AIX 64-bit build support, allow it on AIX-4 as well.
+       Enable 64-bit HP-11 compilation with gcc.
+       Enable 64-bit IRIX64-6 cc build support.
+       Correct FreeBSD thread library linkage.
+       Add OSF1 static build support.
+       Improve SunOS-5 shared build SHLIB_LD macro.
+
+2002-07-20  Zoran Vasiljevic  <zoran@archiware.com>
+
+       * tcl.m4: Added MINGW32 to list of systems checked for Windows build.
+       Also, fixes some indentation issues with "--with-XXX" options.
+
+2002-04-23  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_ENABLE_THREADS): added USE_THREAD_ALLOC define to
+       use new threaded allocatory by default on Unix for Tcl 8.4.
+       (TEA_CONFIG_CFLAGS): corrected LD_SEARCH_FLAGS for FreeBSD-3+.
+
+2002-04-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4 (TEA_SETUP_COMPILER): removed call to AC_CYGWIN so that
+       we can use autoconf 2.5x as well as 2.13.  This prevents us from
+       being able to warn against the use of cygwin gcc at configure
+       time, but allows autoconf 2.5x, which is what is shipped with most
+       newer systems.
+
+2002-04-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: Enabled COFF as well as CV style debug info with
+       --enable-symbols to allow Dr. Watson users to see function info.
+       More info on debugging levels can be obtained at:
+       http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+
+2002-04-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: change all SC_* macros to TEA_*.  The SC_ was for
+       Scriptics, which is no more.  TEA represents a better, independent
+       prefix that won't need changing.
+       Added preliminary mingw gcc support. [Patch #538772]
+       Added TEA_PREFIX macro that handles defaulting the prefix and
+       exec_prefix vars to those used by Tcl if none were specified.
+       Added TEA_SETUP_COMPILER macro that encompasses the AC_PROG_CC
+       check and several other basic AC_PROG checks needed for making
+       executables.  This greatly simplifies user's configure.in files.
+       Collapsed AIX-5 defines into AIX-* with extra checks for doing the
+       ELF stuff on AIX-5-ia64.
+       Updated TEA_ENABLE_THREADS to take an optional arg to allow
+       switching it on by default (for Thread) and add sanity checking to
+       warn the user if configuring threads incompatibly.
+
+2002-03-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: made sure that SHLIB_LDFLAGS was set to LDFLAGS_DEFAULT.
+       Removed --enable-64bit support for AIX-4 because it wasn't correct.
+       Added -MT or -MD Windows linker switches to properly support
+       symbols-enabled builds.
+
+2002-03-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: called AC_MSG_ERROR when SC_TEA_INIT wasn't called first
+       instead of calling it as that inlines it each time in shell code.
+       Changed Windows CFLAGS_OPTIMIZE to use -O2 instead of -Oti.
+       Noted TCL_LIB_VERSIONS_OK=nodots for Windows builds.
+       A few changes to support itcl (and perhaps others):
+       Added support for making your own stub libraries to SC_MAKE_LIB.
+       New SC_PATH_CONFIG and SC_LOAD_CONFIG that take a package name arg
+       and find that ${pkg}Config.sh file.  itk uses this for itcl.
+
+2002-03-27  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: made SC_LOAD_TKCONFIG recognize when working with a Tk
+       build dir setup.
+       Added EXTRA_CFLAGS and SHLIB_LD_LIBS substs to SC_CONFIG_CFLAGS.
+       Added XLIBSW onto LIBS when it is defined.
+       Remove TCL_LIBS from MAKE_LIB and correctly use SHLIB_LD_LIBS
+       instead to not rely as much on tclConfig.sh cached info.
+       Add TK_BIN_DIR to paths to find wish in SC_PROG_WISH.
+       These move towards making TEA much more independent of *Config.sh.
+
+2002-03-19  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: corrected forgotten (UN)SHARED_LIB_SUFFIX and
+       SHLIB_SUFFIX defines for Win.
+       (SC_PATH_X): made this only do the check on unix platforms.
+
+2002-03-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * README.txt: updated to reflect fewer files
+
+2002-03-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * config.guess (removed):
+       * config.sub (removed): removed unnecessary files
+
+       * installFile.tcl (removed):
+       * mkinstalldirs (removed): these aren't really necessary for
+       making TEA work
+
+       * tcl.m4 (SC_PUBLIC_TCL_HEADERS, SC_PUBLIC_TK_HEADERS): don't
+       check /usr(/local)/include for includes on Windows when not using
+       gcc
+
+2002-03-05  Jeff Hobbs  <jeffh@ActiveState.com>
+
+       * tcl.m4: added warnings on Windows, removed RELPATH define and
+       added TCL_LIBS to MAKE_LIB macro.
+
+       This import represents 2.0.0, or a new start at attempting to
+       make TEA much easier for C extension developers.
+
+       **** moved from tclpro project to core tcl project, ****
+       **** renamed to 'tclconfig'                         ****
+
+2001-03-15    Karl Lehenbauer <karl@procplace.com>
+
+       * installFile.tcl: Added updating of the modification time of
+         the target file whether we overwrote it or decided that it
+         hadn't changed.  This was necessary for us to be able to
+         determine whether or not a module install touched the file.
+
+2001-03-08    Karl Lehenbauer <karl@procplace.com>
+
+       * installFile.tcl: Added support for converting new-style (1.1+)
+         Cygnus drive paths to Tcl-style.
+
+2001-01-15    <brent.welch@interwoven.com>
+
+       * tcl.m4: Added FreeBSD clause.
+
+2001-01-03    <brent.welch@interwoven.com>
+
+       * tcl.m4: Fixed typo in SC_LIB_SPEC where it is checking
+       for exec-prefix.
+
+2000-12-01    <brent.welch@interwoven.com>
+
+       * tcl.m4: Concatenated most of the Ajuba acsite.m4 file
+       so we don't need to modify the autoconf installation.
+       * config.guess:
+       * config.sub:
+       * installFile.tcl:
+       Added files from the itcl config subdirectory,
+       which should go away.
+
+2000-7-29    <welch@ajubasolutions.com>
+
+       * Fixed the use of TCL_SRC_DIR and TK_SRC_DIR within
+       TCL_PRIVATE_INCLUDES and TK_PRIVATE_INCLUDES to match their recent
+       change from $(srcdir) to $(srcdir)/..
diff --git a/8.x/thread/tclconfig/README.txt b/8.x/thread/tclconfig/README.txt
new file mode 100644 (file)
index 0000000..59b5a3e
--- /dev/null
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension.  For more information on TEA see:
+
+       http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+       http://tcl.sourceforge.net/
+
+This package is a freely available open source package.  You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt     This file
+
+install-sh     Program used for copying binaries and script files
+               to their install locations.
+
+tcl.m4         Collection of Tcl autoconf macros.  Included by a package's
+               aclocal.m4 to define TEA_* macros.
diff --git a/8.x/thread/tclconfig/install-sh b/8.x/thread/tclconfig/install-sh
new file mode 100755 (executable)
index 0000000..0ff4b6a
--- /dev/null
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+       echo "install:  no destination specified"
+       exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+       dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/8.x/thread/tclconfig/tcl.m4 b/8.x/thread/tclconfig/tcl.m4
new file mode 100644 (file)
index 0000000..d58dc2e
--- /dev/null
@@ -0,0 +1,4232 @@
+# tcl.m4 --
+#
+#      This file provides a set of autoconf macros to help TEA-enable
+#      a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: tcl.m4,v 1.142 2010/07/05 18:29:32 nijtmans Exp $
+
+AC_PREREQ(2.57)
+
+dnl TEA extensions pass us the version of TEA they think they
+dnl are compatible with (must be set in TEA_INIT below)
+dnl TEA_VERSION="3.7"
+
+# Possible values for key variables defined:
+#
+# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
+# TEA_PLATFORM        - windows unix
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+#      Locate the tclConfig.sh file and perform a sanity check on
+#      the Tcl compile flags
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tcl=...
+#
+#      Defines the following vars:
+#              TCL_BIN_DIR     Full path to the directory containing
+#                              the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+       AC_ARG_WITH(tcl,
+           AC_HELP_STRING([--with-tcl],
+               [directory containing tcl configuration (tclConfig.sh)]),
+           with_tclconfig="${withval}")
+       AC_MSG_CHECKING([for Tcl configuration])
+       AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case "${with_tclconfig}" in
+                   */tclConfig.sh )
+                       if test -f "${with_tclconfig}"; then
+                           AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+                           with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+               else
+                   AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test "${TEA_PLATFORM}" = "windows" \
+                           -a -f "$i/win/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+                       break
+                   fi
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
+                       break
+                   fi
+               done
+           fi
+
+           # TEA specific: on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig="`(cd $i; pwd)`"
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig="`(cd $i; pwd)`"
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test "${TEA_PLATFORM}" = "windows" \
+                           -a -f "$i/win/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+                       break
+                   fi
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+                   break
+               fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           AC_MSG_ERROR([Can't find Tcl configuration definitions])
+       else
+           no_tcl=
+           TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+           AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+#      Locate the tkConfig.sh file
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tk=...
+#
+#      Defines the following vars:
+#              TK_BIN_DIR      Full path to the directory containing
+#                              the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+    #
+    # Ok, lets find the tk configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tk
+    #
+
+    if test x"${no_tk}" = x ; then
+       # we reset no_tk in case something fails here
+       no_tk=true
+       AC_ARG_WITH(tk,
+           AC_HELP_STRING([--with-tk],
+               [directory containing tk configuration (tkConfig.sh)]),
+           with_tkconfig="${withval}")
+       AC_MSG_CHECKING([for Tk configuration])
+       AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+           # First check to see if --with-tkconfig was specified.
+           if test x"${with_tkconfig}" != x ; then
+               case "${with_tkconfig}" in
+                   */tkConfig.sh )
+                       if test -f "${with_tkconfig}"; then
+                           AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+                           with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+                       fi ;;
+               esac
+               if test -f "${with_tkconfig}/tkConfig.sh" ; then
+                   ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+               else
+                   AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tk library
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ../tk \
+                       `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tk \
+                       `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tk \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test "${TEA_PLATFORM}" = "windows" \
+                           -a -f "$i/win/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+                       break
+                   fi
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tk.framework/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig="`(cd $i; pwd)`"
+                       break
+                   fi
+               done
+           fi
+
+           # TEA specific: on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig="`(cd $i; pwd)`"
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tk \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test "${TEA_PLATFORM}" = "windows" \
+                           -a -f "$i/win/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+                       break
+                   fi
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tkconfig}" = x ; then
+           TK_BIN_DIR="# no Tk configs found"
+           AC_MSG_ERROR([Can't find Tk configuration definitions])
+       else
+           no_tk=
+           TK_BIN_DIR="${ac_cv_c_tkconfig}"
+           AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+#      Load the tclConfig.sh file
+#
+# Arguments:
+#
+#      Requires the following vars to be set:
+#              TCL_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              TCL_BIN_DIR
+#              TCL_SRC_DIR
+#              TCL_LIB_FILE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${TCL_BIN_DIR}/tclConfig.sh"
+    else
+        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+        TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+        TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitrary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+                   for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+                            "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+                   TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+    AC_SUBST(TCL_VERSION)
+    AC_SUBST(TCL_PATCH_LEVEL)
+    AC_SUBST(TCL_BIN_DIR)
+    AC_SUBST(TCL_SRC_DIR)
+
+    AC_SUBST(TCL_LIB_FILE)
+    AC_SUBST(TCL_LIB_FLAG)
+    AC_SUBST(TCL_LIB_SPEC)
+
+    AC_SUBST(TCL_STUB_LIB_FILE)
+    AC_SUBST(TCL_STUB_LIB_FLAG)
+    AC_SUBST(TCL_STUB_LIB_SPEC)
+
+    case "`uname -s`" in
+       *CYGWIN_*)
+           AC_MSG_CHECKING([for cygwin variant])
+           case ${TCL_EXTRA_CFLAGS} in
+               *-mwin32*|*-mno-cygwin*)
+                   TEA_PLATFORM="windows"
+                   CFLAGS="$CFLAGS -mwin32"
+                   AC_MSG_RESULT([win32])
+                   ;;
+               *)
+                   TEA_PLATFORM="unix"
+                   AC_MSG_RESULT([unix])
+                   ;;
+           esac
+           EXEEXT=".exe"
+           ;;
+       *)
+           ;;
+    esac
+
+    # TEA specific:
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(TCL_DEFS)
+    AC_SUBST(TCL_EXTRA_CFLAGS)
+    AC_SUBST(TCL_LD_FLAGS)
+    AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+#      Load the tkConfig.sh file
+#
+# Arguments:
+#
+#      Requires the following vars to be set:
+#              TK_BIN_DIR
+#
+# Results:
+#
+#      Sets the following vars that should be in tkConfig.sh:
+#              TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${TK_BIN_DIR}/tkConfig.sh"
+    else
+        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+    # If the TK_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TK_LIB_SPEC will be set to the value
+    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+    # instead of TK_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+        TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+        TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tk was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tk.framework installed in an arbitrary location.
+       case ${TK_DEFS} in
+           *TK_FRAMEWORK*)
+               if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+                   for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+                            "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+                           TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+                   TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+                   TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+    # TEA specific: Ensure windowingsystem is defined
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       case ${TK_DEFS} in
+           *MAC_OSX_TK*)
+               AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+               TEA_WINDOWINGSYSTEM="aqua"
+               ;;
+           *)
+               TEA_WINDOWINGSYSTEM="x11"
+               ;;
+       esac
+    elif test "${TEA_PLATFORM}" = "windows" ; then
+       TEA_WINDOWINGSYSTEM="win32"
+    fi
+
+    AC_SUBST(TK_VERSION)
+    AC_SUBST(TK_BIN_DIR)
+    AC_SUBST(TK_SRC_DIR)
+
+    AC_SUBST(TK_LIB_FILE)
+    AC_SUBST(TK_LIB_FLAG)
+    AC_SUBST(TK_LIB_SPEC)
+
+    AC_SUBST(TK_STUB_LIB_FILE)
+    AC_SUBST(TK_STUB_LIB_FLAG)
+    AC_SUBST(TK_STUB_LIB_SPEC)
+
+    # TEA specific:
+    AC_SUBST(TK_LIBS)
+    AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+#      Determine the fully qualified path name of the tclsh executable
+#      in the Tcl build directory or the tclsh installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the tclsh executable even if tclsh has not yet been
+#      built in the build directory. The tclsh found is always
+#      associated with a tclConfig.sh file. This tclsh should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+    AC_MSG_CHECKING([for tclsh])
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+    fi
+    AC_MSG_RESULT([${TCLSH_PROG}])
+    AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+#      Determine the fully qualified path name of the wish executable
+#      in the Tk build directory or the wish installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the wish executable even if wish has not yet been
+#      built in the build directory. The wish found is always
+#      associated with a tkConfig.sh file. This wish should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+    AC_MSG_CHECKING([for wish])
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        # tkConfig.sh is in Tk build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="${TK_BIN_DIR}/wish"
+        fi
+    else
+        # tkConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+        fi
+        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${WISH_PROG}" ; then
+                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+                break
+            fi
+        done
+        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+    fi
+    AC_MSG_RESULT([${WISH_PROG}])
+    AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+#      Allows the building of shared libraries
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-shared=yes|no
+#
+#      Defines the following vars:
+#              STATIC_BUILD    Used for building import/export libraries
+#                              on Windows.
+#
+#      Sets the following vars:
+#              SHARED_BUILD    Value of 1 or 0
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SHARED], [
+    AC_MSG_CHECKING([how to build libraries])
+    AC_ARG_ENABLE(shared,
+       AC_HELP_STRING([--enable-shared],
+           [build and link with shared libraries (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       AC_MSG_RESULT([shared])
+       SHARED_BUILD=1
+    else
+       AC_MSG_RESULT([static])
+       SHARED_BUILD=0
+       AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
+    fi
+    AC_SUBST(SHARED_BUILD)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+#      Specify if thread support should be enabled.  If "yes" is specified
+#      as an arg (optional), threads are enabled by default, "no" means
+#      threads are disabled.  "yes" is the default.
+#
+#      TCL_THREADS is checked so that if you are compiling an extension
+#      against a threaded core, your extension must be compiled threaded
+#      as well.
+#
+#      Note that it is legal to have a thread enabled extension run in a
+#      threaded or non-threaded Tcl core, but a non-threaded extension may
+#      only run in a non-threaded Tcl core.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-threads
+#
+#      Sets the following vars:
+#              THREADS_LIBS    Thread library(s)
+#
+#      Defines the following vars:
+#              TCL_THREADS
+#              _REENTRANT
+#              _THREAD_SAFE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+    AC_ARG_ENABLE(threads,
+       AC_HELP_STRING([--enable-threads],
+           [build with threads]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+           AC_DEFINE(USE_THREAD_ALLOC, 1,
+               [Do we want to use the threaded memory allocator?])
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           if test "`uname -s`" = "SunOS" ; then
+               AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+                       [Do we really want to follow the standard? Yes we do!])
+           fi
+           AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+           AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               AC_CHECK_LIB(pthread, __pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               AC_CHECK_LIB(pthreads, pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   AC_CHECK_LIB(c, pthread_mutex_init,
+                       tcl_ok=yes, tcl_ok=no)
+                   if test "$tcl_ok" = "no"; then
+                       AC_CHECK_LIB(c_r, pthread_mutex_init,
+                           tcl_ok=yes, tcl_ok=no)
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    AC_MSG_CHECKING([for building with threads])
+    if test "${TCL_THREADS}" = 1; then
+       AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+       AC_MSG_RESULT([yes (default)])
+    else
+       AC_MSG_RESULT([no])
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               AC_MSG_WARN([
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads.])
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               AC_MSG_WARN([
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core.])
+           fi
+           ;;
+    esac
+    AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+#      Specify if debugging symbols should be used.
+#      Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+#      none
+#
+#      TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+#      the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+#      Requires the following vars to be set in the Makefile:
+#              CFLAGS_DEFAULT
+#              LDFLAGS_DEFAULT
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-symbols
+#
+#      Defines the following vars:
+#              CFLAGS_DEFAULT  Sets to $(CFLAGS_DEBUG) if true
+#                              Sets to $(CFLAGS_OPTIMIZE) if false
+#              LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+#                              Sets to $(LDFLAGS_OPTIMIZE) if false
+#              DBGX            Formerly used as debug library extension;
+#                              always blank now.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_CONFIG_CFLAGS])
+    AC_MSG_CHECKING([for build with symbols])
+    AC_ARG_ENABLE(symbols,
+       AC_HELP_STRING([--enable-symbols],
+           [build with debugging symbols (default: off)]),
+       [tcl_ok=$enableval], [tcl_ok=no])
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       AC_MSG_RESULT([no])
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           AC_MSG_RESULT([yes (standard debugging)])
+       fi
+    fi
+    # TEA specific:
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+    AC_SUBST(CFLAGS_DEFAULT)
+    AC_SUBST(LDFLAGS_DEFAULT)
+    AC_SUBST(TCL_DBGX)
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+       AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           AC_MSG_RESULT([enabled symbols mem debugging])
+       else
+           AC_MSG_RESULT([enabled $tcl_ok debugging])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+#      Allows use of modern nl_langinfo check for better l10n.
+#      This is only relevant for Unix.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-langinfo=yes|no (default is yes)
+#
+#      Defines the following vars:
+#              HAVE_LANGINFO   Triggers use of nl_langinfo if defined.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+    AC_ARG_ENABLE(langinfo,
+       AC_HELP_STRING([--enable-langinfo],
+           [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+       [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+    HAVE_LANGINFO=0
+    if test "$langinfo_ok" = "yes"; then
+       AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+    fi
+    AC_MSG_CHECKING([whether to use nl_langinfo])
+    if test "$langinfo_ok" = "yes"; then
+       AC_CACHE_VAL(tcl_cv_langinfo_h, [
+           AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+                   [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+       AC_MSG_RESULT([$tcl_cv_langinfo_h])
+       if test $tcl_cv_langinfo_h = yes; then
+           AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+       fi
+    else
+       AC_MSG_RESULT([$langinfo_ok])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+#      Determine what the system is (some things cannot be easily checked
+#      on a feature-driven basis, alas). This can usually be done via the
+#      "uname" command, but there are a few systems, like Next, where
+#      this doesn't work.
+#
+# Arguments:
+#      none
+#
+# Results:
+#      Defines the following var:
+#
+#      system -        System/platform/version identification code.
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+       # TEA specific:
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               AC_MSG_WARN([can't find uname command])
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+    ])
+    system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+#      Try to determine the proper flags to pass to the compiler
+#      for building shared libraries and other such nonsense.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substitutes the following vars:
+#
+#       DL_OBJS -       Name of the object file that implements dynamic
+#                       loading for Tcl on this system.
+#       DL_LIBS -       Library file(s) to include in tclsh and other base
+#                       applications in order for the "load" command to work.
+#       LDFLAGS -      Flags to pass to the compiler when linking object
+#                       files into an executable application binary such
+#                       as tclsh.
+#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
+#                       be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+#       CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile.
+#       SHLIB_CFLAGS -  Flags to pass to cc when compiling the components
+#                       of a shared library (may request position-independent
+#                       code, among other things).
+#       SHLIB_LD -      Base command to use for combining object files
+#                       into a shared library.
+#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+#                       creating shared libraries.  This symbol typically
+#                       goes at the end of the "ld" commands that build
+#                       shared libraries. The value of the symbol is
+#                       "${LIBS}" if all of the dependent libraries should
+#                       be specified when creating a shared library.  If
+#                       dependent libraries should not be specified (as on
+#                       SunOS 4.x, where they cause the link to fail, or in
+#                       general if Tcl and Tk aren't themselves shared
+#                       libraries), then this symbol has an empty string
+#                       as its value.
+#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
+#                       extensions.  An empty string means we don't know how
+#                       to use shared libraries on this platform.
+#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
+#                       in a static or shared library name, using the $VERSION variable
+#                       to put the version in the right place.  This is used
+#                       by platforms that need non-standard library names.
+#                       Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
+#                       to have a version after the .so, and ${VERSION}.a
+#                       on AIX, since a shared library needs to have
+#                       a .a extension whereas shared objects for loadable
+#                       extensions have a .so extension.  Defaults to
+#                       ${VERSION}${SHLIB_SUFFIX}.
+#       TCL_NEEDS_EXP_FILE -
+#                       1 means that an export file is needed to link to a
+#                       shared library.
+#       TCL_EXP_FILE -  The name of the installed export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#       TCL_BUILD_EXP_FILE -
+#                       The name of the built export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#      CFLAGS_DEBUG -
+#                      Flags used when running the compiler in debug mode
+#      CFLAGS_OPTIMIZE -
+#                      Flags used when running the compiler in optimize mode
+#      CFLAGS -        Additional CFLAGS added as necessary (usually 64-bit)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+    dnl TEA specific: Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+
+    # Step 0.a: Enable 64 bit support?
+
+    AC_MSG_CHECKING([if 64bit support is requested])
+    AC_ARG_ENABLE(64bit,
+       AC_HELP_STRING([--enable-64bit],
+           [enable 64bit support (default: off)]),
+       [do64bit=$enableval], [do64bit=no])
+    AC_MSG_RESULT([$do64bit])
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+    AC_ARG_ENABLE(64bit-vis,
+       AC_HELP_STRING([--enable-64bit-vis],
+           [enable 64bit Sparc VIS support (default: off)]),
+       [do64bitVIS=$enableval], [do64bitVIS=no])
+    AC_MSG_RESULT([$do64bitVIS])
+    # Force 64bit on with VIS
+    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+    # Step 0.c: Check if visibility support is available. Do this here so
+    # that platform specific alternatives can be used below if this fails.
+
+    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+       tcl_cv_cc_visibility_hidden, [
+       hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+       AC_TRY_LINK([
+           extern __attribute__((__visibility__("hidden"))) void f(void);
+           void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+           tcl_cv_cc_visibility_hidden=no)
+       CFLAGS=$hold_cflags])
+    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+       AC_DEFINE(MODULE_SCOPE,
+           [extern __attribute__((__visibility__("hidden")))],
+           [Compiler support for module scope symbols])
+    ])
+
+    # Step 0.d: Disable -rpath support?
+
+    AC_MSG_CHECKING([if rpath support is requested])
+    AC_ARG_ENABLE(rpath,
+       AC_HELP_STRING([--disable-rpath],
+           [disable rpath support (default: on)]),
+       [doRpath=$enableval], [doRpath=yes])
+    AC_MSG_RESULT([$doRpath])
+
+    # TEA specific: Cross-compiling options for Windows/CE builds?
+
+    AS_IF([test "${TEA_PLATFORM}" = windows], [
+       AC_MSG_CHECKING([if Windows/CE build is requested])
+       AC_ARG_ENABLE(wince,
+           AC_HELP_STRING([--enable-wince],
+               [enable Win/CE support (where applicable)]),
+           [doWince=$enableval], [doWince=no])
+       AC_MSG_RESULT([$doWince])
+    ])
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+    TEA_CONFIG_SYSTEM
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
+
+    # Require ranlib early so we can override it in special cases below.
+
+    AC_REQUIRE([AC_PROG_RANLIB])
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    # TEA specific: use PACKAGE_VERSION instead of VERSION
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    AS_IF([test "$GCC" = yes], [
+       # TEA specific:
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall"
+    ], [CFLAGS_WARNING=""])
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
+dnl AC_CHECK_TOOL(AR, ar)
+    AC_CHECK_PROG(AR, ar, ar)
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION="1.0"])
+    case $system in
+       # TEA specific:
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+                   AC_MSG_WARN([Ensure latest Platform SDK is installed])
+                   do64bit="no"
+               else
+                   AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+               fi
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+               fi
+               TEA_PATH_CELIB
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+           if ([$]1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+           if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+           if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+                   TEA_ADD_LIBS([bufferoverflowU.lib])
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+                       AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+                   done
+                   AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+                   AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+                   AC_SUBST(CELIB_DIR)
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # and also
+               # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug -debugtype:cv"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r|*_r\ *)
+                       # ok ...
+                       ;;
+                   *)
+                       # Make sure only first arg gets _r
+                       CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
+                       ;;
+               esac
+               AC_MSG_RESULT([Using $CC for compiling with threads])
+           ])
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           AS_IF([test "$do64bit" = yes -a "`uname -v`" -gt 3], [
+               AS_IF([test "$GCC" = yes], [
+                   AC_MSG_WARN([64bit mode not supported with GCC on $system])
+               ], [
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+               ])
+           ])
+
+           AS_IF([test "`uname -m`" = ia64], [
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               AS_IF([test "$GCC" = yes], [
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               ], [
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+               ])
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           ], [
+               AS_IF([test "$GCC" = yes], [SHLIB_LD='${CC} -shared'], [
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+               ])
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               # TEA specific: use PACKAGE_VERSION instead of VERSION
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+           ])
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           AS_IF([test "$system" = "AIX-4.1" -o "`uname -v`" -lt 4], [
+               AC_LIBOBJ([tclLoadAix])
+               DL_LIBS="-lld"
+           ])
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
+           AS_IF([test $libbsd = yes], [
+               MATH_LIBS="$MATH_LIBS -lbsd"
+               AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
+           ])
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -nostart'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD='${CC} -shared'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       CYGWIN_*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD='${CC} -shared'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           EXE_SUFFIX=".exe"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       Haiku*)
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-lroot"
+           AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+           AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+           # TEA specific: Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           AS_IF([test "`uname -m`" = ia64], [
+               SHLIB_SUFFIX=".so"
+               # Use newer C++ library for C++ extensions
+               #if test "$GCC" != "yes" ; then
+               #   CPPFLAGS="-AA"
+               #fi
+           ], [
+               SHLIB_SUFFIX=".sl"
+           ])
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           AS_IF([test "$tcl_ok" = yes], [
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           ])
+           AS_IF([test "$GCC" = yes], [
+               SHLIB_LD='${CC} -shared'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           ], [
+               CFLAGS="$CFLAGS -z"
+               # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+               #CFLAGS="$CFLAGS +DAportable"
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+           ])
+
+           # Check to enable 64-bit flags for compiler/linker
+           AS_IF([test "$do64bit" = "yes"], [
+               AS_IF([test "$GCC" = yes], [
+                   case `${CC} -dumpmachine` in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD='${CC} -shared'
+                           SHLIB_LD_LIBS='${LIBS}'
+                           AS_IF([test $doRpath = yes], [
+                               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           AC_MSG_WARN([64bit mode not supported with GCC on $system])
+                           ;;
+                   esac
+               ], [
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+               ])
+           ]) ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           AS_IF([test "$tcl_ok" = yes], [
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           ]) ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           AS_IF([test "$GCC" = yes], [
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+           ], [
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+           ])
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           AS_IF([test "$do64bit" = yes], [
+               AS_IF([test "$GCC" = yes], [
+                   AC_MSG_WARN([64bit mode not supported by gcc])
+               ], [
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               ])
+           ])
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           # TEA specific:
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+           AS_IF([test $do64bit = yes], [
+               AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+                   CFLAGS=$hold_cflags])
+               AS_IF([test $tcl_cv_cc_m64 = yes], [
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+               ])
+          ])
+
+           # The combo of gcc + glibc has a bug related to inlining of
+           # functions like strtod(). The -fno-builtin flag should address
+           # this problem but it does not work. The -fno-inline flag is kind
+           # of overkill but it works. Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+
+           AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD='${CC} -shared'
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD='${CC} -shared'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-1.*|FreeBSD-[[1-2]].*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           AS_IF([test $tcl_cv_ld_elf = yes], [
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+           ], [
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+           ])
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           AS_IF([test $tcl_cv_ld_elf = yes], [
+               LDFLAGS=-Wl,-export-dynamic
+           ], [LDFLAGS=""])
+           AS_IF([test "${TCL_THREADS}" = "1"], [
+               # OpenBSD builds and links with -pthread, never -lpthread.
+               LIBS=`echo $LIBS | sed s/-lpthread//`
+               CFLAGS="$CFLAGS -pthread"
+               SHLIB_CFLAGS="$SHLIB_CFLAGS -pthread"
+           ])
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       NetBSD-*|FreeBSD-[[3-4]].*)
+           # FreeBSD 3.* and greater have ELF.
+           # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           AS_IF([test "${TCL_THREADS}" = "1"], [
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+           ])
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       FreeBSD-*)
+           # This configuration from FreeBSD Ports.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -shared"
+           TCL_SHLIB_LD_EXTRAS="-soname \$[@]"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           AS_IF([test "${TCL_THREADS}" = "1"], [
+               # The -pthread needs to go in the LDFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+               LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
+           # Version numbers are dot-stripped by system policy.
+           TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           # To avoid discrepancies between what headers configure sees during
+           # preprocessing tests and compiling tests, move any -isysroot and
+           # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+           CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
+           CFLAGS="`echo " ${CFLAGS}" | \
+               awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+               if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
+           AS_IF([test $do64bit = yes], [
+               case `arch` in
+                   ppc)
+                       AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+                               tcl_cv_cc_arch_ppc64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+                                   tcl_cv_cc_arch_ppc64=no)
+                           CFLAGS=$hold_cflags])
+                       AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+                       ]);;
+                   i386)
+                       AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+                               tcl_cv_cc_arch_x86_64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+                                   tcl_cv_cc_arch_x86_64=no)
+                           CFLAGS=$hold_cflags])
+                       AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+                       ]);;
+                   *)
+                       AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+               esac
+           ], [
+               # Check for combined 32-bit and 64-bit fat build
+               AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+                   && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+                   fat_32_64=yes])
+           ])
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+               LDFLAGS=$hold_ldflags])
+           AS_IF([test $tcl_cv_ld_single_module = yes], [
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+           ])
+           # TEA specific: link shlib with current and compatiblity version flags
+           vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+           SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+               "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+               LDFLAGS="$LDFLAGS -prebind"])
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+                   tcl_cv_ld_search_paths_first, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+                       tcl_cv_ld_search_paths_first=no)
+               LDFLAGS=$hold_ldflags])
+           AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+           ])
+           AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+               AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+                   [Compiler support for module scope symbols])
+               tcl_cv_cc_visibility_hidden=yes
+           ])
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+           # TEA specific: for combined 32 & 64 bit fat builds of Tk
+           # extensions, verify that 64-bit build is possible.
+           AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+               AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+                   AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+                       done
+                       CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+                       LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+                       AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
+                           tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval $v'="$hold_'$v'"'
+                       done])
+               ])
+               AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
+                   AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+                       done
+                       CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+                       LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+                       AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
+                           tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
+                       for v in CFLAGS CPPFLAGS LDFLAGS; do
+                           eval $v'="$hold_'$v'"'
+                       done])
+               ])
+               # remove 64-bit arch flags from CFLAGS et al. if configuration
+               # does not support 64-bit.
+               AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
+                   AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
+                   for v in CFLAGS CPPFLAGS LDFLAGS; do
+                       eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+                   done])
+           ])
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD='${CC} -nostdlib -r'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+           AC_DEFINE(_OE_SOCKETS, 1,   # needed in sys/socket.h
+               [Should OS/390 do the right thing with sockets?])
+           ;;
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export $@:'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           AS_IF([test "$SHARED_BUILD" = 1], [SHLIB_LD="ld -shared"], [
+               SHLIB_LD="ld -non_shared"
+           ])
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           AS_IF([test "$SHARED_BUILD" = 1], [
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+           ], [
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+           ])
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           AS_IF([test $doRpath = yes], [
+               CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+           AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           AS_IF([test "${TCL_THREADS}" = 1], [
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               AS_IF([test "$GCC" = yes], [
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+               ], [
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+               ])
+           ])
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           AS_IF([test "$GCC" = yes], [
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+           ], [
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+           ])
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[[0-6]])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           AS_IF([test "$GCC" = yes], [
+               SHLIB_LD='${CC} -shared'
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           ], [
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           ])
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           AS_IF([test "$do64bit" = yes], [
+               arch=`isainfo`
+               AS_IF([test "$arch" = "sparcv9 sparc"], [
+                   AS_IF([test "$GCC" = yes], [
+                       AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+                           AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+                       ], [
+                           do64bit_ok=yes
+                           CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                           LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                           SHLIB_CFLAGS="-fPIC"
+                       ])
+                   ], [
+                       do64bit_ok=yes
+                       AS_IF([test "$do64bitVIS" = yes], [
+                           CFLAGS="$CFLAGS -xarch=v9a"
+                           LDFLAGS_ARCH="-xarch=v9a"
+                       ], [
+                           CFLAGS="$CFLAGS -xarch=v9"
+                           LDFLAGS_ARCH="-xarch=v9"
+                       ])
+                       # Solaris 64 uses this as well
+                       #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+                   ])
+               ], [AS_IF([test "$arch" = "amd64 i386"], [
+                   AS_IF([test "$GCC" = yes], [
+                       case $system in
+                           SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64"
+                               LDFLAGS="$LDFLAGS -m64";;
+                           *)
+                               AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+                       esac
+                   ], [
+                       do64bit_ok=yes
+                       case $system in
+                           SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+                               CFLAGS="$CFLAGS -m64"
+                               LDFLAGS="$LDFLAGS -m64";;
+                           *)
+                               CFLAGS="$CFLAGS -xarch=amd64"
+                               LDFLAGS="$LDFLAGS -xarch=amd64";;
+                       esac
+                   ])
+               ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+           ])
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           AS_IF([test "$GCC" = yes], [
+               SHLIB_LD='${CC} -shared'
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               AS_IF([test "$do64bit_ok" = yes], [
+                   AS_IF([test "$arch" = "sparcv9 sparc"], [
+                       # We need to specify -static-libgcc or we need to
+                       # add the path to the sparv9 libgcc.
+                       # JH: static-libgcc is necessary for core Tcl, but may
+                       # not be necessary for extensions.
+                       SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                       # for finding sparcv9 libgcc, get the regular libgcc
+                       # path, remove so name and append 'sparcv9'
+                       #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                       #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+                   ], [AS_IF([test "$arch" = "amd64 i386"], [
+                       # JH: static-libgcc is necessary for core Tcl, but may
+                       # not be necessary for extensions.
+                       SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+                   ])])
+               ])
+           ], [
+               case $system in
+                   SunOS-5.[[1-9]][[0-9]]*)
+                       # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+                       SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+                   *)
+                       SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+               esac
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           ])
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD='${CC} -G'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+               LDFLAGS=$hold_ldflags])
+           AS_IF([test $tcl_cv_ld_Bexport = yes], [
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           ])
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+       AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+    ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    AC_ARG_ENABLE(load,
+       AC_HELP_STRING([--enable-load],
+           [allow dynamic loading and "load" command (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+    AS_IF([test "$tcl_ok" = no], [DL_OBJS=""])
+
+    AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [
+       AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.])
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+    ])
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
+       case $system in
+           AIX-*) ;;
+           BSD/OS*) ;;
+           CYGWIN_*) ;;
+           IRIX*) ;;
+           NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+           Darwin-*) ;;
+           SCO_SV-3.2*) ;;
+           windows) ;;
+           *) SHLIB_CFLAGS="-fPIC" ;;
+       esac])
+
+    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+       AC_DEFINE(MODULE_SCOPE, [extern],
+           [No Compiler support for module scope symbols])
+       AC_DEFINE(NO_VIZ)
+    ])
+
+    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+       # TEA specific: use PACKAGE_VERSION instead of VERSION
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
+    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+       # TEA specific: use PACKAGE_VERSION instead of VERSION
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
+
+    AC_SUBST(DL_LIBS)
+
+    AC_SUBST(CFLAGS_DEBUG)
+    AC_SUBST(CFLAGS_OPTIMIZE)
+    AC_SUBST(CFLAGS_WARNING)
+
+    AC_SUBST(STLIB_LD)
+    AC_SUBST(SHLIB_LD)
+
+    AC_SUBST(SHLIB_LD_LIBS)
+    AC_SUBST(SHLIB_CFLAGS)
+
+    AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+    TEA_TCL_EARLY_FLAGS
+    TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+#      Determine which interface to use to talk to the serial port.
+#      Note that #include lines must begin in leftmost column for
+#      some compilers to recognize them as preprocessor directives,
+#      and some build environments have stdin not pointing at a
+#      pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines only one of the following vars:
+#              HAVE_SYS_MODEM_H
+#              USE_TERMIOS
+#              USE_TERMIO
+#              USE_SGTTY
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+    AC_CHECK_HEADERS(sys/modem.h)
+    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+    AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+    }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+    fi])
+    case $tcl_cv_api_serial in
+       termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+       termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+       sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_MISSING_POSIX_HEADERS
+#
+#      Supply substitutes for missing POSIX header files.  Special
+#      notes:
+#          - stdlib.h doesn't define strtol, strtoul, or
+#            strtod in some versions of SunOS
+#          - some versions of string.h don't declare procedures such
+#            as strstr
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines some of the following vars:
+#              NO_DIRENT_H
+#              NO_ERRNO_H
+#              NO_VALUES_H
+#              HAVE_LIMITS_H or NO_LIMITS_H
+#              NO_STDLIB_H
+#              NO_STRING_H
+#              NO_SYS_WAIT_H
+#              NO_DLFCN_H
+#              HAVE_SYS_PARAM_H
+#
+#              HAVE_STRING_H ?
+#
+# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+# CHECK on limits.h
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
+    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
+    AC_TRY_LINK([#include <sys/types.h>
+#include <dirent.h>], [
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
+
+    if test $tcl_cv_dirent_h = no; then
+       AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
+    fi
+
+    # TEA specific:
+    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
+    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
+    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
+    AC_CHECK_HEADER(limits.h,
+       [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
+       [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
+    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
+    fi
+    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
+    fi
+
+    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
+    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+    AC_HAVE_HEADERS(sys/param.h)
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+#      Locate the X11 header files and the X11 library archive.  Try
+#      the ac_path_x macro first, but if it doesn't find the X stuff
+#      (e.g. because there's no xmkmf program) then check through
+#      a list of possible directories.  Under some conditions the
+#      autoconf macro will return an include directory that contains
+#      no include files, so double-check its result just to be safe.
+#
+#      This should be called after TEA_CONFIG_CFLAGS as setting the
+#      LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets the following vars:
+#              XINCLUDES
+#              XLIBSW
+#              PKG_LIBS (appends to)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+       TEA_PATH_UNIX_X
+    fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+    AC_PATH_X
+    not_really_there=""
+    if test "$no_x" = ""; then
+       if test "$x_includes" = ""; then
+           AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
+       else
+           if test ! -r $x_includes/X11/Intrinsic.h; then
+               not_really_there="yes"
+           fi
+       fi
+    fi
+    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+       AC_MSG_CHECKING([for X11 header files])
+       found_xincludes="no"
+       AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
+       if test "$found_xincludes" = "no"; then
+           dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+           for i in $dirs ; do
+               if test -r $i/X11/Intrinsic.h; then
+                   AC_MSG_RESULT([$i])
+                   XINCLUDES=" -I$i"
+                   found_xincludes="yes"
+                   break
+               fi
+           done
+       fi
+    else
+       if test "$x_includes" != ""; then
+           XINCLUDES="-I$x_includes"
+           found_xincludes="yes"
+       fi
+    fi
+    if test found_xincludes = "no"; then
+       AC_MSG_RESULT([couldn't find any!])
+    fi
+
+    if test "$no_x" = yes; then
+       AC_MSG_CHECKING([for X11 libraries])
+       XLIBSW=nope
+       dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+       for i in $dirs ; do
+           if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+               AC_MSG_RESULT([$i])
+               XLIBSW="-L$i -lX11"
+               x_libraries="$i"
+               break
+           fi
+       done
+    else
+       if test "$x_libraries" = ""; then
+           XLIBSW=-lX11
+       else
+           XLIBSW="-L$x_libraries -lX11"
+       fi
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_MSG_RESULT([could not find any!  Using -lX11.])
+       XLIBSW=-lX11
+    fi
+    # TEA specific:
+    if test x"${XLIBSW}" != x ; then
+       PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+#      The statements below check for systems where POSIX-style
+#      non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+#      On these systems (mostly older ones), use the old BSD-style
+#      FIONBIO approach instead.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines some of the following vars:
+#              HAVE_SYS_IOCTL_H
+#              HAVE_SYS_FILIO_H
+#              USE_FIONBIO
+#              O_NONBLOCK
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+    AC_CHECK_HEADERS(sys/ioctl.h)
+    AC_CHECK_HEADERS(sys/filio.h)
+    TEA_CONFIG_SYSTEM
+    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+    case $system in
+       # There used to be code here to use FIONBIO under AIX.  However, it
+       # was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
+       # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
+       # code (JO, 5/31/97).
+
+       OSF*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       SunOS-4*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       *)
+           AC_MSG_RESULT([O_NONBLOCK])
+           ;;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANDLER
+#
+#      Checks how the system deals with time.h, what time structures
+#      are used on the system, and what fields the structures have.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines some of the following vars:
+#              USE_DELTA_FOR_TZ
+#              HAVE_TM_GMTOFF
+#              HAVE_TM_TZADJ
+#              HAVE_TIMEZONE_VAR
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+    AC_CHECK_HEADERS(sys/time.h)
+    AC_HEADER_TIME
+    AC_STRUCT_TIMEZONE
+
+    AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+           tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+    if test $tcl_cv_member_tm_tzadj = yes ; then
+       AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+    fi
+
+    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+           tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+    if test $tcl_cv_member_tm_gmtoff = yes ; then
+       AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+    fi
+
+    #
+    # Its important to include time.h in this check, as some systems
+    # (like convex) have timezone functions, etc.
+    #
+    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+       AC_TRY_COMPILE([#include <time.h>],
+           [extern long timezone;
+           timezone += 1;
+           exit (0);],
+           tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+    if test $tcl_cv_timezone_long = yes ; then
+       AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+    else
+       #
+       # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+       #
+       AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+           AC_TRY_COMPILE([#include <time.h>],
+               [extern time_t timezone;
+               timezone += 1;
+               exit (0);],
+               tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+       if test $tcl_cv_timezone_time = yes ; then
+           AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+#      Under Solaris 2.4, strtod returns the wrong value for the
+#      terminating character under some conditions.  Check for this
+#      and if the problem exists use a substitute procedure
+#      "fixstrtod" (provided by Tcl) that corrects the error.
+#      Also, on Compaq's Tru64 Unix 5.0,
+#      strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Might defines some of the following vars:
+#              strtod (=fixstrtod)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+    if test "$tcl_strtod" = 1; then
+       AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+           AC_TRY_RUN([
+               extern double strtod();
+               int main() {
+                   char *infString="Inf", *nanString="NaN", *spaceString=" ";
+                   char *term;
+                   double value;
+                   value = strtod(infString, &term);
+                   if ((term != infString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(nanString, &term);
+                   if ((term != nanString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(spaceString, &term);
+                   if (term == (spaceString+1)) {
+                       exit(1);
+                   }
+                   exit(0);
+               }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+                   tcl_cv_strtod_buggy=buggy)])
+       if test "$tcl_cv_strtod_buggy" = buggy; then
+           AC_LIBOBJ([fixstrtod])
+           USE_COMPAT=1
+           AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_LINK_LIBS
+#
+#      Search for the libraries needed to link the Tcl shell.
+#      Things like the math library (-lm) and socket stuff (-lsocket vs.
+#      -lnsl) are dealt with here.
+#
+# Arguments:
+#      Requires the following vars to be set in the Makefile:
+#              DL_LIBS
+#              LIBS
+#              MATH_LIBS
+#
+# Results:
+#
+#      Subst's the following var:
+#              TCL_LIBS
+#              MATH_LIBS
+#
+#      Might append to the following vars:
+#              LIBS
+#
+#      Might define the following vars:
+#              HAVE_NET_ERRNO_H
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_LINK_LIBS], [
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+    AC_CHECK_HEADER(net/errno.h, [
+       AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+    if test "$tcl_checkSocket" = 1; then
+       AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
+           LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
+    fi
+    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
+           [LIBS="$LIBS -lnsl"])])
+
+    # TEA specific: Don't perform the eval of the libraries here because
+    # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(MATH_LIBS)
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+#      Check for what flags are needed to be passed so the correct OS
+#      features are available.
+#
+# Arguments:
+#      None
+#
+# Results:
+#
+#      Might define the following vars:
+#              _ISOC99_SOURCE
+#              _LARGEFILE64_SOURCE
+#              _LARGEFILE_SOURCE64
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+       AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+           AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+       AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+       tcl_flags="$tcl_flags $1"
+    fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+    AC_MSG_CHECKING([for required early compiler flags])
+    tcl_flags=""
+    TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+       [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+       [struct stat64 buf; int i = stat64("/", &buf);])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+       [char *p = (char *)open64;])
+    if test "x${tcl_flags}" = "x" ; then
+       AC_MSG_RESULT([none])
+    else
+       AC_MSG_RESULT([${tcl_flags}])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+#      Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+#      None
+#
+# Results:
+#
+#      Might define the following vars:
+#              TCL_WIDE_INT_IS_LONG
+#              TCL_WIDE_INT_TYPE
+#              HAVE_STRUCT_DIRENT64
+#              HAVE_STRUCT_STAT64
+#              HAVE_TYPE_OFF64_T
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+    AC_MSG_CHECKING([for 64-bit integer type])
+    AC_CACHE_VAL(tcl_cv_type_64bit,[
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+           tcl_type_64bit=__int64, tcl_type_64bit="long long")
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        AC_TRY_COMPILE(,[switch (0) {
+            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
+        }],tcl_cv_type_64bit=${tcl_type_64bit})])
+    if test "${tcl_cv_type_64bit}" = none ; then
+       AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+       AC_MSG_RESULT([using long])
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # TEA specific: We actually want to use the default tcl.h checks in
+       # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       AC_MSG_RESULT([using Tcl header defaults])
+    else
+       AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+           [What type should be used to define wide integers?])
+       AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+       # Now check for auxiliary declarations
+       AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+           AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/dirent.h>],[struct dirent64 p;],
+               tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+       fi
+
+       AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+           AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+               tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+       fi
+
+       AC_CHECK_FUNCS(open64 lseek64)
+       AC_MSG_CHECKING([for off64_t])
+       AC_CACHE_VAL(tcl_cv_type_off64_t,[
+           AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+               tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+       dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+       dnl functions lseek64 and open64 are defined.
+       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+           AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+           AC_MSG_RESULT([yes])
+       else
+           AC_MSG_RESULT([no])
+       fi
+    fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+#      Init various Tcl Extension Architecture (TEA) variables.
+#      This should be the first called TEA_* macro.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              CYGPATH
+#              EXEEXT
+#      Defines only:
+#              TEA_VERSION
+#              TEA_INITED
+#              TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+#      Select the executable extension based on the host type.  This
+#      is a lightweight replacement for AC_EXEEXT that doesn't require
+#      a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.7"
+
+    AC_MSG_CHECKING([for correct TEA configuration])
+    if test x"${PACKAGE_NAME}" = x ; then
+       AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.in])
+    fi
+    if test x"$1" = x ; then
+       AC_MSG_ERROR([
+TEA version not specified.])
+    elif test "$1" != "${TEA_VERSION}" ; then
+       AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
+    else
+       AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*MINGW32_*)
+           AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *CYGWIN_*)
+           CYGPATH=echo
+           EXEEXT=".exe"
+           # TEA_PLATFORM is determined later
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+    AC_SUBST(EXEEXT)
+    AC_SUBST(CYGPATH)
+
+    # This package name must be replaced statically for AC_SUBST to work
+    AC_SUBST(PKG_LIB_FILE)
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+    AC_SUBST(PKG_STUB_LIB_FILE)
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+    AC_SUBST(PKG_TCL_SOURCES)
+    AC_SUBST(PKG_HEADERS)
+    AC_SUBST(PKG_INCLUDES)
+    AC_SUBST(PKG_LIBS)
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_SOURCES
+#              PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       case $i in
+           [\$]*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               # To add more dirs here (like 'src'), you have to update VPATH
+               # in Makefile.in as well
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   AC_MSG_ERROR([could not find source file '$i'])
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+    AC_SUBST(PKG_SOURCES)
+    AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_STUB_SOURCES
+#              PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           AC_MSG_ERROR([could not find stub source file '$i'])
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+#      Specify one or more Tcl source files.  These should be platform
+#      independent runtime files.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+    AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+#      Specify one or more source headers.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+    AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+#      Specify one or more include dirs.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+    vars="$@"
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+    AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+#      Specify one or more libraries.  Users should check for
+#      the right platform before adding to their list.  For Windows,
+#      libraries provided in "foo.lib" format will be converted to
+#      "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+    vars="$@"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+    AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+#      Specify one or more CFLAGS.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+    PKG_CFLAGS="$PKG_CFLAGS $@"
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+#      Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      If --prefix or --exec-prefix was not specified, $prefix and
+#      $exec_prefix will be set to the values given to Tcl when it was
+#      configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+           prefix=${TCL_PREFIX}
+       else
+           AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+           exec_prefix=$prefix
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+#      Do compiler checks the way we want.  This is just a replacement
+#      for AC_PROG_CC in TEA configure.in files to make them cleaner.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    AC_PROG_CC
+    AC_PROG_CPP
+
+    AC_PROG_INSTALL
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    AC_PROG_MAKE_SET
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    AC_PROG_RANLIB
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+    AC_OBJEXT
+    AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+#      Do compiler checks that use the compiler.  This must go after
+#      TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+    AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       AC_CACHE_CHECK([if the compiler understands -pipe],
+           tcl_cv_cc_pipe, [
+           hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+           AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+           CFLAGS=$hold_cflags])
+       if test $tcl_cv_cc_pipe = yes; then
+           CFLAGS="$CFLAGS -pipe"
+       fi
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    AC_C_BIGENDIAN
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       TEA_TCL_LINK_LIBS
+       TEA_MISSING_POSIX_HEADERS
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+#      Generate a line that can be used to build a shared/unshared library
+#      in a platform independent manner.
+#
+# Arguments:
+#      none
+#
+#      Requires:
+#
+# Results:
+#
+#      Defines the following vars:
+#      CFLAGS -        Done late here to note disturb other AC macros
+#       MAKE_LIB -      Command to execute to build the Tcl library;
+#                       differs depending on whether or not Tcl is being
+#                       compiled as a shared library.
+#      MAKE_SHARED_LIB Makefile rule for building a shared library
+#      MAKE_STATIC_LIB Makefile rule for building a static library
+#      MAKE_STUB_LIB   Makefile rule for building a stub library
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+    AC_SUBST(MAKE_LIB)
+    AC_SUBST(MAKE_SHARED_LIB)
+    AC_SUBST(MAKE_STATIC_LIB)
+    AC_SUBST(MAKE_STUB_LIB)
+    AC_SUBST(RANLIB_STUB)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+#      Compute the name of an existing object library located in libdir
+#      from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+#      basename        The base name of the library without version
+#                      numbers, extensions, or "lib" prefixes.
+#      extra_dir       Extra directory in which to search for the
+#                      library.  This location is used first, then
+#                      $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+#      TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+#      Defines the following vars:
+#              ${basename}_LIB_NAME    The computed library name.
+#              ${basename}_LIB_SPEC    The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+    AC_MSG_CHECKING([for $1 library])
+
+    # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+    tea_lib_name_dir="${exec_prefix}/lib"
+
+    # Or in a user-specified location.
+
+    if test x"$2" != x ; then
+       tea_extra_lib_dir=$2
+    else
+       tea_extra_lib_dir=NONE
+    fi
+
+    for i in \
+           `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+       if test -f "$i" ; then
+           tea_lib_name_dir=`dirname $i`
+           $1_LIB_NAME=`basename $i`
+           $1_LIB_PATH_NAME=$i
+           break
+       fi
+    done
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+    else
+       # Strip off the leading "lib" and trailing ".a" or ".so"
+
+       tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+       $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+    fi
+
+    if test "x${$1_LIB_NAME}" = x ; then
+       AC_MSG_ERROR([not found])
+    else
+       AC_MSG_RESULT([${$1_LIB_SPEC}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+#      Locate the private Tcl include files
+#
+# Arguments:
+#
+#      Requires:
+#              TCL_SRC_DIR     Assumes that TEA_LOAD_TCLCONFIG has
+#                              already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TCL_TOP_DIR_NATIVE
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+    # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+    AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+    AC_MSG_CHECKING([for Tcl private include files])
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+    # Check to see if tcl<Plat>Port.h isn't already with the public headers
+    # Don't look for tclInt.h because that resides with tcl.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+       -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+       result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+       -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+       result="private headers found with public headers"
+    else
+       TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+       if test "${TEA_PLATFORM}" = "windows"; then
+           TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+       else
+           TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+       fi
+       # Overwrite the previous TCL_INCLUDES as this should capture both
+       # public and private headers in the same set.
+       # We want to ensure these are substituted so as not to require
+       # any *_NATIVE vars be defined in the Makefile
+       TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+       if test "`uname -s`" = "Darwin"; then
+            # If Tcl was built as a framework, attempt to use
+            # the framework's Headers and PrivateHeaders directories
+            case ${TCL_DEFS} in
+               *TCL_FRAMEWORK*)
+                   if test -d "${TCL_BIN_DIR}/Headers" -a \
+                           -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+                       TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+                   else
+                       TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+                   fi
+                   ;;
+           esac
+           result="Using ${TCL_INCLUDES}"
+       else
+           if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+               AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+           fi
+           result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+       fi
+    fi
+
+    AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+    AC_SUBST(TCL_INCLUDES)
+    AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+#      Locate the installed public Tcl header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tclinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl public headers])
+
+    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tclh, [
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+           fi
+       else
+           list=""
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       AC_MSG_ERROR([tcl.h not found.  Please specify its location with --with-tclinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tclh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+#      Locate the private Tk include files
+#
+# Arguments:
+#
+#      Requires:
+#              TK_SRC_DIR      Assumes that TEA_LOAD_TKCONFIG has
+#                               already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+    # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+    AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+    AC_MSG_CHECKING([for Tk private include files])
+
+    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+    # Check to see if tk<Plat>Port.h isn't already with the public headers
+    # Don't look for tkInt.h because that resides with tk.h in the core
+    # sources, but the <plat>Port headers are in a different directory
+    if test "${TEA_PLATFORM}" = "windows" -a \
+       -f "${ac_cv_c_tkh}/tkWinPort.h"; then
+       result="private headers found with public headers"
+    elif test "${TEA_PLATFORM}" = "unix" -a \
+       -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+       result="private headers found with public headers"
+    else
+       TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+       TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+       if test "${TEA_PLATFORM}" = "windows"; then
+           TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+       else
+           TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+       fi
+       # Overwrite the previous TK_INCLUDES as this should capture both
+       # public and private headers in the same set.
+       # We want to ensure these are substituted so as not to require
+       # any *_NATIVE vars be defined in the Makefile
+       TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+       # Detect and add ttk subdir
+       if test -d "${TK_SRC_DIR}/generic/ttk"; then
+          TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+       fi
+       if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+          TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+       fi
+       if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+          TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+       fi
+       if test "`uname -s`" = "Darwin"; then
+           # If Tk was built as a framework, attempt to use
+           # the framework's Headers and PrivateHeaders directories
+           case ${TK_DEFS} in
+               *TK_FRAMEWORK*)
+                       if test -d "${TK_BIN_DIR}/Headers" -a \
+                               -d "${TK_BIN_DIR}/PrivateHeaders"; then
+                           TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+                       else
+                           TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+                       fi
+                       ;;
+           esac
+           result="Using ${TK_INCLUDES}"
+       else
+           if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+              AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+           fi
+           result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+       fi
+    fi
+
+    AC_SUBST(TK_TOP_DIR_NATIVE)
+    AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+    AC_SUBST(TK_INCLUDES)
+    AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+#      Locate the installed public Tk header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tkinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk public headers])
+
+    AC_ARG_WITH(tkinclude, [  --with-tkinclude        directory containing the public Tk header files], with_tkinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tkh, [
+       # Use the value from --with-tkinclude, if it was given
+
+       if test x"${with_tkinclude}" != x ; then
+           if test -f "${with_tkinclude}/tk.h" ; then
+               ac_cv_c_tkh=${with_tkinclude}
+           else
+               AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+           fi
+       else
+           list=""
+           if test "`uname -s`" = "Darwin"; then
+               # If Tk was built as a framework, attempt to use
+               # the framework's Headers directory.
+               case ${TK_DEFS} in
+                   *TK_FRAMEWORK*)
+                       list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tk is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TK_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tk's --prefix location,
+           # relative to directory of tkConfig.sh, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TK_PREFIX}/include      2>/dev/null` \
+               `ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TK_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tk.h" ; then
+                   ac_cv_c_tkh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tkh}" = x ; then
+       AC_MSG_ERROR([tk.h not found.  Please specify its location with --with-tkinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tkh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TK_INCLUDES)
+
+    if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+       # On Windows and Aqua, we need the X compat headers
+       AC_MSG_CHECKING([for X11 header files])
+       if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+           INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+           TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+           AC_SUBST(TK_XINCLUDES)
+       fi
+       AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+#      Locate the ${1}Config.sh file and perform a sanity check on
+#      the ${1} compile flags.  These are used by packages like
+#      [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-$1=...
+#
+#      Defines the following vars:
+#              $1_BIN_DIR      Full path to the directory containing
+#                              the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+    #
+    # Ok, lets find the $1 configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-$1
+    #
+
+    if test x"${no_$1}" = x ; then
+       # we reset no_$1 in case something fails here
+       no_$1=true
+       AC_ARG_WITH($1, [  --with-$1              directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+       AC_MSG_CHECKING([for $1 configuration])
+       AC_CACHE_VAL(ac_cv_c_$1config,[
+
+           # First check to see if --with-$1 was specified.
+           if test x"${with_$1config}" != x ; then
+               case ${with_$1config} in
+                   */$1Config.sh )
+                       if test -f ${with_$1config}; then
+                           AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+                           with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+                       fi;;
+               esac
+               if test -f "${with_$1config}/$1Config.sh" ; then
+                   ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+               fi
+           fi
+
+           # then check for a private $1 installation
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in \
+                       ../$1 \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../$1 \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../$1 \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../$1 \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+                   if test -f "$i/unix/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_$1config}" = x ; then
+           $1_BIN_DIR="# no $1 configs found"
+           AC_MSG_WARN([Cannot find $1 configuration definitions])
+           exit 0
+       else
+           no_$1=
+           $1_BIN_DIR=${ac_cv_c_$1config}
+           AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+#      Load the $1Config.sh file
+#
+# Arguments:
+#
+#      Requires the following vars to be set:
+#              $1_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              $1_SRC_DIR
+#              $1_LIB_FILE
+#              $1_LIB_SPEC
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+        AC_MSG_RESULT([loading])
+       . "${$1_BIN_DIR}/$1Config.sh"
+    else
+        AC_MSG_RESULT([file not found])
+    fi
+
+    #
+    # If the $1_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable $1_LIB_SPEC will be set to the value
+    # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+    # instead of $1_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    #
+
+    if test -f "${$1_BIN_DIR}/Makefile" ; then
+       AC_MSG_WARN([Found Makefile - using build library specs for $1])
+        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+    fi
+
+    AC_SUBST($1_VERSION)
+    AC_SUBST($1_BIN_DIR)
+    AC_SUBST($1_SRC_DIR)
+
+    AC_SUBST($1_LIB_FILE)
+    AC_SUBST($1_LIB_SPEC)
+
+    AC_SUBST($1_STUB_LIB_FILE)
+    AC_SUBST($1_STUB_LIB_SPEC)
+    AC_SUBST($1_STUB_LIB_PATH)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+#      Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-celib=...
+#
+#      Defines the following vars:
+#              CELIB_DIR       Full path to the directory containing
+#                              the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+       AC_ARG_WITH(celib,[  --with-celib=DIR        use Windows/CE support library from DIR], with_celibconfig=${withval})
+       AC_MSG_CHECKING([for Windows/CE celib directory])
+       AC_CACHE_VAL(ac_cv_c_celibconfig,[
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           AC_MSG_ERROR([Cannot find celib support library directory])
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           AC_MSG_RESULT([found $CELIB_DIR])
+       fi
+    fi
+])
+
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/8.x/thread/tests/all.tcl b/8.x/thread/tests/all.tcl
new file mode 100644 (file)
index 0000000..d7eca88
--- /dev/null
@@ -0,0 +1,66 @@
+# all.tcl --
+#
+# This file contains a top-level script to run all of the Tcl
+# tests.  Execute it by invoking "source all.test" when running tcltest
+# in this directory.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+# 
+# RCS: @(#) $Id: all.tcl,v 1.5 2004/12/18 13:26:03 vasiljevic Exp $
+
+package require tcltest
+namespace import -force ::tcltest::*
+
+set ::tcltest::testSingleFile false
+set ::tcltest::testsDirectory [file dir [info script]]
+
+# We need to ensure that the testsDirectory is absolute
+::tcltest::normalizePath ::tcltest::testsDirectory
+
+puts stdout "Tcl $tcl_patchLevel tests running in interp:  [info nameofexecutable]"
+puts stdout "Tests running in working dir:  $::tcltest::testsDirectory"
+if {[llength $::tcltest::skip] > 0} {
+    puts stdout "Skipping tests that match:  $::tcltest::skip"
+}
+if {[llength $::tcltest::match] > 0} {
+    puts stdout "Only running tests that match:  $::tcltest::match"
+}
+
+if {[llength $::tcltest::skipFiles] > 0} {
+    puts stdout "Skipping test files that match:  $::tcltest::skipFiles"
+}
+if {[llength $::tcltest::matchFiles] > 0} {
+    puts stdout "Only sourcing test files that match:  $::tcltest::matchFiles"
+}
+
+set timeCmd {clock format [clock seconds]}
+puts stdout "Tests began at [eval $timeCmd]"
+
+
+# These tests need to know which is the main thread
+
+# Require the accurate version for the tests so we don't pick up
+# older Thread packages by accident
+package require Tcl 8.4
+package require Thread 2.6
+set ::tcltest::mainThread [thread::id]
+
+puts stdout "Thread [package provide Thread]"
+puts stdout "Mainthread id is $::tcltest::mainThread"
+
+# Source each of the specified tests
+foreach file [lsort [::tcltest::getMatchingFiles]] {
+    set tail [file tail $file]
+    puts stdout $tail
+    if {[catch {source $file} msg]} {
+        puts stdout $msg
+    }
+}
+
+# Cleanup
+puts stdout "\nTests ended at [eval $timeCmd]"
+::tcltest::cleanupTests 1
+
+return
+
diff --git a/8.x/thread/tests/thread.test b/8.x/thread/tests/thread.test
new file mode 100644 (file)
index 0000000..0721095
--- /dev/null
@@ -0,0 +1,1165 @@
+# Commands covered:  thread
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Scriptics Corporation.
+# Copyright (c) 2002 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: thread.test,v 1.23 2009/05/03 23:57:26 ferrieux Exp $
+
+package require tcltest; namespace import -force ::tcltest::*
+
+# Require the accurate version for the tests so we don't pick up
+# older Thread packages by accident
+package require Tcl 8.4
+package require Thread 2.6
+
+tcltest::testConstraint chanTransfer               \
+    [expr {   $::tcl_platform(platform) == "unix"  \
+           || $::tcl_patchLevel > "8.4.10"}]
+
+set dummy [::tcltest::makeFile dummyForTransfer dummyForTransfer]
+set tcltest::mainThread [thread::id]
+
+proc ThreadReap {} {
+    while {[llength [thread::names]] > 1} {
+        foreach tid [thread::names] {
+            if {$tid != $::tcltest::mainThread} {
+                catch {thread::release -wait $tid}
+            }
+        }
+    }
+    llength [thread::names]
+}
+
+test thread-2.0 {no global thread command} {
+    info commands thread
+} {}
+
+test thread-2.84 {thread subcommands} {
+    lsort [info commands thread::*]
+} {::thread::attach ::thread::broadcast ::thread::cond ::thread::configure ::thread::create ::thread::detach ::thread::errorproc ::thread::eval ::thread::exists ::thread::exit ::thread::id ::thread::join ::thread::mutex ::thread::names ::thread::preserve ::thread::release ::thread::rwmutex ::thread::send ::thread::transfer ::thread::unwind ::thread::wait}
+
+test thread-3.0 {thread::names initial thread list} {
+    list [ThreadReap] [llength [thread::names]]
+} {1 1}
+
+test thread-4.0 {thread::create: create server thread} {
+    ThreadReap
+    set tid [thread::create]
+    update
+    set l [llength [thread::names]]
+    ThreadReap
+    set l
+} {2}
+
+test thread-4.1 {thread::create: create one shot thread} {
+    ThreadReap
+    thread::create {set x 5}
+    foreach try {0 1 2 4 5 6} {
+        # Try various ways to yield
+        update
+        after 10
+        set l [llength [thread::names]]
+        if {$l == 1} {
+            break
+        }
+    }
+    ThreadReap
+    set l
+} {1}
+
+test thread-4.2 {thread::create - create preservable thread} {
+    ThreadReap
+    set tid [thread::create -preserved]
+    set c [thread::preserve $tid]
+    thread::release -wait $tid
+    ThreadReap
+    set c
+} {2}
+
+test thread-4.3 {thread::create - release a thread} {
+    ThreadReap
+    set tid [thread::create {thread::release}]
+    update
+    after 10
+    set l [llength [thread::names]]
+    ThreadReap
+    set l
+} {1}
+
+test thread-4.4 {thread::create - create joinable thread} {
+    ThreadReap
+    set tid [thread::create -joinable {set x 5}]
+    set c [thread::join $tid]
+    ThreadReap
+    set c
+} {0}
+
+test thread-4.5 {thread::create - join detached thread} {
+    ThreadReap
+    set tid [thread::create]
+    thread::send -async $tid {after 1000 ; thread::release}
+    catch {set res [thread::join $tid]} msg
+    ThreadReap
+    lrange $msg 0 2
+} {cannot join thread}
+
+test thread-5.0 {thread::release} {
+    ThreadReap
+    set tid [thread::create {thread::release}]
+    update
+    after 10
+    set l [llength [thread::names]]
+    ThreadReap
+    set l
+} {1}
+
+test thread-6.0 {thread::unwind - simple unwind} {
+    ThreadReap
+    thread::create {thread::unwind}
+    update
+    after 10
+    set l [llength [thread::names]]
+    ThreadReap
+    set l
+} {1}
+
+test thread-6.1 {thread::unwind - blocked unwind} {
+    ThreadReap
+    thread::create {thread::unwind; vwait dummy}
+    update
+    after 10
+    set l [llength [thread::names]]
+    ThreadReap
+    set l
+} {2}
+
+test thread-7.0 {thread::exit} {
+    ThreadReap
+    set tid [thread::create -joinable {thread::exit}]
+    set c [thread::join $tid]
+    ThreadReap
+    set c
+} {666}
+
+test thread-8.0 {thread::exists - true} {
+    ThreadReap
+    set c [thread::exists [thread::create]]
+    ThreadReap
+    set c
+} {1}
+
+test thread-8.1 {thread::exists - false} {
+    ThreadReap
+    set tid [thread::create {set x 5}]
+    update
+    after 10
+    set c [thread::exists $tid]
+    ThreadReap
+    set c
+} {0}
+
+test thread-9.0 {thread::id} {
+    expr {[thread::id] == $::tcltest::mainThread}
+} {1}
+
+test thread-9.1 {thread::id - args} {
+    set x [catch {thread::id x} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::id"}}
+
+test thread-10.0 {thread::names args} {
+    set x [catch {thread::names x} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::names"}}
+
+test thread-11.0 {thread::send - no args} {
+    set x [catch {thread::send} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::send ?-async? ?-head? id script ?varName?"}}
+
+test thread-11.1 {thread::send - simple script} {
+    ThreadReap
+    set tid [thread::create]
+    set five [thread::send $tid {set x 5}]
+    ThreadReap
+    set five
+} 5
+
+test thread-11.2 {thread::send - bad thread id} {
+    set tid dummy
+    set x [catch {thread::send $tid {set x 5}} msg]
+    list $x $msg
+} {1 {invalid thread handle "dummy"}}
+
+test thread-11.3 {thread::send - test TCL_ERROR return code} {
+    ThreadReap
+    set tid [thread::create]
+    set c [thread::send $tid {dummy} msg]
+    ThreadReap
+    list $c $msg} {1 {invalid command name "dummy"}}
+
+test thread-11.4 {thread::send - test TCL_RETURN return code} {
+    ThreadReap
+    set tid [thread::create]
+    set c [thread::send $tid {return} msg]
+    ThreadReap
+    list $c $msg
+} {2 {}}
+
+test thread-11.5 {thread::send - test TCL_BREAK return code} {
+    ThreadReap
+    set tid [thread::create]
+    set c [thread::send $tid {break} msg]
+    ThreadReap
+    list $c $msg
+} {3 {}}
+
+test thread-11.6 {thread::send - asynchronous send} {
+    ThreadReap
+    set tid [thread::create]
+    thread::send -async $tid {set x 5}
+    update
+    after 10
+    set five [thread::send $tid {set x}]
+    ThreadReap
+    set five
+} {5}
+
+test thread-11.7 {thread::send - async send with event-loop wait} {
+    ThreadReap
+    set tid [thread::create]
+    thread::send -async $tid {set x 5} five
+    vwait five
+    ThreadReap
+    set five
+} {5}
+
+test thread-11.8 {thread::send - send to self directly} {
+    thread::send [thread::id] {set x 5} five
+    set five
+} {5}
+
+test thread-11.9 {thread::send - send to self asynchronously} {
+    set c [catch {thread::send -async [thread::id] {set x 5} five} msg]
+    list $c $msg
+} {1 {can't notify self}}
+
+
+test thread-11.10 {thread::send - preserve errorInfo} {
+    ThreadReap
+    set len [llength [thread::names]]
+    set tid [thread::create]
+    set c [catch {thread::send $tid {set undef}} msg]
+    ThreadReap
+    list $c $msg $errorInfo
+} {1 {can't read "undef": no such variable} {can't read "undef": no such variable
+    while executing
+"set undef"
+    invoked from within
+"thread::send $tid {set undef}"}}
+
+test thread-11.11 {Thread_Send preserve errorCode} {
+    ThreadReap
+    set tid [thread::create]
+    set c [catch {thread::send $tid {error ERR INFO CODE}} msg]
+    ThreadReap
+    list $c $msg $errorCode
+} {1 ERR CODE}
+
+test thread-12.0 {thread::wait} {
+    ThreadReap
+    set tid [thread::create {set x 5; thread::wait}]
+    thread::send $tid {set x} five
+    ThreadReap
+    set five
+} {5}
+
+test thread-13.0 {thread::broadcast} {
+    ThreadReap
+    catch {unset tids}
+    foreach i {1 2 3 4} {
+        lappend tids [thread::create]
+    }
+    thread::broadcast {set x 5}
+    update
+    catch {unset r}
+    foreach tid $tids {
+        lappend r [thread::send $tid {if {[info exists x]} {set x}}]
+    }
+    ThreadReap
+    set r
+} {5 5 5 5}
+
+test thread-13.1 {thread::broadcast no args} {
+    set c [catch {thread::broadcast} msg]
+    list $c $msg
+} {1 {wrong # args: should be "thread::broadcast script"}}
+
+
+test thread-14.0 {thread::eval - no arguments} {
+    set c [catch {thread::eval} msg]
+    list $c $msg
+} {1 {wrong # args: should be "thread::eval ?-lock <mutexHandle>? arg ?arg...?"}}
+
+test thread-14.1 {thread::eval - bad arguments} {
+    set c [catch {thread::eval -lock} msg]
+    list $c $msg
+} {1 {wrong # args: should be "thread::eval ?-lock <mutexHandle>? arg ?arg...?"}}
+
+test thread-14.2 {thread::eval - missing script argument} {
+    set c [catch {thread::eval -lock dummy} msg]
+    list $c $msg
+} {1 {wrong # args: should be "thread::eval ?-lock <mutexHandle>? arg ?arg...?"}}
+
+test thread-14.3 {thread::eval - bad mutex handle} {
+    set c [catch {thread::eval -lock dummy {set x 5}} msg]
+    list $c $msg
+} {1 {no such mutex "dummy"}}
+
+test thread-14.4 {thread::eval - nested eval} {
+    thread::eval {thread::eval {thread::eval {set x 5}}}
+} {5}
+
+test thread-15.0 {thread::configure - bad arguments} {
+    set c [catch {thread::configure} msg]
+    list $c $msg
+} {1 {wrong # args: should be "thread::configure threadlId ?optionName? ?value? ?optionName value?..."}}
+
+test thread-15.1 {thread::configure - bad thread id argument} {
+    set c [catch {thread::configure dummy} msg]
+    list $c $msg
+} {1 {invalid thread handle "dummy"}}
+
+test thread-15.2 {thread::configure - bad configure option} {
+    set c [catch {thread::configure [thread::id] -dummy} msg]
+    list $c $msg
+} {1 {bad option "-dummy", should be one of -eventmark, -unwindonerror or -errorstate}}
+
+test thread-15.3 {thread::configure - read all configure options} {
+    ThreadReap
+    set tid [thread::create]
+    catch {unset opts}
+    set opts [thread::configure $tid]
+    ThreadReap
+    expr {[llength $opts] % 2}
+} {0}
+
+test thread-15.4 {thread::configure - check configure option names} {
+    ThreadReap
+    set tid [thread::create]
+    update
+    after 10
+    catch {unset opts}
+    array set opts [thread::configure $tid]
+    ThreadReap
+    array names opts
+} {-errorstate -unwindonerror -eventmark}
+
+test thread-15.5 {thread::configure - get one config option} {
+    ThreadReap
+    set tid [thread::create]
+    update
+    after 10
+    set l ""
+    lappend l [thread::configure $tid -eventmark]
+    lappend l [thread::configure $tid -unwindonerror]
+    lappend l [thread::configure $tid -errorstate]
+    ThreadReap
+    set l
+} {0 0 0}
+
+test thread-15.6 {thread::configure - set -unwindonerror option} {
+    ThreadReap
+    set tid [thread::create]
+    update
+    after 10
+    thread::configure $tid -unwindonerror 1
+    set c [catch {thread::send $tid {set dummy}}]
+    update
+    after 10
+    set e [thread::exists $tid]
+    ThreadReap
+    list $c $e
+} {1 0}
+
+test thread-15.7 {thread::configure - set -errorstate option} {
+    ThreadReap
+    set tid [thread::create]
+    update
+    after 10
+    thread::configure $tid -errorstate 1
+    set c [thread::send $tid {set dummy} msg]
+    ThreadReap
+    list $c $msg
+} {1 {thread is in error}}
+
+test thread-15.8 {thread::configure - set -eventmark option} {
+    ThreadReap
+    set tid [thread::create]
+    update
+    after 10
+    thread::configure $tid -eventmark 1
+    thread::send -async $tid {after 2000}
+    set t1 [clock seconds]
+    thread::send -async $tid {after 2000}
+    set t2 [clock seconds]
+    ThreadReap
+    expr {($t2 - $t1) >= 2}
+} {1}
+
+test thread-16.0 {thread::errorproc - args} {
+    set x [catch {thread::errorproc foo bar} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::errorproc ?proc?"}}
+
+test thread-16.1 {thread::errorproc - errorproc change} {
+    thread::errorproc foo
+    thread::errorproc ThreadError
+    set new [thread::errorproc]
+} {ThreadError}
+
+test thread-16.2 {thread::errorproc - async reporting} {
+    set etid ""
+    set emsg ""
+    proc myerrproc {tid msg} {
+        global etid emsg
+        set etid $tid
+        set emsg $msg
+    }
+    ThreadReap
+    thread::errorproc myerrproc
+    set tid [thread::create]
+    update
+    after 10
+    thread::send -async $tid {set x}
+    after 10
+    update
+    ThreadReap
+    list [expr {$etid == $tid}] $emsg
+} {1 {can't read "x": no such variable
+    while executing
+"set x"}}
+
+test thread-17.1 {thread::transfer - channel lists} {chanTransfer} {
+    ThreadReap
+    set tid [thread::create]
+    set file [open $dummy r]
+    set res [regexp $file [file channels]]
+    thread::transfer $tid $file
+    lappend res [regexp $file [file channels]]
+    lappend res [regexp $file [thread::send $tid {file channels}]]
+    thread::send $tid "close $file"
+    ThreadReap
+    set res
+} {1 0 1}
+
+test thread-17.2 {thread::transfer - target thread dying} {chanTransfer} {
+    ThreadReap
+    set tid [thread::create]
+    set file [open $dummy r]
+    thread::send -async $tid {after 3000 ; thread::release}
+    catch {thread::transfer $tid $file} msg
+    close $file
+    ThreadReap
+    set msg
+} {transfer failed: target thread died}
+
+test thread-17.3 {thread::transfer - clearing of fileevents} {chanTransfer} {
+    proc _HandleIt_ {} {
+        global gotEvents tid file    
+        if {$gotEvents == 0} {
+            thread::transfer $tid $file
+            # From now on no events should be delivered anymore,
+            # restricting the end value to 1
+        }
+        incr gotEvents
+    }
+    ThreadReap
+    set tid [thread::create]
+    set file [open $dummy r]
+    set gotEvents 0
+    fileevent $file readable _HandleIt_
+    vwait gotEvents
+    thread::send $tid "close $file"
+    ThreadReap
+    set gotEvents
+} {1}
+
+test thread-17.4 {thread::transfer - file - readable?} {chanTransfer} {
+    ThreadReap
+    set tid [thread::create]
+    set file [open $dummy r]
+    set res [regexp $file [file channels]]
+    thread::transfer $tid $file
+    set res [string length [thread::send $tid "read -nonewline $file"]]
+    thread::send $tid "close $file"
+    ThreadReap
+    set res
+} [string length [::tcltest::viewFile dummyForTransfer]]
+
+test thread-17.5 {thread::transfer - file - closeable?} {chanTransfer} {
+    set tid [thread::create]
+    set file [open $dummy r]
+    set res [regexp $file [file channels]]
+    thread::transfer $tid $file
+    set res [thread::send $tid "close $file"]
+    ThreadReap
+    set res
+} {}
+
+test thread-17.6 {thread::transfer - socket - readable?} {chanTransfer} {
+    set tid [thread::create]
+    set lsock ""
+    proc accept {sock host port} {global lsock ; set lsock $sock}
+    set listener [socket -server accept 0]
+    set port [lindex [fconfigure $listener -sockname] 2]
+    set socket [socket localhost $port]
+    update ;# To run accept.
+
+    thread::transfer $tid $socket
+
+    puts  $lsock hello
+    flush $lsock
+
+    set res [thread::send $tid [list gets $socket]]
+    thread::send $tid [list close $socket]
+
+    ThreadReap
+    close $listener
+    close $lsock
+
+    set res
+} {hello}
+
+test thread-17.7 {thread::transfer - socket - closeable?} {chanTransfer} {
+    set tid [thread::create]
+    set lsock ""
+    proc accept {sock host port} {global lsock ; set lsock $sock}
+    set listener [socket -server accept 0]
+    set port [lindex [fconfigure $listener -sockname] 2]
+    set socket [socket localhost $port]
+    update ;# To run accept.
+
+    thread::transfer $tid $socket
+
+    set     res [thread::send $tid "regexp {$socket} \[file channels\]"]
+    lappend res [thread::send $tid [list close $socket]]
+    lappend res [thread::send $tid "regexp {$socket} \[file channels\]"]
+
+    ThreadReap
+    close $listener
+    close $lsock
+
+    set res
+} {1 {} 0}
+
+# We cannot test console channels, nor serials. Because we do not
+# really know if they are available, and under what names. But a pipe
+# channel, which uses the same type of code is something we can
+# do. Lucky us.
+
+test thread-17.8 {thread::transfer - pipe - readable?} {chanTransfer} {
+    set tid [thread::create]
+
+    set s [makeFile {
+       puts hello
+       flush stdout
+       exit
+    } pscript]
+    set pipe [open "|[info nameofexecutable] $s" r]
+
+    thread::transfer $tid $pipe
+
+    thread::send $tid [list set pipe $pipe]
+
+    set res [thread::send $tid {gets $pipe}]
+    thread::send  $tid {catch {close $pipe}}
+
+    ThreadReap
+    removeFile pscript
+
+    set res
+} {hello}
+
+# The difference between 9 and 10 is the location of the close
+# operation. For 9 it is the original thread, for 10 the other
+# thread. 10 currently fails. It seems to be some signal stuff.
+
+test thread-17.9 {thread::transfer - pipe - closable?} {chanTransfer} {
+    set tid [thread::create]
+
+    set s [makeFile {
+       fileevent stdin readable {if {[eof stdin]} {exit 0} ; gets stdin}
+       vwait forever
+       exit 0
+    } pscript]
+    set pipe [open "|[info nameofexecutable] $s" r+]
+    thread::send $tid [list set chan $pipe]
+
+    thread::transfer $tid $pipe
+    thread::send     $tid {thread::detach $chan}
+    thread::attach $pipe
+
+    set     res [regexp $pipe [file channels]]
+    lappend res [close  $pipe]
+    lappend res [regexp $pipe [file channels]]
+
+    ThreadReap
+    removeFile pscript
+
+    set res
+} {1 {} 0}
+
+test thread-17.10 {thread::transfer - pipe - closable?} {chanTransfer} {
+
+    set tid [thread::create]
+
+    set s [makeFile {
+       fileevent stdin readable {if {[eof stdin]} {exit 0} ; gets stdin}
+       vwait forever
+       exit 0
+    } pscript]
+    set pipe [open "|[info nameofexecutable] $s" r+]
+    thread::send $tid [list set chan $pipe]
+
+    thread::transfer $tid $pipe
+
+    set     res [thread::send $tid {regexp $chan [file channels]}]
+
+    if {[catch {
+       # This can fail on Linux, because there a thread cannot 'wait' on
+       # the children of a different thread (in the same process). This
+       # is for Linux < 2.4. For 2.4 it should be possible, but the
+       # language is cautionary, so it may still fail.
+
+       lappend res [thread::send $tid {close  $chan}]
+    }]} {
+       # Fake a result
+       lappend res {}
+    }
+
+    lappend res [thread::send $tid {regexp $chan [file channels]}]
+
+    ThreadReap
+    removeFile pscript
+
+    set res
+} {1 {} 0}
+
+test thread-17.11a {thread::transfer - pipe - readable event - no transfer} {
+    set tid [thread::create]
+
+    set s [makeFile {
+       after 5000 {exit 0}
+       fileevent stdin readable {
+           if {[eof  stdin]} {exit 0}
+           if {[gets stdin line] <0} return
+           puts response
+       }
+       vwait forever
+       exit 0
+    } pscript] ;# {}
+
+    set pipe [open "|[info nameofexecutable] $s" r+]
+
+    fconfigure $pipe -blocking 0
+    fileevent  $pipe readable {read $pipe ; set cond ok}
+    after 3000 {set cond timeout}
+
+    puts $pipe tick ; flush $pipe
+
+    vwait ::cond
+    catch {close $pipe}
+    removeFile pscript
+
+    set cond
+} ok
+
+test thread-17.11b {thread::transfer - pipe - readable event - with transfer} {
+    set tid [thread::create]
+
+    set s [makeFile {
+       after 5000 {exit 0}
+       fileevent stdin readable {
+           if {[eof stdin]} {exit 0}
+           if {[gets stdin line] <0} return
+           puts response
+       }
+       vwait forever
+       exit 0
+    } pscript] ;# {}
+    set pipe [open "|[info nameofexecutable] $s" r+]
+
+    thread::transfer $tid $pipe
+
+    thread::send $tid [list set chan $pipe]
+    set cond [thread::send $tid {
+       fconfigure $chan -blocking 0
+       fileevent  $chan readable {read $chan ; set cond ok}
+       after 3000 {set cond timeout}
+
+       puts $chan tick ; flush $chan
+
+       vwait ::cond
+       catch {close $pipe}
+       set cond
+    }]
+
+    ThreadReap
+    removeFile pscript
+
+    set cond
+} ok
+
+
+test thread-18.0 {thread::detach - args} {
+    set x [catch {thread::detach} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::detach channel"}}
+
+
+test thread-18.1 {thread::detach - channel} {
+    global fd
+    set fd [open $dummy r]
+    set r1 [regexp $fd [file channels]]
+    thread::detach $fd
+    set r2 [regexp $fd [file channels]]
+    list $r1 $r2
+} {1 0}
+
+test thread-18.2 {thread::attach - in different thread} {
+    global fd
+    ThreadReap
+    set tid [thread::create]
+    thread::send $tid "thread::attach $fd"
+    set r1 [thread::send $tid "regexp $fd \[file channels\]"]
+    thread::send $tid "thread::detach $fd"
+    list $r1
+} {1}
+
+test thread-18.3 {thread::attach - in same thread} {
+    global fd
+    thread::attach $fd
+    set r1 [regexp $fd [file channels]]
+    close $fd
+    set r1
+} {1}
+
+test thread-19.0 {thread::mutex - args} {
+    set x [catch {thread::mutex} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::mutex option ?args?"}}
+
+test thread-19.1 {thread::mutex - command options} {
+    set x [catch {thread::mutex dummy} msg]
+    list $x $msg
+} {1 {bad option "dummy": must be create, destroy, lock, or unlock}}
+
+test thread-19.2 {thread::mutex - more command options} {
+    set x [catch {thread::mutex create -dummy} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::mutex create ?-recursive?"}}
+
+
+test thread-19.3 {thread::mutex - create exclusive mutex} {
+    set emutex [thread::mutex create]
+    set c [regexp {mid[0-9]+} $emutex]
+    thread::mutex destroy $emutex
+    set c
+} {1}
+
+test thread-19.4 {thread::mutex - create recursive mutex} {
+    set rmutex [thread::mutex create -recursive]
+    set c [regexp {rid[0-9]+} $rmutex]
+    thread::mutex destroy $rmutex
+    set c
+} {1}
+
+test thread-19.5 {thread::mutex - lock/unlock exclusive mutex} {
+    set emutex [thread::mutex create]
+    thread::mutex lock $emutex
+    thread::mutex unlock $emutex
+    thread::mutex destroy $emutex
+} {}
+
+test thread-19.6 {thread::mutex - deadlock exclusive mutex} {
+    set emutex [thread::mutex create]
+    thread::mutex lock $emutex
+    set x [catch {thread::mutex lock $emutex} msg]
+    thread::mutex unlock $emutex
+    thread::mutex destroy $emutex
+    list $x $msg
+} {1 {locking the same exclusive mutex twice from the same thread}}
+
+test thread-19.7 {thread::mutex - lock invalid mutex} {
+    set x [catch {thread::mutex lock dummy} msg]
+    list $x $msg
+} {1 {no such mutex "dummy"}}
+
+test thread-19.8 {thread::mutex - lock/unlock recursive mutex} {
+    set rmutex [thread::mutex create -recursive]
+    thread::mutex lock $rmutex
+    thread::mutex unlock $rmutex
+    thread::mutex destroy $rmutex
+} {}
+
+test thread-19.9 {thread::mutex - deadlock exclusive mutex} {
+    set rmutex [thread::mutex create -recursive]
+    thread::mutex lock $rmutex
+    set x [catch {thread::mutex lock $rmutex} msg]
+    thread::mutex unlock $rmutex
+    thread::mutex unlock $rmutex
+    thread::mutex destroy $rmutex
+    list $x $msg
+} {0 {}}
+
+test thread-19.10 {thread::mutex - destroy locked exclusive mutex} {
+    set emutex [thread::mutex create]
+    thread::mutex lock $emutex
+    set x [catch {thread::mutex destroy $emutex} msg]
+    thread::mutex unlock $emutex
+    thread::mutex destroy $emutex
+    list $x $msg
+} {1 {mutex is in use}}
+
+test thread-19.11 {thread::mutex - destroy locked recursive mutex} {
+    set rmutex [thread::mutex create -recursive]
+    thread::mutex lock $rmutex
+    set x [catch {thread::mutex destroy $rmutex} msg]
+    thread::mutex unlock $rmutex
+    thread::mutex destroy $rmutex
+    list $x $msg
+} {1 {mutex is in use}}
+
+test thread-19.12 {thread::mutex - lock exclusive between threads} {
+    ThreadReap
+    set tid [thread::create]
+    set emutex [thread::mutex create]
+    thread::send -async $tid [subst {
+        thread::mutex lock $emutex
+        after 2000
+        thread::mutex unlock $emutex
+    }]
+    update
+    after 10
+    set time1 [clock seconds]
+    thread::mutex lock $emutex
+    set time2 [clock seconds]
+    thread::mutex unlock $emutex
+    ThreadReap
+    thread::mutex destroy $emutex
+    expr {($time2 - $time1) >= 1}
+} {1}
+
+test thread-19.13 {thread::mutex - lock args} {
+    set x [catch {thread::mutex lock} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::mutex lock mutexHandle"}}
+
+test thread-19.14 {thread::mutex - unlock args} {
+    set x [catch {thread::mutex unlock} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::mutex unlock mutexHandle"}}
+
+test thread-19.15 {thread::mutex - destroy args} {
+    set x [catch {thread::mutex destroy} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::mutex destroy mutexHandle"}}
+
+test thread-20.0 {thread::rwmutex - args} {
+    set x [catch {thread::rwmutex} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::rwmutex option ?args?"}}
+
+test thread-20.1 {thread::rwmutex - command options} {
+    set x [catch {thread::rwmutex dummy} msg]
+    list $x $msg
+} {1 {bad option "dummy": must be create, destroy, rlock, wlock, or unlock}}
+
+test thread-20.2 {thread::rwmutex - more command options} {
+    set x [catch {thread::rwmutex create dummy} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::rwmutex create"}}
+
+test thread-20.3 {thread::rwmutex - more command options} {
+    set x [catch {thread::rwmutex create dummy} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::rwmutex create"}}
+
+test thread-20.4 {thread::rwmutex - mutex handle} {
+    set rwmutex [thread::rwmutex create]
+    set c [regexp {wid[0-9]+} $rwmutex]
+    thread::rwmutex destroy $rwmutex
+    set c
+} {1}
+
+test thread-20.5 {thread::rwmutex - bad handle} {
+    set x [catch {thread::rwmutex rlock dummy} msg]
+    list $x $msg
+} {1 {no such mutex "dummy"}}
+
+test thread-20.6 {thread::mutex - destroy readlocked mutex} {
+    set rwmutex [thread::rwmutex create]
+    thread::rwmutex rlock $rwmutex
+    set x [catch {thread::rwmutex destroy $rwmutex} msg]
+    thread::rwmutex unlock $rwmutex
+    thread::rwmutex destroy $rwmutex
+    list $x $msg
+} {1 {mutex is in use}}
+
+test thread-20.7 {thread::mutex - destroy writelocked mutex} {
+    set rwmutex [thread::rwmutex create]
+    thread::rwmutex wlock $rwmutex
+    set x [catch {thread::rwmutex destroy $rwmutex} msg]
+    thread::rwmutex unlock $rwmutex
+    thread::rwmutex destroy $rwmutex
+    list $x $msg
+} {1 {mutex is in use}}
+
+test thread-20.8 {thread::rwmutex - readlock mutex} {
+    ThreadReap
+    set tid [thread::create]
+    set rwmutex [thread::rwmutex create]
+    thread::send -async $tid [subst {
+        thread::rwmutex rlock $rwmutex
+        after 1000
+        thread::rwmutex unlock $rwmutex
+    }]
+    update
+    after 10
+    set time1 [clock seconds]
+    thread::rwmutex rlock $rwmutex
+    set time2 [clock seconds]
+    thread::rwmutex unlock $rwmutex
+    ThreadReap
+    thread::rwmutex destroy $rwmutex
+    expr {($time2 - $time1) < 1}
+} {1}
+
+test thread-20.9 {thread::rwmutex - writelock mutex} {
+    ThreadReap
+    set tid [thread::create]
+    set rwmutex [thread::rwmutex create]
+    thread::send -async $tid [subst {
+        thread::rwmutex wlock $rwmutex
+        after 2000
+        thread::rwmutex unlock $rwmutex
+    }]
+    update
+    after 10
+    set time1 [clock seconds]
+    thread::rwmutex rlock $rwmutex
+    set time2 [clock seconds]
+    thread::rwmutex unlock $rwmutex
+    ThreadReap
+    thread::rwmutex destroy $rwmutex
+    expr {($time2 - $time1) >= 1}
+} {1}
+
+test thread-20.10 {thread::rwmutex - readlock args} {
+    set x [catch {thread::rwmutex rlock} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::rwmutex rlock mutexHandle"}}
+
+test thread-20.11 {thread::rwmutex - writelock args} {
+    set x [catch {thread::rwmutex wlock} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::rwmutex wlock mutexHandle"}}
+
+test thread-20.12 {thread::rwmutex - unlock args} {
+    set x [catch {thread::rwmutex unlock} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::rwmutex unlock mutexHandle"}}
+
+test thread-20.13 {thread::rwmutex - destroy args} {
+    set x [catch {thread::rwmutex destroy} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::rwmutex destroy mutexHandle"}}
+
+test thread-20.14 {thread::mutex - write-lock write-locked mutex} {
+    set rwmutex [thread::rwmutex create]
+    thread::rwmutex wlock $rwmutex
+    set x [catch {thread::rwmutex wlock $rwmutex} msg]
+    thread::rwmutex unlock $rwmutex
+    thread::rwmutex destroy $rwmutex
+    list $x $msg
+} {1 {write-locking the same read-write mutex twice from the same thread}}
+
+test thread-20.15 {thread::mutex - read-lock write-locked mutex} {
+    set rwmutex [thread::rwmutex create]
+    thread::rwmutex wlock $rwmutex
+    set x [catch {thread::rwmutex rlock $rwmutex} msg]  
+    thread::rwmutex unlock $rwmutex 
+    thread::rwmutex destroy $rwmutex
+    list $x $msg
+} {1 {read-locking already write-locked mutex from the same thread}}
+
+test thread-20.16 {thread::mutex - unlock not locked mutex} {
+    set rwmutex [thread::rwmutex create]
+    set x [catch {thread::rwmutex unlock $rwmutex} msg]
+    thread::rwmutex destroy $rwmutex
+    list $x $msg
+} {1 {mutex is not locked}}
+
+test thread-21.0 {thread::cond - args} {
+    set x [catch {thread::cond} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::cond option ?args?"}}
+
+test thread-21.1 {thread::cond - command options} {
+    set x [catch {thread::cond dummy} msg]
+    list $x $msg
+} {1 {bad option "dummy": must be create, destroy, notify, or wait}}
+
+test thread-21.2 {thread::cond - more command options} {
+    set x [catch {thread::cond create dummy} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::cond create"}}
+
+test thread-21.3 {thread::cond - cond handle} {
+    set cond [thread::cond create]
+    set c [regexp {cid[0-9]+} $cond]
+    thread::cond destroy $cond
+    set c
+} {1}
+
+test thread-21.4 {thread::cond - destroy args} {
+    set x [catch {thread::cond destroy} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::cond destroy condHandle ?args?"}}
+
+test thread-21.5 {thread::cond - destroy bad handle} {
+    set x [catch {thread::cond destroy dummy} msg]
+    list $x $msg
+} {1 {no such condition variable "dummy"}}
+
+test thread-21.6 {thread::cond - notify args} {
+    set x [catch {thread::cond notify} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::cond notify condHandle ?args?"}}
+
+test thread-21.7 {thread::cond - wait args} {
+    set x [catch {thread::cond wait} msg]
+    list $x $msg
+} {1 {wrong # args: should be "thread::cond wait condHandle ?args?"}}
+
+test thread-21.8 {thread::cond - wait bad handle} {
+    set x [catch {thread::cond wait dummy} msg]
+    list $x $msg
+} {1 {no such condition variable "dummy"}}
+
+test thread-21.9 {thread::cond - wait no mutex} {
+    set cond [thread::cond create]
+    set x [catch {thread::cond wait $cond} msg]
+    thread::cond destroy $cond
+    list $x $msg
+} {1 {wrong # args: should be "thread::cond wait condHandle mutexHandle ?timeout?"}}
+
+test thread-21.10 {thread::cond - wait bad mutex} {
+    set cond [thread::cond create]
+    set x [catch {thread::cond wait $cond dummy} msg]
+    thread::cond destroy $cond
+    list $x $msg
+} {1 {no such mutex "dummy"}}
+
+test thread-21.11 {thread::cond - wait unlocked mutex} {
+    set cond [thread::cond create]
+    set emutex [thread::mutex create]
+    set x [catch {thread::cond wait $cond $emutex} msg]
+    thread::cond destroy $cond
+    thread::mutex destroy $emutex
+    list $x $msg
+} {1 {mutex not locked or wrong type}}
+
+test thread-21.12 {thread::cond - wait locked mutex from wrong thread} {
+    ThreadReap
+    set tid [thread::create]
+    set emutex [thread::mutex create]
+    set cond [thread::cond create]
+    thread::mutex lock $emutex
+    thread::send -async $tid [subst -nocommands {
+        set code [catch {thread::cond wait $cond $emutex 1000} result]
+    }]
+    update
+    after 20
+    thread::cond notify $cond
+    set c [thread::send $tid "set code"]
+    set r [thread::send $tid "set result"]
+    ThreadReap
+    thread::cond destroy $cond
+    thread::mutex unlock $emutex
+    thread::mutex destroy $emutex
+    list $c $r
+} {1 {mutex not locked or wrong type}}
+
+test thread-21.13 {thread::cond - wait recursive mutex} {
+    set cond [thread::cond create]
+    set rmutex [thread::mutex create -recursive]
+    set x [catch {thread::cond wait $cond $rmutex} msg]
+    thread::cond destroy $cond
+    thread::mutex destroy $rmutex
+    list $x $msg
+} {1 {mutex not locked or wrong type}}
+
+test thread-21.14 {thread::cond - wait readwrite mutex} {
+    set cond [thread::cond create]
+    set rwmutex [thread::rwmutex create]
+    set x [catch {thread::cond wait $cond $rwmutex} msg]
+    thread::cond destroy $cond
+    thread::rwmutex destroy $rwmutex
+    list $x $msg
+} {1 {mutex not locked or wrong type}}
+
+test thread-21.15 {thread::cond - regular timed wait} {
+    ThreadReap
+    set tid [thread::create]
+    set emutex [thread::mutex create]
+    set cond [thread::cond create]
+    thread::send -async $tid [subst {
+        thread::mutex lock $emutex
+        thread::cond wait $cond $emutex 2000
+        thread::mutex unlock $emutex
+        set test 1
+    }]
+    update
+    after 10
+    set time1 [clock seconds]
+    thread::cond notify $cond
+    set c [thread::send $tid "info exists test"]
+    set time2 [clock seconds]
+    ThreadReap
+    thread::mutex destroy $emutex
+    thread::cond destroy $cond
+    list $c [expr {($time2 - $time1) < 2}]
+} {1 1}
+
+test thread-21.16 {thread::cond - delete waited variable} {
+    ThreadReap
+    set tid [thread::create]
+    set emutex [thread::mutex create]
+    set cond [thread::cond create]
+    thread::send -async $tid [subst {
+        thread::mutex lock $emutex
+        thread::cond wait $cond $emutex 500
+        thread::mutex unlock $emutex
+    }]
+    update
+    after 10
+    set c1 [catch {thread::cond destroy $cond} r1]
+    thread::cond notify $cond
+    after 1000
+    set c2 [catch {thread::cond destroy $cond} r2]
+    ThreadReap
+    thread::mutex destroy $emutex
+    list $c1 $c2 $r1 $r2
+} {1 0 {condition variable is in use} {}}
+
+::tcltest::cleanupTests
diff --git a/8.x/thread/tests/tpool.test b/8.x/thread/tests/tpool.test
new file mode 100644 (file)
index 0000000..a09c863
--- /dev/null
@@ -0,0 +1 @@
+return
diff --git a/8.x/thread/tests/tsv.test b/8.x/thread/tests/tsv.test
new file mode 100644 (file)
index 0000000..a09c863
--- /dev/null
@@ -0,0 +1 @@
+return
diff --git a/8.x/thread/tests/ttrace.test b/8.x/thread/tests/ttrace.test
new file mode 100644 (file)
index 0000000..a09c863
--- /dev/null
@@ -0,0 +1 @@
+return
diff --git a/8.x/thread/unix/CONFIG b/8.x/thread/unix/CONFIG
new file mode 100644 (file)
index 0000000..3de8710
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# This file contains collection of configure directives
+# for building the Threading extension.
+#
+# Comment-out next line if building with GCC compiler.
+#
+# CC=gcc; export CC
+#
+#
+# Tcl on Unix (uses public Tcl library)
+# ----------------------------------------------------
+# ../configure --enable-threads
+#
+# As of 2.6, the threading extension supports persistent
+# shared variables. As an working example of this, there
+# is a simple wrapper for the popular Gdbm library.
+# Uncomment the following line if you like to compile the
+# Gdbm wrapper for persistent shared variables.
+# 
+# ../configure --enable-threads --with-gdbm
+#
+# If your Gdbm library is not installed in one of the
+# default system locations (/usr/lib, /usr/local/lib ...)
+# please use following directive. Note that both library
+# file *and* includes should be located in "/my/gdbm". 
+# Of course, you have to replace the "/my/gdbm" below
+# with the exact location, as found in your system:
+# 
+# ../configure --enable-threads --with-gdbm=/my/gdbm
+#
+#
+# AOLserver 4.X; Uses public Tcl library.
+# ----------------------------------------------------
+# aoldir="/usr/local/aolserver"
+# ../configure --enable-threads \
+#   --with-aolserver=$aoldir \
+#   --prefix=$aoldir --exec-prefix=$aoldir
+#
+# AOLserver uses its own package loading mechanism.
+# To load, just do "ns_eval package require Thread"
+# at the AOLserver startup or later from any thread.
+#
+#
+# Mac OS X; Uses public Tcl library.
+# ----------------------------------------------------
+# ../configure --enable-threads \
+#   --mandir=/usr/local/share/man \
+#   --libdir=/Library/Tcl \
+#   --with-tcl=/Library/Frameworks/Tcl.framework \
+#   --with-tclinclude=/Library/Frameworks/Tcl.framework/Headers
+#
+# EOF
diff --git a/8.x/thread/unix/README b/8.x/thread/unix/README
new file mode 100644 (file)
index 0000000..5c433dd
--- /dev/null
@@ -0,0 +1,69 @@
+
+I. Building the Tcl thread extension for Unix
+=============================================
+
+Extension can be compiled on several Unix derivates including various
+distributions of Linux. Build process is pretty straightforward. I've
+checked some versions of Solaris, Linux and Darwin, but the extension
+should compile without problems on any Unix-like operating system
+with a proper pthreads library implementation.
+
+To build on Unix-like operating systems, start with the CONFIG script
+and see if there is already a combination of the "configure" options
+which may satisfy your needs. If not, you can run the configure script
+located in the root of the distribution directory with a choice of 
+supported options yourself.  If yes, you can uncomment corresponding
+lines from the CONFIG script and do:
+
+    % sh CONFIG
+
+Either way, this will create a Makefile which you use to run "make" and
+"make install".
+You can use "make clean" to clean the directory from temporary compilation
+files and/or "make distclean" to additionaly remove local config files.
+You might want to do "make test" before doing the "make install" in order
+to run the regression tests on the package. 
+
+To explore other building options, look into the CONFIG file for more
+information.
+
+
+Note for AOLserver users
+------------------------
+
+The extension can be compiled as a loadable module for the AOLserver 
+version 4.0 or higher. In order to do this, use "--with-aolserver"
+configure option to specify the directory containing the AOLserver
+distribution. The CONFIG script has an example how to invoke configure
+in order to build the extension as AOLserver module.
+Note, however, that "make install" and "make test" targets are still
+not supported for AOLserver builds. This will be corrected in one of
+the future releases.
+
+To fine-tune, you might also want to make the tsv::* commands replace
+the AOLserver built-in nsv_* family of commands, since they are API 
+compatible and provide richer command set plus advanced shared-object
+storage of shared data. Go to the generic/threadSvCmd.h file and look
+at the beginning of the file for the:
+
+/* #define NSV_COMPAT 1 */
+
+So, uncomment the line, recompile and there you go.
+
+
+II. Building optional support libraries
+=======================================
+
+As of 2.6 release, this extension supports persistent shared variables.
+To use this functionality, you might need to download and compile some 
+other supporting libraries. Currently, there is a simple implementation
+of shared variable persistency built atop of popular GNU Gdbm package.
+You can obtain the latest version of the Gdbm package from the GNU 
+website at: http://www.gnu.org/software/gdbm/gdbm.html
+To compile with GNU Gdbm support you must configure with --with-gdbm
+switch. This option, if used, will try to locate the Gdbm library on
+your system at couple of standard locations. You might override this
+behaviour by giving --with-gdbm=/some/dir. Note that both library file
+and the include file must then reside in this directory.
+
+-EOF-
diff --git a/8.x/thread/unix/threadUnix.c b/8.x/thread/unix/threadUnix.c
new file mode 100644 (file)
index 0000000..00d80c6
--- /dev/null
@@ -0,0 +1,29 @@
+/* 
+ * threadUnix.c --
+ *
+ * Unix specific aspects for the thread extension.
+ *
+ * see http://dev.activestate.com/doc/howto/thread_model.html
+ *
+ * Some of this code is based on work done by Richard Hipp on behalf of
+ * Conservation Through Innovation, Limited, with their permission.
+ *
+ * Copyright (c) 1998 by Sun Microsystems, Inc.
+ * Copyright (c) 1999,2000 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: threadUnix.c,v 1.1 2002/01/19 23:27:09 vasiljevic Exp $
+ */
+
+#include "../generic/tclThread.h"
+
+/* EOF $RCSfile: threadUnix.c,v $ */
+
+/* Emacs Setup Variables */
+/* Local Variables:      */
+/* mode: C               */
+/* indent-tabs-mode: nil */
+/* c-basic-offset: 4     */
+/* End:                  */
diff --git a/8.x/thread/win/CONFIG b/8.x/thread/win/CONFIG
new file mode 100644 (file)
index 0000000..df5aac1
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# This is how I run configure.  You'll want to change the
+# pathnames to match your system, of course.
+#
+# Remember that if you use the --enable-sybols, you need to
+# use the thread25d.dll in a tclsh that has also been compiled
+# with symbols (e.g., tclsh84g.exe or tclsh84d.exe).
+# If you want to build both debug and non-debug versions, then
+# create "debug" and "release" directories and run configure
+# from in those directories with the appropriate flags.
+#
+# Note the CC=gcc must be set *before* the "configure" is ran.
+# This is really needed, otherwise configure will not be able
+# to compile the small test file which checks the presence
+# of the MinGW build environment. It is *not* enough to use
+# "--enable-gcc" configure option; you *need* to define CC.
+# 
+
+export CC=gcc
+sh ../configure --enable-threads --with-tcl=e:/tcl/win
+
diff --git a/8.x/thread/win/README.txt b/8.x/thread/win/README.txt
new file mode 100644 (file)
index 0000000..ce9c32a
--- /dev/null
@@ -0,0 +1,52 @@
+
+I. Building the Tcl thread extension for Windows
+================================================
+
+Thread extension supports two build options:
+
+
+o. MinGW builds:
+----------------
+
+The extension can be compiled under Windows using the
+MinGW (http://www.mingw.org) environment. You can also
+download the ready-to-go copy of the MinGW from the
+same place you've downloaded this extension.
+
+You should compile the Tcl core with MinGW first. After
+that, you can compile the extension by running the
+configure/make from this directory. You can also use the
+CONFIG script to do this. You might want to edit the
+script to match your environment and then just do:
+
+    sh CONFIG
+
+This should go smoothly, once you got Tcl core compiled ok.
+
+
+o. Microsoft MSVC++ build:
+--------------------------
+
+You should use the makefile.vc file for the MSVC++ located
+in the vc/ directory. Please consult the vc/README.txt and
+vc/makefile.vc files for more details.
+Alternatively, you can use the MSVC++ IDE and open the 
+thread_win.dsw workspace file.
+
+
+II. Building optional support libraries
+=======================================
+
+As of 2.6 release, this extension supports persistent shared 
+variables. To use this functionality, you might need to download 
+and compile some other supporting libraries. Currently, there is 
+a simple implementation of shared variable persistency built atop
+of popular GNU Gdbm package. You can obtain the latest version of
+the Gdbm from: http://www.gnu.org/software/gdbm/gdbm.html.
+
+For the impatient, there are Windows ports of GNU Gdbm found on
+various places on the Internet. The easiest way to start is to go 
+to the GnuWin32 project: http://sourceforge.net/projects/gnuwin32
+and fetch yourself a compiled GNU Gdbm DLL. 
+
+-EOF-
diff --git a/8.x/thread/win/thread.rc b/8.x/thread/win/thread.rc
new file mode 100644 (file)
index 0000000..71cd8c2
--- /dev/null
@@ -0,0 +1,48 @@
+// RCS: @(#) $Id: thread.rc,v 1.5 2007/05/03 22:22:27 patthoyts Exp $
+//
+// Version resource script
+//
+
+#include <winver.h>
+
+#define RESOURCE_INCLUDED
+#include <tcl.h>
+
+LANGUAGE 0x9, 0x1    /* LANG_ENGLISH, SUBLANG_DEFAULT */
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION    PACKAGE_MAJOR,PACKAGE_MINOR,0,0
+ PRODUCTVERSION PACKAGE_MAJOR,PACKAGE_MINOR,0,0
+ FILEFLAGSMASK  0x3fL
+#if DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS     0x4    /* VOS__WINDOWS32 */
+ FILETYPE     0x2    /* VFT_DLL */
+ FILESUBTYPE     0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
+        BEGIN
+            VALUE "FileDescription", "Threading extension library for Tcl\0"
+#if DEBUG
+            VALUE "OriginalFilename", "thread" STRINGIFY(JOIN(PACKAGE_MAJOR,PACKAGE_MINOR)) "d.dll\0"
+#else
+            VALUE "OriginalFilename", "thread" STRINGIFY(JOIN(PACKAGE_MAJOR,PACKAGE_MINOR)) ".dll\0"
+#endif
+            VALUE "CompanyName", "NONE! Open-sourced with no owner\0"
+            VALUE "FileVersion", PACKAGE_VERSION
+            VALUE "LegalCopyright", "Under BSD license\0"
+            VALUE "ProductName", "Tcl for Windows\0"
+            VALUE "ProductVersion", PACKAGE_VERSION
+            VALUE "Authors", "Brent Welch,\r\n" "Andreas Kupries, \r\n" "David Gravereaux,\r\n" "Zoran Vasiljevic" "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
diff --git a/8.x/thread/win/threadWin.c b/8.x/thread/win/threadWin.c
new file mode 100644 (file)
index 0000000..757e78b
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * threadWin.c --
+ *
+ * Windows specific aspects for the thread extension.
+ *
+ * see http://dev.activestate.com/doc/howto/thread_model.html
+ *
+ * Some of this code is based on work done by Richard Hipp on behalf of
+ * Conservation Through Innovation, Limited, with their permission.
+ *
+ * Copyright (c) 1998 by Sun Microsystems, Inc.
+ * Copyright (c) 1999,2000 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: threadWin.c,v 1.5 2002/01/27 04:52:21 davygrvy Exp $
+ */
+
+#include "../generic/tclThread.h"
+#include <windows.h>
+#include <process.h>
+
+#if 0
+/* only Windows 2000 (XP, too??) has this function */
+HANDLE (WINAPI *winOpenThreadProc)(DWORD, BOOL, DWORD);
+
+void
+ThreadpInit (void)
+{
+    HMODULE hKernel = GetModuleHandle("kernel32.dll");
+    winOpenThreadProc = (HANDLE (WINAPI *)(DWORD, BOOL, DWORD))
+           GetProcAddress(hKernel, "OpenThread");
+}
+
+int
+ThreadpKill (Tcl_Interp *interp, long id)
+{
+    HANDLE hThread;
+    int result = TCL_OK;
+
+    if (winOpenThreadProc) {
+       hThread = winOpenThreadProc(THREAD_TERMINATE, FALSE, id);
+       /* 
+        * not to be misunderstood as "devilishly clever",
+        * but evil in it's pure form.
+        */
+       TerminateThread(hThread, 666);
+    } else {
+       Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+               "Can't (yet) kill threads on this OS, sorry.", NULL);
+       result = TCL_ERROR;
+    }
+    return result;
+}
+#endif
diff --git a/8.x/thread/win/vc/.cvsignore b/8.x/thread/win/vc/.cvsignore
new file mode 100644 (file)
index 0000000..6d60d04
--- /dev/null
@@ -0,0 +1,9 @@
+Debug
+Release
+*.opt
+*.ncb
+*.plg
+*.00?
+.#*
+nmakehlp.exe
+nmakehlp.obj
diff --git a/8.x/thread/win/vc/README.txt b/8.x/thread/win/vc/README.txt
new file mode 100644 (file)
index 0000000..f103390
--- /dev/null
@@ -0,0 +1,18 @@
+
+Files in this directory may be useful if you have not set up
+your TEA (i.e., MinGW) environment and you're using the MSVC++
+from Micro$oft.
+
+To build the extension invoke the following command:
+
+    nmake -f makefile.vc TCLDIR=<path>
+
+You would need to give the <path> of the Tcl distribution where
+tcl.h and other needed Tcl files are located.
+Please look into the makefile.vc file for more information.
+
+Alternatively, you can open the extension workspace and project files
+(thread_win.dsw and thread_win.dsp) from within the MSVC++ and press
+the F7 key to build the extension under the control of the MSVC IDE.
+
+-EOF-
diff --git a/8.x/thread/win/vc/makefile.vc b/8.x/thread/win/vc/makefile.vc
new file mode 100644 (file)
index 0000000..dad9daf
--- /dev/null
@@ -0,0 +1,490 @@
+# makefile.vc --                                               -*- Makefile -*-
+#
+# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
+#
+# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
+# make it suitable as a general package makefile. Look for the word EDIT
+# which marks sections that may need modification. As a minumum you will
+# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
+# relevant to your package.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+# Copyright (c) 2001 ActiveState Corporation.
+# Copyright (c) 2001-2002 David Gravereaux.
+# Copyright (c) 2003-2006 Pat Thoyts
+#
+#-------------------------------------------------------------------------
+# RCS: @(#)$Id: makefile.vc,v 1.33 2009/05/04 22:46:17 patthoyts Exp $
+#-------------------------------------------------------------------------
+
+# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
+# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
+# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
+MSG = ^
+You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
+Platform SDK first to setup the environment.  Jump to this line to read^
+the build instructions.
+!error $(MSG)
+!endif
+
+#------------------------------------------------------------------------------
+# HOW TO USE this makefile:
+#
+# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
+#     used  as a check to see if vcvars32.bat had been run prior to running
+#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
+#     been set globally and the PATH adjusted.  Either way is valid.
+#
+#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
+#     directory to setup the proper environment, if needed, for your current
+#     setup.  This is a needed bootstrap requirement and allows the swapping of
+#     different environments to be easier.
+#
+# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
+#     vcvars32.bat according to the instructions for it.  This can also turn on
+#     the 64-bit compiler, if your SDK has it.
+#
+# 3)  Targets are:
+#      all       -- Builds everything.
+#       <project> -- Builds the project (eg: nmake sample)
+#      test      -- Builds and runs the test suite.
+#      install   -- Installs the built binaries and libraries to $(INSTALLDIR)
+#                   in an appropriate subdirectory.
+#      clean/realclean/distclean -- varying levels of cleaning.
+#
+# 4)  Macros usable on the commandline:
+#      INSTALLDIR=<path>
+#              Sets where to install Tcl from the built binaries.
+#              C:\Progra~1\Tcl is assumed when not specified.
+#
+#      OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
+#              Sets special options for the core.  The default is for none.
+#              Any combination of the above may be used (comma separated).
+#              'none' will over-ride everything to nothing.
+#
+#              static  =  Builds a static library of the core instead of a
+#                         dll.  The shell will be static (and large), as well.
+#              msvcrt  =  Effects the static option only to switch it from
+#                         using libcmt(d) as the C runtime [by default] to
+#                         msvcrt(d). This is useful for static embedding
+#                         support.
+#              staticpkg = Effects the static option only to switch
+#                         tclshXX.exe to have the dde and reg extension linked
+#                         inside it.
+#              nothreads = Turns off multithreading support (not recommended)
+#              thrdalloc = Use the thread allocator (shared global free pool).
+#              symbols =  Adds symbols for step debugging.
+#              profile =  Adds profiling hooks.  Map file is assumed.
+#              loimpact =  Adds a flag for how NT treats the heap to keep memory
+#                         in use, low.  This is said to impact alloc performance.
+#
+#      STATS=memdbg,compdbg,none
+#              Sets optional memory and bytecode compiler debugging code added
+#              to the core.  The default is for none.  Any combination of the
+#              above may be used (comma separated).  'none' will over-ride
+#              everything to nothing.
+#
+#              memdbg   = Enables the debugging memory allocator.
+#              compdbg  = Enables byte compilation logging.
+#
+#      MACHINE=(IX86|IA64|ALPHA|AMD64)
+#              Set the machine type used for the compiler, linker, and
+#              resource compiler.  This hook is needed to tell the tools
+#              when alternate platforms are requested.  IX86 is the default
+#              when not specified. If the CPU environment variable has been
+#              set (ie: recent Platform SDK) then MACHINE is set from CPU.
+#
+#      TMP_DIR=<path>
+#      OUT_DIR=<path>
+#              Hooks to allow the intermediate and output directories to be
+#              changed.  $(OUT_DIR) is assumed to be 
+#              $(BINROOT)\(Release|Debug) based on if symbols are requested.
+#              $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
+#
+#      TESTPAT=<file>
+#              Reads the tests requested to be run from this file.
+#
+#      CFG_ENCODING=encoding
+#              name of encoding for configuration information. Defaults
+#              to cp1252
+#
+# 5)  Examples:
+#
+#      Basic syntax of calling nmake looks like this:
+#      nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
+#
+#                        Standard (no frills)
+#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+#       Setting environment for using Microsoft Visual C++ tools.
+#       c:\tcl_src\win\>nmake -f makefile.vc all
+#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
+#
+#                         Building for Win64
+#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+#       Setting environment for using Microsoft Visual C++ tools.
+#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
+#       Targeting Windows pre64 RETAIL
+#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
+#
+#------------------------------------------------------------------------------
+#==============================================================================
+###############################################################################
+#------------------------------------------------------------------------------
+
+!if !exist("makefile.vc")
+MSG = ^
+You must run this makefile only from the directory it is in.^
+Please `cd` to its location first.
+!error $(MSG)
+!endif
+
+#-------------------------------------------------------------------------
+# Project specific information (EDIT)
+#
+# You should edit this with the name and version of your project. This
+# information is used to generate the name of the package library and
+# it's install location.
+#
+# For example, the sample extension is  going to build sample04.dll and
+# would install it into $(INSTALLDIR)\lib\sample04
+#
+# You need to specify the object files that need to be linked into your
+# binary here.
+#
+#-------------------------------------------------------------------------
+
+PROJECT = thread
+
+# Uncomment the following line if this is a Tk extension.
+#PROJECT_REQUIRES_TK=1
+!include "rules.vc"
+
+!include "pkg.vc"
+
+DOTVERSION      = $(PACKAGE_VERSION:"=) #"
+VERSION         = $(PACKAGE_MAJOR)$(PACKAGE_MINOR)
+STUBPREFIX      = $(PROJECT)stub
+
+DLLOBJS = \
+       $(TMP_DIR)\threadCmd.obj \
+       $(TMP_DIR)\threadSvCmd.obj \
+       $(TMP_DIR)\threadSpCmd.obj \
+       $(TMP_DIR)\threadPoolCmd.obj \
+       $(TMP_DIR)\psGdbm.obj \
+       $(TMP_DIR)\threadSvListCmd.obj \
+       $(TMP_DIR)\threadSvKeylistCmd.obj \
+       $(TMP_DIR)\tclXkeylist.obj \
+       $(TMP_DIR)\threadWin.obj \
+!if !$(STATIC_BUILD)
+       $(TMP_DIR)\thread.res
+!endif
+
+PRJHEADERS = 
+
+#-------------------------------------------------------------------------
+# Target names and paths ( shouldn't need changing )
+#-------------------------------------------------------------------------
+
+BINROOT                = .
+ROOT            = ..\..
+
+PRJIMPLIB      = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME     = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+PRJLIB         = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB     = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+### Make sure we use backslash only.
+PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR     = $(PRJ_INSTALL_DIR)
+INCLUDE_INSTALL_DIR    = $(_TCLDIR)\include
+
+### The following paths CANNOT have spaces in them.
+GENERICDIR     = $(ROOT)\generic
+WINDIR         = $(ROOT)\win
+LIBDIR          = $(ROOT)\lib
+DOCDIR         = $(ROOT)\doc
+TOOLSDIR       = $(ROOT)\tools
+COMPATDIR      = $(ROOT)\compat
+
+#---------------------------------------------------------------------
+# Compile flags
+#---------------------------------------------------------------------
+
+!if !$(DEBUG)
+!if $(OPTIMIZING)
+### This cranks the optimization level to maximize speed
+cdebug = $(OPTIMIZATIONS)
+!else
+cdebug =
+!endif
+!else if "$(MACHINE)" == "IA64" #|| "$(MACHINE)" == "AMD64"
+### Warnings are too many, can't support warnings into errors.
+cdebug = -Zi -Od $(DEBUGFLAGS)
+!else
+cdebug = -Zi -W3 $(DEBUGFLAGS)
+!endif
+
+### Declarations common to all compiler options
+cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
+cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
+
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+!if !$(STATIC_BUILD)
+cflags = $(cflags) -DUSE_TCL_STUBS
+!if defined(TKSTUBLIB)
+cflags = $(cflags) -DUSE_TK_STUBS
+!endif
+!endif
+
+INCLUDES       = $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)"
+BASE_CFLAGS    = $(cflags) $(cdebug) $(crt) $(INCLUDES)
+CON_CFLAGS     = $(cflags) $(cdebug) $(crt) -DCONSOLE
+TCL_CFLAGS     = -DPACKAGE_NAME="\"$(PROJECT)\"" \
+                  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+                 -DBUILD_$(PROJECT) \
+                  $(BASE_CFLAGS) $(OPTDEFINES)
+
+#---------------------------------------------------------------------
+# Link flags
+#---------------------------------------------------------------------
+
+!if $(DEBUG)
+ldebug = -debug:full -debugtype:cv
+!if $(MSVCRT)
+ldebug = $(ldebug) -nodefaultlib:msvcrt
+!endif
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!endif
+
+### Declarations common to all linker options
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(PROFILE)
+lflags = $(lflags) -profile
+!endif
+
+!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
+### Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
+### Align sections for speed in loading by choosing the virtual page size.
+lflags = $(lflags) -align:4096
+!endif
+
+!if $(LOIMPACT)
+lflags = $(lflags) -ws:aggressive
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+!if !$(STATIC_BUILD)
+baselibs  = $(TCLSTUBLIB)
+!if defined(TKSTUBLIB)
+baselibs  = $(baselibs) $(TKSTUBLIB)
+!endif
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) >= 1400 && $(VCVERSION) < 1500
+baselibs   = $(baselibs) bufferoverflowU.lib
+!endif
+!endif
+
+#---------------------------------------------------------------------
+# TclTest flags
+#---------------------------------------------------------------------
+
+!IF "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!ENDIF
+
+#---------------------------------------------------------------------
+# Project specific targets (EDIT)
+#---------------------------------------------------------------------
+
+all:       setup $(PROJECT)
+$(PROJECT): setup pkgIndex $(PRJLIB)
+install:    install-binaries install-libraries install-docs
+pkgIndex:   $(OUT_DIR)\pkgIndex.tcl
+
+test: setup $(PROJECT)
+       @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+       @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+       @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+       @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+       @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
+       $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS)
+!else
+        @echo Please wait while the tests are collected...
+        $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) > tests.log
+       type tests.log | more
+!endif
+
+shell: setup $(PROJECT)
+       @set VLERQ_LIBRARY=$(LIBDIR:\=/)
+       @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+       @set TCLLIBPATH=$(OUT_DIR:\=/)
+       @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+       @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+       @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+       $(DEBUGGER) $(TCLSH) $(SCRIPT)
+
+setup:
+       @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+       @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+# See <tcl>/win/coffbase.txt for extension base addresses.
+$(PRJLIB): $(DLLOBJS)
+!if $(STATIC_BUILD)
+       $(lib32) -nologo -out:$@ @<<
+$**
+<<
+!else
+       $(link32) $(dlllflags) -base:0x10C80000 -out:$@ $(baselibs) @<<
+$**
+<<
+       $(_VC_MANIFEST_EMBED_DLL)
+       -@del $*.exp
+!endif
+
+$(PRJSTUBLIB): $(PRJSTUBOBJS)
+       $(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
+
+#---------------------------------------------------------------------
+# Implicit rules
+#---------------------------------------------------------------------
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+       $(rc32) -fo $@ -r -i "$(GENERICDIR)" $(TCL_INCLUDES) \
+               -D__WIN32__ \
+                -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
+                -DDOTVERSION=\"$(DOTVERSION)\" \
+                -DVERSION=\"$(VERSION)$(SUFX)\" \
+               -DDEBUG=$(DEBUG) \
+               -DPACKAGE_MAJOR=$(PACKAGE_MAJOR) \
+               -DPACKAGE_MINOR=$(PACKAGE_MINOR) \
+               -DPACKAGE_VERSION=\"$(PACKAGE_VERSION)\" \
+!if $(DEBUG)
+       -d DEBUG \
+!endif
+!if $(TCL_THREADS)
+       -d TCL_THREADS \
+!endif
+!if $(STATIC_BUILD)
+       -d STATIC_BUILD \
+!endif
+       $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+#-------------------------------------------------------------------------
+# Explicit dependency rules
+#
+#-------------------------------------------------------------------------
+
+#{$(WINDIR)}.c{$(TMP_DIR)}.obj ::
+$(GENERICDIR)\psGdbm.c: $(GENERICDIR)\psGdbm.h
+$(GENERICDIR)\threadSpCmd.c : $(GENERICDIR)\tclThread.h
+$(GENERICDIR)\threadSvCmd.c : $(GENERICDIR)\tclThread.h
+$(GENERICDIR)\threadPoolCmd.c : $(GENERICDIR)\tclThread.h
+$(GENERICDIR)\threadSvListCmd.c : $(GENERICDIR)\tclThread.h
+$(GENERICDIR)\threadSvKeylistCmd.c : $(GENERICDIR)\tclThread.h
+
+.PHONY: $(OUT_DIR)\pkgIndex.tcl
+
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+       @nmakehlp -s << $** > $@
+@PACKAGE_NAME@       thread
+@PACKAGE_VERSION@    $(DOTVERSION)
+@PKG_LIB_FILE@       $(PRJLIBNAME)
+<<
+
+#---------------------------------------------------------------------
+# Installation. (EDIT)
+#
+# You may need to modify this section to reflect the final distribution
+# of your files and possibly to generate documentation.
+#
+#---------------------------------------------------------------------
+
+install-binaries:
+       @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+       @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+       @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+install-libraries:
+       @echo Installing library files to '$(SCRIPT_INSTALL_DIR)'
+       @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+       @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)"
+
+install-docs:
+       @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+       @if exist $(DOCDIR)\man $(CPY) $(DOCDIR)\man\*.n "$(DOC_INSTALL_DIR)"
+
+#---------------------------------------------------------------------
+# Clean up
+#---------------------------------------------------------------------
+
+clean:
+       @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+       @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+       @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+       @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+       @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+
+realclean: clean
+       @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+distclean: realclean
+       @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+       @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
diff --git a/8.x/thread/win/vc/nmakehlp.c b/8.x/thread/win/vc/nmakehlp.c
new file mode 100644 (file)
index 0000000..d21288d
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ * ----------------------------------------------------------------------------
+ * nmakehlp.c --
+ *
+ *     This is used to fix limitations within nmake and the environment.
+ *
+ * Copyright (c) 2002 by David Gravereaux.
+ * Copyright (c) 2006 by Pat Thoyts
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * ----------------------------------------------------------------------------
+ * RCS: @(#) $Id: nmakehlp.c,v 1.4 2009/05/04 22:46:17 patthoyts Exp $
+ * ----------------------------------------------------------------------------
+ */
+
+#define _CRT_SECURE_NO_DEPRECATE
+#include <windows.h>
+#define NO_SHLWAPI_GDI
+#define NO_SHLWAPI_STREAM
+#define NO_SHLWAPI_REG
+#include <shlwapi.h>
+#pragma comment (lib, "user32.lib")
+#pragma comment (lib, "kernel32.lib")
+#pragma comment (lib, "shlwapi.lib")
+#include <stdio.h>
+#include <math.h>
+
+/*
+ * This library is required for x64 builds with _some_ versions of MSVC
+ */
+#if defined(_M_IA64) || defined(_M_AMD64)
+#if _MSC_VER >= 1400 && _MSC_VER < 1500
+#pragma comment(lib, "bufferoverflowU")
+#endif
+#endif
+
+/* ISO hack for dumb VC++ */
+#ifdef _MSC_VER
+#define   snprintf     _snprintf
+#endif
+
+
+
+/* protos */
+
+int            CheckForCompilerFeature(const char *option);
+int            CheckForLinkerFeature(const char *option);
+int            IsIn(const char *string, const char *substring);
+int            GrepForDefine(const char *file, const char *string);
+int            SubstituteFile(const char *substs, const char *filename);
+int            QualifyPath(const char *path);
+const char *    GetVersionFromFile(const char *filename, const char *match);
+DWORD WINAPI   ReadFromPipe(LPVOID args);
+
+/* globals */
+
+#define CHUNK  25
+#define STATICBUFFERSIZE    1000
+typedef struct {
+    HANDLE pipe;
+    char buffer[STATICBUFFERSIZE];
+} pipeinfo;
+
+pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
+pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
+\f
+/*
+ * exitcodes: 0 == no, 1 == yes, 2 == error
+ */
+
+int
+main(
+    int argc,
+    char *argv[])
+{
+    char msg[300];
+    DWORD dwWritten;
+    int chars;
+
+    /*
+     * Make sure children (cl.exe and link.exe) are kept quiet.
+     */
+
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+
+    /*
+     * Make sure the compiler and linker aren't effected by the outside world.
+     */
+
+    SetEnvironmentVariable("CL", "");
+    SetEnvironmentVariable("LINK", "");
+
+    if (argc > 1 && *argv[1] == '-') {
+       switch (*(argv[1]+1)) {
+       case 'c':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -c <compiler option>\n"
+                       "Tests for whether cl.exe supports an option\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return CheckForCompilerFeature(argv[2]);
+       case 'l':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -l <linker option>\n"
+                       "Tests for whether link.exe supports an option\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return CheckForLinkerFeature(argv[2]);
+       case 'f':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -f <string> <substring>\n"
+                       "Find a substring within another\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           } else if (argc == 3) {
+               /*
+                * If the string is blank, there is no match.
+                */
+
+               return 0;
+           } else {
+               return IsIn(argv[2], argv[3]);
+           }
+       case 'g':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -g <file> <string>\n"
+                       "grep for a #define\n"
+                       "exitcodes: integer of the found string (no decimals)\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return GrepForDefine(argv[2], argv[3]);
+       case 's':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -s <substitutions file> <file>\n"
+                       "Perform a set of string map type substutitions on a file\n"
+                       "exitcodes: 0\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return SubstituteFile(argv[2], argv[3]);
+       case 'V':
+           if (argc != 4) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                   "usage: %s -V filename matchstring\n"
+                   "Extract a version from a file:\n"
+                   "eg: pkgIndex.tcl \"package ifneeded http\"",
+                   argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                   &dwWritten, NULL);
+               return 0;
+           }
+           printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
+           return 0;
+       case 'Q':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                   "usage: %s -q path\n"
+                   "Emit the fully qualified path\n"
+                   "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                   &dwWritten, NULL);
+               return 2;
+           }
+           return QualifyPath(argv[2]);
+       }
+    }
+    chars = snprintf(msg, sizeof(msg) - 1,
+           "usage: %s -c|-l|-f|-g|-V|-s|-Q ...\n"
+           "This is a little helper app to equalize shell differences between WinNT and\n"
+           "Win9x and get nmake.exe to accomplish its job.\n",
+           argv[0]);
+    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
+    return 2;
+}
+\f
+int
+CheckForCompilerFeature(
+    const char *option)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    SECURITY_ATTRIBUTES sa;
+    DWORD threadID;
+    char msg[300];
+    BOOL ok;
+    HANDLE hProcess, h, pipeThreads[2];
+    char cmdline[100];
+
+    hProcess = GetCurrentProcess();
+
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO);
+    si.dwFlags   = STARTF_USESTDHANDLES;
+    si.hStdInput = INVALID_HANDLE_VALUE;
+
+    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = FALSE;
+
+    /*
+     * Create a non-inheritible pipe.
+     */
+
+    CreatePipe(&Out.pipe, &h, &sa, 0);
+
+    /*
+     * Dupe the write side, make it inheritible, and close the original.
+     */
+
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Same as above, but for the error side.
+     */
+
+    CreatePipe(&Err.pipe, &h, &sa, 0);
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Base command line.
+     */
+
+    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
+
+    /*
+     * Append our option for testing
+     */
+
+    lstrcat(cmdline, option);
+
+    /*
+     * Filename to compile, which exists, but is nothing and empty.
+     */
+
+    lstrcat(cmdline, " .\\nul");
+
+    ok = CreateProcess(
+           NULL,           /* Module name. */
+           cmdline,        /* Command line. */
+           NULL,           /* Process handle not inheritable. */
+           NULL,           /* Thread handle not inheritable. */
+           TRUE,           /* yes, inherit handles. */
+           DETACHED_PROCESS, /* No console for you. */
+           NULL,           /* Use parent's environment block. */
+           NULL,           /* Use parent's starting directory. */
+           &si,            /* Pointer to STARTUPINFO structure. */
+           &pi);           /* Pointer to PROCESS_INFORMATION structure. */
+
+    if (!ok) {
+       DWORD err = GetLastError();
+       int chars = snprintf(msg, sizeof(msg) - 1,
+               "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
+               FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
+               (300-chars), 0);
+       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+       return 2;
+    }
+
+    /*
+     * Close our references to the write handles that have now been inherited.
+     */
+
+    CloseHandle(si.hStdOutput);
+    CloseHandle(si.hStdError);
+
+    WaitForInputIdle(pi.hProcess, 5000);
+    CloseHandle(pi.hThread);
+
+    /*
+     * Start the pipe reader threads.
+     */
+
+    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
+    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
+
+    /*
+     * Block waiting for the process to end.
+     */
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    CloseHandle(pi.hProcess);
+
+    /*
+     * Wait for our pipe to get done reading, should it be a little slow.
+     */
+
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
+    CloseHandle(pipeThreads[0]);
+    CloseHandle(pipeThreads[1]);
+
+    /*
+     * Look for the commandline warning code in both streams.
+     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
+     */
+
+    return !(strstr(Out.buffer, "D4002") != NULL
+             || strstr(Err.buffer, "D4002") != NULL
+             || strstr(Out.buffer, "D9002") != NULL
+             || strstr(Err.buffer, "D9002") != NULL
+             || strstr(Out.buffer, "D2021") != NULL
+             || strstr(Err.buffer, "D2021") != NULL);
+}
+\f
+int
+CheckForLinkerFeature(
+    const char *option)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    SECURITY_ATTRIBUTES sa;
+    DWORD threadID;
+    char msg[300];
+    BOOL ok;
+    HANDLE hProcess, h, pipeThreads[2];
+    char cmdline[100];
+
+    hProcess = GetCurrentProcess();
+
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO);
+    si.dwFlags   = STARTF_USESTDHANDLES;
+    si.hStdInput = INVALID_HANDLE_VALUE;
+
+    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = TRUE;
+
+    /*
+     * Create a non-inheritible pipe.
+     */
+
+    CreatePipe(&Out.pipe, &h, &sa, 0);
+
+    /*
+     * Dupe the write side, make it inheritible, and close the original.
+     */
+
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Same as above, but for the error side.
+     */
+
+    CreatePipe(&Err.pipe, &h, &sa, 0);
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Base command line.
+     */
+
+    lstrcpy(cmdline, "link.exe -nologo ");
+
+    /*
+     * Append our option for testing.
+     */
+
+    lstrcat(cmdline, option);
+
+    ok = CreateProcess(
+           NULL,           /* Module name. */
+           cmdline,        /* Command line. */
+           NULL,           /* Process handle not inheritable. */
+           NULL,           /* Thread handle not inheritable. */
+           TRUE,           /* yes, inherit handles. */
+           DETACHED_PROCESS, /* No console for you. */
+           NULL,           /* Use parent's environment block. */
+           NULL,           /* Use parent's starting directory. */
+           &si,            /* Pointer to STARTUPINFO structure. */
+           &pi);           /* Pointer to PROCESS_INFORMATION structure. */
+
+    if (!ok) {
+       DWORD err = GetLastError();
+       int chars = snprintf(msg, sizeof(msg) - 1,
+               "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
+               FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
+               (300-chars), 0);
+       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+       return 2;
+    }
+
+    /*
+     * Close our references to the write handles that have now been inherited.
+     */
+
+    CloseHandle(si.hStdOutput);
+    CloseHandle(si.hStdError);
+
+    WaitForInputIdle(pi.hProcess, 5000);
+    CloseHandle(pi.hThread);
+
+    /*
+     * Start the pipe reader threads.
+     */
+
+    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
+    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
+
+    /*
+     * Block waiting for the process to end.
+     */
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    CloseHandle(pi.hProcess);
+
+    /*
+     * Wait for our pipe to get done reading, should it be a little slow.
+     */
+
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
+    CloseHandle(pipeThreads[0]);
+    CloseHandle(pipeThreads[1]);
+
+    /*
+     * Look for the commandline warning code in the stderr stream.
+     */
+
+    return !(strstr(Out.buffer, "LNK1117") != NULL ||
+           strstr(Err.buffer, "LNK1117") != NULL ||
+           strstr(Out.buffer, "LNK4044") != NULL ||
+           strstr(Err.buffer, "LNK4044") != NULL);
+}
+\f
+DWORD WINAPI
+ReadFromPipe(
+    LPVOID args)
+{
+    pipeinfo *pi = (pipeinfo *) args;
+    char *lastBuf = pi->buffer;
+    DWORD dwRead;
+    BOOL ok;
+
+  again:
+    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
+       CloseHandle(pi->pipe);
+       return (DWORD)-1;
+    }
+    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
+    if (!ok || dwRead == 0) {
+       CloseHandle(pi->pipe);
+       return 0;
+    }
+    lastBuf += dwRead;
+    goto again;
+
+    return 0;  /* makes the compiler happy */
+}
+\f
+int
+IsIn(
+    const char *string,
+    const char *substring)
+{
+    return (strstr(string, substring) != NULL);
+}
+\f
+/*
+ * Find a specified #define by name.
+ *
+ * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
+ */
+
+int
+GrepForDefine(
+    const char *file,
+    const char *string)
+{
+    char s1[51], s2[51], s3[51];
+    FILE *f = fopen(file, "rt");
+
+    if (f == NULL) {
+       return 0;
+    }
+
+    do {
+       int r = fscanf(f, "%50s", s1);
+
+       if (r == 1 && !strcmp(s1, "#define")) {
+           /*
+            * Get next two words.
+            */
+
+           r = fscanf(f, "%50s %50s", s2, s3);
+           if (r != 2) {
+               continue;
+           }
+
+           /*
+            * Is the first word what we're looking for?
+            */
+
+           if (!strcmp(s2, string)) {
+               double d1;
+
+               fclose(f);
+
+               /*
+                * Add 1 past first double quote char. "8.5"
+                */
+
+               d1 = atof(s3 + 1);                /*    8.5  */
+               while (floor(d1) != d1) {
+                   d1 *= 10.0;
+               }
+               return ((int) d1);                /*    85   */
+           }
+       }
+    } while (!feof(f));
+
+    fclose(f);
+    return 0;
+}
+\f
+/*
+ * GetVersionFromFile --
+ *     Looks for a match string in a file and then returns the version
+ *     following the match where a version is anything acceptable to
+ *     package provide or package ifneeded.
+ */
+
+const char *
+GetVersionFromFile(
+    const char *filename,
+    const char *match)
+{
+    size_t cbBuffer = 100;
+    static char szBuffer[100];
+    char *szResult = NULL;
+    FILE *fp = fopen(filename, "rt");
+
+    if (fp != NULL) {
+       /*
+        * Read data until we see our match string.
+        */
+
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           LPSTR p, q;
+
+           p = strstr(szBuffer, match);
+           if (p != NULL) {
+               /*
+                * Skip to first digit.
+                */
+
+               while (*p && !isdigit(*p)) {
+                   ++p;
+               }
+
+               /*
+                * Find ending whitespace.
+                */
+
+               q = p;
+               while (*q && (isalnum(*q) || *q == '.')) {
+                   ++q;
+               }
+
+               memcpy(szBuffer, p, q - p);
+               szBuffer[q-p] = 0;
+               szResult = szBuffer;
+               break;
+           }
+       }
+       fclose(fp);
+    }
+    return szResult;
+}
+\f
+/*
+ * List helpers for the SubstituteFile function
+ */
+
+typedef struct list_item_t {
+    struct list_item_t *nextPtr;
+    char * key;
+    char * value;
+} list_item_t;
+
+/* insert a list item into the list (list may be null) */
+static list_item_t *
+list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
+{
+    list_item_t *itemPtr = malloc(sizeof(list_item_t));
+    if (itemPtr) {
+       itemPtr->key = strdup(key);
+       itemPtr->value = strdup(value);
+       itemPtr->nextPtr = NULL;
+
+       while(*listPtrPtr) {
+           listPtrPtr = &(*listPtrPtr)->nextPtr;
+       }
+       *listPtrPtr = itemPtr;
+    }
+    return itemPtr;
+}
+
+static void
+list_free(list_item_t **listPtrPtr)
+{
+    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
+    while (listPtr) {
+       tmpPtr = listPtr;
+       listPtr = listPtr->nextPtr;
+       free(tmpPtr->key);
+       free(tmpPtr->value);
+       free(tmpPtr);
+    }
+}
+\f
+/*
+ * SubstituteFile --
+ *     As windows doesn't provide anything useful like sed and it's unreliable
+ *     to use the tclsh you are building against (consider x-platform builds -
+ *     eg compiling AMD64 target from IX86) we provide a simple substitution
+ *     option here to handle autoconf style substitutions.
+ *     The substitution file is whitespace and line delimited. The file should
+ *     consist of lines matching the regular expression:
+ *       \s*\S+\s+\S*$
+ *
+ *     Usage is something like:
+ *       nmakehlp -S << $** > $@
+ *        @PACKAGE_NAME@ $(PACKAGE_NAME)
+ *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
+ *        <<
+ */
+
+int
+SubstituteFile(
+    const char *substitutions,
+    const char *filename)
+{
+    size_t cbBuffer = 1024;
+    static char szBuffer[1024], szCopy[1024];
+    char *szResult = NULL;
+    list_item_t *substPtr = NULL;
+    FILE *fp, *sp;
+
+    fp = fopen(filename, "rt");
+    if (fp != NULL) {
+
+       /*
+        * Build a list of substutitions from the first filename
+        */
+
+       sp = fopen(substitutions, "rt");
+       if (sp != NULL) {
+           while (fgets(szBuffer, cbBuffer, sp) != NULL) {
+               char *ks, *ke, *vs, *ve;
+               ks = szBuffer;
+               while (ks && *ks && isspace(*ks)) ++ks;
+               ke = ks;
+               while (ke && *ke && !isspace(*ke)) ++ke;
+               vs = ke;
+               while (vs && *vs && isspace(*vs)) ++vs;
+               ve = vs;
+               while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
+               *ke = 0, *ve = 0;
+               list_insert(&substPtr, ks, vs);
+           }
+           fclose(sp);
+       }
+
+       /* debug: dump the list */
+#ifdef _DEBUG
+       {
+           int n = 0;
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
+               fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
+           }
+       }
+#endif
+       
+       /*
+        * Run the substitutions over each line of the input
+        */
+       
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr) {
+               char *m = strstr(szBuffer, p->key);
+               if (m) {
+                   char *cp, *op, *sp;
+                   cp = szCopy;
+                   op = szBuffer;
+                   while (op != m) *cp++ = *op++;
+                   sp = p->value;
+                   while (sp && *sp) *cp++ = *sp++;
+                   op += strlen(p->key);
+                   while (*op) *cp++ = *op++;
+                   *cp = 0;
+                   memcpy(szBuffer, szCopy, sizeof(szCopy));
+               }
+           }
+           printf(szBuffer);
+       }
+       
+       list_free(&substPtr);
+    }
+    fclose(fp);
+    return 0;
+}
+\f
+/*
+ * QualifyPath --
+ *
+ *     This composes the current working directory with a provided path
+ *     and returns the fully qualified and normalized path.
+ *     Mostly needed to setup paths for testing.
+ */
+
+int
+QualifyPath(
+    const char *szPath)
+{
+    char szCwd[MAX_PATH + 1];
+    char szTmp[MAX_PATH + 1];
+    char *p;
+    GetCurrentDirectory(MAX_PATH, szCwd);
+    while ((p = strchr(szPath, '/')) && *p)
+       *p = '\\';
+    PathCombine(szTmp, szCwd, szPath);
+    PathCanonicalize(szCwd, szTmp);
+    printf("%s\n", szCwd);
+    return 0;
+}
+
+/*
+ * Local variables:
+ *   mode: c
+ *   c-basic-offset: 4
+ *   fill-column: 78
+ *   indent-tabs-mode: t
+ *   tab-width: 8
+ * End:
+ */
diff --git a/8.x/thread/win/vc/nmakehlp.exe b/8.x/thread/win/vc/nmakehlp.exe
new file mode 100644 (file)
index 0000000..54ae9ed
Binary files /dev/null and b/8.x/thread/win/vc/nmakehlp.exe differ
diff --git a/8.x/thread/win/vc/nmakehlp.obj b/8.x/thread/win/vc/nmakehlp.obj
new file mode 100644 (file)
index 0000000..6ac4648
Binary files /dev/null and b/8.x/thread/win/vc/nmakehlp.obj differ
diff --git a/8.x/thread/win/vc/pkg.vc b/8.x/thread/win/vc/pkg.vc
new file mode 100644 (file)
index 0000000..9dbf803
--- /dev/null
@@ -0,0 +1,6 @@
+# remember to change configure.in as well when these change
+# (then re-autoconf)
+
+PACKAGE_MAJOR  = 2
+PACKAGE_MINOR  = 6
+PACKAGE_VERSION        = "2.6.5"
diff --git a/8.x/thread/win/vc/rules.vc b/8.x/thread/win/vc/rules.vc
new file mode 100644 (file)
index 0000000..b94575a
--- /dev/null
@@ -0,0 +1,622 @@
+#------------------------------------------------------------------------------
+# rules.vc --
+#
+#      Microsoft Visual C++ makefile include for decoding the commandline
+#      macros.  This file does not need editing to build Tcl.
+#
+#      This version is modified from the Tcl source version to support
+#      building extensions using nmake.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# Copyright (c) 2001-2002 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+#
+#------------------------------------------------------------------------------
+# RCS: @(#) $Id: rules.vc,v 1.3 2009/05/04 22:46:17 patthoyts Exp $
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+cc32           = $(CC)   # built-in default.
+link32         = link
+lib32          = lib
+rc32           = $(RC)   # built-in default.
+
+!ifndef INSTALLDIR
+### Assume the normal default.
+_INSTALLDIR    = C:\Program Files\Tcl
+!else
+### Fix the path separators.
+_INSTALLDIR    = $(INSTALLDIR:/=\)
+!endif
+
+!ifndef MACHINE
+!if "$(CPU)" == "" || "$(CPU)" == "i386"
+MACHINE         = IX86
+!else
+MACHINE         = $(CPU)
+!endif
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING   = \"cp1252\"
+!endif
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+!if "$(OS)" == "Windows_NT"
+RMDIR  = rmdir /S /Q
+ERRNULL  = 2>NUL
+!if ![ver | find "4.0" > nul]
+CPY    = echo y | xcopy /i >NUL
+COPY   = copy >NUL
+!else
+CPY    = xcopy /i /y >NUL
+COPY   = copy /y >NUL
+!endif
+!else # "$(OS)" != "Windows_NT"
+CPY    = xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
+COPY   = copy >_JUNK.OUT # On Win98 NUL does not work here.
+RMDIR  = deltree /Y
+NULL    = \NUL # Used in testing directory existence
+ERRNULL = >NUL # Win9x shell cannot redirect stderr
+!endif
+MKDIR   = mkdir
+
+!message ===============================================================================
+
+#----------------------------------------------------------
+# build the helper app we need to overcome nmake's limiting
+# environment.
+#----------------------------------------------------------
+
+!if !exist(nmakehlp.exe)
+!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
+!endif
+!endif
+
+#----------------------------------------------------------
+# Test for compiler features
+#----------------------------------------------------------
+
+### test for optimizations
+!if [nmakehlp -c -Ot]
+!message *** Compiler has 'Optimizations'
+OPTIMIZING     = 1
+!else
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING     = 0
+!endif
+
+OPTIMIZATIONS  =
+
+!if [nmakehlp -c -Ot]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
+!endif
+
+!if [nmakehlp -c -Oi]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
+!endif
+
+!if [nmakehlp -c -Op]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
+!endif
+
+!if [nmakehlp -c -fp:strict]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
+!endif
+
+!if [nmakehlp -c -Gs]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
+!endif
+
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
+!endif
+
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
+!endif
+
+DEBUGFLAGS     =
+
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
+!endif
+
+COMPILERFLAGS  =-W3
+
+# In v13 -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+!if ![nmakehlp -c -GL]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
+!endif
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+COMPILERFLAGS  = $(COMPILERFLAGSS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+!if "$(MACHINE)" == "IA64"
+### test for Itanium errata
+!if [nmakehlp -c -QIA64_Bx]
+!message *** Compiler has 'B-stepping errata workarounds'
+COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
+!else
+!message *** Compiler does not have 'B-stepping errata workarounds'
+!endif
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for -align:4096, when align:512 will do.
+!if [nmakehlp -l -opt:nowin98]
+!message *** Linker has 'Win98 alignment problem'
+ALIGN98_HACK   = 1
+!else
+!message *** Linker does not have 'Win98 alignment problem'
+ALIGN98_HACK   = 0
+!endif
+!else
+ALIGN98_HACK   = 0
+!endif
+
+LINKERFLAGS     =
+
+!if [nmakehlp -l -ltcg]
+LINKERFLAGS     =-ltcg
+!endif
+
+#----------------------------------------------------------
+# MSVC8 (ships with Visual Studio 2005) generates a manifest
+# file that we should link into the binaries. This is how.
+#----------------------------------------------------------
+
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
+!include vercl.i
+!if $(VCVERSION) >= 1500
+VCVER=9
+!elseif $(VCVERSION) >= 1400
+VCVER=8
+!elseif $(VCVERSION) >= 1300
+VCVER=7
+!elseif $(VCVERSION) >= 1200
+VCVER=6
+!endif
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+#----------------------------------------------------------
+# Decode the options requested.
+#----------------------------------------------------------
+
+!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
+STATIC_BUILD   = 0
+TCL_THREADS    = 1
+DEBUG          = 0
+PROFILE                = 0
+MSVCRT         = 0
+LOIMPACT       = 0
+TCL_USE_STATIC_PACKAGES        = 0
+USE_THREAD_ALLOC = 1
+USE_THREAD_STORAGE = 1
+UNCHECKED       = 0
+!else
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD   = 1
+!else
+STATIC_BUILD   = 0
+!endif
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT         = 1
+!else
+MSVCRT         = 0
+!endif
+!if [nmakehlp -f $(OPTS) "staticpkg"]
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES        = 1
+!else
+TCL_USE_STATIC_PACKAGES        = 0
+!endif
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS    = 0
+!else
+TCL_THREADS     = 1
+!endif
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG          = 1
+!else
+DEBUG          = 0
+!endif
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE                = 1
+!else
+PROFILE                = 0
+!endif
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Doing loimpact
+LOIMPACT       = 1
+!else
+LOIMPACT       = 0
+!endif
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!else
+USE_THREAD_ALLOC = 0
+!endif
+!if [nmakehlp -f $(OPTS) "thrdstorage"]
+!message *** Doing thrdstorage
+USE_THREAD_STORAGE = 1
+!else
+USE_THREAD_STORAGE = 0
+!endif
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+!endif
+
+
+!if !$(STATIC_BUILD)
+# Make sure we don't build overly fat DLLs.
+MSVCRT         = 1
+# We shouldn't statically put the extensions inside the shell when dynamic.
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+
+#----------------------------------------------------------
+# Figure-out how to name our intermediate and output directories.
+# We wouldn't want different builds to use the same .obj files
+# by accident.
+#----------------------------------------------------------
+
+#----------------------------------------
+# Naming convention:
+#   t = full thread support.
+#   s = static library (as opposed to an
+#      import library)
+#   g = linked to the debug enabled C
+#      run-time.
+#   x = special static build when it
+#      links to the dynamic C run-time.
+#----------------------------------------
+SUFX       = sgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX       = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX       = $(SUFX:s=)
+EXT        = dll
+!if $(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX       = $(SUFX:x=)
+!endif
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT        = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX       = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX       = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR            = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR            = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR            = $(TMP_DIR)
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Decode the statistics requested.
+#----------------------------------------------------------
+
+!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
+TCL_MEM_DEBUG      = 0
+TCL_COMPILE_DEBUG   = 0
+!else
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG      = 1
+!else
+TCL_MEM_DEBUG      = 0
+!endif
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG   = 1
+!else
+TCL_COMPILE_DEBUG   = 0
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Decode the checks requested.
+#----------------------------------------------------------
+
+!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
+TCL_NO_DEPRECATED          = 0
+WARNINGS                   = -W3
+!else
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED          = 1
+!else
+TCL_NO_DEPRECATED          = 0
+!endif
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS                   = -W4
+!if [nmakehlp -l -warn:3]
+LINKERFLAGS                = $(LINKERFLAGS) -warn:3
+!endif
+!else
+WARNINGS                   = -W3
+!endif
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS                   = $(WARNINGS) -Wp64
+!endif
+!endif
+
+#----------------------------------------------------------
+# Set our defines now armed with our options.
+#----------------------------------------------------------
+
+OPTDEFINES     = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES     = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!if $(USE_THREAD_STORAGE)
+OPTDEFINES     = $(OPTDEFINES) -DUSE_THREAD_STORAGE=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES     = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_DEBUG
+!elseif $(OPTIMIZING)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!if $(PROFILE)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+
+
+#----------------------------------------------------------
+# Get common info used when building extensions.
+#----------------------------------------------------------
+
+!if "$(PROJECT)" != "tcl"
+
+# If INSTALLDIR set to tcl root dir then reset to the lib dir.
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+!if !defined(TCLDIR)
+!if exist("$(_INSTALLDIR)\..\include\tcl.h")
+TCLINSTALL     = 1
+_TCLDIR                = $(_INSTALLDIR)\..
+_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h
+TCLDIR          = $(_INSTALLDIR)\..
+!else
+MSG=^
+Failed to find tcl.h.  Set the TCLDIR macro.
+!error $(MSG)
+!endif
+!else
+_TCLDIR        = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h")
+TCLINSTALL     = 1
+_TCL_H          = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h")
+TCLINSTALL     = 0
+_TCL_H          = $(_TCLDIR)\generic\tcl.h
+!else
+MSG =^
+Failed to find tcl.h.  The TCLDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+
+!if [echo REM = This file is generated from rules.vc > version.vc]
+!endif
+!if exist("$(_TCL_H)")
+!if [echo TCL_DOTVERSION = \>> version.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_VERSION >> version.vc]
+!endif
+!endif
+!include version.vc
+TCL_VERSION    = $(TCL_DOTVERSION:.=)
+
+!if $(TCLINSTALL)
+TCLSH          = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TCLSTUBLIB     = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB      = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
+TCL_LIBRARY    = $(_TCLDIR)\lib
+TCL_INCLUDES    = -I"$(_TCLDIR)\include"
+!else
+TCLSH          = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH          = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TCLSTUBLIB     = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
+TCL_LIBRARY    = $(_TCLDIR)\library
+TCL_INCLUDES   = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+!endif
+
+!endif
+
+#----------------------------------------------------------
+# Optionally check for Tk info for building extensions.
+#----------------------------------------------------------
+
+!ifdef PROJECT_REQUIRES_TK
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+
+!if !defined(TKDIR)
+!if exist("$(_INSTALLDIR)\..\include\tk.h")
+TKINSTALL      = 1
+_TKDIR         = $(_INSTALLDIR)\..
+_TK_H          = $(_TKDIR)\include\tk.h
+TKDIR          = $(_TKDIR)
+!elseif exist("$(_TCLDIR)\include\tk.h")
+TKINSTALL      = 1
+_TKDIR         = $(_TCLDIR)
+_TK_H          = $(_TKDIR)\include\tk.h
+TKDIR          = $(_TKDIR)
+!endif
+!else
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL      = 1
+_TK_H          = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL      = 0
+_TK_H          = $(_TKDIR)\generic\tk.h
+!else
+MSG =^
+Failed to find tk.h. The TKDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+
+!if defined(TKDIR)
+TK_DOTVERSION = 8.4
+!if exist("$(_TK_H)")
+!if [echo TK_DOTVERSION = \>> version.vc] \
+   && [nmakehlp -V "$(_TK_H)" TK_VERSION >> version.vc]
+!endif
+!endif
+!include version.vc
+TK_VERSION = $(TK_DOTVERSION:.=)
+
+!if $(TKINSTALL)
+WISH           = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
+!if !exist($(WISH)) && $(TCL_THREADS)
+WISH           = "$(_TKDIR)\bin\wish$(TK_VERSION)t$(SUFX).exe"
+!endif
+TKSTUBLIB      = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
+TKIMPLIB       = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
+TK_INCLUDES     = -I"$(_TKDIR)\include"
+TK_LIBRARY     = $(_TKDIR)\lib
+!else
+WISH           = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(WISH)) && $(TCL_THREADS)
+WISH           = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TKSTUBLIB      = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
+TKIMPLIB       = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
+TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+TK_LIBRARY     = $(_TKDIR)\library
+!endif
+
+!endif
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Setup the fully qualified OUT_DIR path as OUT_DIR_PATH
+#----------------------------------------------------------
+!if [echo OUT_DIR_PATH = \>> version.vc] \
+    && [nmakehlp -Q "$(OUT_DIR)" >> version.vc]
+!endif
+!include version.vc
+
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Optional defines are '$(OPTDEFINES)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
+!message *** Link options '$(LINKERFLAGS)'
+
+!endif
diff --git a/8.x/thread/win/vc/thread_win.dsp b/8.x/thread/win/vc/thread_win.dsp
new file mode 100644 (file)
index 0000000..fe8d51e
--- /dev/null
@@ -0,0 +1,269 @@
+# Microsoft Developer Studio Project File - Name="thread" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) External Target" 0x0106\r
+\r
+CFG=thread - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "thread_win.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "thread_win.mak" CFG="thread - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "thread - Win32 Release" (based on "Win32 (x86) External Target")\r
+!MESSAGE "thread - Win32 Debug" (based on "Win32 (x86) External Target")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+\r
+!IF  "$(CFG)" == "thread - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Cmd_Line "NMAKE /f thread.mak"\r
+# PROP BASE Rebuild_Opt "/a"\r
+# PROP BASE Target_File "thread.exe"\r
+# PROP BASE Bsc_Name "thread.bsc"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Cmd_Line "nmake -nologo -f makefile.vc TCLDIR=E:\tcl MSVCDIR=IDE"\r
+# PROP Rebuild_Opt "-a"\r
+# PROP Target_File "Release\thread26.dll"\r
+# PROP Bsc_Name ""\r
+# PROP Target_Dir ""\r
+\r
+!ELSEIF  "$(CFG)" == "thread - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Cmd_Line "NMAKE /f thread.mak"\r
+# PROP BASE Rebuild_Opt "/a"\r
+# PROP BASE Target_File "thread.exe"\r
+# PROP BASE Bsc_Name "thread.bsc"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols TCLDIR=E:\tcl MSVCDIR=IDE"\r
+# PROP Rebuild_Opt "-a"\r
+# PROP Target_File "Debug\thread26d.dll"\r
+# PROP Bsc_Name ""\r
+# PROP Target_Dir ""\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "thread - Win32 Release"\r
+# Name "thread - Win32 Debug"\r
+\r
+!IF  "$(CFG)" == "thread - Win32 Release"\r
+\r
+!ELSEIF  "$(CFG)" == "thread - Win32 Debug"\r
+\r
+!ENDIF \r
+\r
+# Begin Group "generic"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\aolstub.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\psGdbm.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\psGdbm.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\tclThread.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\tclXkeylist.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\tclXkeylist.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadCmd.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadPoolCmd.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadSpCmd.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadSvCmd.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadSvCmd.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadSvKeylistCmd.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadSvKeylistCmd.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadSvListCmd.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\generic\threadSvListCmd.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "doc"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Group "html"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\html\thread.html\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\html\tpool.html\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\html\tsv.html\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\html\ttrace.html\r
+# End Source File\r
+# End Group\r
+# Begin Group "man"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\man\thread.n\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\man\tpool.n\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\man\tsv.n\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\man\ttrace.n\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\format.tcl\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\man.macros\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\thread.man\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\tpool.man\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\tsv.man\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\doc\ttrace.man\r
+# End Source File\r
+# End Group\r
+# Begin Group "win"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Group "vc"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\makefile.vc\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\nmakehlp.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pkg.vc\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\README.txt\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\rules.vc\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=..\README.txt\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\thread.rc\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\threadWin.c\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=..\..\ChangeLog\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\license.terms\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\README\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/8.x/thread/win/vc/thread_win.dsw b/8.x/thread/win/vc/thread_win.dsw
new file mode 100644 (file)
index 0000000..5599cd6
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "thread"=.\thread.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/8.x/vqtcl/ChangeLog b/8.x/vqtcl/ChangeLog
new file mode 100644 (file)
index 0000000..00700f4
--- /dev/null
@@ -0,0 +1,39 @@
+2009-02-20 patthoyts
+  * merge: Merged the following changes from the old repository.
+      - Fixed mkcl for recent change to all branches that propagates errors
+       from matchin directory functions which was breaking tclkit's based
+       on vlerq vfs.
+      - Updated for 8.6 changes. interp->errorLine is now replaced by
+       Tcl_GetErrorLine and the stubs variables are now const. Use
+       -ltclstubs for vqtcl.
+      - Updated the nmake build files for MSCV9 and added a target to run
+       the test suite. Fixed three tests that had unix expectations to
+       pass with windows as well.
+      - Applied patch from kostix to solve problems opening tclkit when
+       the directory has non-ascii characters in the path. Tcl provides a
+       utf-8 string and we need to convert it to the external encoding.
+      - Support release build with symbols under msvc
+      - For 8.6 - do not define USE_TCL_STUBS for static builds
+      - add code signing support for Win32, add stdint.h for newer mingw
+      - stdint.h required. Patched to permit operation on authenticode signed binaries
+2009-02-03  jcw
+  * all: this code was copied from http://www.equi4.com/pub/vq/vqtcl.tgz
+2007-01-26  jcw
+  * vlerq.c: updated to get rid of stdint.h header
+2007-01-25  jcw
+  * all: vlerq update
+2007-01-16  jcw
+  * all: vlerq update
+2007-01-02  jcw
+  * all: vlerq update
+2006-12-28  jcw
+  * all: vlerq and tclconfig updates
+2006-12-12  jcw
+  * all: vlerq update
+2006-12-06  jcw
+  * Added ratcl package and "view" operator, many tweaks, bump to 4.1
+  * m2mvfs.tcl: updated to 1.8 for sdx wrapping of starpacks
+2006-11-15  jcw
+  * all: Initial 4.0 release
+2006-11-05  jcw
+  * Sources brought under darcs revision control
diff --git a/8.x/vqtcl/Makefile.in b/8.x/vqtcl/Makefile.in
new file mode 100644 (file)
index 0000000..ef29880
--- /dev/null
@@ -0,0 +1,434 @@
+# Makefile.in --
+#
+#      This file is a Makefile for Vlerq TEA Extension.  If it has the name
+#      "Makefile.in" then it is a template for a Makefile;  to generate the
+#      actual Makefile, run "./configure", which is a configuration script
+#      generated by the "autoconf" program (constructs like "@foo@" will get
+#      replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#VLERQ_NEW_VAR = @VLERQ_NEW_VAR@
+
+#========================================================================
+# Nothing of the variables below this line should need to be changed.
+# Please check the TARGETS section below to make sure the make targets
+# are correct.
+#========================================================================
+
+#========================================================================
+# The names of the source files is defined in the configure script.
+# The object files are used for linking into the final library.
+# This will be used when a dist target is added to the Makefile.
+# It is not important to specify the directory, as long as it is the
+# $(srcdir) or in the generic, win or unix subdirectory.
+#========================================================================
+
+PKG_SOURCES    = @PKG_SOURCES@
+PKG_OBJECTS    = @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+#========================================================================
+# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
+# this package that need to be installed, if any.
+#========================================================================
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+
+#========================================================================
+# This is a list of public header files to be installed, if any.
+#========================================================================
+
+PKG_HEADERS    = @PKG_HEADERS@
+
+#========================================================================
+# "PKG_LIB_FILE" refers to the library (dynamic or static as per
+# configuration options) composed of the named objects.
+#========================================================================
+
+PKG_LIB_FILE   = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES   = $(PKG_LIB_FILE)
+BINARIES       = $(lib_BINARIES)
+
+SHELL          = @SHELL@
+
+srcdir         = @srcdir@
+prefix         = @prefix@
+exec_prefix    = @exec_prefix@
+
+bindir         = @bindir@
+libdir         = @libdir@
+datadir                = @datadir@
+mandir         = @mandir@
+includedir     = @includedir@
+
+DESTDIR                =
+
+PKG_DIR                = $(PACKAGE_NAME)$(PACKAGE_VERSION)
+pkgdatadir     = $(datadir)/$(PKG_DIR)
+pkglibdir      = $(libdir)/$(PKG_DIR)
+pkgincludedir  = $(includedir)/$(PKG_DIR)
+
+top_builddir   = .
+
+INSTALL                = @INSTALL@
+INSTALL_PROGRAM        = @INSTALL_PROGRAM@
+INSTALL_DATA   = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+PACKAGE_NAME   = @PACKAGE_NAME@
+PACKAGE_VERSION        = @PACKAGE_VERSION@
+CC             = @CC@
+CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+CLEANFILES     = @CLEANFILES@
+EXEEXT         = @EXEEXT@
+LDFLAGS_DEFAULT        = @LDFLAGS_DEFAULT@
+MAKE_LIB       = @MAKE_LIB@
+MAKE_SHARED_LIB        = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB        = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB  = @MAKE_STUB_LIB@
+OBJEXT         = @OBJEXT@
+RANLIB         = @RANLIB@
+RANLIB_STUB    = @RANLIB_STUB@
+SHLIB_CFLAGS   = @SHLIB_CFLAGS@
+SHLIB_LD       = @SHLIB_LD@
+SHLIB_LD_FLAGS = @SHLIB_LD_FLAGS@
+SHLIB_LD_LIBS  = @SHLIB_LD_LIBS@
+STLIB_LD       = @STLIB_LD@
+TCL_DEFS       = @TCL_DEFS@
+TCL_BIN_DIR    = @TCL_BIN_DIR@
+TCL_SRC_DIR    = @TCL_SRC_DIR@
+# This is necessary for packages that use private Tcl headers
+#TCL_TOP_DIR_NATIVE    = @TCL_TOP_DIR_NATIVE@
+# Not used, but retained for reference of what libs Tcl required
+TCL_LIBS       = @TCL_LIBS@
+
+#========================================================================
+# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
+# package without installing.  The other environment variables allow us
+# to test against an uninstalled Tcl.  Add special env vars that you
+# require for testing here (like TCLX_LIBRARY).
+#========================================================================
+
+EXTRA_PATH     = $(top_builddir):$(TCL_BIN_DIR)
+TCLSH_ENV      = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
+                 @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+                 PATH="$(EXTRA_PATH):$(PATH)" \
+                 TCLLIBPATH="$(top_builddir)"
+
+TCLSH_PROG     = @TCLSH_PROG@
+TCLSH          = $(TCLSH_ENV) $(TCLSH_PROG)
+
+SHARED_BUILD   = @SHARED_BUILD@
+
+INCLUDES       = @PKG_INCLUDES@ @TCL_INCLUDES@
+
+PKG_CFLAGS     = @PKG_CFLAGS@
+
+# TCL_DEFS is not strictly need here, but if you remove it, then you
+# must make sure that configure.in checks for the necessary components
+# that your library may use.  TCL_DEFS can actually be a problem if
+# you do not compile with a similar machine setup as the Tcl core was
+# compiled with.
+#DEFS          = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
+DEFS           = @DEFS@ $(PKG_CFLAGS)
+
+CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
+
+CPPFLAGS       = @CPPFLAGS@
+LIBS           = @PKG_LIBS@ @LIBS@
+AR             = @AR@
+CFLAGS         = @CFLAGS@
+COMPILE                = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+#========================================================================
+# Start of user-definable TARGETS section
+#========================================================================
+
+#========================================================================
+# TEA TARGETS.  Please note that the "libraries:" target refers to platform
+# independent files, and the "binaries:" target inclues executable programs and
+# platform-dependent libraries.  Modify these targets so that they install
+# the various pieces of your package.  The make and install rules
+# for the BINARIES that you specified above have already been done.
+#========================================================================
+
+all: binaries libraries doc
+
+#========================================================================
+# The binaries target builds executable programs, Windows .dll's, unix
+# shared/static libraries, and any other platform-dependent files.
+# The list of targets to build for "binaries:" is specified at the top
+# of the Makefile, in the "BINARIES" variable.
+#========================================================================
+
+binaries: $(BINARIES) pkgIndex.tcl
+
+libraries:
+
+doc: vlerq.html vlerq.n ratcl.html ratcl.n
+
+install: all install-binaries install-libraries install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+
+#========================================================================
+# This rule installs platform-independent files, such as header files.
+# The list=...; for p in $$list handles the empty list case x-platform.
+#========================================================================
+
+install-libraries: libraries
+       @mkdir -p $(DESTDIR)$(includedir)
+       @echo "Installing header files in $(DESTDIR)$(includedir)"
+       @list='$(PKG_HEADERS)'; for i in $$list; do \
+           echo "Installing $(srcdir)/$$i" ; \
+           $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+       done;
+
+#========================================================================
+# Install documentation.  Unix manpages should go in the $(mandir)
+# directory.
+#========================================================================
+
+install-doc: doc
+       @mkdir -p $(DESTDIR)$(mandir)/mann
+       @echo "Installing documentation in $(DESTDIR)$(mandir)"
+       @list='$(srcdir)/doc/*.n'; for i in $$list; do \
+           echo "Installing $$i"; \
+           rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
+           $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
+       done
+
+test: binaries libraries
+       $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+shell: binaries libraries
+       @$(TCLSH) $(SCRIPT)
+
+gdb:
+       $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+#========================================================================
+# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
+# mentioned above.  That will ensure that this target is built when you
+# run "make binaries".
+#
+# The $(PKG_OBJECTS) objects are created and linked into the final
+# library.  In most cases these object files will correspond to the
+# source files above.
+#========================================================================
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+       -rm -f $(PKG_LIB_FILE)
+       ${MAKE_LIB}
+       $(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+       -rm -f $(PKG_STUB_LIB_FILE)
+       ${MAKE_STUB_LIB}
+       $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#========================================================================
+# We need to enumerate the list of .c to .o lines here.
+#
+# In the following lines, $(srcdir) refers to the toplevel directory
+# containing your extension.  If your sources are in a subdirectory,
+# you will have to modify the paths to reflect this:
+#
+# vlerq.$(OBJEXT): $(srcdir)/generic/vlerq.c
+#      $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/vlerq.c` -o $@
+#
+# Setting the VPATH variable to a list of paths will cause the makefile
+# to look into these paths when resolving .c to .obj dependencies.
+# As necessary, add $(srcdir):$(srcdir)/compat:....
+#========================================================================
+
+VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/doc
+
+.c.@OBJEXT@:
+       $(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#========================================================================
+# Create the pkgIndex.tcl file.
+# It is usually easiest to let Tcl do this for you with pkg_mkIndex, but
+# you may find that you need to customize the package.  If so, either
+# modify the -hand version, or create a pkgIndex.tcl.in file and have
+# the configure script output the pkgIndex.tcl by editing configure.in.
+#========================================================================
+
+pkgIndex.tcl-auto:
+       ( echo pkg_mkIndex . $(PKG_LIB_FILE) \; exit; ) | $(TCLSH)
+
+pkgIndex.tcl-hand:
+       (\
+       echo "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
+           [list load [file join \$$dir $(PKG_LIB_FILE)]]";\
+       ) > pkgIndex.tcl
+
+#========================================================================
+# Distribution creation
+# You may need to tweak this target to make it work correctly.
+#========================================================================
+
+#COMPRESS      = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS       = gnutar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT      = /tmp/dist
+DIST_DIR       = $(DIST_ROOT)/$(PKG_DIR)
+
+dist-clean:
+       rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
+
+dist: dist-clean doc
+       mkdir -p $(DIST_DIR)
+       cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
+               $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
+               $(DIST_DIR)/
+       chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
+       chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
+
+       mkdir $(DIST_DIR)/tclconfig
+       cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
+               $(DIST_DIR)/tclconfig/
+       chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
+       chmod +x $(DIST_DIR)/tclconfig/install-sh
+
+       list='data demos doc generic library mac tests unix win'; \
+       for p in $$list; do \
+           if test -d $(srcdir)/$$p ; then \
+               mkdir $(DIST_DIR)/$$p; \
+               cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
+           fi; \
+       done
+
+       (cd $(DIST_ROOT); $(COMPRESS);)
+
+#========================================================================
+# End of user-definable section
+#========================================================================
+
+#========================================================================
+# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
+# variable in configure.in
+#========================================================================
+
+clean:  
+       -test -z "$(BINARIES)" || rm -f $(BINARIES)
+       -rm -f *.$(OBJEXT) core *.core
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+       -rm -f *.tab.c
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log config.status
+
+#========================================================================
+# Install binary object libraries.  On Windows this includes both .dll and
+# .lib files.  Because the .lib files are not explicitly listed anywhere,
+# we need to deduce their existence from the .dll file of the same name.
+# Library files go into the lib directory.
+# In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh shell)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-lib-binaries:
+       @mkdir -p $(DESTDIR)$(pkglibdir)
+       @list='$(lib_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+           stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
+           if test "x$$stub" = "xstub"; then \
+               echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
+           else \
+               echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
+               $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
+           fi; \
+           ext=`echo $$p|sed -e "s/.*\.//"`; \
+           if test "x$$ext" = "xdll"; then \
+               lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+               if test -f $$lib; then \
+                   echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
+                   $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+               fi; \
+           fi; \
+         fi; \
+       done
+       @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         if test -f $(srcdir)/$$p; then \
+           destp=`basename $$p`; \
+           echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
+           $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
+         fi; \
+       done
+       echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
+       $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); 
+
+#========================================================================
+# Install binary executables (e.g. .exe files and dependent .dll files)
+# This is for files that must go in the bin directory (located next to
+# wish and tclsh), like dependent .dll files on Windows.
+#
+# You should not have to modify this target, except to define bin_BINARIES
+# above if necessary.
+#========================================================================
+
+install-bin-binaries:
+       @mkdir -p $(DESTDIR)$(bindir)
+       @list='$(bin_BINARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
+           $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+         fi; \
+       done
+
+.SUFFIXES: .c .$(OBJEXT)
+.SUFFIXES: .man .html .n
+
+.man.html:
+       dtplite -o "$@" html "`@CYGPATH@ $<`"
+       mv "$@" doc
+
+.man.n:
+       dtplite -o "$@" nroff "`@CYGPATH@ $<`"
+       mv "$@" doc
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+       list='$(lib_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+         p=`basename $$p`; \
+         rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+       done
+       list='$(bin_BINARIES)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/$$p; \
+       done
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/8.x/vqtcl/README b/8.x/vqtcl/README
new file mode 100644 (file)
index 0000000..26c7cb8
--- /dev/null
@@ -0,0 +1,53 @@
+This is Vlerq, a Tcl extension for data manipulation and storage.
+
+This package is released as open source under the same license as Tcl,
+see ./license.terms and http://www.tcl.tk/software/tcltk/license.html
+
+UNIX BUILD
+==========
+
+Building under most UNIX systems is easy, just run the configure script
+and then run make. For more information about the build process, see the
+tcl/unix/README file in the Tcl src dist. The following will configure,
+test, build, and install the vlerq extension in the /opt/tcl directory.
+
+       $ ./configure --prefix=/opt/tcl --exec-prefix=/opt/tcl
+       $ make
+       $ make test
+       $ make install
+
+WINDOWS BUILD
+=============
+
+The recommended method to build extensions under windows is to use the Msys
++ Mingw build process. This provides a Unix-style build while generating
+native Windows binaries. Using the Msys + Mingw build tools means that you
+can use the same configure script as per the Unix build to create a
+Makefile. See the tcl/win/README file for the URL of the Msys + Mingw
+download.
+
+If you have VC++ then you may wish to use the files in the win subdirectory
+and build the extension using just VC++. These files have been designed to
+be as generic as possible but will require some additional maintenance by
+the project developer to synchronise with the TEA configure.in and
+Makefile.in files. Instructions for using the VC++ makefile are written in
+the first part of the Makefile.vc file.
+
+INSTALLATION
+============
+
+The installation of a TEA package is structured like so:
+
+         $exec_prefix
+          /       \
+        lib       bin
+         |         |
+   PACKAGEx.y   (dependent .dll files on Windows)
+         |
+  pkgIndex.tcl (.so|.dll|.dylib and .tcl files)
+
+The main .so|.dll library file gets installed in the versioned PACKAGE
+directory, which is OK on all platforms because it will be directly
+referenced with by 'load' in the pkgIndex.tcl file.  Dependent DLL files on
+Windows must go in the bin directory (or other directory on the user's
+PATH) in order for them to be found.
diff --git a/8.x/vqtcl/aclocal.m4 b/8.x/vqtcl/aclocal.m4
new file mode 100644 (file)
index 0000000..0b05739
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Include the TEA standard macro set
+#
+
+builtin(include,tclconfig/tcl.m4)
+
+#
+# Add here whatever m4 macros you want to define for your package
+#
diff --git a/8.x/vqtcl/configure b/8.x/vqtcl/configure
new file mode 100755 (executable)
index 0000000..c3a9e03
--- /dev/null
@@ -0,0 +1,10858 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for vqtcl 4.1.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='vqtcl'
+PACKAGE_TARNAME='vqtcl'
+PACKAGE_VERSION='4.1'
+PACKAGE_STRING='vqtcl 4.1'
+PACKAGE_BUGREPORT=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB ac_ct_RANLIB EGREP MATH_LIBS PKG_SOURCES PKG_OBJECTS CLEANFILES TCL_INCLUDES TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS LD_LIBRARY_PATH_VAR TCL_DBGX CFLAGS_DEFAULT LDFLAGS_DEFAULT MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures vqtcl 4.1 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of vqtcl 4.1:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-threads        build with threads
+  --enable-shared         build and link with shared libraries (default: on)
+  --enable-64bit          enable 64bit support (default: off)
+  --enable-64bit-vis      enable 64bit Sparc VIS support (default: off)
+  --enable-wince          enable Win/CE support (where applicable)
+  --enable-load           allow dynamic loading and "load" command (default:
+                          on)
+  --enable-symbols        build with debugging symbols (default: off)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-tcl              directory containing tcl configuration
+                          (tclConfig.sh)
+  --with-tclinclude       directory containing the public Tcl header files
+  --with-celib=DIR        use Windows/CE support library from DIR
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+vqtcl configure 4.1
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by vqtcl $as_me 4.1, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.5"
+
+    echo "$as_me:$LINENO: checking for correct TEA configuration" >&5
+echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6
+    if test x"${PACKAGE_NAME}" = x ; then
+       { { echo "$as_me:$LINENO: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5
+echo "$as_me: error:
+The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test x"3.5" = x ; then
+       { { echo "$as_me:$LINENO: error:
+TEA version not specified." >&5
+echo "$as_me: error:
+TEA version not specified." >&2;}
+   { (exit 1); exit 1; }; }
+    elif test "3.5" != "${TEA_VERSION}" ; then
+       echo "$as_me:$LINENO: result: warning: requested TEA version \"3.5\", have \"${TEA_VERSION}\"" >&5
+echo "${ECHO_T}warning: requested TEA version \"3.5\", have \"${TEA_VERSION}\"" >&6
+    else
+       echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5
+echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+           # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CYGPATH+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CYGPATH"; then
+  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CYGPATH="cygpath -w"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+  echo "$as_me:$LINENO: result: $CYGPATH" >&5
+echo "${ECHO_T}$CYGPATH" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+
+
+
+    # This package name must be replaced statically for AC_SUBST to work
+
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in tclconfig $srcdir/tclconfig; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in tclconfig $srcdir/tclconfig" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+
+
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+
+# Check whether --with-tcl or --without-tcl was given.
+if test "${with_tcl+set}" = set; then
+  withval="$with_tcl"
+  with_tclconfig=${withval}
+fi;
+       echo "$as_me:$LINENO: checking for Tcl configuration" >&5
+echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6
+       if test "${ac_cv_c_tclconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
+echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5
+echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+
+fi
+
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           { echo "$as_me:$LINENO: WARNING: Can't find Tcl configuration definitions" >&5
+echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;}
+           exit 0
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6
+       fi
+    fi
+
+
+    echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        echo "$as_me:$LINENO: result: loading" >&5
+echo "${ECHO_T}loading" >&6
+       . ${TCL_BIN_DIR}/tclConfig.sh
+    else
+        echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
+echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f ${TCL_BIN_DIR}/Makefile ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f ${TCL_BIN_DIR}/${TCL_LIB_FILE}; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+#TEA_PATH_TKCONFIG
+#TEA_LOAD_TKCONFIG
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
+echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
+           prefix=${TCL_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5
+echo "$as_me: --prefix defaulting to /usr/local" >&6;}
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
+echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5
+echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;}
+           exec_prefix=$prefix
+       fi
+    fi
+
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
+# the basic setup necessary to compile executables.
+#-----------------------------------------------------------------------
+
+
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+    # Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5
+echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6
+       OLDCC="$CC"
+       CC="$CC -pipe"
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+CC="$OLDCC"
+           echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+    if test "${TEA_PLATFORM}" = "unix" ; then
+
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking for sin" >&5
+echo $ECHO_N "checking for sin... $ECHO_C" >&6
+if test "${ac_cv_func_sin+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define sin to an innocuous variant, in case <limits.h> declares sin.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define sin innocuous_sin
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char sin (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef sin
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char sin ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_sin) || defined (__stub___sin)
+choke me
+#else
+char (*f) () = sin;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != sin;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_sin=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_sin=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5
+echo "${ECHO_T}$ac_cv_func_sin" >&6
+if test $ac_cv_func_sin = yes; then
+  MATH_LIBS=""
+else
+  MATH_LIBS="-lm"
+fi
+
+    echo "$as_me:$LINENO: checking for main in -lieee" >&5
+echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6
+if test "${ac_cv_lib_ieee_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lieee  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ieee_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ieee_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5
+echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6
+if test $ac_cv_lib_ieee_main = yes; then
+  MATH_LIBS="-lieee $MATH_LIBS"
+fi
+
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    echo "$as_me:$LINENO: checking for main in -linet" >&5
+echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6
+if test "${ac_cv_lib_inet_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5
+echo "${ECHO_T}$ac_cv_lib_inet_main" >&6
+if test $ac_cv_lib_inet_main = yes; then
+  LIBS="$LIBS -linet"
+fi
+
+    if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking net/errno.h usability" >&5
+echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <net/errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking net/errno.h presence" >&5
+echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <net/errno.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: net/errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: net/errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for net/errno.h" >&5
+echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_net_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_net_errno_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
+
+fi
+if test $ac_cv_header_net_errno_h = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NET_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+if test $ac_cv_func_connect = yes; then
+  tcl_checkSocket=0
+else
+  tcl_checkSocket=1
+fi
+
+    if test "$tcl_checkSocket" = 1; then
+       echo "$as_me:$LINENO: checking for setsockopt" >&5
+echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6
+if test "${ac_cv_func_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define setsockopt to an innocuous variant, in case <limits.h> declares setsockopt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define setsockopt innocuous_setsockopt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char setsockopt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef setsockopt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char setsockopt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_setsockopt) || defined (__stub___setsockopt)
+choke me
+#else
+char (*f) () = setsockopt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != setsockopt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_setsockopt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_func_setsockopt" >&6
+if test $ac_cv_func_setsockopt = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5
+echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_setsockopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char setsockopt ();
+int
+main ()
+{
+setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_setsockopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_setsockopt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6
+if test $ac_cv_lib_socket_setsockopt = yes; then
+  LIBS="$LIBS -lsocket"
+else
+  tcl_checkBoth=1
+fi
+
+fi
+
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       echo "$as_me:$LINENO: checking for accept" >&5
+echo $ECHO_N "checking for accept... $ECHO_C" >&6
+if test "${ac_cv_func_accept+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define accept to an innocuous variant, in case <limits.h> declares accept.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define accept innocuous_accept
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char accept (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef accept
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char accept ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_accept) || defined (__stub___accept)
+choke me
+#else
+char (*f) () = accept;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != accept;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_accept=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_accept=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5
+echo "${ECHO_T}$ac_cv_func_accept" >&6
+if test $ac_cv_func_accept = yes; then
+  tcl_checkNsl=0
+else
+  LIBS=$tk_oldLibs
+fi
+
+    fi
+    echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+char (*f) () = gethostbyname;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != gethostbyname;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
+if test $ac_cv_func_gethostbyname = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  LIBS="$LIBS -lnsl"
+fi
+
+fi
+
+
+    # Don't perform the eval of the libraries here because DL_LIBS
+    # won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+
+
+
+
+    echo "$as_me:$LINENO: checking dirent.h" >&5
+echo $ECHO_N "checking dirent.h... $ECHO_C" >&6
+if test "${tcl_cv_dirent_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_dirent_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_dirent_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5
+echo "${ECHO_T}$tcl_cv_dirent_h" >&6
+
+    if test $tcl_cv_dirent_h = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DIRENT_H 1
+_ACEOF
+
+    fi
+
+    if test "${ac_cv_header_errno_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking errno.h usability" >&5
+echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <errno.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking errno.h presence" >&5
+echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <errno.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: errno.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: errno.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for errno.h" >&5
+echo $ECHO_N "checking for errno.h... $ECHO_C" >&6
+if test "${ac_cv_header_errno_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_errno_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5
+echo "${ECHO_T}$ac_cv_header_errno_h" >&6
+
+fi
+if test $ac_cv_header_errno_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_ERRNO_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_float_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking float.h usability" >&5
+echo $ECHO_N "checking float.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <float.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking float.h presence" >&5
+echo $ECHO_N "checking float.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <float.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: float.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: float.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for float.h" >&5
+echo $ECHO_N "checking for float.h... $ECHO_C" >&6
+if test "${ac_cv_header_float_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_float_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
+echo "${ECHO_T}$ac_cv_header_float_h" >&6
+
+fi
+if test $ac_cv_header_float_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_FLOAT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_values_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking values.h usability" >&5
+echo $ECHO_N "checking values.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <values.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking values.h presence" >&5
+echo $ECHO_N "checking values.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <values.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: values.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: values.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for values.h" >&5
+echo $ECHO_N "checking for values.h... $ECHO_C" >&6
+if test "${ac_cv_header_values_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_values_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
+echo "${ECHO_T}$ac_cv_header_values_h" >&6
+
+fi
+if test $ac_cv_header_values_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_VALUES_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_limits_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking limits.h usability" >&5
+echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <limits.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking limits.h presence" >&5
+echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <limits.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: limits.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: limits.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for limits.h" >&5
+echo $ECHO_N "checking for limits.h... $ECHO_C" >&6
+if test "${ac_cv_header_limits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_limits_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5
+echo "${ECHO_T}$ac_cv_header_limits_h" >&6
+
+fi
+if test $ac_cv_header_limits_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIMITS_H 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_LIMITS_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking stdlib.h usability" >&5
+echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <stdlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking stdlib.h presence" >&5
+echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: stdlib.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: stdlib.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for stdlib.h" >&5
+echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdlib_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_stdlib_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
+
+fi
+if test $ac_cv_header_stdlib_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtol" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtoul" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strtod" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STDLIB_H 1
+_ACEOF
+
+    fi
+    if test "${ac_cv_header_string_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking string.h usability" >&5
+echo $ECHO_N "checking string.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <string.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking string.h presence" >&5
+echo $ECHO_N "checking string.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: string.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: string.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for string.h" >&5
+echo $ECHO_N "checking for string.h... $ECHO_C" >&6
+if test "${ac_cv_header_string_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_string_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
+echo "${ECHO_T}$ac_cv_header_string_h" >&6
+
+fi
+if test $ac_cv_header_string_h = yes; then
+  tcl_ok=1
+else
+  tcl_ok=0
+fi
+
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strstr" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "strerror" >/dev/null 2>&1; then
+  :
+else
+  tcl_ok=0
+fi
+rm -f conftest*
+
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STRING_H 1
+_ACEOF
+
+    fi
+
+    if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/wait.h usability" >&5
+echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <sys/wait.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/wait.h presence" >&5
+echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/wait.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/wait.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/wait.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for sys/wait.h" >&5
+echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_wait_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+
+fi
+if test $ac_cv_header_sys_wait_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+
+    if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking dlfcn.h usability" >&5
+echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <dlfcn.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking dlfcn.h presence" >&5
+echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <dlfcn.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_dlfcn_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
+
+fi
+if test $ac_cv_header_dlfcn_h = yes; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_DLFCN_H 1
+_ACEOF
+
+fi
+
+
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+
+for ac_header in sys/param.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to the vqtcl lists.  ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+
+
+#-----------------------------------------------------------------------
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+
+    vars="vlerq.c"
+    for i in $vars; do
+       case $i in
+           \$*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5
+echo "$as_me: error: could not find source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+
+
+
+    vars=""
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+
+
+
+    vars=""
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+
+    PKG_CFLAGS="$PKG_CFLAGS "
+
+
+
+    vars=""
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5
+echo "$as_me: error: could not find stub source file '$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+
+
+
+
+    vars="library/m2mvfs.tcl
+                     library/mkclvfs.tcl
+                     library/mklite.tcl
+                    library/ratcl.tcl"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5
+echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;}
+   { (exit 1); exit 1; }; }
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+
+
+
+#--------------------------------------------------------------------
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_vlerq in this case) so
+# that we create the export library with the dll.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define BUILD_vlerq 1
+_ACEOF
+
+    CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+    #TEA_ADD_SOURCES([win/winFile.c])
+    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+    CLEANFILES=""
+    #TEA_ADD_SOURCES([unix/unixFile.c])
+    #TEA_ADD_LIBS([-lsuperfly])
+fi
+
+
+#--------------------------------------------------------------------
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
+#--------------------------------------------------------------------
+
+
+    echo "$as_me:$LINENO: checking for Tcl public headers" >&5
+echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6
+
+
+# Check whether --with-tclinclude or --without-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then
+  withval="$with_tclinclude"
+  with_tclinclude=${withval}
+fi;
+
+    if test "${ac_cv_c_tclh+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5
+echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;}
+   { (exit 1); exit 1; }; }
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+
+fi
+
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       { { echo "$as_me:$LINENO: error: tcl.h not found.  Please specify its location with --with-tclinclude" >&5
+echo "$as_me: error: tcl.h not found.  Please specify its location with --with-tclinclude" >&2;}
+   { (exit 1); exit 1; }; }
+    else
+       echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5
+echo "${ECHO_T}${ac_cv_c_tclh}" >&6
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+
+
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+
+    # Check whether --enable-threads or --disable-threads was given.
+if test "${enable_threads+set}" = set; then
+  enableval="$enable_threads"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_THREAD_ALLOC 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+           if test "`uname -s`" = "SunOS" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+           fi
+
+cat >>confdefs.h <<\_ACEOF
+#define _THREAD_SAFE 1
+_ACEOF
+
+           echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6
+if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5
+echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char __pthread_mutex_init ();
+int
+main ()
+{
+__pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread___pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread___pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6
+if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6
+if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthreads_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthreads_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6
+if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6
+if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_c_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_c_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6
+if test $ac_cv_lib_c_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                   if test "$tcl_ok" = "no"; then
+                       echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5
+echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6
+if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc_r  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_mutex_init ();
+int
+main ()
+{
+pthread_mutex_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_c_r_pthread_mutex_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_c_r_pthread_mutex_init=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
+echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6
+if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           { echo "$as_me:$LINENO: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5
+echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;}
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    echo "$as_me:$LINENO: checking for building with threads" >&5
+echo $ECHO_N "checking for building with threads... $ECHO_C" >&6
+    if test "${TCL_THREADS}" = 1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_THREADS 1
+_ACEOF
+
+       echo "$as_me:$LINENO: result: yes (default)" >&5
+echo "${ECHO_T}yes (default)" >&6
+    else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               { echo "$as_me:$LINENO: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&5
+echo "$as_me: WARNING:
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads." >&2;}
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               { echo "$as_me:$LINENO: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&5
+echo "$as_me: WARNING:
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core." >&2;}
+           fi
+           ;;
+    esac
+
+
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+
+    echo "$as_me:$LINENO: checking how to build libraries" >&5
+echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6
+    # Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       echo "$as_me:$LINENO: result: shared" >&5
+echo "${ECHO_T}shared" >&6
+       SHARED_BUILD=1
+    else
+       echo "$as_me:$LINENO: result: static" >&5
+echo "${ECHO_T}static" >&6
+       SHARED_BUILD=0
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_BUILD 1
+_ACEOF
+
+    fi
+
+
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+
+
+
+    # Step 0.a: Enable 64 bit support?
+
+    echo "$as_me:$LINENO: checking if 64bit support is requested" >&5
+echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6
+    # Check whether --enable-64bit or --disable-64bit was given.
+if test "${enable_64bit+set}" = set; then
+  enableval="$enable_64bit"
+  do64bit=$enableval
+else
+  do64bit=no
+fi;
+    echo "$as_me:$LINENO: result: $do64bit" >&5
+echo "${ECHO_T}$do64bit" >&6
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5
+echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6
+    # Check whether --enable-64bit-vis or --disable-64bit-vis was given.
+if test "${enable_64bit_vis+set}" = set; then
+  enableval="$enable_64bit_vis"
+  do64bitVIS=$enableval
+else
+  do64bitVIS=no
+fi;
+    echo "$as_me:$LINENO: result: $do64bitVIS" >&5
+echo "${ECHO_T}$do64bitVIS" >&6
+
+    if test "$do64bitVIS" = "yes"; then
+       # Force 64bit on with VIS
+       do64bit=yes
+    fi
+
+    # Step 0.c: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5
+echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6
+       # Check whether --enable-wince or --disable-wince was given.
+if test "${enable_wince+set}" = set; then
+  enableval="$enable_wince"
+  doWince=$enableval
+else
+  doWince=no
+fi;
+       echo "$as_me:$LINENO: result: $doWince" >&5
+echo "${ECHO_T}$doWince" >&6
+    fi
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+
+    echo "$as_me:$LINENO: checking system version" >&5
+echo $ECHO_N "checking system version... $ECHO_C" >&6
+if test "${tcl_cv_sys_version+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5
+echo "$as_me: WARNING: can't find uname command" >&2;}
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $3}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5
+echo "${ECHO_T}$tcl_cv_sys_version" >&6
+    system=$tcl_cv_sys_version
+
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  have_dl=yes
+else
+  have_dl=no
+fi
+
+
+    # Require ranlib early so we can override it in special cases below.
+
+
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    if test "$GCC" = "yes" ; then
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall -Wno-implicit-int"
+    else
+       CFLAGS_WARNING=""
+    fi
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+    # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    case $system in
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+                   { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5
+echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+                   do64bit="no"
+               else
+                   echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
+echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5
+echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+               if test "$GCC" = "yes" ; then
+                   { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5
+echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+
+# Check whether --with-celib or --without-celib was given.
+if test "${with_celib+set}" = set; then
+  withval="$with_celib"
+  with_celibconfig=${withval}
+fi;
+       echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
+echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6
+       if test "${ac_cv_c_celibconfig+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5
+echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;}
+   { (exit 1); exit 1; }; }
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+fi
+
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5
+echo "$as_me: error: Cannot find celib support library directory" >&2;}
+   { (exit 1); exit 1; }; }
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5
+echo "${ECHO_T}found $CELIB_DIR" >&6
+       fi
+    fi
+
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
+           if ($1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
+           if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
+           if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5
+echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;}
+   { (exit 1); exit 1; }; }
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+
+    vars="bufferoverflowU.lib"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+
+
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower($0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+
+cat >>confdefs.h <<_ACEOF
+#define $i 1
+_ACEOF
+
+                   done
+
+cat >>confdefs.h <<_ACEOF
+#define _WIN32_WCE $CEVERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNDER_CE $CEVERSION
+_ACEOF
+
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r)
+                       # ok ...
+                       ;;
+                   *)
+                       CC=${CC}_r
+                       ;;
+               esac
+               echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5
+echo "${ECHO_T}Using $CC for compiling with threads" >&6
+           fi
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
+               if test "$GCC" = "yes" ; then
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+               fi
+           fi
+
+           if test "`uname -m`" = "ia64" ; then
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               if test "$GCC" = "yes" ; then
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               else
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+               fi
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           else
+               if test "$GCC" = "yes" ; then
+                   SHLIB_LD="gcc -shared"
+               else
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+               fi
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+           fi
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
+               case $LIBOBJS in
+    "tclLoadAix.$ac_objext"   | \
+  *" tclLoadAix.$ac_objext"   | \
+    "tclLoadAix.$ac_objext "* | \
+  *" tclLoadAix.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;;
+esac
+
+               DL_LIBS="-lld"
+           fi
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5
+echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6
+if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gettimeofday ();
+int
+main ()
+{
+gettimeofday ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bsd_gettimeofday=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bsd_gettimeofday=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5
+echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6
+if test $ac_cv_lib_bsd_gettimeofday = yes; then
+  libbsd=yes
+else
+  libbsd=no
+fi
+
+           if test $libbsd = yes; then
+               MATH_LIBS="$MATH_LIBS -lbsd"
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_DELTA_FOR_TZ 1
+_ACEOF
+
+           fi
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -nostart"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5
+echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6
+if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbind  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_ntoa ();
+int
+main ()
+{
+inet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bind_inet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bind_inet_ntoa=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6
+if test $ac_cv_lib_bind_inet_ntoa = yes; then
+  LIBS="$LIBS -lbind -lsocket"
+fi
+
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD="cc -shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+
+cat >>confdefs.h <<\_ACEOF
+#define _XOPEN_SOURCE_EXTENDED 1
+_ACEOF
+
+           # Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           SHLIB_SUFFIX=".sl"
+           echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="gcc -shared"
+               SHLIB_LD_LIBS='${LIBS}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+
+           # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+           #CFLAGS="$CFLAGS +DAportable"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   hpux_arch=`${CC} -dumpmachine`
+                   case $hpux_arch in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD="${CC} -shared"
+                           SHLIB_LD_LIBS='${LIBS}'
+                           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+                           ;;
+                   esac
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+               fi
+           fi
+           ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  tcl_ok=yes
+else
+  tcl_ok=no
+fi
+
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+           else
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+           fi
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5
+echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
+               else
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               fi
+           fi
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           if test $do64bit = yes; then
+               echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_m64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_m64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_m64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                   CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5
+echo "${ECHO_T}$tcl_cv_cc_m64" >&6
+               if test $tcl_cv_cc_m64 = yes; then
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+               fi
+           fi
+
+           # The combo of gcc + glibc has a bug related
+           # to inlining of functions like strtod(). The
+           # -fno-builtin flag should address this problem
+           # but it does not work. The -fno-inline flag
+           # is kind of overkill but it works.
+           # Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+           if test x"${USE_COMPAT}" != x ; then
+               CFLAGS="$CFLAGS -fno-inline"
+           fi
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD="${CC} -shared"
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD="${CC} -shared "
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-*|FreeBSD-[1-2].*)
+           # NetBSD/SPARC needs -fPIC, -fpic will not do.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6
+           if test $tcl_cv_ld_elf = yes; then
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+           else
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           fi
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
+           case `machine` in
+           sparc|sparc64)
+               SHLIB_CFLAGS="-fPIC";;
+           *)
+               SHLIB_CFLAGS="-fpic";;
+           esac
+           SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           echo "$as_me:$LINENO: checking for ELF" >&5
+echo $ECHO_N "checking for ELF... $ECHO_C" >&6
+if test "${tcl_cv_ld_elf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef __ELF__
+       yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  tcl_cv_ld_elf=yes
+else
+  tcl_cv_ld_elf=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
+echo "${ECHO_T}$tcl_cv_ld_elf" >&6
+           if test $tcl_cv_ld_elf = yes; then
+               LDFLAGS=-Wl,-export-dynamic
+           else
+               LDFLAGS=""
+           fi
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       FreeBSD-*)
+           # FreeBSD 3.* and greater have ELF.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "${TCL_THREADS}" = "1" ; then
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+           fi
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           if test $do64bit = yes; then
+               case `arch` in
+                   ppc)
+                       echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_arch_ppc64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_arch_ppc64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_arch_ppc64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6
+                       if test $tcl_cv_cc_arch_ppc64 = yes; then
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+                       fi;;
+                   i386)
+                       echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5
+echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6
+if test "${tcl_cv_cc_arch_x86_64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_cc_arch_x86_64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_cc_arch_x86_64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+                           CFLAGS=$hold_cflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5
+echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6
+                       if test $tcl_cv_cc_arch_x86_64 = yes; then
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+                       fi;;
+                   *)
+                       { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
+               esac
+           else
+               # Check for combined 32-bit and 64-bit fat build
+               echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
+                   echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
+                   fat_32_64=yes
+           fi
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5
+echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_single_module+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_single_module=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_single_module=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5
+echo "${ECHO_T}$tcl_cv_ld_single_module" >&6
+           if test $tcl_cv_ld_single_module = yes; then
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+           fi
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
+               "`echo "${CFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4 && \
+               LDFLAGS="$LDFLAGS -prebind"
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5
+echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_search_paths_first+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_search_paths_first=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_search_paths_first=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5
+echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6
+           if test $tcl_cv_ld_search_paths_first = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+
+           # TEA specific: for Tk extensions, remove 64-bit arch flags from
+           # CFLAGS for combined 32-bit and 64-bit fat builds as neither TkAqua
+           # nor TkX11 can be built for 64-bit at present.
+           test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}" && \
+               CFLAGS="`echo "$CFLAGS " | sed -e 's/-arch ppc64 / /g' -e 's/-arch x86_64 / /g'`"
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="cc -nostdlib -r"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+
+cat >>confdefs.h <<\_ACEOF
+#define _OE_SOCKETS 1
+_ACEOF
+
+           ;;
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export :'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD="ld -shared"
+           else
+               SHLIB_LD="ld -non_shared"
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+           else
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mieee"
+            else
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+           fi
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           if test "${TCL_THREADS}" = "1" ; then
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               if test "$GCC" = "yes" ; then
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+               else
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+               fi
+           fi
+
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           if test "$GCC" = "yes" ; then
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+           else
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+           fi
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[0-6])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_PTHREAD_SEMANTICS 1
+_ACEOF
+
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               arch=`isainfo`
+               if test "$arch" = "sparcv9 sparc" ; then
+                       if test "$GCC" = "yes" ; then
+                           if test "`gcc -dumpversion | awk -F. '{print $1}'`" -lt "3" ; then
+                               { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
+                           else
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                               LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                               SHLIB_CFLAGS="-fPIC"
+                           fi
+                       else
+                           do64bit_ok=yes
+                           if test "$do64bitVIS" = "yes" ; then
+                               CFLAGS="$CFLAGS -xarch=v9a"
+                               LDFLAGS_ARCH="-xarch=v9a"
+                           else
+                               CFLAGS="$CFLAGS -xarch=v9"
+                               LDFLAGS_ARCH="-xarch=v9"
+                           fi
+                           # Solaris 64 uses this as well
+                           #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+                       fi
+               elif test "$arch" = "amd64 i386" ; then
+                   if test "$GCC" = "yes" ; then
+                       { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
+echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+                   else
+                       do64bit_ok=yes
+                       CFLAGS="$CFLAGS -xarch=amd64"
+                       LDFLAGS="$LDFLAGS -xarch=amd64"
+                   fi
+               else
+                   { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5
+echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+               fi
+           fi
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               if test "$do64bit_ok" = "yes" ; then
+                   # We need to specify -static-libgcc or we need to
+                   # add the path to the sparv9 libgcc.
+                   # JH: static-libgcc is necessary for core Tcl, but may
+                   # not be necessary for extensions.
+                   SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                   # for finding sparcv9 libgcc, get the regular libgcc
+                   # path, remove so name and append 'sparcv9'
+                   #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                   #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+               fi
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           fi
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5
+echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6
+if test "${tcl_cv_ld_Bexport+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_ld_Bexport=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_ld_Bexport=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS=$hold_ldflags
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5
+echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6
+           if test $tcl_cv_ld_Bexport = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
+       { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+    fi
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    # Check whether --enable-load or --disable-load was given.
+if test "${enable_load+set}" = set; then
+  enableval="$enable_load"
+  tcl_ok=$enableval
+else
+  tcl_ok=yes
+fi;
+    if test "$tcl_ok" = "no"; then
+       DL_OBJS=""
+    fi
+
+    if test "x$DL_OBJS" != "x" ; then
+       BUILD_DLTEST="\$(DLTEST_TARGETS)"
+    else
+       echo "Can't figure out how to do dynamic loading or shared libraries"
+       echo "on this system."
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+    fi
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$DL_OBJS" != "tclLoadNone.o" ; then
+       if test "$GCC" = "yes" ; then
+           case $system in
+               AIX-*)
+                   ;;
+               BSD/OS*)
+                   ;;
+               IRIX*)
+                   ;;
+               NetBSD-*|FreeBSD-*)
+                   ;;
+               Darwin-*)
+                   ;;
+               SCO_SV-3.2*)
+                   ;;
+               windows)
+                   ;;
+               *)
+                   SHLIB_CFLAGS="-fPIC"
+                   ;;
+           esac
+       fi
+    fi
+
+    if test "$SHARED_LIB_SUFFIX" = "" ; then
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+    fi
+    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+    fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+
+    echo "$as_me:$LINENO: checking for required early compiler flags" >&5
+echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6
+    tcl_flags=""
+
+    if test "${tcl_cv_flag__isoc99_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__isoc99_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__isoc99_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__isoc99_source=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _ISOC99_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _ISOC99_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile64_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile64_source=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE64_SOURCE 1
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile64_source=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__largefile64_source=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE64_SOURCE 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
+    fi
+
+
+    if test "${tcl_cv_flag__largefile_source64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile_source64=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE_SOURCE64 1
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_flag__largefile_source64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_flag__largefile_source64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _LARGEFILE_SOURCE64 1
+_ACEOF
+
+       tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
+    fi
+
+    if test "x${tcl_flags}" = "x" ; then
+       echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+    else
+       echo "$as_me:$LINENO: result: ${tcl_flags}" >&5
+echo "${ECHO_T}${tcl_flags}" >&6
+    fi
+
+
+    echo "$as_me:$LINENO: checking for 64-bit integer type" >&5
+echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6
+    if test "${tcl_cv_type_64bit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__int64 value = (__int64) 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_type_64bit=__int64
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_type_64bit="long long"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+switch (0) {
+            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+        }
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_type_64bit=${tcl_type_64bit}
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+    if test "${tcl_cv_type_64bit}" = none ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_WIDE_INT_IS_LONG 1
+_ACEOF
+
+       echo "$as_me:$LINENO: result: using long" >&5
+echo "${ECHO_T}using long" >&6
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # We actually want to use the default tcl.h checks in this
+       # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       echo "$as_me:$LINENO: result: using Tcl header defaults" >&5
+echo "${ECHO_T}using Tcl header defaults" >&6
+    else
+
+cat >>confdefs.h <<_ACEOF
+#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
+_ACEOF
+
+       echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5
+echo "${ECHO_T}${tcl_cv_type_64bit}" >&6
+
+       # Now check for auxiliary declarations
+       echo "$as_me:$LINENO: checking for struct dirent64" >&5
+echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6
+if test "${tcl_cv_struct_dirent64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/dirent.h>
+int
+main ()
+{
+struct dirent64 p;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_struct_dirent64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_struct_dirent64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5
+echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_DIRENT64 1
+_ACEOF
+
+       fi
+
+       echo "$as_me:$LINENO: checking for struct stat64" >&5
+echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6
+if test "${tcl_cv_struct_stat64+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 p;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_struct_stat64=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_struct_stat64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5
+echo "${ECHO_T}$tcl_cv_struct_stat64" >&6
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_STAT64 1
+_ACEOF
+
+       fi
+
+
+
+for ac_func in open64 lseek64
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+       echo "$as_me:$LINENO: checking for off64_t" >&5
+echo $ECHO_N "checking for off64_t... $ECHO_C" >&6
+       if test "${tcl_cv_type_off64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+off64_t offset;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  tcl_cv_type_off64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_type_off64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+                       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TYPE_OFF64_T 1
+_ACEOF
+
+           echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+           echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+       fi
+    fi
+
+
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+
+
+    echo "$as_me:$LINENO: checking for build with symbols" >&5
+echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6
+    # Check whether --enable-symbols or --disable-symbols was given.
+if test "${enable_symbols+set}" = set; then
+  enableval="$enable_symbols"
+  tcl_ok=$enableval
+else
+  tcl_ok=no
+fi;
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
+echo "${ECHO_T}yes (standard debugging)" >&6
+       fi
+    fi
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+
+
+
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TCL_MEM_DEBUG 1
+_ACEOF
+
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5
+echo "${ECHO_T}enabled symbols mem debugging" >&6
+       else
+           echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
+echo "${ECHO_T}enabled $tcl_ok debugging" >&6
+       fi
+    fi
+
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.  Add Tk too if necessary.
+#--------------------------------------------------------------------
+
+
+if test "${SHARED_BUILD}" = "1"; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_TCL_STUBS 1
+_ACEOF
+
+#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
+fi
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+
+    echo "$as_me:$LINENO: checking for tclsh" >&5
+echo $ECHO_N "checking for tclsh... $ECHO_C" >&6
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}"
+    fi
+    echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5
+echo "${ECHO_T}${TCLSH_PROG}" >&6
+
+
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+# You may alternatively have a special pkgIndex.tcl.in or other files
+# which require substituting th AC variables in.  Include these here.
+#--------------------------------------------------------------------
+
+                    ac_config_files="$ac_config_files Makefile pkgIndex.tcl"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by vqtcl $as_me 4.1, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+vqtcl config.status 4.1
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "pkgIndex.tcl" ) CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CYGPATH@,$CYGPATH,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@PKG_LIB_FILE@,$PKG_LIB_FILE,;t t
+s,@PKG_STUB_LIB_FILE@,$PKG_STUB_LIB_FILE,;t t
+s,@PKG_STUB_SOURCES@,$PKG_STUB_SOURCES,;t t
+s,@PKG_STUB_OBJECTS@,$PKG_STUB_OBJECTS,;t t
+s,@PKG_TCL_SOURCES@,$PKG_TCL_SOURCES,;t t
+s,@PKG_HEADERS@,$PKG_HEADERS,;t t
+s,@PKG_INCLUDES@,$PKG_INCLUDES,;t t
+s,@PKG_LIBS@,$PKG_LIBS,;t t
+s,@PKG_CFLAGS@,$PKG_CFLAGS,;t t
+s,@TCL_VERSION@,$TCL_VERSION,;t t
+s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
+s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t
+s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t
+s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t
+s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t
+s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t
+s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t
+s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t
+s,@TCL_LIBS@,$TCL_LIBS,;t t
+s,@TCL_DEFS@,$TCL_DEFS,;t t
+s,@TCL_EXTRA_CFLAGS@,$TCL_EXTRA_CFLAGS,;t t
+s,@TCL_LD_FLAGS@,$TCL_LD_FLAGS,;t t
+s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@EGREP@,$EGREP,;t t
+s,@MATH_LIBS@,$MATH_LIBS,;t t
+s,@PKG_SOURCES@,$PKG_SOURCES,;t t
+s,@PKG_OBJECTS@,$PKG_OBJECTS,;t t
+s,@CLEANFILES@,$CLEANFILES,;t t
+s,@TCL_INCLUDES@,$TCL_INCLUDES,;t t
+s,@TCL_THREADS@,$TCL_THREADS,;t t
+s,@SHARED_BUILD@,$SHARED_BUILD,;t t
+s,@AR@,$AR,;t t
+s,@CELIB_DIR@,$CELIB_DIR,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@DL_LIBS@,$DL_LIBS,;t t
+s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t
+s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t
+s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
+s,@STLIB_LD@,$STLIB_LD,;t t
+s,@SHLIB_LD@,$SHLIB_LD,;t t
+s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t
+s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t
+s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t
+s,@TCL_DBGX@,$TCL_DBGX,;t t
+s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t
+s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t
+s,@MAKE_LIB@,$MAKE_LIB,;t t
+s,@MAKE_SHARED_LIB@,$MAKE_SHARED_LIB,;t t
+s,@MAKE_STATIC_LIB@,$MAKE_STATIC_LIB,;t t
+s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t
+s,@RANLIB_STUB@,$RANLIB_STUB,;t t
+s,@TCLSH_PROG@,$TCLSH_PROG,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/8.x/vqtcl/configure.in b/8.x/vqtcl/configure.in
new file mode 100644 (file)
index 0000000..6a08367
--- /dev/null
@@ -0,0 +1,179 @@
+#!/bin/bash -norc
+dnl    This file is an input file used by the GNU "autoconf" program to
+dnl    generate the file "configure", which is run during Tcl installation
+dnl    to configure the system for the local environment.
+
+#-----------------------------------------------------------------------
+# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
+# set as provided.  These will also be added as -D defs in your Makefile
+# so you can encode the package version directly into the source files.
+#-----------------------------------------------------------------------
+
+AC_INIT([vqtcl], [4.1])
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+TEA_INIT([3.5])
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+#TEA_PATH_TKCONFIG
+#TEA_LOAD_TKCONFIG
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+TEA_PREFIX
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
+# the basic setup necessary to compile executables.
+#-----------------------------------------------------------------------
+
+TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+TEA_ADD_SOURCES([vlerq.c])
+TEA_ADD_HEADERS([])
+TEA_ADD_INCLUDES([])
+TEA_ADD_LIBS([])
+TEA_ADD_CFLAGS([])
+TEA_ADD_STUB_SOURCES([])
+TEA_ADD_TCL_SOURCES([library/m2mvfs.tcl
+                     library/mkclvfs.tcl
+                     library/mklite.tcl
+                    library/ratcl.tcl])
+
+#--------------------------------------------------------------------
+# A few miscellaneous platform-specific items:
+#
+# Define a special symbol for Windows (BUILD_vlerq in this case) so
+# that we create the export library with the dll.
+#
+# Windows creates a few extra files that need to be cleaned up.
+# You can add more files to clean if your extension creates any extra
+# files.
+#
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+if test "${TEA_PLATFORM}" = "windows" ; then
+    AC_DEFINE(BUILD_vlerq, 1, [Build windows export dll])
+    CLEANFILES="*.lib *.dll *.exp *.ilk *.pdb vc*.pch"
+    #TEA_ADD_SOURCES([win/winFile.c])
+    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+    CLEANFILES=""
+    #TEA_ADD_SOURCES([unix/unixFile.c])
+    #TEA_ADD_LIBS([-lsuperfly])
+fi
+AC_SUBST(CLEANFILES)
+
+#--------------------------------------------------------------------
+# Choose which headers you need.  Extension authors should try very
+# hard to only rely on the Tcl public header files.  Internal headers
+# contain private data structures and are subject to change without
+# notice.
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
+#--------------------------------------------------------------------
+
+TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_THREADS
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SHARED
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects.  This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+TEA_CONFIG_CFLAGS
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SYMBOLS
+
+#--------------------------------------------------------------------
+# Everyone should be linking against the Tcl stub library.  If you
+# can't for some reason, remove this definition.  If you aren't using
+# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
+# link against the non-stubbed Tcl library.  Add Tk too if necessary.
+#--------------------------------------------------------------------
+
+if test "${SHARED_BUILD}" = "1"; then
+AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
+#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
+fi
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library.  It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+TEA_MAKE_LIB
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+TEA_PROG_TCLSH
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Finally, substitute all of the various values into the Makefile.
+# You may alternatively have a special pkgIndex.tcl.in or other files
+# which require substituting th AC variables in.  Include these here.
+#--------------------------------------------------------------------
+
+AC_OUTPUT([Makefile pkgIndex.tcl])
diff --git a/8.x/vqtcl/data/gtest.db b/8.x/vqtcl/data/gtest.db
new file mode 100644 (file)
index 0000000..d7ce5d4
Binary files /dev/null and b/8.x/vqtcl/data/gtest.db differ
diff --git a/8.x/vqtcl/data/lkit-be.db b/8.x/vqtcl/data/lkit-be.db
new file mode 100644 (file)
index 0000000..fec01ce
Binary files /dev/null and b/8.x/vqtcl/data/lkit-be.db differ
diff --git a/8.x/vqtcl/data/lkit-le.db b/8.x/vqtcl/data/lkit-le.db
new file mode 100644 (file)
index 0000000..759ec6c
Binary files /dev/null and b/8.x/vqtcl/data/lkit-le.db differ
diff --git a/8.x/vqtcl/data/mkblk.db b/8.x/vqtcl/data/mkblk.db
new file mode 100644 (file)
index 0000000..912be05
Binary files /dev/null and b/8.x/vqtcl/data/mkblk.db differ
diff --git a/8.x/vqtcl/doc/ratcl.html b/8.x/vqtcl/doc/ratcl.html
new file mode 100644 (file)
index 0000000..aee398b
--- /dev/null
@@ -0,0 +1,96 @@
+<html><head>
+<title>ratcl - Relational Algebra for Tcl </title>
+</head>
+<! -- Generated from file './doc/ratcl.man' by tcllib/doctools with format 'html'
+   -->
+<! -- CVS: $Id: ratcl.html 7 2009-02-20 14:00:31Z patthoyts $ ratcl.n
+   -->
+
+<body>
+<h1> ratcl(n) 4 ratcl &quot;Relational Algebra for Tcl&quot;</h1>
+<h2><a name="name">NAME</a></h2>
+<p>
+<p> ratcl - A Relational Algebra extension for Tcl
+
+
+
+<h2><a name="table_of_contents">TABLE OF CONTENTS</a></h2>
+<p>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#table_of_contents">TABLE OF CONTENTS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#synopsis">SYNOPSIS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#description">DESCRIPTION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#commands">COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#example">EXAMPLE</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#see_also">SEE ALSO</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#keywords">KEYWORDS</a><br>
+<h2><a name="synopsis">SYNOPSIS</a></h2>
+<p>
+package require <b>ratcl ?4?</b><br>
+<br><table border=1 width=100% cellspacing=0 cellpadding=0><tr            bgcolor=lightyellow><td bgcolor=lightyellow><table 0 width=100% cellspacing=0 cellpadding=0><tr valign=top ><td ><a href="#1"><b class='cmd'>view</b> <i class='arg'>arg</i> <b class='cmd'>operator</b> <i class='arg'>...</i> | <i class='arg'>...</i></a></td></tr>
+<tr valign=top ><td ><a href="#2">... <i class='arg'>view</i> | <b class='cmd'>names</b></a></td></tr>
+<tr valign=top ><td ><a href="#3">... <i class='arg'>filename</i> | <b class='cmd'>open</b></a></td></tr>
+<tr valign=top ><td ><a href="#4">... <i class='arg'>view</i> | <b class='cmd'>to</b> <i class='arg'>varname</i></a></td></tr>
+</table></td></tr></table>
+<h2><a name="description">DESCRIPTION</a></h2>
+<p>
+<p>
+
+The <strong>ratcl</strong> package implements a general-purpose relational algebra
+and persistence framework as a notation on top of the Vlerq extension.
+
+<h2><a name="commands">COMMANDS</a></h2>
+<p>
+<dl>
+
+<dt><a name="1"><b class='cmd'>view</b> <i class='arg'>arg</i> <b class='cmd'>operator</b> <i class='arg'>...</i> | <i class='arg'>...</i></a><dd>
+
+
+The <b class='cmd'>view</b> command wraps all the different operators provided by
+the <strong>vlerq</strong> package and lets you create pipelines,
+whereby the output of one operator is fed as input to the next.
+
+<br><br>
+<dt><a name="2">... <i class='arg'>view</i> | <b class='cmd'>names</b></a><dd>
+
+
+Return a list with all the column names of <i class='arg'>view</i>.
+
+<br><br>
+<dt><a name="3">... <i class='arg'>filename</i> | <b class='cmd'>open</b></a><dd>
+
+
+The <b class='cmd'>open</b> operator opens a Metakit-compatible datafile and returns
+its root view.
+
+<br><br>
+<dt><a name="4">... <i class='arg'>view</i> | <b class='cmd'>to</b> <i class='arg'>varname</i></a><dd>
+
+
+Store a view in the <i class='arg'>varname</i> variable.
+That same view is also returned as result.
+
+</dl>
+
+<p>
+THIS DOCUMENTATION NEEDS TO BE FINISHED
+
+<h2><a name="example">EXAMPLE</a></h2>
+<p>
+
+<p>
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+package require ratcl
+view myile.db open | to v
+puts [view $v names]
+</pre></td></tr></table></p>
+<p>
+This lists all the sub-views available in the myfile.db file.
+
+
+
+<h2><a name="see_also">SEE ALSO</a></h2>
+<p>
+metakit, vlerq
+<h2><a name="keywords">KEYWORDS</a></h2>
+<p>
+algebra, database, persistence, relational
+</body></html>
diff --git a/8.x/vqtcl/doc/ratcl.man b/8.x/vqtcl/doc/ratcl.man
new file mode 100644 (file)
index 0000000..29d99ce
--- /dev/null
@@ -0,0 +1,52 @@
+[manpage_begin ratcl n 4]
+[moddesc   {Relational Algebra for Tcl}]
+[titledesc {A Relational Algebra extension for Tcl}]
+[require ratcl [opt 4]]
+[description]
+[para]
+
+The [package ratcl] package implements a general-purpose relational algebra
+and persistence framework as a notation on top of the Vlerq extension.
+
+[section COMMANDS]
+[list_begin definitions]
+
+[call [cmd view] [arg arg] [cmd operator] [arg ...] | [arg ...]]
+
+The [cmd view] command wraps all the different operators provided by
+the [package vlerq] package and lets you create pipelines,
+whereby the output of one operator is fed as input to the next.
+
+[call ... [arg view] | [cmd names]]
+
+Return a list with all the column names of [arg view].
+
+[call ... [arg filename] | [cmd open]]
+
+The [cmd open] operator opens a Metakit-compatible datafile and returns
+its root view.
+
+[call ... [arg view] | [cmd to] [arg varname]]
+
+Store a view in the [arg varname] variable.
+That same view is also returned as result.
+
+[list_end]
+
+[para]
+THIS DOCUMENTATION NEEDS TO BE FINISHED
+
+[section EXAMPLE]
+
+[para]
+[example {
+package require ratcl
+view myile.db open | to v
+puts [view $v names]
+}]
+[para]
+This lists all the sub-views available in the myfile.db file.
+
+[see_also vlerq metakit]
+[keywords database persistence relational algebra]
+[manpage_end]
diff --git a/8.x/vqtcl/doc/ratcl.n b/8.x/vqtcl/doc/ratcl.n
new file mode 100644 (file)
index 0000000..5019c5f
--- /dev/null
@@ -0,0 +1,58 @@
+'\"
+'\" Generated from file './doc/ratcl.man' by tcllib/doctools with format 'nroff'
+'\"
+.so man.macros
+.TH "ratcl" n 4 ratcl "Relational Algebra for Tcl"
+.BS
+.SH NAME
+ratcl \- A Relational Algebra extension for Tcl
+.SH SYNOPSIS
+package require \fBratcl  ?4?\fR
+.sp
+\fBview\fR \fIarg\fR \fBoperator\fR \fI...\fR | \fI...\fR
+.sp
+... \fIview\fR | \fBnames\fR
+.sp
+... \fIfilename\fR | \fBopen\fR
+.sp
+... \fIview\fR | \fBto\fR \fIvarname\fR
+.sp
+.BE
+.SH DESCRIPTION
+.PP
+The \fBratcl\fR package implements a general-purpose relational algebra
+and persistence framework as a notation on top of the Vlerq extension.
+.SH COMMANDS
+.TP
+\fBview\fR \fIarg\fR \fBoperator\fR \fI...\fR | \fI...\fR
+The \fBview\fR command wraps all the different operators provided by
+the \fBvlerq\fR package and lets you create pipelines,
+whereby the output of one operator is fed as input to the next.
+.TP
+... \fIview\fR | \fBnames\fR
+Return a list with all the column names of \fIview\fR.
+.TP
+... \fIfilename\fR | \fBopen\fR
+The \fBopen\fR operator opens a Metakit-compatible datafile and returns
+its root view.
+.TP
+... \fIview\fR | \fBto\fR \fIvarname\fR
+Store a view in the \fIvarname\fR variable.
+That same view is also returned as result.
+.PP
+THIS DOCUMENTATION NEEDS TO BE FINISHED
+.SH EXAMPLE
+.PP
+.nf
+
+package require ratcl
+view myile.db open | to v
+puts [view $v names]
+
+.fi
+.PP
+This lists all the sub-views available in the myfile.db file.
+.SH "SEE ALSO"
+metakit, vlerq
+.SH KEYWORDS
+algebra, database, persistence, relational
\ No newline at end of file
diff --git a/8.x/vqtcl/doc/vlerq.html b/8.x/vqtcl/doc/vlerq.html
new file mode 100644 (file)
index 0000000..dd8c632
--- /dev/null
@@ -0,0 +1,80 @@
+<html><head>
+<title>vlerq - Vlerq data manipulation core engine </title>
+</head>
+<! -- Generated from file './doc/vlerq.man' by tcllib/doctools with format 'html'
+   -->
+<! -- CVS: $Id: vlerq.html 7 2009-02-20 14:00:31Z patthoyts $ vlerq.n
+   -->
+
+<body>
+<h1> vlerq(n) 4 vlerq &quot;Vlerq data manipulation core engine&quot;</h1>
+<h2><a name="name">NAME</a></h2>
+<p>
+<p> vlerq - The engine used by the Ratcl extension
+
+
+
+<h2><a name="table_of_contents">TABLE OF CONTENTS</a></h2>
+<p>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#table_of_contents">TABLE OF CONTENTS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#synopsis">SYNOPSIS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#description">DESCRIPTION</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#commands">COMMANDS</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#example">EXAMPLE</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#see_also">SEE ALSO</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#keywords">KEYWORDS</a><br>
+<h2><a name="synopsis">SYNOPSIS</a></h2>
+<p>
+package require <b>vlerq ?4?</b><br>
+<br><table border=1 width=100% cellspacing=0 cellpadding=0><tr            bgcolor=lightyellow><td bgcolor=lightyellow><table 0 width=100% cellspacing=0 cellpadding=0><tr valign=top ><td ><a href="#1"><b class='cmd'>vlerq</b> <i class='arg'>command</i> <i class='arg'>...</i></a></td></tr>
+<tr valign=top ><td ><a href="#2"><b class='cmd'>vlerq</b> <b class='cmd'>open</b> <i class='arg'>filename</i></a></td></tr>
+</table></td></tr></table>
+<h2><a name="description">DESCRIPTION</a></h2>
+<p>
+<p>
+
+The <strong>vlerq</strong> package provides commands used by the Ratcl extension
+to implement a general-purpose relational algebra and persistence framework.
+
+<h2><a name="commands">COMMANDS</a></h2>
+<p>
+<dl>
+
+<dt><a name="1"><b class='cmd'>vlerq</b> <i class='arg'>command</i> <i class='arg'>...</i></a><dd>
+
+
+The <b class='cmd'>vlerq</b> command wraps all the different sub-commands provided by
+the <strong>vlerq</strong> package.
+
+<br><br>
+<dt><a name="2"><b class='cmd'>vlerq</b> <b class='cmd'>open</b> <i class='arg'>filename</i></a><dd>
+
+
+The <b class='cmd'>open</b> sub-command opens a Metakit-compatible datafile and returns
+its root view.
+
+</dl>
+
+<p>
+THIS DOCUMENTATION NEEDS TO BE FINISHED
+
+<h2><a name="example">EXAMPLE</a></h2>
+<p>
+
+<p>
+<p><table><tr><td bgcolor=black>&nbsp;</td><td><pre class='sample'>
+package require vlerq
+set v [vlerq open myfile.db]
+puts [vlerq names $v]
+</pre></td></tr></table></p>
+<p>
+This lists all the sub-views available in the myfile.db file.
+
+
+
+<h2><a name="see_also">SEE ALSO</a></h2>
+<p>
+metakit, ratcl
+<h2><a name="keywords">KEYWORDS</a></h2>
+<p>
+algebra, database, persistence, relational
+</body></html>
diff --git a/8.x/vqtcl/doc/vlerq.man b/8.x/vqtcl/doc/vlerq.man
new file mode 100644 (file)
index 0000000..267799f
--- /dev/null
@@ -0,0 +1,42 @@
+[manpage_begin vlerq n 4]
+[moddesc   {Vlerq data manipulation core engine}]
+[titledesc {The engine used by the Ratcl extension}]
+[require vlerq [opt 4]]
+[description]
+[para]
+
+The [package vlerq] package provides commands used by the Ratcl extension
+to implement a general-purpose relational algebra and persistence framework.
+
+[section COMMANDS]
+[list_begin definitions]
+
+[call [cmd vlerq] [arg command] [arg ...]]
+
+The [cmd vlerq] command wraps all the different sub-commands provided by
+the [package vlerq] package.
+
+[call [cmd vlerq] [cmd open] [arg filename]]
+
+The [cmd open] sub-command opens a Metakit-compatible datafile and returns
+its root view.
+
+[list_end]
+
+[para]
+THIS DOCUMENTATION NEEDS TO BE FINISHED
+
+[section EXAMPLE]
+
+[para]
+[example {
+package require vlerq
+set v [vlerq open myfile.db]
+puts [vlerq names $v]
+}]
+[para]
+This lists all the sub-views available in the myfile.db file.
+
+[see_also ratcl metakit]
+[keywords database persistence relational algebra]
+[manpage_end]
diff --git a/8.x/vqtcl/doc/vlerq.n b/8.x/vqtcl/doc/vlerq.n
new file mode 100644 (file)
index 0000000..b907249
--- /dev/null
@@ -0,0 +1,46 @@
+'\"
+'\" Generated from file './doc/vlerq.man' by tcllib/doctools with format 'nroff'
+'\"
+.so man.macros
+.TH "vlerq" n 4 vlerq "Vlerq data manipulation core engine"
+.BS
+.SH NAME
+vlerq \- The engine used by the Ratcl extension
+.SH SYNOPSIS
+package require \fBvlerq  ?4?\fR
+.sp
+\fBvlerq\fR \fIcommand\fR \fI...\fR
+.sp
+\fBvlerq\fR \fBopen\fR \fIfilename\fR
+.sp
+.BE
+.SH DESCRIPTION
+.PP
+The \fBvlerq\fR package provides commands used by the Ratcl extension
+to implement a general-purpose relational algebra and persistence framework.
+.SH COMMANDS
+.TP
+\fBvlerq\fR \fIcommand\fR \fI...\fR
+The \fBvlerq\fR command wraps all the different sub-commands provided by
+the \fBvlerq\fR package.
+.TP
+\fBvlerq\fR \fBopen\fR \fIfilename\fR
+The \fBopen\fR sub-command opens a Metakit-compatible datafile and returns
+its root view.
+.PP
+THIS DOCUMENTATION NEEDS TO BE FINISHED
+.SH EXAMPLE
+.PP
+.nf
+
+package require vlerq
+set v [vlerq open myfile.db]
+puts [vlerq names $v]
+
+.fi
+.PP
+This lists all the sub-views available in the myfile.db file.
+.SH "SEE ALSO"
+metakit, ratcl
+.SH KEYWORDS
+algebra, database, persistence, relational
\ No newline at end of file
diff --git a/8.x/vqtcl/generic/vlerq.c b/8.x/vqtcl/generic/vlerq.c
new file mode 100644 (file)
index 0000000..1168933
--- /dev/null
@@ -0,0 +1,7602 @@
+/* vlerq.c - this is the single-source-file version of Vlerq for Tcl */
+
+/* %includeDir<../src>% */
+/* %includeDir<../src_tcl>% */
+
+/* %include<bits.c>% */
+/*
+ * bits.c - Implementation of bitwise operations.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * intern.h - Internal definitions.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <unistd.h>
+
+typedef ptrdiff_t Int_t; /* large enough to hold a pointer */
+
+typedef unsigned char Byte_t;
+
+#ifdef OBJECT_TYPE
+typedef OBJECT_TYPE Object_p;
+#else
+/*
+ * defs.h - Binding-specific definitions needed by the general code.
+ */
+
+typedef struct Tcl_Obj *Object_p;
+#endif
+
+#if !defined(VALUES_MUST_BE_ALIGNED) && (defined(__sparc__) || defined(__sgi__))
+#define VALUES_MUST_BE_ALIGNED 1
+#endif
+
+#if !defined(_BIG_ENDIAN) && defined(WORDS_BIGENDIAN)
+#define _BIG_ENDIAN 1
+#endif
+
+#if DEBUG+0
+#define Assert(x) do if (!(x)) FailedAssert(#x, __FILE__, __LINE__); while (0)
+#define DbgIf(x)  if (GetShared()->debug && (x))
+#else
+#define Assert(x)
+#define DbgIf(x)  if (0)
+#endif
+
+#define DBG_trace   (1<<0)
+#define DBG_deps    (1<<1)
+
+#define PUSH_KEEP_REFS                            \
+  { Shared_p _shared = GetShared();               \
+    struct Buffer _keep, *_prev = _shared->keeps; \
+    InitBuffer(_shared->keeps = &_keep);
+    
+#define POP_KEEP_REFS         \
+    ReleaseSequences(&_keep); \
+    _shared->keeps = _prev;   \
+  }
+
+/* keep in sync with CharAsItemType() in column.c */
+typedef enum ItemTypes {
+    IT_unknown,
+    IT_int,
+    IT_wide,
+    IT_float,
+    IT_double,
+    IT_string,
+    IT_bytes,
+    IT_object,
+    IT_column,
+    IT_view,
+    IT_error
+} ItemTypes;
+
+typedef enum ErrorCodes {
+    EC_cioor,
+    EC_rioor,
+    EC_cizwv,
+    EC_nmcw,
+    EC_rambe,
+    EC_nalor,
+    EC_wnoa
+} ErrorCodes;
+
+struct Shared {
+    struct SharedInfo *info;   /* ext_tcl.c */
+    int                refs;   /* ext_tcl.c */
+    int                debug;  /* debug flags */
+    struct Buffer     *keeps;  /* column.c */
+    struct Sequence   *empty;  /* view.c */
+};
+
+typedef struct Shared   *Shared_p;
+typedef struct SeqType  *SeqType_p;
+typedef struct Sequence *Seq_p;
+typedef struct Column   *Column_p;
+typedef union Item      *Item_p;
+typedef Seq_p            View_p;
+
+typedef ItemTypes  (*Getter) (int row, Item_p item);
+typedef void       (*Cleaner) (Seq_p seq);
+
+struct SeqType {
+  const char *name;      /* for introspection only */
+  Getter      getfun;    /* item accessor, copied to Sequence during setup */
+  short       cleanups;  /* octal for data[0..3].p: 0=none, 1=decref, 2=free */
+  Cleaner     cleaner;   /* called before performing the above cleanups */
+};
+
+struct Sequence {
+  int        count;   /* number of entries */
+  int        refs;    /* reference count */
+  SeqType_p  type;    /* type dispatch table */
+  Getter     getter;  /* item accessor function */
+  union { int i; void *p; Seq_p q; Object_p o; } data[4]; /* getter-specific */
+};
+
+#define IncRefCount(seq) AdjustSeqRefs(seq, 1)
+#define DecRefCount(seq) AdjustSeqRefs(seq, -1)
+#define KeepRef(seq) IncRefCount(LoseRef(seq))
+
+typedef struct Column {
+    Seq_p        seq;    /* the sequence which will handle accesses */
+    int          pos;    /* position of this column in the view */
+} Column;              
+                       
+typedef union Item {
+    char         b [8];  /* used for raw access and byte-swapping */
+    int          q [2];  /* used for hash calculation of wides and doubles */
+    int          i;      /* IT_int */
+    int64_t      w;      /* IT_wide */
+    float        f;      /* IT_float */
+    double       d;      /* IT_double */
+    const void  *p;      /* used to convert pointers */
+    const char  *s;      /* IT_string */
+    struct { const Byte_t *ptr; int len; } u; /* IT_bytes */
+    Object_p     o;      /* IT_object */
+    Column       c;      /* IT_column */
+    View_p       v;      /* IT_view */
+    ErrorCodes   e;      /* IT_error */
+} Item;
+
+/* column.c */
+
+void      *(AdjustSeqRefs) (void *refs, int count);
+void       (AppendToStrVec) (const void *s, int bytes, Seq_p seq);
+int        (CastObjToItem) (char type, Item_p item);
+ItemTypes  (CharAsItemType) (char type);
+Column     (CoerceColumn) (ItemTypes type, Object_p obj);
+void       (FailedAssert) (const char *msg, const char *file, int line);
+Column     (ForceStringColumn) (Column column);
+Item       (GetColItem) (int row, Column column, ItemTypes type);
+ItemTypes  (GetItem) (int row, Item_p item);
+Item       (GetSeqItem) (int row, Seq_p seq, ItemTypes type);
+Item       (GetViewItem) (View_p view, int row, int col, ItemTypes type);
+Seq_p      (LoseRef) (Seq_p seq);
+Seq_p      (NewBitVec) (int count);
+Seq_p      (NewIntVec) (int count, int **dataptr);
+Seq_p      (NewPtrVec) (int count, Int_t **dataptr);
+Seq_p      (NewSequence) (int count, SeqType_p type, int auxbytes);
+Seq_p      (NewSequenceNoRef) (int count, SeqType_p type, int auxbytes);
+Seq_p      (NewSeqVec) (ItemTypes type, const Seq_p *p, int n);
+Seq_p      (NewStrVec) (int istext);
+Seq_p      (FinishStrVec) (Seq_p seq);
+void       (ReleaseSequences) (struct Buffer *keep);
+Seq_p      (ResizeSeq) (Seq_p seq, int pos, int diff, int elemsize);
+Column     (SeqAsCol) (Seq_p seq);
+
+/* buffer.c */
+
+typedef struct Buffer *Buffer_p;
+typedef struct Overflow *Overflow_p;
+
+struct Buffer {
+    union { char *c; int *i; const void **p; } fill;
+    char       *limit;
+    Overflow_p  head;
+    Int_t       saved;
+    Int_t       used;
+    char       *ofill;
+    char       *result;
+    char        buf [128];
+    char        slack [8];
+};
+
+#define ADD_ONEC_TO_BUF(b,x) (*(b).fill.c++ = (x))
+
+#define ADD_CHAR_TO_BUF(b,x) \
+          { char _c = (x); \
+            if ((b).fill.c < (b).limit) *(b).fill.c++ = _c; \
+              else AddToBuffer(&(b), &_c, sizeof _c); }
+
+#define ADD_INT_TO_BUF(b,x) \
+          { int _i = (x); \
+            if ((b).fill.c < (b).limit) *(b).fill.i++ = _i; \
+              else AddToBuffer(&(b), &_i, sizeof _i); }
+
+#define ADD_PTR_TO_BUF(b,x) \
+          { const void *_p = (x); \
+            if ((b).fill.c < (b).limit) *(b).fill.p++ = _p; \
+              else AddToBuffer(&(b), &_p, sizeof _p); }
+
+#define BufferFill(b) ((b)->saved + ((b)->fill.c - (b)->buf))
+
+void   (InitBuffer) (Buffer_p bp);
+void   (ReleaseBuffer) (Buffer_p bp, int keep);
+void   (AddToBuffer) (Buffer_p bp, const void *data, Int_t len);
+void  *(BufferAsPtr) (Buffer_p bp, int fast);
+Seq_p  (BufferAsIntVec) (Buffer_p bp);
+int    (NextBuffer) (Buffer_p bp, char **firstp, int *countp);
+
+/* view.c */
+
+typedef enum MetaCols {
+  MC_name, MC_type, MC_subv, MC_limit
+} MetaCols;
+
+#define V_Cols(view) ((Column_p) ((Seq_p) (view) + 1))
+#define V_Types(view) (*(char**) ((view)->data))
+#define V_Meta(view) (*(View_p*) ((view)->data+1))
+
+#define ViewAsCol(v) SeqAsCol(v)
+#define ViewWidth(view) ((view)->count)
+#define ViewCol(view,col) (V_Cols(view)[col])
+#define ViewColType(view,col) ((ItemTypes) V_Types(view)[col])
+#define ViewCompat(view1,view2) MetaIsCompatible(V_Meta(view1), V_Meta(view2))
+
+View_p  (DescAsMeta) (const char** desc, const char* end);
+View_p  (EmptyMetaView) (void);
+char    (GetColType) (View_p meta, int col);
+View_p  (IndirectView) (View_p meta, Seq_p seq);
+View_p  (NewView) (View_p meta);
+View_p  (MakeIntColMeta) (const char *name);
+int     (MetaIsCompatible) (View_p meta1, View_p meta2);
+void    (ReleaseUnusedViews) (void);
+void    (SetViewCols) (View_p view, int first, int count, Column src);
+void    (SetViewSeqs) (View_p view, int first, int count, Seq_p src);
+
+/* hash.c */
+
+int    (HashMapAdd) (Seq_p hmap, int key, int value);
+int    (HashMapLookup) (Seq_p hmap, int key, int defval);
+Seq_p  (HashMapNew) (void);
+int    (HashMapRemove) (Seq_p hmap, int key);
+
+/* file.c */
+
+typedef Seq_p MappedFile_p;
+
+MappedFile_p  (InitMappedFile) (const char *data, Int_t length, Cleaner fun);
+View_p        (MappedToView) (MappedFile_p map, View_p base);
+View_p        (OpenDataFile) (const char *filename);
+
+/* emit.c */
+
+typedef void *(*SaveInitFun)(void*,Int_t);
+typedef void *(*SaveDataFun)(void*,const void*,Int_t);
+
+void   (MetaAsDesc) (View_p meta, Buffer_p buffer);
+Int_t  (ViewSave) (View_p view, void *aux, SaveInitFun, SaveDataFun, int);
+
+/* getters.c */
+
+SeqType_p (PickIntGetter) (int bits);
+SeqType_p (FixedGetter) (int bytes, int rows, int real, int flip);
+
+/* bits.c */
+      
+char  *(Bits2elias) (const char *bytes, int count, int *outsize);
+void   (ClearBit) (Seq_p bitmap, int row);
+int    (CountBits) (Seq_p seq);
+Seq_p  (MinBitCount) (Seq_p *pbitmap, int count);
+int    (NextBits) (Seq_p bits, int *fromp, int *countp);
+int    (NextElias) (const char *bytes, int count, int *inbits);
+int    (SetBit) (Seq_p *pbitmap, int row);
+void   (SetBitRange) (Seq_p bits, int from, int count);
+int    (TestBit) (Seq_p bitmap, int row);
+int    (TopBit) (int v);
+
+/* mutable.c */
+
+enum MutPrepares {
+    MP_insdat, MP_adjdat, MP_usemap, MP_delmap, MP_adjmap,
+    MP_insmap, MP_revmap, MP_limit
+};
+
+int     (IsMutable) (View_p view);
+View_p  (MutableView) (View_p view);
+Seq_p   (MutPrepare) (View_p view);
+View_p  (ViewSet) (View_p view, int row, int col, Item_p item);
+
+/* the following must be supplied in the language binding */
+
+int            (ColumnByName) (View_p meta, Object_p obj);
+struct Shared *(GetShared) (void);
+void           (InvalidateView) (Object_p obj);
+Object_p       (ItemAsObj) (ItemTypes type, Item_p item);
+Object_p       (NeedMutable) (Object_p obj);
+Column         (ObjAsColumn) (Object_p obj);
+View_p         (ObjAsView) (Object_p obj);
+int            (ObjToItem) (ItemTypes type, Item_p item);
+
+int TestBit (Seq_p bitmap, int row) {
+    if (bitmap != NULL && row < bitmap->count) {
+        const Byte_t *bits = bitmap->data[0].p;
+        return (bits[row>>3] >> (row&7)) & 1;
+    }
+    return 0;
+}
+
+int SetBit (Seq_p *pbitmap, int row) {
+    Byte_t *bits;
+    Seq_p bitmap = *pbitmap;
+    
+    if (bitmap == NULL)
+        *pbitmap = bitmap = IncRefCount(NewBitVec(row+1));
+
+    if (TestBit(bitmap, row))
+        return 0;
+    
+    if (row >= bitmap->count) {
+        int bytes = bitmap->data[1].i;
+        if (row >= 8 * bytes) {
+            Seq_p newbitmap = IncRefCount(NewBitVec(12 * bytes));
+            memcpy(newbitmap->data[0].p, LoseRef(bitmap)->data[0].p, bytes);
+            *pbitmap = bitmap = newbitmap;
+        }
+        bitmap->count = row + 1;
+    }
+
+    bits = bitmap->data[0].p;
+    bits[row>>3] |= 1 << (row&7);
+    
+    return 8 * bitmap->data[1].i;
+}
+
+void ClearBit (Seq_p bitmap, int row) {
+    if (TestBit(bitmap, row)) {
+        Byte_t *bits = bitmap->data[0].p;
+        bits[row>>3] &= ~ (1 << (row&7));
+    }
+}
+
+void SetBitRange (Seq_p bits, int from, int count) {
+    while (--count >= 0)
+        SetBit(&bits, from++);
+}
+
+Seq_p MinBitCount (Seq_p *pbitmap, int count) {
+    if (*pbitmap == NULL || (*pbitmap)->count < count) {
+        SetBit(pbitmap, count);
+        ClearBit(*pbitmap, count);
+        --(*pbitmap)->count;
+    }
+    return *pbitmap;
+}
+
+int NextBits (Seq_p bits, int *fromp, int *countp) {
+    int curr = *fromp + *countp;
+    
+    while (curr < bits->count && !TestBit(bits, curr))
+        ++curr;
+        
+    *fromp = curr;
+    
+    while (curr < bits->count && TestBit(bits, curr))
+        ++curr;
+        
+    *countp = curr - *fromp;
+    return *countp;
+}
+
+int TopBit (int v) {
+#define Vn(x) (v < (1<<x))
+    return Vn(16) ? Vn( 8) ? Vn( 4) ? Vn( 2) ? Vn( 1) ? v-1 : 1
+                                             : Vn( 3) ?  2 :  3
+                                    : Vn( 6) ? Vn( 5) ?  4 :  5
+                                             : Vn( 7) ?  6 :  7
+                           : Vn(12) ? Vn(10) ? Vn( 9) ?  8 :  9
+                                             : Vn(11) ? 10 : 11
+                                    : Vn(14) ? Vn(13) ? 12 : 13
+                                             : Vn(15) ? 14 : 15
+                  : Vn(24) ? Vn(20) ? Vn(18) ? Vn(17) ? 16 : 17
+                                             : Vn(19) ? 18 : 19
+                                    : Vn(22) ? Vn(21) ? 20 : 21
+                                             : Vn(23) ? 22 : 23
+                           : Vn(28) ? Vn(26) ? Vn(25) ? 24 : 25
+                                             : Vn(27) ? 26 : 27
+                                    : Vn(30) ? Vn(29) ? 28 : 29
+                                             : Vn(31) ? 30 : 31;
+#undef Vn
+}
+
+static void EmitBits(char *bytes, int val, int *ppos) {
+    char *curr = bytes + (*ppos >> 3);
+    int bit = 8 - (*ppos & 7);
+    int top = TopBit(val), n = top + 1;
+    
+    Assert(val > 0);
+    
+    while (top >= bit) {
+        ++curr;
+        top -= bit;
+        bit = 8;
+    }
+    
+    bit -= top;
+    
+    while (n >= bit) {
+        *curr++ |= (char) (val >> (n-bit));
+        val &= (1 << (n-bit)) - 1;
+        n -= bit;
+        bit = 8;
+    }
+    
+    *curr |= (char) (val << (bit - n));
+    *ppos = ((curr - bytes) << 3) + (8 - bit) + n;
+}
+
+char *Bits2elias (const char *bytes, int count, int *outbits) {
+    int i, last, bits = 0;
+    char *out;
+    
+    if (count <= 0) {
+        *outbits = 0;
+        return NULL;
+    }
+    
+    out = calloc(1, (count+count/2)/8+1);
+    last = *bytes & 1;
+    *out = last << 7;
+    *outbits = 1;
+    for (i = 0; i < count; ++i) {
+        if (((bytes[i>>3] >> (i&7)) & 1) == last)
+            ++bits;
+        else {
+            EmitBits(out, bits, outbits);
+            bits = 1;
+            last ^= 1;
+        }
+    }
+
+    if (bits)
+        EmitBits(out, bits, outbits);
+    
+    return out;
+}
+
+int NextElias (const char *bytes, int count, int *inbits) {
+    int val = 0;
+    const char *in;
+    
+    if (*inbits == 0)
+        *inbits = 1;
+    
+    in = bytes + (*inbits >> 3);
+    if (in < bytes + count) {
+        int i = 0, bit = 8 - (*inbits & 7);
+        
+        for (;;) {
+            ++i;
+            if (*in & (1 << (bit-1)))
+                break;
+            if (--bit <= 0) {
+                if (++in >= bytes + count)
+                    return 0;
+                bit = 8;
+            }
+        }
+        
+        while (i >= bit) {
+            val <<= bit;
+            val |= (*in++ & ((1 << bit) - 1));
+            i -= bit;
+            bit = 8;
+        }
+        
+        val <<= i;
+        val |= (*in >> (bit - i)) & ((1 << i) - 1);
+        *inbits = ((in - bytes) << 3) + (8 - bit) + i;
+    }
+    
+    return val;
+}
+
+int CountBits (Seq_p seq) {
+    int result = 0, from = 0, count = 0;
+
+    if (seq != NULL)
+        while (NextBits(seq, &from, &count))
+            result += count;
+
+    return result;
+}
+
+ItemTypes BitRunsCmd_i (Item_p a) {
+    int i, outsize, count = a->c.seq->count, pos = 0;
+    char *data;
+    struct Buffer buffer;
+    Seq_p temp;
+
+    temp = NewBitVec(count);
+    
+    for (i = 0; i < count; ++i) {
+        if (GetColItem(i, a->c, IT_int).i)
+            SetBit(&temp, i);
+    }
+
+    data = Bits2elias(temp->data[0].p, count, &outsize);
+
+    count = (outsize + 7) / 8;
+    InitBuffer(&buffer);
+    
+    if (count > 0) {
+        ADD_INT_TO_BUF(buffer, (*data & 0x80) != 0);
+        while ((i = NextElias(data, count, &pos)) != 0)
+            ADD_INT_TO_BUF(buffer, i);
+    }
+    
+    free(data);
+    
+    a->c = SeqAsCol(BufferAsIntVec(&buffer));
+    return IT_column;
+}
+/* %include<buffer.c>% */
+/*
+ * buffer.c - Implementation of a simple temporary buffer.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+typedef struct Overflow {
+    char                b[4096];    /* must be first member */
+    Overflow_p  next;
+} Overflow;
+
+void InitBuffer (Buffer_p bp) {
+    bp->fill.c = bp->buf;
+    bp->limit = bp->buf + sizeof bp->buf;
+    bp->head = 0;
+    bp->ofill = 0;
+    bp->saved = 0;
+    bp->result = 0;
+}
+
+void ReleaseBuffer (Buffer_p bp, int keep) {
+    while (bp->head != 0) {
+        Overflow_p op = bp->head;
+        bp->head = op->next;
+        free(op);
+    }
+    if (!keep && bp->result != 0)
+        free(bp->result);
+}
+
+void AddToBuffer (Buffer_p bp, const void *data, Int_t len) {
+    Int_t n;
+    while (len > 0) {
+        if (bp->fill.c >= bp->limit) {
+            if (bp->head == 0 || 
+                    bp->ofill >= bp->head->b + sizeof bp->head->b) {
+                Overflow_p op = (Overflow_p) malloc(sizeof(Overflow));
+                op->next = bp->head;
+                bp->head = op;
+                bp->ofill = op->b;
+            }
+            memcpy(bp->ofill, bp->buf, sizeof bp->buf);
+            bp->ofill += sizeof bp->buf;
+            bp->saved += sizeof bp->buf;
+            n = bp->fill.c - bp->slack;
+            memcpy(bp->buf, bp->slack, n);
+            bp->fill.c = bp->buf + n;
+        }
+        n = len;
+        if (n > bp->limit - bp->fill.c)
+            n = bp->limit - bp->fill.c; /* TODO: copy big chunks to overflow */
+        memcpy(bp->fill.c, data, n);
+        bp->fill.c += n;
+        data = (const char*) data + n;
+        len -= n;
+    }
+}
+
+int NextBuffer (Buffer_p bp, char **firstp, int *countp) {
+    int count;
+    
+    if (*firstp == NULL) {
+        Overflow_p p = bp->head, q = NULL;
+        while (p != NULL) {
+            Overflow_p t = p->next;
+            p->next = q;
+            q = p;
+            p = t;
+        }
+        
+        bp->head = q;
+        bp->used = 0;
+    } else if (*firstp == bp->head->b) {
+        bp->head = bp->head->next;
+        bp->used += *countp;
+        free(*firstp);
+    } else if (*firstp == bp->buf)
+        return *countp == 0;
+    
+    if (bp->head != NULL) {
+        *firstp = bp->head->b;
+        count = bp->saved - bp->used;
+        if (count > sizeof bp->head->b)
+            count = sizeof bp->head->b;
+    } else {
+        count = bp->fill.c - bp->buf;
+        *firstp = bp->buf;
+    }
+    
+    *countp = count;
+    return *countp;
+}
+
+void *BufferAsPtr (Buffer_p bp, int fast) {
+    Int_t len;
+    char *data, *ptr = NULL;
+    int cnt;
+
+    if (fast && bp->saved == 0)
+        return bp->buf;
+
+    len = BufferFill(bp);
+    if (bp->result == 0)
+        bp->result = malloc(len);
+        
+    for (data = bp->result; NextBuffer(bp, &ptr, &cnt); data += cnt)
+        memcpy(data, ptr, cnt);
+
+    return bp->result;
+}
+
+Seq_p BufferAsIntVec (Buffer_p bp) {
+    int cnt;
+    char *data, *ptr = NULL;
+    Seq_p seq;
+    
+    seq = NewIntVec(BufferFill(bp) / sizeof(int), (void*) &data);
+
+    for (; NextBuffer(bp, &ptr, &cnt); data += cnt)
+        memcpy(data, ptr, cnt);
+
+    return seq;
+}
+/* %include<column.c>% */
+/*
+ * column.c - Implementation of sequences, columns, and items.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* wrap_gen.h - generated code, do not edit */
+
+View_p (BlockedView) (View_p);
+View_p (CloneView) (View_p);
+Column (CoerceCmd) (Object_p, const char*);
+View_p (ColMapView) (View_p, Column);
+View_p (ColOmitView) (View_p, Column);
+View_p (ConcatView) (View_p, View_p);
+View_p (DescToMeta) (const char*);
+View_p (FirstView) (View_p, int);
+Column (GetHashInfo) (View_p, View_p, int);
+View_p (GroupCol) (View_p, Column, const char*);
+View_p (GroupedView) (View_p, Column, Column, const char*);
+int    (HashDoFind) (View_p, int, View_p, Column, Column, Column);
+Column (HashValues) (View_p);
+View_p (IjoinView) (View_p, View_p);
+Column (IntersectMap) (View_p, View_p);
+View_p (JoinView) (View_p, View_p, const char*);
+View_p (LastView) (View_p, int);
+Column (NewCountsColumn) (Column);
+Column (NewIotaColumn) (int);
+View_p (NoColumnView) (int);
+View_p (ObjAsMetaView) (Object_p);
+Column (OmitColumn) (Column, int);
+View_p (OneColView) (View_p, int);
+View_p (PairView) (View_p, View_p);
+View_p (RemapSubview) (View_p, Column, int, int);
+int    (RowCompare) (View_p, int, View_p, int);
+int    (RowEqual) (View_p, int, View_p, int);
+int    (RowHash) (View_p, int);
+Column (SortMap) (View_p);
+View_p (StepView) (View_p, int, int, int, int);
+int    (StringLookup) (const char*, Column);
+View_p (TagView) (View_p, const char*);
+View_p (TakeView) (View_p, int);
+View_p (UngroupView) (View_p, int);
+Column (UniqMap) (View_p);
+View_p (V_Meta) (View_p);
+Column (ViewAsCol) (View_p);
+Column (ViewCol) (View_p, int);
+int    (ViewCompare) (View_p, View_p);
+int    (ViewCompat) (View_p, View_p);
+View_p (ViewReplace) (View_p, int, int, View_p);
+int    (ViewSize) (View_p);
+int    (ViewWidth) (View_p);
+
+ItemTypes (AppendCmd_VV) (Item_p a);
+ItemTypes (AtCmd_VIO) (Item_p a);
+ItemTypes (AtRowCmd_OI) (Item_p a);
+ItemTypes (BitRunsCmd_i) (Item_p a);
+ItemTypes (BlockedCmd_V) (Item_p a);
+ItemTypes (CloneCmd_V) (Item_p a);
+ItemTypes (CoerceCmd_OS) (Item_p a);
+ItemTypes (ColConvCmd_C) (Item_p a);
+ItemTypes (ColMapCmd_Vn) (Item_p a);
+ItemTypes (ColOmitCmd_Vn) (Item_p a);
+ItemTypes (CompareCmd_VV) (Item_p a);
+ItemTypes (CompatCmd_VV) (Item_p a);
+ItemTypes (ConcatCmd_VV) (Item_p a);
+ItemTypes (CountsCmd_VN) (Item_p a);
+ItemTypes (CountsColCmd_C) (Item_p a);
+ItemTypes (CountViewCmd_I) (Item_p a);
+ItemTypes (DataCmd_VX) (Item_p a);
+ItemTypes (DebugCmd_I) (Item_p a);
+ItemTypes (DefCmd_OO) (Item_p a);
+ItemTypes (DeleteCmd_VII) (Item_p a);
+ItemTypes (DepsCmd_O) (Item_p a);
+ItemTypes (EmitCmd_V) (Item_p a);
+ItemTypes (EmitModsCmd_V) (Item_p a);
+ItemTypes (ExceptCmd_VV) (Item_p a);
+ItemTypes (ExceptMapCmd_VV) (Item_p a);
+ItemTypes (FirstCmd_VI) (Item_p a);
+ItemTypes (GetCmd_VX) (Item_p a);
+ItemTypes (GetColCmd_VN) (Item_p a);
+ItemTypes (GetInfoCmd_VVI) (Item_p a);
+ItemTypes (GroupCmd_VnS) (Item_p a);
+ItemTypes (GroupedCmd_ViiS) (Item_p a);
+ItemTypes (HashColCmd_SO) (Item_p a);
+ItemTypes (HashFindCmd_VIViii) (Item_p a);
+ItemTypes (HashViewCmd_V) (Item_p a);
+ItemTypes (IjoinCmd_VV) (Item_p a);
+ItemTypes (InsertCmd_VIV) (Item_p a);
+ItemTypes (IntersectCmd_VV) (Item_p a);
+ItemTypes (IotaCmd_I) (Item_p a);
+ItemTypes (IsectMapCmd_VV) (Item_p a);
+ItemTypes (JoinCmd_VVS) (Item_p a);
+ItemTypes (LastCmd_VI) (Item_p a);
+ItemTypes (LoadCmd_O) (Item_p a);
+ItemTypes (LoadModsCmd_OV) (Item_p a);
+ItemTypes (LoopCmd_X) (Item_p a);
+ItemTypes (MaxCmd_VN) (Item_p a);
+ItemTypes (MdefCmd_O) (Item_p a);
+ItemTypes (MdescCmd_S) (Item_p a);
+ItemTypes (MetaCmd_V) (Item_p a);
+ItemTypes (MinCmd_VN) (Item_p a);
+ItemTypes (MutInfoCmd_V) (Item_p a);
+ItemTypes (NameColCmd_V) (Item_p a);
+ItemTypes (NamesCmd_V) (Item_p a);
+ItemTypes (OmitMapCmd_iI) (Item_p a);
+ItemTypes (OneColCmd_VN) (Item_p a);
+ItemTypes (OpenCmd_S) (Item_p a);
+ItemTypes (PairCmd_VV) (Item_p a);
+ItemTypes (ProductCmd_VV) (Item_p a);
+ItemTypes (RefCmd_OX) (Item_p a);
+ItemTypes (RefsCmd_O) (Item_p a);
+ItemTypes (RemapCmd_Vi) (Item_p a);
+ItemTypes (RemapSubCmd_ViII) (Item_p a);
+ItemTypes (RenameCmd_VO) (Item_p a);
+ItemTypes (RepeatCmd_VI) (Item_p a);
+ItemTypes (ReplaceCmd_VIIV) (Item_p a);
+ItemTypes (ResizeColCmd_iII) (Item_p a);
+ItemTypes (ReverseCmd_V) (Item_p a);
+ItemTypes (RowCmpCmd_VIVI) (Item_p a);
+ItemTypes (RowEqCmd_VIVI) (Item_p a);
+ItemTypes (RowHashCmd_VI) (Item_p a);
+ItemTypes (SaveCmd_VS) (Item_p a);
+ItemTypes (SetCmd_MIX) (Item_p a);
+ItemTypes (SizeCmd_V) (Item_p a);
+ItemTypes (SliceCmd_VIII) (Item_p a);
+ItemTypes (SortCmd_V) (Item_p a);
+ItemTypes (SortMapCmd_V) (Item_p a);
+ItemTypes (SpreadCmd_VI) (Item_p a);
+ItemTypes (StepCmd_VIIII) (Item_p a);
+ItemTypes (StrLookupCmd_Ss) (Item_p a);
+ItemTypes (StructDescCmd_V) (Item_p a);
+ItemTypes (StructureCmd_V) (Item_p a);
+ItemTypes (SumCmd_VN) (Item_p a);
+ItemTypes (TagCmd_VS) (Item_p a);
+ItemTypes (TakeCmd_VI) (Item_p a);
+ItemTypes (ToCmd_OO) (Item_p a);
+ItemTypes (TypeCmd_O) (Item_p a);
+ItemTypes (TypesCmd_V) (Item_p a);
+ItemTypes (UngroupCmd_VN) (Item_p a);
+ItemTypes (UnionCmd_VV) (Item_p a);
+ItemTypes (UnionMapCmd_VV) (Item_p a);
+ItemTypes (UniqueCmd_V) (Item_p a);
+ItemTypes (UniqueMapCmd_V) (Item_p a);
+ItemTypes (ViewCmd_X) (Item_p a);
+ItemTypes (ViewAsColCmd_V) (Item_p a);
+ItemTypes (ViewConvCmd_V) (Item_p a);
+ItemTypes (WidthCmd_V) (Item_p a);
+ItemTypes (WriteCmd_VO) (Item_p a);
+
+/* end of generated code */
+
+ItemTypes DebugCmd_I (Item_p a) {
+       Shared_p sh = GetShared();
+       a->i = sh->debug ^= a[0].i;
+       return IT_int;
+}
+
+void *AdjustSeqRefs (void *refs, int count) {
+       /*if (count > 0)*/
+       if (refs != NULL) {
+               Seq_p ptr = refs;
+               ptr->refs += count;
+               if (ptr->refs <= 0) {
+                       if (ptr->type != NULL) {
+                               int i, f;
+                               
+                               if (ptr->type->cleaner != NULL)
+                                       ptr->type->cleaner(ptr);
+
+                               for (i = 0, f = ptr->type->cleanups; f > 0; ++i, f >>= 3)
+                                       if (f & 1)
+                                               DecRefCount(ptr->data[i].p);
+                                       else if (f & 2)
+                                               free(ptr->data[i].p);
+                       }
+                       free(refs);
+                       refs = NULL;
+               }
+       }
+       return refs;
+}
+
+Seq_p LoseRef (Seq_p seq) {
+       ADD_PTR_TO_BUF(*GetShared()->keeps, seq);
+       return seq;
+}
+
+Column SeqAsCol (Seq_p seq) {
+       Column result;
+       result.seq = seq;
+       result.pos = -1;
+       return result;
+}
+
+Seq_p NewSequenceNoRef (int count, SeqType_p type, int bytes) {
+       Seq_p seq;
+       
+       seq = calloc(1, sizeof(struct Sequence) + bytes);
+       seq->count = count;
+       seq->type = type;
+       seq->getter = type->getfun;
+
+       /* default for data[0].p is to point to the aux bytes after the sequence */
+       /* default for data[1].i is to contain number of extra bytes allocated */
+       seq->data[0].p = seq + 1;
+       seq->data[1].i = bytes;
+       
+       /* make sure 64-bit values have a "natural" 8-byte alignment */
+       Assert(((Int_t) seq->data[0].p) % 8 == 0);
+
+       return seq;
+}
+
+Seq_p NewSequence (int count, SeqType_p type, int bytes) {
+       return KeepRef(NewSequenceNoRef(count, type, bytes));
+}
+
+void ReleaseSequences (Buffer_p keep) {
+       int cnt;
+       char *ptr = NULL;
+       
+       while (NextBuffer(keep, &ptr, &cnt)) {
+               Seq_p *refs = (Seq_p*) ptr;
+               int count = cnt / sizeof(Seq_p);
+
+               while (--count >= 0)
+                       DecRefCount(refs[count]);
+       }
+}
+
+/* TODO: not used yet, should review refcount scenarios, might be wrong now */
+Seq_p ResizeSeq (Seq_p seq, int pos, int diff, int elemsize) {
+       int newcnt, olimit, nlimit = 0, bytes;
+       Seq_p result = seq;
+       
+       Assert(seq->refs == 1);
+       
+       newcnt = seq->count + diff;
+       bytes = seq->data[1].i;
+       olimit = bytes / elemsize;
+       
+       if (diff > 0) { /* grow when limit is reached */
+               if (newcnt > olimit) {
+                       nlimit = (olimit / 2) * 3 + 4;
+                       if (nlimit < newcnt)
+                               nlimit = newcnt + 4;
+               }
+       } else { /* shrink when less than half full */
+               if (newcnt < olimit / 2) {
+                       nlimit = newcnt + 2;
+                       bytes = seq->count * elemsize;
+               }
+       }
+
+       if (nlimit > 0) {
+               result = IncRefCount(NewSequence(seq->count, seq->type,
+                                                               nlimit * elemsize));
+               result->getter = seq->getter;
+               result->data[2] = seq->data[2];
+               result->data[3] = seq->data[3];
+               memcpy(result+1, seq+1, pos * elemsize);
+
+               seq->type = NULL; /* release and prevent from calling cleaner */
+               /*LoseRef(seq);*/
+       }
+
+       if (diff > 0) {
+               memmove((char*) (result+1) + (pos + diff) * elemsize,
+                                               (char*) (seq+1) + pos * elemsize,
+                                               (seq->count - pos) * elemsize);
+               memset((char*) (result+1) + pos * elemsize, 0, diff * elemsize);
+       } else
+               memmove((char*) (result+1) + pos * elemsize,
+                                               (char*) (seq+1) + (pos - diff) * elemsize,
+                                               (seq->count - (pos - diff)) * elemsize);
+       
+       result->count += diff;
+       return result;
+}
+
+ItemTypes ResizeColCmd_iII (Item_p a) {
+       int r, *data;
+       Seq_p seq, result;
+       
+       seq = a[0].c.seq;
+       result = NewIntVec(seq->count, &data);
+       for (r = 0; r < seq->count; ++r)
+               data[r] = GetSeqItem(r, seq, IT_int).i;
+               
+       a->c.seq = ResizeSeq(result, a[1].i, a[2].i, sizeof(int));
+       return IT_column;
+}
+
+Seq_p NewBitVec (int count) {
+       return NewSequence(count, PickIntGetter(1), (count + 7) / 8);
+}
+
+Seq_p NewIntVec (int count, int **dataptr) {
+       const int w = sizeof(int);
+       Seq_p seq = NewSequence(count, PickIntGetter(8 * w), w * count);
+       if (dataptr != NULL)
+               *dataptr = seq->data[0].p;
+       return seq;
+}
+
+Seq_p NewPtrVec (int count, Int_t **dataptr) {
+       const int w = sizeof(Int_t);
+       Seq_p result = NewSequence(count, PickIntGetter(8 * w), w * count);
+       if (dataptr != NULL)
+               *dataptr = result->data[0].p;
+       return result;
+}
+
+ItemTypes GetItem (int row, Item_p item) {
+       Seq_p seq = item->c.seq;
+       
+       if (row < 0 || row >= seq->count) {
+               item->e = EC_rioor;
+               return IT_error;
+       }
+               
+       return seq->getter(row, item);
+}
+
+Item GetColItem (int row, Column column, ItemTypes type) {
+       Item item;
+       ItemTypes got;
+       
+       item.c = column;
+       got = GetItem(row, &item);
+       Assert(got == type);
+       return item;
+}
+
+Item GetSeqItem (int row, Seq_p seq, ItemTypes type) {
+       Item item;
+       ItemTypes got;
+       
+       item.c.seq = seq;
+       item.c.pos = -1;
+       got = GetItem(row, &item);
+       Assert(got == type);
+       return item;
+}
+
+Item GetViewItem (View_p view, int row, int col, ItemTypes type) {
+       Item item;
+       ItemTypes got;
+       
+       item.c = ViewCol(view, col);
+       got = GetItem(row, &item);
+       Assert(got == type);
+       return item;
+}
+
+#if 0 /* unused */
+const char *ItemTypeAsString (ItemTypes type) {
+       static const char *typeTable[] = {
+               "",      /* IT_unknown */
+               "I", /* IT_int */
+               "L", /* IT_wide */
+               "D", /* IT_double */
+               "S", /* IT_string */
+               "O", /* IT_object */
+               "C", /* IT_column */
+               "V", /* IT_view */
+               "E", /* IT_error */
+       };
+
+       return typeTable[type];
+}
+#endif
+
+ItemTypes CharAsItemType (char type) {
+       switch (type) {
+               case 0:         return IT_unknown;
+               case 'I': return IT_int;
+               case 'L': return IT_wide;
+               case 'F': return IT_float;
+               case 'D': return IT_double;
+               case 'S': return IT_string;
+               case 'B': return IT_bytes;
+               case 'O': return IT_object;
+               case 'C': return IT_column;
+               case 'V': return IT_view;
+       }
+       return IT_error;
+}
+
+static ItemTypes StringGetter (int row, Item_p item) {
+       char **ptrs = (char**) item->c.seq->data[0].p;
+       item->s = ptrs[row];
+       return IT_string;
+}
+
+static struct SeqType ST_String = { "string", StringGetter, 0102 };
+
+static ItemTypes BytesGetter (int row, Item_p item) {
+       char **ptrs = (char**) item->c.seq->data[0].p;
+       item->u.ptr = (const Byte_t*) ptrs[row];
+       item->u.len = ptrs[row+1] - ptrs[row];
+       return IT_bytes;
+}
+
+static struct SeqType ST_Bytes = { "string", BytesGetter, 0102 };
+
+Seq_p NewStrVec (int istext) {
+       Seq_p seq;
+       Buffer_p bufs;
+
+       bufs = malloc(2 * sizeof(struct Buffer));
+       InitBuffer(bufs);
+       InitBuffer(bufs+1);
+
+       seq = NewSequence(0, istext ? &ST_String : &ST_Bytes, 0);
+       /* data[0] starts as two buffers, then becomes vector of string pointers */
+       /* data[1] is not used */
+       /* data[2] is an optional pointer to hash map sequence, see StringLookup */
+       seq->data[0].p = bufs;
+       
+       return seq;
+}
+
+void AppendToStrVec (const void *string, int bytes, Seq_p seq) {
+       Buffer_p bufs = seq->data[0].p;
+
+       if (bytes < 0)
+               bytes = strlen((const char*) string) + 1;
+       
+       /* TODO: consider tracking pointers i.s.o. making actual copies here */
+       AddToBuffer(bufs, string, bytes);
+       ADD_INT_TO_BUF(bufs[1], bytes);
+       
+       ++seq->count;
+}
+
+Seq_p FinishStrVec (Seq_p seq) {
+       int r = 0, cnt = 0, *iptr = NULL;
+       char *fill, **ptrs, *cptr = NULL;
+       Buffer_p bufs = seq->data[0].p;
+
+       ptrs = malloc((seq->count+1) * sizeof(char*) + BufferFill(bufs));
+
+       fill = (char*) (ptrs + seq->count + 1);
+       while (NextBuffer(bufs+1, (void*) &iptr, &cnt)) {
+               int i, n = cnt / sizeof(int);
+               for (i = 0; i < n; ++i) {
+                       ptrs[r++] = fill;
+                       fill += iptr[i];
+               }
+       }
+       ptrs[r] = fill; /* past-end mark needed to provide length of last entry */
+
+       fill = (char*) (ptrs + seq->count + 1);
+       while (NextBuffer(bufs, &cptr, &cnt)) {
+               memcpy(fill, cptr, cnt);
+               fill += cnt;
+       }
+       
+       ReleaseBuffer(bufs, 0);
+       ReleaseBuffer(bufs+1, 0);
+       free(seq->data[0].p);
+       
+       seq->data[0].p = ptrs;
+       return seq;
+}
+
+Column ForceStringColumn (Column column) {
+       int r, rows;
+       Seq_p result;
+       
+       /* this code needed to always make name column of meta views string cols */
+       
+       if (column.seq == NULL || column.seq->getter == StringGetter)
+               return column;
+               
+       rows = column.seq->count;
+       result = NewStrVec(1);
+       
+       for (r = 0; r < rows; ++r)
+               AppendToStrVec(GetColItem(r, column, IT_string).s, -1, result);
+       
+       return SeqAsCol(FinishStrVec(result));
+}
+
+static ItemTypes IotaGetter (int row, Item_p item) {
+       item->i = row;
+       return IT_int;
+}
+
+static struct SeqType ST_Iota = { "iota", IotaGetter };
+
+Column NewIotaColumn (int count) {
+       return SeqAsCol(NewSequence(count, &ST_Iota, 0));
+}
+
+static void SequenceCleaner (Seq_p seq) {
+       int i;
+       View_p *items = seq->data[0].p;
+
+       for (i = 0; i < seq->count; ++i)
+               DecRefCount(items[i]);
+}
+
+static ItemTypes SequenceGetter (int row, Item_p item) {
+       void **items = (void**) item->c.seq->data[0].p;
+       ItemTypes type = item->c.seq->data[1].i;
+
+       switch (type) {
+
+               case IT_view:
+                       item->v = items[row];
+                       return IT_view;
+
+               case IT_column:
+                       item->c.seq = items[row];
+                       item->c.pos = -1;
+                       return IT_column;
+
+               default:
+                       return IT_unknown;
+       }
+}
+
+static struct SeqType ST_Sequence = {
+       "sequence", SequenceGetter, 0, SequenceCleaner
+};
+
+Seq_p NewSeqVec (ItemTypes type, const Seq_p *items, int count) {
+       int i, bytes;
+       Seq_p seq;
+
+       bytes = count * sizeof(View_p);
+       seq = NewSequence(count, &ST_Sequence, bytes);
+       /* data[0] points to a list of pointers */
+       /* data[1] is the type of the returned items */
+       seq->data[1].i = type;
+
+       if (items != NULL) {
+               memcpy(seq->data[0].p, items, bytes);
+               for (i = 0; i < count; ++i)
+                       IncRefCount(items[i]);
+       }
+
+       return seq;
+}
+
+static ItemTypes CountsGetter (int row, Item_p item) {
+       const View_p *items = (const View_p*) item->c.seq->data[0].p;
+
+       item->i = ViewSize(items[row]);
+       return IT_int;
+}
+
+Column NewCountsColumn (Column column) {
+       int r, rows;
+       View_p *items;
+       Seq_p seq;
+       
+       rows = column.seq->count;        
+       seq = NewSeqVec(IT_view, NULL, rows);
+       seq->getter = CountsGetter;
+
+       items = seq->data[0].p;
+       for (r = 0; r < rows; ++r)
+               items[r] = IncRefCount(GetColItem(r, column, IT_view).v);
+
+       return SeqAsCol(seq);
+}
+
+Column OmitColumn (Column omit, int size) {
+       int i, *data, j = 0, outsize;
+       Seq_p seq, map;
+       
+       if (omit.seq == NULL)
+               return omit;
+               
+       outsize = size - omit.seq->count;
+       
+       /* FIXME: wasteful for large views, consider sorting input col instead */
+       map = NewBitVec(size);
+       for (i = 0; i < omit.seq->count; ++i)
+               SetBit(&map, GetColItem(i, omit, IT_int).i);
+
+       seq = NewIntVec(outsize, &data);
+       
+       for (i = 0; i < size; ++i)
+               if (!TestBit(map, i)) {
+                       Assert(j < outsize);
+                       data[j++] = i;
+               }
+               
+       return SeqAsCol(seq);
+}
+
+#if 0
+static ItemTypes UnknownGetter (int row, Item_p item) {
+       return IT_unknown;
+}
+
+static struct SeqType ST_Unknown = { "unknown", UnknownGetter };
+
+static Seq_p NewUnknownVec (int count) {
+       return NewSequence(count, &ST_Unknown, 0);
+}
+#endif
+
+Column CoerceColumn (ItemTypes type, Object_p obj) {
+       int i, n;
+       void *data;
+       Seq_p seq;
+       Item item;
+       Column out, column = ObjAsColumn(obj);
+
+       if (column.seq == NULL)
+               return column;
+               
+       /* determine the input column type by fetching one item */
+       item.c = column;
+       n = column.seq->count;
+
+       if (GetItem(0, &item) == type)
+               return column;
+               
+       switch (type) {
+               case IT_int:    seq = NewIntVec(n, (void*) &data); break;
+               case IT_wide:   seq = NewSequence(n, PickIntGetter(64), 8 * n); break;
+               case IT_float:  seq = NewSequence(n, FixedGetter(4,1,1,0), 4 * n);
+                               break;
+               case IT_double: seq = NewSequence(n, FixedGetter(8,1,1,0), 8 * n);
+                               break;
+               case IT_string: seq = NewStrVec(1); break;
+               case IT_bytes:  seq = NewStrVec(0); break;
+               case IT_view:   seq = NewSeqVec(IT_view, NULL, n); break;
+               default:                Assert(0);
+       }
+
+       out = SeqAsCol(seq);
+       data = out.seq->data[0].p;
+
+       for (i = 0; i < n; ++i) {
+               item.o = GetColItem(i, column, IT_object).o;
+               if (!ObjToItem(type, &item)) {
+                       out.seq = NULL;
+                       out.pos = i;
+                       break;
+               }
+       
+               switch (type) {
+                       case IT_int:    ((int*) data)[i] = item.i; break;
+                       case IT_wide:   ((int64_t*) data)[i] = item.w; break;
+                       case IT_float:  ((float*) data)[i] = item.f; break;
+                       case IT_double: ((double*) data)[i] = item.d; break;
+                       case IT_string: AppendToStrVec(item.s, -1, out.seq); break;
+                       case IT_bytes:  AppendToStrVec(item.u.ptr, item.u.len, out.seq);
+                                       break;
+                       case IT_view:   ((Seq_p*) data)[i] = IncRefCount(item.v); break;
+                       default:                Assert(0);
+               }
+       }
+
+       if (type == IT_string || type == IT_bytes)
+               FinishStrVec(seq);
+
+       return out;
+}
+
+Column CoerceCmd (Object_p obj, const char *str) {
+       return CoerceColumn(CharAsItemType(str[0]), obj);
+}
+
+int CastObjToItem (char type, Item_p item) {
+       switch (type) {
+
+               case 'M':
+                       item->o = NeedMutable(item->o);
+                       return (void*) item->o != NULL;
+                       
+               case 'N':
+                       item->i = ColumnByName(V_Meta(item[-1].v), item->o);
+                       return item->i >= 0;
+               
+               case 'n': {
+                       int *data, r, rows;
+                       View_p meta;
+                       Column column;
+                       Seq_p seq;
+
+                       column = ObjAsColumn(item->o);
+                       if (column.seq == NULL)
+                               return 0;
+                               
+                       rows = column.seq->count;
+                       seq = NewIntVec(rows, &data);
+                       meta = V_Meta(item[-1].v);
+                       
+                       for (r = 0; r < rows; ++r) {
+                               /* FIXME: this only works if input is a list, not a column! */
+                               data[r] = ColumnByName(meta, GetColItem(r, column,
+                                                                           IT_object).o);
+                               if (data[r] < 0)
+                                       return 0;
+                       }
+                       
+                       item->c = SeqAsCol(seq);
+                       break;
+               }
+               
+               default:
+                       if (type < 'a' || type > 'z')
+                               return ObjToItem(CharAsItemType(type), item);
+
+                       item->c = CoerceColumn(CharAsItemType(type + 'A'-'a'), item->o);
+                       break;
+       }
+
+       return 1; /* cast succeeded */
+}
+/* %include<emit.c>% */
+/*
+ * emit.c - Implementation of file output commands.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+typedef enum EmitTypes {
+    ET_mem
+} EmitTypes;
+
+typedef struct EmitItem {
+    EmitTypes type;
+    Int_t size;
+    const void *data;
+} EmitItem, *EmitItem_p;
+
+typedef struct EmitInfo {
+    int64_t         position;   /* emit offset, track >2 Gb even on 32b arch */
+    struct Buffer  *itembuf;    /* item buffer */
+    struct Buffer  *colbuf;     /* column buffer */
+    int             diff;       /* true if emitting differences */
+} EmitInfo, *EmitInfo_p;
+
+static void EmitView (EmitInfo_p eip, View_p view, int describe); /* forward */
+
+static Int_t EmitBlock (EmitInfo_p eip, const void* data, int size) {
+    EmitItem item;
+    Int_t pos = eip->position;
+
+    if (size > 0) {
+        item.type = ET_mem;
+        item.size = size;
+        item.data = data;
+        AddToBuffer(eip->itembuf, &item, sizeof item);
+
+        eip->position += size;
+    } else
+        free((void*) data);
+    
+    return pos;
+}
+
+static void *EmitCopy (EmitInfo_p eip, const void* data, int size) {
+    void *buf = NULL;
+    if (size > 0) {
+        buf = memcpy(malloc(size), data, size);
+        EmitBlock(eip, buf, size);
+    }
+    return buf;
+}
+
+static Int_t EmitBuffer (EmitInfo_p eip, Buffer_p buf) {
+    Int_t pos = EmitBlock(eip, BufferAsPtr(buf, 0), BufferFill(buf));
+    ReleaseBuffer(buf, 1);
+    return pos;
+}
+
+static void EmitAlign (EmitInfo_p eip) {
+    if (eip->position >= 1024 * 1024)
+        EmitCopy(eip, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 15 & - eip->position);
+}
+
+void MetaAsDesc (View_p meta, Buffer_p buffer) {
+    int r, rows = (int)ViewSize(meta);
+    Column names, types, subvs;
+    char type;
+    const char *name;
+    View_p subv;
+
+    names = ViewCol(meta, MC_name);
+    types = ViewCol(meta, MC_type);
+    subvs = ViewCol(meta, MC_subv);
+
+    for (r = 0; r < rows; ++r) {
+        if (r > 0)
+            AddToBuffer(buffer, ",", 1);
+
+        name = GetColItem(r, names, IT_string).s;
+        type = *GetColItem(r, types, IT_string).s;
+        subv = GetColItem(r, subvs, IT_view).v;
+
+        AddToBuffer(buffer, name, strlen(name));
+        if (type == 'V' && ViewSize(subv) > 0) {
+            AddToBuffer(buffer, "[", 1);
+            MetaAsDesc(subv, buffer);
+            AddToBuffer(buffer, "]", 1);
+        } else {
+            AddToBuffer(buffer, ":", 1);
+            AddToBuffer(buffer, &type, 1);
+        }
+    }
+}
+
+static void EmitVarInt (EmitInfo_p eip, Int_t value) {
+    int n;
+
+#if 0
+    if (value < 0) {
+        ADD_ONEC_TO_BUF(*eip->colbuf, 0);
+        value = ~value;
+    }
+#endif
+
+    Assert(value >= 0);
+    for (n = 7; (value >> n) > 0; n += 7)
+        ;
+    while ((n -= 7) > 0)
+        ADD_ONEC_TO_BUF(*eip->colbuf, (value >> n) & 0x7F);
+    ADD_CHAR_TO_BUF(*eip->colbuf, (value & 0x7F) | 0x80);
+}
+
+static void EmitPair (EmitInfo_p eip, Int_t offset) {
+    Int_t size;
+
+    size = eip->position - offset;
+    EmitVarInt(eip, size);
+    if (size > 0)
+        EmitVarInt(eip, offset);
+}
+
+static int MinWidth (int lo, int hi) {
+    lo = lo > 0 ? 0 : "444444445555555566666666666666666"[TopBit(~lo)+1] & 7;
+    hi = hi < 0 ? 0 : "012334445555555566666666666666666"[TopBit(hi)+1] & 7;
+    return lo > hi ? lo : hi;
+}
+
+static int *PackedIntVec (const int *data, int rows, Int_t *outsize) {
+    int r, width, lo = 0, hi = 0, bits, *result;
+    const int *limit;
+    Int_t bytes;
+
+    for (r = 0; r < rows; ++r) {
+        if (data[r] < lo) lo = data[r];
+        if (data[r] > hi) hi = data[r];
+    }
+
+    width = MinWidth(lo, hi);
+
+    if (width >= 6) {
+        bytes = rows * (1 << (width-4));
+        result = malloc(bytes);
+        memcpy(result, data, bytes);
+    } else if (rows > 0 && width > 0) {
+        if (rows < 5 && width < 4) {
+            static char fudges[3][4] = {    /* n:    1:  2:  3:  4: */
+                {1,1,1,1},          /* 1-bit entries:    1b  2b  3b  4b */
+                {1,1,1,1},          /* 2-bit entries:    2b  4b  6b  8b */
+                {1,1,2,2},          /* 4-bit entries:    4b  8b 12b 16b */
+            };
+            static char widths[3][4] = {    /* n:    1:  2:  3:  4: */
+                {3,3,2,2},          /* 1-bit entries:    4b  4b  2b  2b */
+                {3,3,2,2},          /* 2-bit entries:    4b  4b  2b  2b */
+                {3,3,3,3},          /* 4-bit entries:    4b  4b  4b  4b */
+            };
+            bytes = fudges[width-1][rows-1];
+            width = widths[width-1][rows-1];
+        } else
+            bytes = (((Int_t) rows << width) + 14) >> 4; /* round up */
+            
+        result = malloc(bytes);
+        if (width < 4)
+            memset(result, 0, bytes);
+
+        limit = data + rows;
+        bits = 0;
+
+        switch (width) {
+
+            case 1: { /* 1 bit, 8 per byte */
+                char* q = (char*) result;
+                while (data < limit) {
+                    *q |= (*data++ & 1) << bits; ++bits; q += bits >> 3; 
+                    bits &= 7;
+                }
+                break;
+            }
+
+            case 2: { /* 2 bits, 4 per byte */
+                char* q = (char*) result;
+                while (data < limit) {
+                    *q |= (*data++ & 3) << bits; bits += 2; q += bits >> 3; 
+                    bits &= 7;
+                }
+                break;
+            }
+
+            case 3: { /* 4 bits, 2 per byte */
+                char* q = (char*) result;
+                while (data < limit) {
+                    *q |= (*data++ & 15) << bits; bits += 4; q += bits >> 3;
+                    bits &= 7;
+                }
+                break;
+            }
+
+            case 4: { /* 1-byte (char) */
+                char* q = (char*) result;
+                while (data < limit)
+                    *q++ = (char) *data++;
+                break;
+            }
+
+            case 5: { /* 2-byte (short) */
+                short* q = (short*) result;
+                while (data < limit)
+                    *q++ = (short) *data++;
+                break;
+            }
+        }
+    } else {
+        bytes = 0;
+        result = NULL;
+    }
+
+    *outsize = bytes;
+    return result;
+}
+
+static int EmitFixCol (EmitInfo_p eip, Column column, ItemTypes type) {
+    int r, rows, *tempvec;
+    void *buffer;
+    Int_t bufsize;
+
+    rows = column.seq->count;
+
+    switch (type) {
+
+        case IT_int:
+            bufsize = rows * sizeof(int);
+            tempvec = malloc(bufsize);
+            for (r = 0; r < rows; ++r)
+                tempvec[r] = GetColItem(r, column, type).i;
+            buffer = PackedIntVec(tempvec, rows, &bufsize);
+            free((char*) tempvec); /* TODO: avoid extra copy & malloc */
+            
+            /* try to compress the bitmap, but only in diff save mode */
+            if (eip->diff && rows >= 128 && rows == bufsize * 8) {
+                int ebits;
+
+                tempvec = (void*) Bits2elias(buffer, rows, &ebits);
+
+                /* only keep compressed form if under 80% of plain bitmap */
+                if (ebits + ebits/4 < rows) {
+                    free(buffer);
+                    buffer = tempvec;
+                    bufsize = (ebits + 7) / 8;
+                } else
+                    free((char*) tempvec);
+            }
+            
+            break;
+
+        case IT_wide:
+            bufsize = rows * sizeof(int64_t);
+            buffer = malloc(bufsize);
+            for (r = 0; r < rows; ++r)
+                ((int64_t*) buffer)[r] = GetColItem(r, column, type).w;
+            break;
+
+        case IT_float:
+            bufsize = rows * sizeof(float);
+            buffer = malloc(bufsize);
+            for (r = 0; r < rows; ++r)
+                ((float*) buffer)[r] = GetColItem(r, column, type).f;
+            break;
+
+        case IT_double:
+            bufsize = rows * sizeof(double);
+            buffer = malloc(bufsize);
+            for (r = 0; r < rows; ++r)
+                ((double*) buffer)[r] = GetColItem(r, column, type).d;
+            break;
+
+        default: Assert(0); return 0;
+    }
+
+    /* start using 16-byte alignment once the emitted data reaches 1 Mb */
+    /* only do this for vectors >= 128 bytes, worst-case waste is under 10% */
+    
+    Assert(!(bufsize > 0 && rows == 0));
+    if (bufsize >= 128 && bufsize / rows >= 2) 
+        EmitAlign(eip);
+        
+    EmitPair(eip, EmitBlock(eip, buffer, bufsize));
+    
+    return bufsize != 0;
+}
+
+static void EmitVarCol (EmitInfo_p eip, Column column, int istext) {
+    int r, rows, bytes, *sizevec;
+    Int_t buflen;
+    Item item;
+    struct Buffer buffer;
+    Seq_p sizes;
+
+    InitBuffer(&buffer);
+    rows = column.seq->count;
+    sizes = NewIntVec(rows, &sizevec);
+
+    if (istext)
+        for (r = 0; r < rows; ++r) {
+            item = GetColItem(r, column, IT_string);
+            bytes = strlen(item.s);
+            if (bytes > 0)
+                AddToBuffer(&buffer, item.s, ++bytes);
+            sizevec[r] = bytes;
+        }
+    else
+        for (r = 0; r < rows; ++r) {
+            item = GetColItem(r, column, IT_bytes);
+            AddToBuffer(&buffer, item.u.ptr, item.u.len);
+            sizevec[r] = item.u.len;
+        }
+
+    buflen = BufferFill(&buffer);
+    EmitPair(eip, EmitBuffer(eip, &buffer));    
+    if (buflen > 0)
+        EmitFixCol(eip, SeqAsCol(sizes), 1);
+
+    EmitVarInt(eip, 0); /* no memos */
+}
+
+static void EmitSubCol (EmitInfo_p eip, Column column, int describe) {
+    int r, rows;
+    View_p view;
+    struct Buffer newcolbuf;
+    Buffer_p origcolbuf;
+
+    origcolbuf = eip->colbuf;
+    eip->colbuf = &newcolbuf;
+    InitBuffer(eip->colbuf);
+
+    rows = column.seq->count;
+
+    for (r = 0; r < rows; ++r) {
+        view = GetColItem(r, column, IT_view).v;
+        EmitView(eip, view, describe);
+    }
+
+    eip->colbuf = origcolbuf;
+
+    EmitPair(eip, EmitBuffer(eip, &newcolbuf));  
+}
+
+static void EmitCols (EmitInfo_p eip, View_p view, View_p maps) {
+    int rows = ViewSize(view);
+    
+    EmitVarInt(eip, rows);
+
+    if (rows > 0) {
+        int i, r, c, *rowptr = NULL;
+        ItemTypes type;
+        Column column;
+        Seq_p rowmap;
+        View_p v, subv, meta = V_Meta(view);
+
+        rowmap = NULL;
+        
+        for (c = 0; c < ViewWidth(view); ++c) {          
+            if (maps != NULL) {
+                Column mapcol = ViewCol(maps, c);
+                if (!EmitFixCol(eip, mapcol, IT_int))
+                    continue;
+
+                if (rowmap == NULL)
+                    rowmap = NewIntVec(rows, &rowptr);
+
+                i = 0;
+                for (r = 0; r < rows; ++r)
+                    if (GetColItem(r, mapcol, IT_int).i)
+                        rowptr[i++] = r;
+                        
+                rowmap->count = i;
+                        
+                v = RemapSubview(view, SeqAsCol(rowmap), 0, -1);
+            } else
+                v = view;
+                
+            column = ViewCol(v,c);
+            type = ViewColType(view, c);
+            switch (type) {
+                
+                case IT_int:
+                case IT_wide:
+                case IT_float:
+                case IT_double:
+                    EmitFixCol(eip, column, type); 
+                    break;
+                    
+                case IT_string:
+                    EmitVarCol(eip, column, 1);
+                    break;
+                    
+                case IT_bytes:
+                    EmitVarCol(eip, column, 0);
+                    break;
+                    
+                case IT_view:
+                    subv = GetViewItem(meta, c, MC_subv, IT_view).v;
+                    EmitSubCol(eip, column, ViewSize(subv) == 0);
+                    break;
+                    
+                default: Assert(0);
+            }
+        }
+    }
+}
+
+static void EmitView (EmitInfo_p eip, View_p view, int describe) {
+    EmitVarInt(eip, 0);
+
+    if (eip->diff) {
+        Seq_p mods = MutPrepare(view), *seqs = (void*) (mods + 1);
+
+        EmitVarInt(eip, 0);
+        EmitFixCol(eip, SeqAsCol(seqs[MP_delmap]), IT_int);
+
+        if (EmitFixCol(eip, SeqAsCol(seqs[MP_adjmap]), IT_int))
+            EmitCols(eip, seqs[MP_adjdat], seqs[MP_usemap]);
+
+        EmitCols(eip, seqs[MP_insdat], NULL);
+        if (ViewSize(seqs[MP_insdat]) > 0)
+            EmitFixCol(eip, SeqAsCol(seqs[MP_insmap]), IT_int);
+    } else {
+        if (describe) {
+            int cnt;
+            char *ptr = NULL;
+            struct Buffer desc;
+
+            InitBuffer(&desc);
+            MetaAsDesc(V_Meta(view), &desc);
+
+            EmitVarInt(eip, BufferFill(&desc));
+            
+            while (NextBuffer(&desc, &ptr, &cnt))
+                AddToBuffer(eip->colbuf, ptr, cnt);
+        }
+
+        EmitCols(eip, view, NULL);
+    }
+}
+
+static void SetBigEndian32 (char* dest, Int_t value) {
+    dest[0] = (char) (value >> 24);
+    dest[1] = (char) (value >> 16);
+    dest[2] = (char) (value >> 8);
+    dest[3] = (char) value;
+}
+
+static Int_t EmitComplete (EmitInfo_p eip, View_p view) {
+    int overflow;
+    Int_t rootpos, tailpos, endpos;
+    char tail[16];
+    struct Head { short a; char b; char c; char d[4]; } head, *fixup;
+    struct Buffer newcolbuf;
+
+    if (eip->diff && !IsMutable(view))
+        return 0;
+        
+    eip->position = 0;
+
+    head.a = 'J' + ('L' << 8);
+    head.b = 0x1A;
+    head.c = 0;
+    fixup = EmitCopy(eip, &head, sizeof head);
+
+    eip->colbuf = &newcolbuf;
+    InitBuffer(eip->colbuf);
+
+    EmitView(eip, view, 1);
+
+    EmitAlign(eip);
+    rootpos = EmitBuffer(eip, eip->colbuf);  
+    eip->colbuf = NULL;
+
+    EmitAlign(eip);
+    
+    if (eip->position != (Int_t) eip->position)
+        return -1; /* fail if >= 2 Gb on machines with a 32-bit address space */
+    
+    /* large files will have bit 8 of head[3] and bit 8 of tail[12] set */
+    tailpos = eip->position;
+    endpos = tailpos + sizeof tail;
+    overflow = endpos >> 31;
+
+    /* for file sizes > 2 Gb, store bits 41..31 in tail[2..3] */
+    SetBigEndian32(tail, 0x80000000 + overflow);
+    SetBigEndian32(tail+4, tailpos);
+    SetBigEndian32(tail+8, 
+                    ((eip->diff ? 0x90 : 0x80) << 24) + tailpos - rootpos);
+    SetBigEndian32(tail+12, rootpos);
+    if (overflow)
+        tail[12] |= 0x80;
+    
+    EmitCopy(eip, tail, sizeof tail);
+    
+    if (overflow) {
+        /* store bits 41..36 in head[3], and bits 35..4 in head[4..7] */
+        Assert((endpos & 15) == 0);
+        fixup->c = 0x80 | ((endpos >> 16) >> 20);
+        SetBigEndian32(fixup->d, endpos >> 4);
+    } else
+        SetBigEndian32(fixup->d, endpos);
+        
+    return endpos;
+}
+
+Int_t ViewSave (View_p view, void *aux, SaveInitFun initfun, SaveDataFun datafun, int diff) {
+    int i, numitems;
+    Int_t bytes;
+    struct Buffer buffer;
+    EmitItem_p items;
+    EmitInfo einfo;
+    
+    InitBuffer(&buffer);
+    
+    einfo.itembuf = &buffer;
+    einfo.diff = diff;
+
+    bytes = EmitComplete(&einfo, view);
+
+    numitems = BufferFill(&buffer) / sizeof(EmitItem);
+    items = BufferAsPtr(&buffer, 1);
+
+    if (initfun != NULL)
+        aux = initfun(aux, bytes);
+
+    for (i = 0; i < numitems; ++i) {
+        if (aux != NULL)
+            aux = datafun(aux, items[i].data, items[i].size);
+        free((void*) items[i].data);
+    }
+    
+    if (aux == NULL)
+        bytes = 0;
+    
+    ReleaseBuffer(&buffer, 0);
+    return bytes;
+}
+/* %include<file.c>% */
+/*
+ * file.c - Implementation of memory-mapped file access.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
+
+static View_p MapSubview (MappedFile_p, Int_t, View_p, View_p); /* forward */
+
+#define MF_Data(map) ((const char*) ((map)->data[0].p))
+#define MF_Length(map) ((Int_t) (map)->data[1].p)
+
+static void MappedCleaner (MappedFile_p map) {
+    Cleaner fun = *((Cleaner*) (map + 1));
+    if (fun != NULL)
+        fun(map);
+}
+
+static struct SeqType ST_Mapped = { "mapped", NULL, 0, MappedCleaner };
+
+MappedFile_p InitMappedFile (const char *data, Int_t length, Cleaner fun) {
+    MappedFile_p map;
+    
+    map = NewSequence(0, &ST_Mapped, sizeof(Cleaner));
+    /* data[0] points to the current start of the mapped area */
+    /* data[1] is the current length of the mapped area */
+    /* data[2] points to the original mapped area */
+    /* data[3] is available for storing an Object_p, see ext_tcl.c */
+    map->data[0].p = (void*) data;
+    map->data[1].p = (void*) length;
+    map->data[2].p = (void*) data;
+    
+    *((Cleaner*) (map + 1)) = fun; /* TODO: get rid of this ugly hack */
+    
+    return map;
+}
+
+static void MappedFileCleaner (MappedFile_p map) {
+#if WIN32+0
+    UnmapViewOfFile(map->data[2].p);
+#else
+    int offset = MF_Data(map) - (const char*) map->data[2].p;
+    munmap(map->data[2].p, MF_Length(map) + offset);
+#endif
+}
+
+#if WIN32+0
+/*
+ * If we are opening a Windows PE executable with an attached metakit
+ * then we must check for the presence of an Authenticode certificate
+ * and reduce the length of our mapped region accordingly
+ */
+
+static DWORD
+AuthenticodeOffset(LPBYTE pData, DWORD cbData)
+{
+    if (pData[0] == 'M' && pData[1] == 'Z')              /* IMAGE_DOS_SIGNATURE */
+    {
+        LPBYTE pNT = pData + *(LONG *)(pData + 0x3c);    /* e_lfanew */
+        if (pNT[0] == 'P' && pNT[1] == 'E' && pNT[2] == 0 && pNT[3] == 0)
+        {                                                /* IMAGE_NT_SIGNATURE */
+            DWORD dwCheckSum = 0, dwDirectories = 0;
+            LPBYTE pOpt = pNT + 0x18;                    /* OptionalHeader */
+            LPDWORD pCertDir = NULL;
+            if (pOpt[0] == 0x0b && pOpt[1] == 0x01) {    /* IMAGE_NT_OPTIONAL_HDR_MAGIC */
+                dwCheckSum = *(DWORD *)(pOpt + 0x40);    /* Checksum */
+                dwDirectories = *(DWORD *)(pOpt + 0x5c); /* NumberOfRvaAndSizes */
+                if (dwDirectories > 4) {                 /* DataDirectory[] */
+                    pCertDir = (DWORD *)(pOpt + 0x60 + (4 * 8));
+                }
+            } else {
+                dwCheckSum = *(DWORD *)(pOpt + 0x40);    /* Checksum */
+                dwDirectories = *(DWORD *)(pOpt + 0x6c); /* NumberOfRvaAndSizes */
+                if (dwDirectories > 4) {                 /* DataDirectory[] */
+                    pCertDir = (DWORD *)(pOpt + 0x70 + (4 * 8));
+                }
+            }
+
+            if (pCertDir && pCertDir[1] > 0) {
+                int n = 0;
+                cbData = pCertDir[0];
+                /* need to eliminate any zero padding - up to 8 bytes */
+                while (pData[cbData - 16] != 0x80 && pData[cbData-1] == 0 && n < 16) {
+                    --cbData, ++n;
+                }
+            }
+        }
+    }
+    return cbData;
+}
+#endif /* WIN32 */
+
+static MappedFile_p OpenMappedFile (const char *filename) {
+    const char *data = NULL;
+    Int_t length = -1;
+        
+#if WIN32+0
+    {
+        DWORD n;
+        HANDLE h, f;
+        OSVERSIONINFO os;
+
+        memset(&os, 0, sizeof(os));
+        os.dwOSVersionInfoSize = sizeof(os);
+       os.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
+        GetVersionEx(&os);
+        if (os.dwPlatformId < VER_PLATFORM_WIN32_NT) {
+            f = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, 0,
+                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+        } else {
+            f = CreateFileW((LPCWSTR)filename, GENERIC_READ, FILE_SHARE_READ, 0,
+                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+        }
+        if (f != INVALID_HANDLE_VALUE) {
+            h = CreateFileMapping(f, 0, PAGE_READONLY, 0, 0, 0);
+            if (h != INVALID_HANDLE_VALUE) {
+                n = GetFileSize(f, 0);
+                data = MapViewOfFile(h, FILE_MAP_READ, 0, 0, n);
+                if (data != NULL) {
+                    length = AuthenticodeOffset((LPBYTE)data, n);
+                }
+                CloseHandle(h);
+            }
+            CloseHandle(f);
+        }
+    }
+#else
+    {
+        struct stat sb;
+        int fd = open(filename, O_RDONLY);
+        if (fd != -1) {
+            if (fstat(fd, &sb) == 0) {
+                data = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+                if (data != MAP_FAILED)
+                    length = sb.st_size;
+            }
+            close(fd);
+        }
+    }
+#endif
+
+    if (length < 0)
+        return NULL;
+        
+    return InitMappedFile(data, length, MappedFileCleaner);
+}
+
+static void AdjustMappedFile (MappedFile_p map, int offset) {
+    map->data[0].p = (void*) (MF_Data(map) + offset);
+    map->data[1].p = (void*) (MF_Length(map) - offset);
+}
+
+static int IsReversedEndian(MappedFile_p map) {
+#if _BIG_ENDIAN+0
+    return *MF_Data(map) == 'J';
+#else
+    return *MF_Data(map) == 'L';
+#endif
+}
+
+static Int_t GetVarInt (const char **cp) {
+    int8_t b;
+    Int_t v = 0;
+    do {
+        b = *(*cp)++;
+        v = (v << 7) + b;
+    } while (b >= 0);
+    return v + 128;
+}
+
+static Int_t GetVarPair(const char** cp) {
+    Int_t n = GetVarInt(cp);
+    if (n > 0 && GetVarInt(cp) == 0)
+        *cp += n;
+    return n;
+}
+
+#define MM_cache        data[0].p
+#define MM_offvec       data[1].q
+#define MM_mapf         data[2].q
+#define MM_meta         data[3].q
+
+#define MM_offsets  MM_offvec->data[0].p
+#define MM_base         MM_offvec->data[1].q
+
+
+static void MappedViewCleaner (Seq_p seq) {
+    int i, count;
+    const View_p *subviews = seq->MM_cache;
+    
+    count = seq->MM_offvec->count;
+    for (i = 0; i < count; ++i)
+        DecRefCount(subviews[i]);
+    
+    DecRefCount(seq->MM_base);
+}
+
+static ItemTypes MappedViewGetter (int row, Item_p item) {
+    Seq_p seq = item->c.seq;
+    View_p *subviews = seq->MM_cache;
+    
+    if (subviews[row] == NULL) {
+        Seq_p base = seq->MM_base;
+        const Int_t *offsets = seq->MM_offsets;
+        
+        if (base != NULL)
+            base = GetViewItem(base, row, item->c.pos, IT_view).v;
+        
+        subviews[row] = IncRefCount(MapSubview(seq->MM_mapf, offsets[row],
+                                                        seq->MM_meta, base));
+    }
+    
+    item->v = subviews[row];
+    return IT_view;
+}
+
+static struct SeqType ST_MappedView = {
+    "mappedview", MappedViewGetter, 01110, MappedViewCleaner
+};
+
+static Seq_p MappedViewCol (MappedFile_p map, int rows, const char **nextp, View_p meta, View_p base) {
+    int r, c, cols, subcols;
+    Int_t colsize, colpos, *offsets;
+    const char *next;
+    Seq_p offseq, result;
+    
+    offseq = NewPtrVec(rows, &offsets);
+    
+    cols = ViewSize(meta);
+    
+    colsize = GetVarInt(nextp);
+    colpos = colsize > 0 ? GetVarInt(nextp) : 0;
+    next = MF_Data(map) + colpos;
+    
+    for (r = 0; r < rows; ++r) {
+        offsets[r] = next - MF_Data(map);
+        GetVarInt(&next);
+        if (cols == 0) {
+            Int_t desclen = GetVarInt(&next);
+            const char *desc = next;
+            next += desclen;
+            meta = DescAsMeta(&desc, next);
+        }
+        if (GetVarInt(&next) > 0) {
+            subcols = ViewSize(meta);
+            for (c = 0; c < subcols; ++c)
+                switch (GetColType(meta, c)) {
+                    case 'B': case 'S': if (GetVarPair(&next))
+                                            GetVarPair(&next);
+                                        /* fall through */
+                    default:            GetVarPair(&next);
+                }
+        }
+    }
+    
+    result = NewSequence(rows, &ST_MappedView, rows * sizeof(View_p));
+    /* data[0] points to a subview cache */
+    /* data[1] points to a sequence owning the offest vector */
+    /* data[2] points to the mapped file */
+    /* data[3] points to the meta view */
+    result->MM_offvec = IncRefCount(offseq);
+    result->MM_mapf = IncRefCount(map);
+    result->MM_meta = IncRefCount(cols > 0 ? meta : EmptyMetaView());
+    /* offseq->data[1] points to the base view if there is one */
+    result->MM_base = IncRefCount(base);
+    
+    /* TODO: could combine subview cache and offsets vector */
+    
+    return result;
+}
+
+static struct SeqType ST_MappedFix = { "mappedfix", NULL, 010 };
+
+static Seq_p MappedFixedCol (MappedFile_p map, int rows, const char **nextp, int isreal) {
+    Int_t colsize, colpos;
+    const char *data;
+    Seq_p result;
+
+    colsize = GetVarInt(nextp);
+    colpos = colsize > 0 ? GetVarInt(nextp) : 0;
+    data = MF_Data(map) + colpos;
+    
+    /* if bit count is too low-for single-bit vectors then it's compressed */
+    if (rows >= 128 && 0 < colsize && colsize < rows/8) {
+        int from, pos = 0;
+        
+        result = NewBitVec(rows);
+        from = *data & 0x80 ? 0 : NextElias(data, colsize, &pos);
+            
+        for (;;) {
+            int count = NextElias(data, colsize, &pos);
+            if (count == 0)
+                break;
+            SetBitRange(result, from, count);
+            from += count + NextElias(data, colsize, &pos);
+        }
+    } else {    
+        int rev = IsReversedEndian(map);
+    
+        result = NewSequence(rows, &ST_MappedFix, 0);
+        result->getter = FixedGetter(colsize, rows, isreal, rev)->getfun;
+        /* data[0] points to the mapped data */
+        /* data[1] points to the mapped file */
+        result->data[0].p = (void*) data;
+        result->data[1].p = IncRefCount(map);
+    }
+    
+    return result;
+}
+
+#define MS_offvec       data[0].q
+#define MS_offptr       data[1].p
+#define MS_mapf         data[2].q
+#define MS_sizes        data[3].q
+
+static ItemTypes MappedStringGetter (int row, Item_p item) {
+    const Int_t *offsets = item->c.seq->MS_offptr;
+    const char *data = MF_Data(item->c.seq->MS_mapf);
+
+    if (offsets[row] == 0)
+        item->s = "";
+    else if (offsets[row] > 0)
+        item->s = data + offsets[row];
+    else {
+        const char *next = data - offsets[row];
+        if (GetVarInt(&next) > 0)
+            item->s = data + GetVarInt(&next);
+        else
+            item->s = "";
+    }
+
+    return IT_string;
+}
+
+static struct SeqType ST_MappedString = {
+    "mappedstring", MappedStringGetter, 01101
+};
+
+static ItemTypes MappedBytesGetter (int row, Item_p item) {
+    Seq_p seq = item->c.seq;
+    const Int_t *offsets = seq->MS_offptr;
+    const char *data = MF_Data(seq->MS_mapf);
+    
+    item->u.len = GetSeqItem(row, seq->MS_sizes, IT_int).i;
+    
+    if (offsets[row] >= 0)
+        item->u.ptr = (const Byte_t*) data + offsets[row];
+    else {
+        const char *next = data - offsets[row];
+        item->u.len = GetVarInt(&next);
+        item->u.ptr = (const Byte_t*) data + GetVarInt(&next);
+    }
+
+    return IT_bytes;
+}
+
+static struct SeqType ST_MappedBytes = {
+    "mappedstring", MappedBytesGetter, 01101
+};
+
+static Seq_p MappedStringCol (MappedFile_p map, int rows, const char **nextp, int istext) {
+    int r, len, memopos;
+    Int_t colsize, colpos, *offsets;
+    const char *next, *limit;
+    Seq_p offseq, result, sizes;
+
+    offseq = NewPtrVec(rows, &offsets);
+
+    colsize = GetVarInt(nextp);
+    colpos = colsize > 0 ? GetVarInt(nextp) : 0;
+
+    if (colsize > 0) {
+        sizes = MappedFixedCol(map, rows, nextp, 0);
+        for (r = 0; r < rows; ++r) {
+            len = GetSeqItem(r, sizes, IT_int).i;
+            if (len > 0) {
+                offsets[r] = colpos;
+                colpos += len;
+            }
+        }
+    } else
+        sizes = NewSequence(rows, FixedGetter(0, rows, 0, 0), 0);
+
+    colsize = GetVarInt(nextp);
+    memopos = colsize > 0 ? GetVarInt(nextp) : 0;
+    next = MF_Data(map) + memopos;
+    limit = next + colsize;
+    
+    /* negated offsets point to the size/pos pair in the map */
+    for (r = 0; next < limit; ++r) {
+        r += (int) GetVarInt(&next);
+        offsets[r] = MF_Data(map) - next; /* always < 0 */
+        GetVarPair(&next);
+    }
+
+    result = NewSequence(rows, istext ? &ST_MappedString : &ST_MappedBytes, 0);
+    /* data[0] points to a sequence owning the offset vector */
+    /* data[1] points to that vector of subview offsets */
+    /* data[2] points to the mapped file */
+    /* data[3] points to sizes seq if binary or is null if zero-terminated */
+    result->MS_offvec = IncRefCount(offseq);
+    result->MS_offptr = offsets;
+    result->MS_mapf = IncRefCount(map);
+    result->MS_sizes = istext ? NULL : IncRefCount(sizes);
+
+    return result;
+}
+
+static Seq_p MappedBits (MappedFile_p map, int rows, const char **nextp) {
+    Seq_p seq;
+    
+    if ((**nextp & 0xFF) == 0x80) {
+        ++*nextp;
+        return NULL; /* zero-sized column */
+    }
+        
+    seq = MappedFixedCol(map, rows, nextp, 0);
+
+    /* if this does not use 1-bit encoding, then we need to convert back */
+    if (rows < 8 && seq->getter != PickIntGetter(1)->getfun) {
+        int i;
+        Seq_p result = NULL;
+
+        for (i = 0; i < rows; ++i)
+            if (GetSeqItem(i, seq, IT_int).i)
+                SetBit(&result, i);
+                
+        return result;
+    }
+    
+    return seq;
+}
+
+static View_p MapCols (MappedFile_p map, const char **nextp, View_p meta, View_p base, Seq_p adjseq) {
+    int i, c, r, rows, *rowptr = NULL;
+    View_p result, subview;
+    Seq_p seq, usedmap = NULL, rowmap;
+    Item item;
+    
+    rows = (int) GetVarInt(nextp);
+    
+    if (ViewSize(meta) == 0)
+        return NoColumnView(rows);
+    
+    if (base != NULL) {
+        int pos = 0, from = 0, count = 0;
+        
+        rowmap = NewIntVec(rows, &rowptr);
+        while (NextBits(adjseq, &from, &count))
+            for (i = 0; i < count; ++i)
+                rowptr[pos++] = from + i;
+                
+        result = base;
+    } else
+        result = NewView(meta);
+    
+    if (rows > 0)
+        for (c = 0; c < ViewWidth(result); ++c) {
+            if (base != NULL) {
+                usedmap = MappedBits(map, rows, nextp);
+                r = CountBits(usedmap);
+            } else
+                r = rows;
+                
+            switch (ViewColType(result, c)) {
+                
+                case IT_int:
+                case IT_wide:
+                    seq = MappedFixedCol(map, r, nextp, 0); 
+                    break;
+
+                case IT_float:
+                case IT_double:
+                    seq = MappedFixedCol(map, r, nextp, 1);
+                    break;
+                    
+                case IT_string:
+                    seq = MappedStringCol(map, r, nextp, 1); 
+                    break;
+                    
+                case IT_bytes:
+                    seq = MappedStringCol(map, r, nextp, 0);
+                    break;
+                    
+                case IT_view:
+                    subview = GetViewItem(meta, c, MC_subv, IT_view).v;
+                    seq = MappedViewCol(map, r, nextp, subview, base); 
+                    break;
+                    
+                default:
+                    Assert(0);
+                    return result;
+            }
+            
+            if (base != NULL) {
+                i = 0;
+                for (r = 0; r < usedmap->count; ++r)
+                    if (TestBit(usedmap, r)) {
+                        item.c.seq = seq;
+                        item.c.pos = -1;
+                        GetItem(i++, &item);
+                        result = ViewSet(result, rowptr[r], c, &item);
+                    }
+                Assert(i == seq->count);
+            } else
+                SetViewSeqs(result, c, 1, seq);
+        }
+
+    return result;
+}
+
+static View_p MapSubview (MappedFile_p map, Int_t offset, View_p meta, View_p base) {
+    const char *next;
+    
+    next = MF_Data(map) + offset;
+    GetVarInt(&next);
+    
+    if (base != NULL) {
+        int inscnt;
+        View_p insview;
+        Seq_p delseq, insseq, adjseq;
+        
+        meta = V_Meta(base);
+        
+        GetVarInt(&next); /* structure changes and defaults, NOTYET */
+
+        delseq = MappedBits(map, ViewSize(base), &next);
+        if (delseq != NULL) {
+            int delcnt = 0, from = 0, count = 0;
+            while (NextBits(delseq, &from, &count)) {
+                base = ViewReplace(base, from - delcnt, count, NULL);
+                delcnt += count;
+            }
+        }
+            
+        adjseq = MappedBits(map, ViewSize(base), &next);
+        if (adjseq != NULL)
+            base = MapCols(map, &next, meta, base, adjseq);
+
+        insview = MapCols(map, &next, meta, NULL, NULL);
+        inscnt = ViewSize(insview);
+        if (inscnt > 0) {
+            int shift = 0, from = 0, count = 0;
+            insseq = MappedBits(map, ViewSize(base) + inscnt, &next);
+            while (NextBits(insseq, &from, &count)) {
+                View_p newdata = StepView(insview, count, shift, 1, 1);
+                base = ViewReplace(base, from, 0, newdata);
+                shift += count;
+            }
+        }
+    
+        return base;
+    }
+    
+    if (ViewSize(meta) == 0) {
+        Int_t desclen = GetVarInt(&next);
+        const char *desc = next;
+        next += desclen;
+        meta = DescAsMeta(&desc, next);
+    }
+
+    return MapCols(map, &next, meta, NULL, NULL);
+}
+
+static int BigEndianInt32 (const char *p) {
+    const Byte_t *up = (const Byte_t*) p;
+    return (p[0] << 24) | (up[1] << 16) | (up[2] << 8) | up[3];
+}
+
+View_p MappedToView (MappedFile_p map, View_p base) {
+    int i, t[4];
+    Int_t datalen, rootoff;
+    
+    if (MF_Length(map) <= 24 || *(MF_Data(map) + MF_Length(map) - 16) != '\x80')
+        return NULL;
+        
+    for (i = 0; i < 4; ++i)
+        t[i] = BigEndianInt32(MF_Data(map) + MF_Length(map) - 16 + i * 4);
+        
+    datalen = t[1] + 16;
+    rootoff = t[3];
+
+    if (rootoff < 0) {
+        const Int_t mask = 0x7FFFFFFF; 
+        datalen = (datalen & mask) + ((Int_t) ((t[0] & 0x7FF) << 16) << 15);
+        rootoff = (rootoff & mask) + (datalen & ~mask);
+        /* FIXME: rollover at 2 Gb, prob needs: if (rootoff > datalen) ... */
+    }
+    
+    AdjustMappedFile(map, MF_Length(map) - datalen);
+    return MapSubview(map, rootoff, EmptyMetaView(), base);
+}
+
+View_p OpenDataFile (const char *filename) {
+    MappedFile_p map;
+    
+    map = OpenMappedFile(filename);
+    if (map == NULL)
+        return NULL;
+        
+    return MappedToView(map, NULL);
+}
+/* %include<getters.c>% */
+/*
+ * getters.c - Implementation of several simple getter functions.
+ */
+
+#include <stdlib.h>
+
+
+static ItemTypes Getter_i0 (int row, Item_p item) {
+    item->i = 0;
+    return IT_int;
+}
+
+static ItemTypes Getter_i1 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->i = (ptr[row>>3] >> (row&7)) & 1;
+    return IT_int;
+}
+
+static ItemTypes Getter_i2 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->i = (ptr[row>>2] >> 2*(row&3)) & 3;
+    return IT_int;
+}
+
+static ItemTypes Getter_i4 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->i = (ptr[row>>1] >> 4*(row&1)) & 15;
+    return IT_int;
+}
+
+static ItemTypes Getter_i8 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->i = (int8_t) ptr[row];
+    return IT_int;
+}
+
+#if VALUES_MUST_BE_ALIGNED+0
+
+static ItemTypes Getter_i16 (int row, Item_p item) {
+    const Byte_t *ptr = (const Byte_t*) item->c.seq->data[0].p + row * 2;
+#if _BIG_ENDIAN+0
+    item->i = (((int8_t) ptr[0]) << 8) | ptr[1];
+#else
+    item->i = (((int8_t) ptr[1]) << 8) | ptr[0];
+#endif
+    return IT_int;
+}
+
+static ItemTypes Getter_i32 (int row, Item_p item) {
+    const char *ptr = (const char*) item->c.seq->data[0].p + row * 4;
+    int i;
+    for (i = 0; i < 4; ++i)
+        item->b[i] = ptr[i];
+    return IT_int;
+}
+
+static ItemTypes Getter_i64 (int row, Item_p item) {
+    const char *ptr = (const char*) item->c.seq->data[0].p + row * 8;
+    int i;
+    for (i = 0; i < 8; ++i)
+        item->b[i] = ptr[i];
+    return IT_wide;
+}
+
+static ItemTypes Getter_f32 (int row, Item_p item) {
+    Getter_i32(row, item);
+    return IT_float;
+}
+
+static ItemTypes Getter_f64 (int row, Item_p item) {
+    Getter_i64(row, item);
+    return IT_double;
+}
+
+#else
+
+static ItemTypes Getter_i16 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->i = ((short*) ptr)[row];
+    return IT_int;
+}
+
+static ItemTypes Getter_i32 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->i = ((const int*) ptr)[row];
+    return IT_int;
+}
+
+static ItemTypes Getter_i64 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->w = ((const int64_t*) ptr)[row];
+    return IT_wide;
+}
+
+static ItemTypes Getter_f32 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->f = ((const float*) ptr)[row];
+    return IT_float;
+}
+
+static ItemTypes Getter_f64 (int row, Item_p item) {
+    const char *ptr = item->c.seq->data[0].p;
+    item->d = ((const double*) ptr)[row];
+    return IT_double;
+}
+
+#endif
+
+static ItemTypes Getter_i16r (int row, Item_p item) {
+    const Byte_t *ptr = (const Byte_t*) item->c.seq->data[0].p + row * 2;
+#if _BIG_ENDIAN+0
+    item->i = (((int8_t) ptr[1]) << 8) | ptr[0];
+#else
+    item->i = (((int8_t) ptr[0]) << 8) | ptr[1];
+#endif
+    return IT_int;
+}
+
+static ItemTypes Getter_i32r (int row, Item_p item) {
+    const char *ptr = (const char*) item->c.seq->data[0].p + row * 4;
+    int i;
+    for (i = 0; i < 4; ++i)
+        item->b[i] = ptr[3-i];
+    return IT_int;
+}
+
+static ItemTypes Getter_i64r (int row, Item_p item) {
+    const char *ptr = (const char*) item->c.seq->data[0].p + row * 8;
+    int i;
+    for (i = 0; i < 8; ++i)
+        item->b[i] = ptr[7-i];
+    return IT_wide;
+}
+
+static ItemTypes Getter_f32r (int row, Item_p item) {
+    Getter_i32r(row, item);
+    return IT_float;
+}
+
+static ItemTypes Getter_f64r (int row, Item_p item) {
+    Getter_i64r(row, item);
+    return IT_double;
+}
+
+static struct SeqType ST_Get_i0   = { "get_i0"  , Getter_i0   };
+static struct SeqType ST_Get_i1   = { "get_i1"  , Getter_i1   };
+static struct SeqType ST_Get_i2   = { "get_i2"  , Getter_i2   };
+static struct SeqType ST_Get_i4   = { "get_i4"  , Getter_i4   };
+static struct SeqType ST_Get_i8   = { "get_i8"  , Getter_i8   };
+static struct SeqType ST_Get_i16  = { "get_i16" , Getter_i16  };
+static struct SeqType ST_Get_i32  = { "get_i32" , Getter_i32  };
+static struct SeqType ST_Get_i64  = { "get_i64" , Getter_i64  };
+static struct SeqType ST_Get_i16r = { "get_i16r", Getter_i16r };
+static struct SeqType ST_Get_i32r = { "get_i32r", Getter_i32r };
+static struct SeqType ST_Get_i64r = { "get_i64r", Getter_i64r };
+static struct SeqType ST_Get_f32  = { "get_f32" , Getter_f32  };
+static struct SeqType ST_Get_f64  = { "get_f64" , Getter_f64  };
+static struct SeqType ST_Get_f32r = { "get_f32r", Getter_f32r };
+static struct SeqType ST_Get_f64r = { "get_f64r", Getter_f64r };
+
+SeqType_p PickIntGetter (int bits) {
+    switch (bits) {
+        default:    Assert(0); /* fall through */
+        case 0:     return &ST_Get_i0;
+        case 1:     return &ST_Get_i1;
+        case 2:     return &ST_Get_i2;
+        case 4:     return &ST_Get_i4;
+        case 8:     return &ST_Get_i8;
+        case 16:    return &ST_Get_i16;
+        case 32:    return &ST_Get_i32;
+        case 64:    return &ST_Get_i64;
+    }
+}
+
+SeqType_p FixedGetter (int bytes, int rows, int real, int flip) {
+    int bits;
+
+    static char widths[8][7] = {
+        {0,-1,-1,-1,-1,-1,-1},
+        {0, 8,16, 1,32, 2, 4},
+        {0, 4, 8, 1,16, 2,-1},
+        {0, 2, 4, 8, 1,-1,16},
+        {0, 2, 4,-1, 8, 1,-1},
+        {0, 1, 2, 4,-1, 8,-1},
+        {0, 1, 2, 4,-1,-1, 8},
+        {0, 1, 2,-1, 4,-1,-1},
+    };
+
+    bits = rows < 8 && bytes < 7 ? widths[rows][bytes] : (bytes << 3) / rows;
+
+    switch (bits) {
+        case 16:    return flip ? &ST_Get_i16r : &ST_Get_i16;
+        case 32:    return real ? flip ? &ST_Get_f32r : &ST_Get_f32
+                                : flip ? &ST_Get_i32r : &ST_Get_i32;
+        case 64:    return real ? flip ? &ST_Get_f64r : &ST_Get_f64
+                                : flip ? &ST_Get_i64r : &ST_Get_i64;
+    }
+
+    return PickIntGetter(bits);
+}
+/* %include<hash.c>% */
+/*
+ * hash.c - Implementation of hashing functions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+typedef struct HashInfo *HashInfo_p;
+
+typedef struct HashInfo {
+    View_p  view;       /* input view */
+    int     prime;      /* prime used for hashing */
+    int     fill;       /* used to fill map */
+    int    *map;        /* map of unique rows */
+    Column  mapcol;     /* owner of map */
+    int    *hvec;       /* hash probe vector */
+    Column  veccol;     /* owner of hvec */
+    int    *hashes;     /* hash values, one per view row */
+    Column  hashcol;    /* owner of hashes */
+} HashInfo;
+
+static int StringHash (const char *s, int n) {
+    /* similar to Python's stringobject.c */
+    int i, h = (*s * 0xFF) << 7;
+    if (n < 0)
+        n = strlen(s);
+    for (i = 0; i < n; ++i)
+        h = (1000003 * h) ^ s[i];
+    return h ^ i;
+}
+
+static Column HashCol (ItemTypes type, Column column) {
+    int i, count, *data;
+    Seq_p seq;
+    Item item;
+
+/* the following is not possible: the result may be xor-ed into!
+    if (type == IT_int && column.seq->getter == PickIntGetter(32))
+        return column;
+*/
+
+    count = column.seq->count;
+    seq = NewIntVec(count, &data);
+
+    switch (type) {
+        
+        case IT_int:
+            for (i = 0; i < count; ++i)
+                data[i] = GetColItem(i, column, IT_int).i;
+            break;
+                
+        case IT_wide:
+            for (i = 0; i < count; ++i) {
+                item = GetColItem(i, column, IT_wide);
+                data[i] = item.q[0] ^ item.q[1];
+            }
+            break;
+                
+        case IT_float:
+            for (i = 0; i < count; ++i)
+                data[i] = GetColItem(i, column, IT_float).i;
+            break;
+                
+        case IT_double:
+            for (i = 0; i < count; ++i) {
+                item = GetColItem(i, column, IT_double);
+                data[i] = item.q[0] ^ item.q[1];
+            }
+            break;
+                
+        case IT_string:
+            for (i = 0; i < count; ++i) {
+                item = GetColItem(i, column, IT_string);
+                data[i] = StringHash(item.s, -1);
+            }
+            break;
+                
+        case IT_bytes:
+            for (i = 0; i < count; ++i) {
+                item = GetColItem(i, column, IT_bytes);
+                data[i] = StringHash((const char*) item.u.ptr, item.u.len);
+            }
+            break;
+                
+        case IT_view:
+            for (i = 0; i < count; ++i) {
+                int j, hcount, hval = 0;
+                const int *hvec;
+                Column hashes;
+                
+                item = GetColItem(i, column, IT_view);
+                hashes = HashValues(item.v);
+                hvec = (const int*) hashes.seq->data[0].p;
+                hcount = hashes.seq->count;
+                
+                for (j = 0; j < hcount; ++j)
+                    hval ^= hvec[j];
+                /* TODO: release hashes right now */
+            
+                data[i] = hval ^ hcount;
+            }
+            break;
+                
+        default: Assert(0);
+    }
+
+    return SeqAsCol(seq);
+}
+
+ItemTypes HashColCmd_SO (Item args[]) {
+    ItemTypes type;
+    Column column;
+    
+    type = CharAsItemType(args[0].s[0]);
+    column = CoerceColumn(type, args[1].o);
+    if (column.seq == NULL)
+        return IT_unknown;
+        
+    args->c = HashCol(type, column);
+    return IT_column;
+}
+
+int RowHash (View_p view, int row) {
+    int c, hash = 0;
+    Item item;
+
+    for (c = 0; c < ViewWidth(view); ++c) {
+        item.c = ViewCol(view, c);
+        switch (GetItem(row, &item)) {
+
+            case IT_int:
+                hash ^= item.i;
+                break;
+
+            case IT_string:
+                hash ^= StringHash(item.s, -1);
+                break;
+
+            case IT_bytes:
+                hash ^= StringHash((const char*) item.u.ptr, item.u.len);
+                break;
+
+            default: {
+                View_p rview = StepView(view, 1, row, 1, 1);
+                Column rcol = HashValues(rview);
+                hash = *(const int*) rcol.seq->data[0].p;
+                break;
+            }
+        }
+    }
+
+    return hash;
+}
+
+static void XorWithIntCol (Column src, Column_p dest) {
+    const int *srcdata = (const int*) src.seq->data[0].p;
+    int i, count = src.seq->count, *destdata = (int*) dest->seq->data[0].p;
+
+    for (i = 0; i < count; ++i)
+        destdata[i] ^= srcdata[i];
+}
+
+Column HashValues (View_p view) {
+    int c;
+    Column result;
+
+    if (ViewWidth(view) == 0 || ViewSize(view) == 0)
+        return SeqAsCol(NewIntVec(ViewSize(view), NULL));
+        
+    result = HashCol(ViewColType(view, 0), ViewCol(view, 0));
+    for (c = 1; c < ViewWidth(view); ++c) {
+        Column auxcol = HashCol(ViewColType(view, c), ViewCol(view, c));
+        /* TODO: get rid of the separate xor step by xoring in HashCol */
+        XorWithIntCol(auxcol, &result);
+    }
+    return result;
+}
+
+static int HashFind (View_p keyview, int keyrow, int keyhash, HashInfo_p data) {
+    int probe, datarow, mask, step;
+
+    mask = data->veccol.seq->count - 1;
+    probe = ~keyhash & mask;
+
+    step = (keyhash ^ (keyhash >> 3)) & mask;
+    if (step == 0)
+        step = mask;
+
+    for (;;) {
+        probe = (probe + step) & mask;
+        if (data->hvec[probe] == 0)
+            break;
+
+        datarow = data->map[data->hvec[probe]-1];
+        if (keyhash == data->hashes[datarow] &&
+                RowEqual(keyview, keyrow, data->view, datarow))
+            return data->hvec[probe] - 1;
+
+        step <<= 1;
+        if (step > mask)
+            step ^= data->prime;
+    }
+
+    if (keyview == data->view) {
+        data->hvec[probe] = data->fill + 1;
+        data->map[data->fill++] = keyrow;
+    }
+
+    return -1;
+}
+
+static int StringHashFind (const char *key, Seq_p hseq, Column values) {
+    int probe, datarow, mask, step, keyhash;
+    const int *hvec = (const int*) hseq->data[0].p;
+    int prime = hseq->data[2].i;
+    
+    keyhash = StringHash(key, -1);
+    mask = hseq->count - 1;
+    probe = ~keyhash & mask;
+
+    step = (keyhash ^ (keyhash >> 3)) & mask;
+    if (step == 0)
+        step = mask;
+
+    for (;;) {
+        probe = (probe + step) & mask;
+        datarow = hvec[probe] - 1;
+        if (datarow < 0)
+            break;
+
+        /* These string hashes are much simpler than the standard HashFind:
+             no hashes vector, no indirect map, compute all hashes on-the-fly */
+                
+        if (strcmp(key, GetColItem(datarow, values, IT_string).s) == 0)
+            return datarow;
+
+        step <<= 1;
+        if (step > mask)
+            step ^= prime;
+    }
+
+    return ~probe;
+}
+
+static int Log2bits (int n) {
+    int bits = 0;
+    while ((1 << bits) < n)
+        ++bits;
+    return bits;
+}
+
+static Column HashVector (int rows) {
+    int bits = Log2bits((4 * rows) / 3);
+    if (bits < 2)
+        bits = 2;
+    return SeqAsCol(NewIntVec(1 << bits, NULL));
+}
+
+static void InitHashInfo (HashInfo_p info, View_p view, Column hmap, Column hvec, Column hashes) {
+    int size = hvec.seq->count;
+
+    static char slack [] = {
+        0, 0, 3, 3, 3, 5, 3, 3, 29, 17, 9, 5, 83, 27, 43, 3,
+        45, 9, 39, 39, 9, 5, 3, 33, 27, 9, 71, 39, 9, 5, 83, 0
+    };
+
+    info->view = view;
+    info->prime = size + slack[Log2bits(size-1)];
+    info->fill = 0;
+    
+    info->mapcol = hmap;
+    info->map = (int*) hmap.seq->data[0].p;
+
+    info->veccol = hvec;
+    info->hvec = (int*) hvec.seq->data[0].p;
+
+    info->hashcol = hashes;
+    info->hashes = (int*) hashes.seq->data[0].p;
+}
+
+int StringLookup (const char *key, Column values) {
+    int h, r, rows, *hptr;
+    const char *string;
+    Column hvec;
+    HashInfo info;
+    
+    /* adjust data[2], this assumes values is a string column */
+    
+    if (values.seq->data[2].p == NULL) {
+        rows = values.seq->count;
+        hvec = HashVector(rows);
+        hptr = (int*) hvec.seq->data[0].p;
+        
+        /* use InitHashInfo to get at the prime number, bit of a hack */
+        InitHashInfo(&info, NULL, hvec, hvec, hvec);
+        hvec.seq->data[2].i = info.prime;
+        
+        for (r = 0; r < rows; ++r) {
+            string = GetColItem(r, values, IT_string).s;
+            h = StringHashFind(string, hvec.seq, values);
+            if (h < 0) /* silently ignore duplicates */
+                hptr[~h] = r + 1;
+        }
+        
+        values.seq->data[2].p = IncRefCount(hvec.seq);
+    }
+    
+    h = StringHashFind(key, (Seq_p) values.seq->data[2].p, values);
+    return h >= 0 ? h : -1;
+}
+
+static void FillHashInfo (HashInfo_p info, View_p view) {
+    int r, rows;
+    Column mapcol;
+    
+    rows = ViewSize(view);
+    mapcol = SeqAsCol(NewIntVec(rows, NULL)); /* worst-case, dunno #groups */
+
+    InitHashInfo(info, view, mapcol, HashVector(rows), HashValues(view));
+
+    for (r = 0; r < rows; ++r)
+        HashFind(view, r, info->hashes[r], info);
+
+    /* TODO: reclaim unused entries at end of map */
+    mapcol.seq->count = info->fill;
+}
+
+static void ChaseLinks (HashInfo_p info, int count, const int *hmap, const int *lmap) {
+    int groups = info->fill, *smap = info->hvec, *gmap = info->hashes;
+    
+    while (--groups >= 0) {
+        int head = hmap[groups] - 1;
+        smap[groups] = count;
+        while (head >= 0) {
+            gmap[--count] = head;
+            head = lmap[head];
+        }
+    }
+    /* assert(count == 0); */
+}
+
+void FillGroupInfo (HashInfo_p info, View_p view) {
+    int g, r, rows, *hmap, *lmap;
+    Column mapcol, headmap, linkmap;
+    
+    rows = ViewSize(view);
+    mapcol = SeqAsCol(NewIntVec(rows, NULL)); /* worst-case, dunno #groups */
+    headmap = SeqAsCol(NewIntVec(rows, &hmap)); /* same: don't know #groups */
+    linkmap = SeqAsCol(NewIntVec(rows, &lmap));
+
+    InitHashInfo(info, view, mapcol, HashVector(rows), HashValues(view));
+
+    for (r = 0; r < rows; ++r) {
+        g = HashFind(view, r, info->hashes[r], info);
+        if (g < 0)
+            g = info->fill - 1;
+        lmap[r] = hmap[g] - 1;
+        hmap[g] = r + 1;
+    }
+    
+    /* TODO: reclaim unused entries at end of map and hvec */
+    info->mapcol.seq->count = info->veccol.seq->count = info->fill;
+    
+    ChaseLinks(info, rows, hmap, lmap);
+
+    /* TODO: could release headmap and linkmap but that's a no-op here */
+    
+    /*  There's probably an opportunity to reduce space usage further,
+        since the grouping map points to the starting row of each group:
+            map[i] == gmap[smap[i]]
+        Perhaps "map" (which starts out with #rows entries) can be re-used
+        to append the gmap entries (if we can reduce it by #groups items).
+        Or just release map[x] for grouping views, and use gmap[smap[x]].
+    */
+}
+
+View_p GroupCol (View_p view, Column cols, const char *name) {
+    View_p vkey, vres, gview;
+    HashInfo info;
+    
+    vkey = ColMapView(view, cols);
+    vres = ColMapView(view, OmitColumn(cols, ViewWidth(view)));
+
+    FillGroupInfo(&info, vkey);
+    gview = GroupedView(vres, info.veccol, info.hashcol, name);
+    return PairView(RemapSubview(vkey, info.mapcol, 0, -1), gview);
+}
+
+static void FillJoinInfo (HashInfo_p info, View_p left, View_p right) {
+    int g, r, gleft, nleft, nright, nused = 0, *hmap, *lmap, *jmap;
+    Column mapcol, headmap, linkmap, joincol;
+    
+    nleft = ViewSize(left);
+    mapcol = SeqAsCol(NewIntVec(nleft, NULL)); /* worst-case dunno #groups */
+    joincol = SeqAsCol(NewIntVec(nleft, &jmap));
+    
+    InitHashInfo(info, left, mapcol, HashVector(nleft), HashValues(left));
+
+    for (r = 0; r < nleft; ++r) {
+        g = HashFind(left, r, info->hashes[r], info);
+        if (g < 0)
+            g = info->fill - 1;
+        jmap[r] = g;
+    }
+
+    /* TODO: reclaim unused entries at end of map */
+    mapcol.seq->count = info->fill;
+
+    gleft = info->mapcol.seq->count;
+    nleft = info->hashcol.seq->count;
+    nright = ViewSize(right);
+    
+    headmap = SeqAsCol(NewIntVec(gleft, &hmap)); /* don't know #groups */
+    linkmap = SeqAsCol(NewIntVec(nright, &lmap));
+
+    for (r = 0; r < nright; ++r) {
+        g = HashFind(right, r, RowHash(right, r), info);
+        if (g >= 0) {
+            lmap[r] = hmap[g] - 1;
+            hmap[g] = r + 1;
+            ++nused;
+        }
+    }
+
+    /* we're reusing veccol, but it might not be large enough to start with */
+    /* TODO: reclaim unused entries at end of hvec */
+    if (info->veccol.seq->count < nused)
+        info->veccol = SeqAsCol(NewIntVec(nused, &info->hvec));
+    else 
+        info->veccol.seq->count = nused;
+
+    /* reorder output to match results from FillHashInfo and FillGroupInfo */
+    info->hashcol = info->veccol;
+    info->hashes = info->hvec;
+    info->veccol = info->mapcol;
+    info->hvec = info->map;
+    info->mapcol = joincol;
+    info->map = jmap;
+    
+    ChaseLinks(info, nused, hmap, lmap);
+    
+    /*  As with FillGroupInfo, this is most likely not quite optimal yet.
+        All zero-length groups in smap (info->map, now info->hvec) could be 
+        coalesced into one, and joinmap indices into it adjusted down a bit.
+        Would reduce the size of smap when there are lots of failed matches.
+        Also: FillJoinInfo needs quite a lot of temp vector space right now.
+     */
+}
+
+Column IntersectMap (View_p keys, View_p view) {
+    int r, rows;
+    HashInfo info;
+    struct Buffer buffer;
+    
+    if (!ViewCompat(keys, view)) 
+        return SeqAsCol(NULL);
+        
+    FillHashInfo(&info, view);
+    InitBuffer(&buffer);
+    rows = ViewSize(keys);
+    
+    /* these ints are added in increasing order, could have used a bitmap */
+    for (r = 0; r < rows; ++r)
+        if (HashFind(keys, r, RowHash(keys, r), &info) >= 0)
+            ADD_INT_TO_BUF(buffer, r);
+
+    return SeqAsCol(BufferAsIntVec(&buffer));
+}
+
+/* ReverseIntersectMap returns RHS indices, instead of IntersectMap's LHS */
+static Column ReverseIntersectMap (View_p keys, View_p view) {
+    int r, rows;
+    HashInfo info;
+    struct Buffer buffer;
+    
+    FillHashInfo(&info, view);
+    InitBuffer(&buffer);
+    rows = ViewSize(keys);
+    
+    for (r = 0; r < rows; ++r) {
+        int f = HashFind(keys, r, RowHash(keys, r), &info);
+        if (f >= 0)
+            ADD_INT_TO_BUF(buffer, f);
+    }
+    
+    return SeqAsCol(BufferAsIntVec(&buffer));
+}
+
+View_p JoinView (View_p left, View_p right, const char *name) {
+    View_p lmeta, rmeta, lkey, rkey, rres, gview;
+    Column lmap, rmap;
+    HashInfo info;
+    
+    lmeta = V_Meta(left);
+    rmeta = V_Meta(right);
+    
+    lmap = IntersectMap(lmeta, rmeta);
+    /* TODO: optimize, don't create the hash info twice */
+    rmap = ReverseIntersectMap(lmeta, rmeta);
+
+    lkey = ColMapView(left, lmap);
+    rkey = ColMapView(right, rmap);
+    rres = ColMapView(right, OmitColumn(rmap, ViewWidth(right)));
+
+    FillJoinInfo(&info, lkey, rkey);
+    gview = GroupedView(rres, info.veccol, info.hashcol, name);
+    return PairView(left, RemapSubview(gview, info.mapcol, 0, -1));
+}
+
+Column UniqMap (View_p view) {
+    HashInfo info;
+    FillHashInfo(&info, view);
+    return info.mapcol;
+}
+
+int HashDoFind (View_p view, int row, View_p w, Column a, Column b, Column c) {
+    HashInfo info;
+    /* TODO: avoid Log2bits call in InitHashInfo, since done on each find */
+    InitHashInfo(&info, w, a, b, c);
+    return HashFind(view, row, RowHash(view, row), &info);
+}
+
+Column GetHashInfo (View_p left, View_p right, int type) {
+    HashInfo info;
+    Seq_p seqvec[3];
+
+    switch (type) {
+        case 0:     FillHashInfo(&info, left); break;
+        case 1:     FillGroupInfo(&info, left); break;
+        default:    FillJoinInfo(&info, left, right); break;
+    }
+        
+    seqvec[0] = info.mapcol.seq;
+    seqvec[1] = info.veccol.seq;
+    seqvec[2] = info.hashcol.seq;
+
+    return SeqAsCol(NewSeqVec(IT_column, seqvec, 3));
+}
+
+View_p IjoinView (View_p left, View_p right) {
+    View_p view = JoinView(left, right, "?");
+    return UngroupView(view, ViewWidth(view)-1);
+}
+
+static struct SeqType ST_HashMap = { "hashmap", NULL, 02 };
+
+Seq_p HashMapNew (void) {
+    Seq_p result;
+    
+    result = NewSequence(0, &ST_HashMap, 0);
+    /* data[0] is the key + value + hash vector */
+    /* data[1] is the allocated count */
+    result->data[0].p = NULL;
+    result->data[1].i = 0;
+    
+    return result;
+}
+
+/* FIXME: dumb linear scan instead of hashing for now, for small tests only */
+
+static int HashMapLocate(Seq_p hmap, int key, int *pos) {
+    const int *data = hmap->data[0].p;
+    
+    for (*pos = 0; *pos < hmap->count; ++*pos)
+        if (key == data[*pos])
+            return 1;
+        
+    return 0;
+}
+
+int HashMapAdd (Seq_p hmap, int key, int value) {
+    int pos, *data = hmap->data[0].p;
+    int allocnt = hmap->data[1].i;
+
+    if (HashMapLocate(hmap, key, &pos)) {
+        data[pos+allocnt] = value;
+        return 0;
+    }
+
+    Assert(pos == hmap->count);
+    if (pos >= allocnt) {
+        int newlen = (allocnt / 2) * 3 + 10;
+        hmap->data[0].p = data = realloc(data, newlen * 2 * sizeof(int));
+        memmove(data+newlen, data+allocnt, allocnt * sizeof(int));
+        allocnt = hmap->data[1].i = newlen;
+    }
+    
+    data[pos] = key;
+    data[pos+allocnt] = value;
+    ++hmap->count;
+    return allocnt;
+}
+
+int HashMapLookup (Seq_p hmap, int key, int defval) {
+    int pos;
+
+    if (HashMapLocate(hmap, key, &pos)) {
+        int allocnt = hmap->data[1].i;
+        const int *data = hmap->data[0].p;
+        return data[pos+allocnt];
+    }
+    
+    return defval;
+}
+
+#if 0 /* not yet */
+int HashMapRemove (Seq_p hmap, int key) {
+    int pos;
+
+    if (HashMapLocate(hmap, key, &pos)) {
+        int last = --hmap->count;
+        if (pos < last) {
+            int allocnt = hmap->data[1].i, *data = hmap->data[0].p;
+            data[pos] = data[last];
+            data[pos+allocnt] = data[last+allocnt];
+            return pos;
+        }
+    }
+    
+    return -1;
+}
+#endif
+/* %include<indirect.c>% */
+/*
+ * indirect.c - Implementation of some virtual views.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#define RV_parent   data[0].q
+#define RV_map      data[1].q
+#define RV_start    data[2].i
+
+static ItemTypes RemapGetter (int row, Item_p item) {
+    const int* data;
+    Seq_p seq;
+
+    Assert(item->c.pos >= 0);
+    seq = item->c.seq;
+    data = seq->RV_map->data[0].p;
+
+    item->c = ViewCol(seq->RV_parent, item->c.pos);
+    row += seq->RV_start;
+    if (data[row] < 0)
+        row += data[row];
+    return GetItem(data[row], item);
+}
+
+static struct SeqType ST_Remap = { "remap", RemapGetter, 011 };
+
+View_p RemapSubview (View_p view, Column mapcol, int start, int count) {
+    Seq_p seq;
+
+    if (mapcol.seq == NULL)
+        return NULL;
+        
+    if (count < 0)
+        count = mapcol.seq->count;
+    
+    if (ViewWidth(view) == 0)
+        return NoColumnView(count);
+        
+    seq = NewSequence(count, &ST_Remap, 0);
+    /* data[0] is the parent view to which the map applies */
+    /* data[1] is the map, as a sequence */
+    /* data[2] is the index offset */
+    seq->RV_parent = IncRefCount(view);
+    seq->RV_map = IncRefCount(mapcol.seq);
+    seq->RV_start = start;
+
+    return IndirectView(V_Meta(view), seq);
+}
+
+static View_p MakeMetaSubview (const char *name, View_p view) {
+    View_p meta, result;
+    Seq_p names, types, subvs;
+    
+    names = NewStrVec(1);
+    AppendToStrVec(name, -1, names);
+
+    types = NewStrVec(1);
+    AppendToStrVec("V", -1, types);
+    
+    meta = V_Meta(view);
+    subvs = NewSeqVec(IT_view, &meta, 1);
+    
+    result = NewView(V_Meta(meta));
+    SetViewSeqs(result, MC_name, 1, FinishStrVec(names));
+    SetViewSeqs(result, MC_type, 1, FinishStrVec(types));
+    SetViewSeqs(result, MC_subv, 1, subvs);
+    return result;
+}
+
+#define GV_parent       data[0].q
+#define GV_start        data[1].q
+#define GV_group        data[2].q
+#define GV_cache        data[3].q
+
+static ItemTypes GroupedGetter (int row, Item_p item) {
+    Seq_p seq = item->c.seq;
+    View_p *subviews = seq->GV_cache->data[0].p;
+    
+    if (subviews[row] == NULL) {
+        const int *sptr = seq->GV_start->data[0].p;
+        Seq_p gmap = seq->GV_group;
+        int start = row > 0 ? sptr[row-1] : 0;
+        
+        item->c.seq = gmap;
+        subviews[row] = IncRefCount(RemapSubview(seq->GV_parent, item->c,
+                                                    start, sptr[row] - start));
+    }
+    
+    item->v = subviews[row];
+    return IT_view;
+}
+
+static struct SeqType ST_Grouped = { "grouped", GroupedGetter, 01111 };
+
+View_p GroupedView (View_p view, Column startcol, Column groupcol, const char *name) {
+    int groups;
+    Seq_p seq, subviews;
+    
+    groups = startcol.seq->count;
+    subviews = NewSeqVec(IT_view, NULL, groups);
+
+    seq = NewSequence(groups, &ST_Grouped, 0);
+    /* data[0] is the parent view to which the grouping applies */
+    /* data[1] is the start map, as a sequence */
+    /* data[2] is the group map, as a sequence */
+    /* data[3] is a cache of subviews, as a pointer vector in a sequence */
+    seq->GV_parent = IncRefCount(view);
+    seq->GV_start = IncRefCount(startcol.seq);
+    seq->GV_group = IncRefCount(groupcol.seq);
+    seq->GV_cache = IncRefCount(subviews);
+
+    return IndirectView(MakeMetaSubview(name, view), seq);
+}
+
+#define PV_parent   data[0].q
+#define PV_start    data[1].i
+#define PV_rate     data[2].i
+#define PV_step     data[3].i
+
+static ItemTypes StepGetter (int row, Item_p item) {
+    Seq_p seq = item->c.seq;
+    int rows = ViewSize(seq->PV_parent);
+
+    item->c = ViewCol(seq->PV_parent, item->c.pos);
+    row = (seq->PV_start + (row / seq->PV_rate) * seq->PV_step) % rows;
+    if (row < 0)
+        row += rows;
+    return GetItem(row, item);
+}
+
+static struct SeqType ST_Step = { "step", StepGetter, 01 };
+
+View_p StepView (View_p view, int count, int offset, int rate, int step) {
+    Seq_p seq;
+
+    /* prevent division by zero if input view is empty */
+    if (ViewSize(view) == 0)
+        return view;
+
+    seq = NewSequence(count * rate, &ST_Step, 0);
+    /* data[0] is the parent view to which the changes apply */
+    /* data[1] is the starting offset */
+    /* data[2] is the rate to repeat an item */
+    /* data[3] is the step to the next item */
+    seq->PV_parent = IncRefCount(view);
+    seq->PV_start = offset;
+    seq->PV_rate = rate;
+    seq->PV_step = step;
+
+    return IndirectView(V_Meta(view), seq);
+}
+
+#define CV_left     data[0].q
+#define CV_right    data[1].q
+
+static ItemTypes ConcatGetter (int row, Item_p item) {
+    View_p view = item->c.seq->CV_left;
+    int rows = ViewSize(view);
+    
+    if (row >= rows) {
+        row -= rows;
+        view = item->c.seq->CV_right;
+    }
+
+    item->c = ViewCol(view, item->c.pos);
+    return GetItem(row, item);
+}
+
+static struct SeqType ST_Concat = { "concat", ConcatGetter, 011 };
+
+View_p ConcatView (View_p view1, View_p view2) {
+    int rows1, rows2;
+    Seq_p seq;
+
+    if (view1 == NULL || view2 == NULL || !ViewCompat(view1, view2))
+        return NULL;
+                    
+    rows1 = ViewSize(view1);
+    if (rows1 == 0)
+        return view2;
+
+    rows2 = ViewSize(view2);
+    if (rows2 == 0)
+        return view1;
+
+    seq = NewSequence(rows1 + rows2, &ST_Concat, 0);
+    /* data[0] is the left-hand view */
+    /* data[1] is the right-hand view */
+    seq->CV_left = IncRefCount(view1);
+    seq->CV_right = IncRefCount(view2);
+
+    return IndirectView(V_Meta(view1), seq);
+}
+
+#define UV_parent       data[0].q
+#define UV_unmap        data[1].q
+#define UV_subcol       data[2].i
+#define UV_swidth       data[3].i
+
+static ItemTypes UngroupGetter (int row, Item_p item) {
+    int col, subcol, parentrow;
+    const int *data;
+    View_p view;
+    Seq_p seq;
+
+    col = item->c.pos;
+    seq = item->c.seq;
+
+    view = seq->UV_parent;
+    data = seq->UV_unmap->data[0].p;
+    subcol = seq->UV_subcol;
+
+    parentrow = data[row];
+    if (parentrow < 0) {
+        parentrow = data[row+parentrow];
+        row = -data[row];
+    } else
+        row = 0;
+    
+    if (subcol <= col && col < subcol + seq->UV_swidth) {
+        view = GetViewItem(view, parentrow, subcol, IT_view).v;
+        col -= subcol;
+    } else {
+        if (col >= subcol)
+            col -= seq->UV_swidth - 1;
+        row = parentrow;
+    }
+    
+    item->c = ViewCol(view, col);
+    return GetItem(row, item);
+}
+
+static struct SeqType ST_Ungroup = { "ungroup", UngroupGetter, 011 };
+
+View_p UngroupView (View_p view, int col) {
+    int i, n, r, rows;
+    struct Buffer buffer;
+    View_p subview, meta, submeta, newmeta;
+    Seq_p seq, map;
+    Column column;
+    
+    InitBuffer(&buffer);
+
+    column = ViewCol(view, col);
+    rows = column.seq->count;
+    
+    for (r = 0; r < rows; ++r) {
+        subview = GetColItem(r, column, IT_view).v;
+        n = ViewSize(subview);
+        if (n > 0) {
+            ADD_INT_TO_BUF(buffer, r);
+            for (i = 1; i < n; ++i)
+                ADD_INT_TO_BUF(buffer, -i);
+        }
+    }
+
+    map = BufferAsIntVec(&buffer);
+    
+    /* result meta view replaces subview column with its actual meta view */
+    meta = V_Meta(view);
+    submeta = GetViewItem(meta, col, MC_subv, IT_view).v;
+    newmeta = ConcatView(FirstView(meta, col), submeta);
+    newmeta = ConcatView(newmeta, LastView(meta, ViewSize(meta) - (col + 1)));
+    
+    seq = NewSequence(map->count, &ST_Ungroup, 0);
+    /* data[0] is the parent view */
+    /* data[1] is ungroup map as a sequence */
+    /* data[2] is the subview column */
+    /* data[3] is the subview width */
+    seq->UV_parent = IncRefCount(view);
+    seq->UV_unmap = IncRefCount(map);
+    seq->UV_subcol = col;
+    seq->UV_swidth = ViewSize(submeta);
+    
+    return IndirectView(newmeta, seq);
+}
+
+#define BV_parent       data[0].q
+#define BV_cumcnt       data[1].q
+
+static ItemTypes BlockedGetter (int row, Item_p item) {
+    int block;
+    const int* data;
+    View_p subv;
+    Seq_p seq;
+
+    seq = item->c.seq;
+    data = seq->BV_cumcnt->data[0].p;
+
+    for (block = 0; block + data[block] < row; ++block)
+        ;
+
+    if (row == block + data[block]) {
+        row = block;
+        block = ViewSize(seq->BV_parent) - 1;
+    } else if (block > 0)
+        row -= block + data[block-1];
+
+    subv = GetViewItem(seq->BV_parent, block, 0, IT_view).v;
+    item->c = ViewCol(subv, item->c.pos);    
+    return GetItem(row, item);
+}
+
+static struct SeqType ST_Blocked = { "blocked", BlockedGetter, 011 };
+
+View_p BlockedView (View_p view) {
+    int r, rows, *limits, tally = 0;
+    View_p submeta;
+    Seq_p seq, offsets;
+    Column blocks;
+
+    /* view must have exactly one subview column */
+    if (ViewWidth(view) != 1)
+        return NULL;
+    
+    blocks = ViewCol(view, 0);
+    rows = ViewSize(view);
+    
+    offsets = NewIntVec(rows, &limits);
+    for (r = 0; r < rows; ++r) {
+        tally += ViewSize(GetColItem(r, blocks, IT_view).v);
+        limits[r] = tally;
+    }
+    
+    seq = NewSequence(tally, &ST_Blocked, 0);
+    /* data[0] is the parent view */
+    /* data[1] is a cumulative row count, as a sequence */
+    seq->BV_parent = IncRefCount(view);
+    seq->BV_cumcnt = IncRefCount(offsets);
+    
+    submeta = GetViewItem(V_Meta(view), 0, MC_subv, IT_view).v;
+    return IndirectView(submeta, seq);
+}
+/* %include<mutable.c>% */
+/*
+ * mutable.c - Implementation of mutable views.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#define MUT_DEBUG 0
+
+#define S_aux(seq,typ) ((typ) ((Seq_p) (seq) + 1))
+
+#define SV_data(seq)    S_aux(seq, Seq_p*)
+#define SV_bits         data[0].q
+#define SV_hash         data[1].q
+#define SV_view         data[2].q
+
+static void SettableCleaner (Seq_p seq) {
+    int c, r;
+    View_p view = seq->SV_view;
+    
+    for (c = 0; c < ViewWidth(view); ++c) {
+        Seq_p dseq = SV_data(seq)[c];
+
+        if (dseq != NULL)
+            switch (ViewColType(view, c)) {
+
+                case IT_string: {
+                    char **p = S_aux(dseq, char**);
+                    for (r = 0; r < dseq->count; ++r)
+                        if (p[r] != NULL)
+                            free(p[r]);
+                    break;
+                }
+
+                case IT_bytes: {
+                    const Item *p = S_aux(dseq, const Item*);
+                    for (r = 0; r < dseq->count; ++r)
+                        if (p[r].u.ptr != NULL)
+                            free((char*) p[r].u.ptr);
+                    break;
+                }
+
+                case IT_view: {
+                    const View_p *p = S_aux(dseq, const View_p*);
+                    for (r = 0; r < dseq->count; ++r)
+                        if (p[r] != NULL)
+                            DecRefCount(p[r]);
+                    break;
+                }
+            
+                default: break;
+            }
+
+        DecRefCount(dseq);
+        DecRefCount(SV_data(seq)[ViewWidth(view)+c]);
+    }
+}
+
+static ItemTypes SettableGetter (int row, Item_p item) {
+    int col = item->c.pos;
+    Seq_p seq = item->c.seq;
+    View_p view = seq->SV_view;
+    
+    item->c = ViewCol(view, col);
+    
+    if (TestBit(seq->SV_bits, row)) {
+        int index = HashMapLookup(seq->SV_hash, row, -1);
+        Assert(index >= 0);
+    
+        if (TestBit(SV_data(seq)[ViewWidth(view)+col], index)) {
+            row = index;
+            item->c.seq = SV_data(seq)[col];
+        }
+    }
+    
+    return GetItem(row, item);
+}
+static int SettableWidth (ItemTypes type) {
+    switch (type) {
+        case IT_int:  case IT_float:    return 4;
+        case IT_wide: case IT_double:   return 8;
+        case IT_view: case IT_string:   return sizeof(void*);
+        case IT_bytes:                  return sizeof(Item);
+        default:                        Assert(0); return 0;
+    }
+}
+
+static ItemTypes StringSetGetter (int row, Item_p item) {
+    item->s = S_aux(item->c.seq, const char**)[row];
+    return IT_string;
+}
+
+static ItemTypes BytesSetGetter (int row, Item_p item) {
+    item->u = S_aux(item->c.seq, const Item*)[row].u;
+    return IT_bytes;
+}
+
+static ItemTypes ViewSetGetter (int row, Item_p item) {
+    item->v = S_aux(item->c.seq, const View_p*)[row];
+    return IT_view;
+}
+
+static struct SeqType ST_StringSet = { "stringset", StringSetGetter };
+static struct SeqType ST_BytesSet = { "bytesset", BytesSetGetter };
+static struct SeqType ST_ViewSet = { "viewset", ViewSetGetter };
+
+static SeqType_p PickSetGetter (ItemTypes type) {
+    int w = 8;
+    switch (type) {
+        case IT_int:    w = 4; /* fall through */
+        case IT_wide:   return FixedGetter(w, 1, 0, 0);
+        case IT_float:  w = 4; /* fall through */
+        case IT_double: return FixedGetter(w, 1, 1, 0);
+        case IT_string: return &ST_StringSet;
+        case IT_bytes:  return &ST_BytesSet;
+        case IT_view:   return &ST_ViewSet;
+        default:        Assert(0); return NULL;
+    }
+}
+
+static struct SeqType ST_Settable = {
+    "settable", SettableGetter, 0111, SettableCleaner
+};
+
+static int IsSettable(View_p view) {
+    Seq_p seq = ViewCol(view, 0).seq;
+    return seq != NULL && seq->type == &ST_Settable;
+}
+
+static void SettableSetter (View_p view, int row, int col, Item_p item) {
+    int index, count, limit;
+    ItemTypes type;
+    Seq_p seq, dseq, hash;
+    
+    Assert(IsSettable(view));
+    
+    seq = ViewCol(view, col).seq;
+    type = ViewColType(view, col);
+    dseq = SV_data(seq)[col];
+    hash = seq->SV_hash;
+
+    if (SetBit(&seq->SV_bits, row)) {
+        index = hash->count;
+        HashMapAdd(hash, row, index);
+    } else {
+        index = HashMapLookup(hash, row, -1);
+        Assert(index >= 0);
+    }
+    
+    limit = SetBit(&SV_data(seq)[ViewWidth(view)+col], index);
+    count = dseq != NULL ? dseq->count : 0;
+    
+    /* clumsy: resize a settable column so it can store more items if needed */
+    if (limit > count) {
+        int w = SettableWidth(type);
+        Seq_p nseq;
+        nseq = IncRefCount(NewSequence(limit, PickSetGetter(type), limit * w));
+        memcpy(nseq + 1, LoseRef(dseq) + 1, count * w);
+        SV_data(seq)[col] = dseq = nseq;
+    }
+    
+    switch (type) {
+        
+        case IT_int:    S_aux(dseq, int*    )[index] = item->i; break;
+        case IT_wide:   S_aux(dseq, int64_t*)[index] = item->w; break;
+        case IT_float:  S_aux(dseq, float*  )[index] = item->f; break;                                  
+        case IT_double: S_aux(dseq, double* )[index] = item->d; break;
+
+        case IT_string: {
+            char **p = S_aux(dseq, char**) + index;
+            free(*p);
+            *p = strdup(item->s);
+            break;
+        }
+        
+        case IT_bytes: {
+            Item *p = S_aux(dseq, Item*) + index;
+            free((char*) p->u.ptr);
+            p->u.len = item->u.len;
+            p->u.ptr = memcpy(malloc(p->u.len), item->u.ptr, p->u.len);
+            break;
+        }
+        
+        case IT_view: {
+            View_p *p = S_aux(dseq, View_p*) + index;
+            LoseRef(*p);
+            *p = IncRefCount(item->v);
+            break;
+        }
+        
+        default: Assert(0); break;
+    }
+}
+
+static View_p SettableView (View_p view) {
+    Int_t bytes = 2 * ViewWidth(view) * sizeof(Seq_p*);
+    Seq_p seq;
+    
+    /* room for a set of new data columns, then a set of "used" bitmaps */
+    seq = NewSequence(ViewSize(view), &ST_Settable, bytes);
+    /* data[0] is the adjusted bitmap */
+    /* data[1] points to hash row map */
+    /* data[2] points to the original view */
+    seq->SV_bits = NULL;
+    seq->SV_hash = IncRefCount(HashMapNew());
+    seq->SV_view = IncRefCount(view);
+
+    return IndirectView(V_Meta(view), seq);
+}    
+
+#define MV_parent       data[0].q
+#define MV_mutmap       data[1].q
+
+    typedef struct MutRange {
+        int start;
+        int shift;
+        View_p added;
+    } *MutRange_p;
+
+static void MutableCleaner (Seq_p seq) {
+    int i;
+    Seq_p map;
+    MutRange_p range;
+    
+    map = seq->MV_mutmap;
+    range = S_aux(map, MutRange_p);
+
+    for (i = 0; i < map->count; ++i)
+        DecRefCount(range[i].added);
+}
+
+#if MUT_DEBUG
+#include <stdio.h>
+static void DumpRanges (const char *msg, View_p view) {
+    int i;
+    Seq_p seq, map;
+    MutRange_p range;
+
+    seq = ViewCol(view, 0).seq;
+    map = seq->MV_mutmap;
+    range = S_aux(map, MutRange_p);
+
+    printf("%s: view %p rc %d, has %d rows %d ranges\n",
+                 msg, (void*) view, view->refs, ViewSize(view), map->count);
+    for (i = 0; i < map->count; ++i) {
+        View_p v = range[i].added;
+        printf("    %2d: st %3d sh %3d", i, range[i].start, range[i].shift);
+        if (v != NULL)
+            printf(" - %p: sz %3d rc %3d\n", (void*) v, ViewSize(v), v->refs);
+        printf("\n");
+    }
+}
+#else
+#define DumpRanges(a,b)
+#endif
+
+static int MutSlot (MutRange_p range, int pos) {
+    int i = -1;
+    /* TODO: use binary i.s.o. linear search */
+    while (pos > range[++i].start)
+        ;
+    return pos < range[i].start ? i-1 : i;
+}
+
+static int ChooseMutView (Seq_p seq, int *prow) {
+    int slot, row = *prow;
+    MutRange_p range;
+    
+    range = S_aux(seq->MV_mutmap, MutRange_p);
+    
+    slot = MutSlot(range, row);
+    row -= range[slot].start;
+    Assert(row >= 0);
+
+    *prow = range[slot].added != NULL ? slot : -1;
+    return row + range[slot].shift;
+}
+
+static ItemTypes MutableGetter (int row, Item_p item) {
+    Seq_p seq = item->c.seq;
+    View_p view = seq->MV_parent;
+    int index = ChooseMutView(seq, &row);
+
+    if (row >= 0) {
+        MutRange_p range = S_aux(seq->MV_mutmap, MutRange_p);
+        view = range[row].added;
+    }
+
+    item->c = ViewCol(view, item->c.pos);
+    return GetItem(index, item);
+}
+
+static MutRange_p MutResize (Seq_p *seqp, int pos, int diff) {
+    int i, limit = 0, count = 0;
+    MutRange_p range = NULL;
+    Seq_p map;
+    
+    map = *seqp;
+    if (map != NULL) {
+        count = map->count;
+        limit = map->data[1].i / sizeof(struct MutRange);
+        range = S_aux(map, MutRange_p);
+    }
+    
+    /* TODO: this only grows the ranges, should also shrink when possible */
+    if (diff > 0 && count + diff > limit) {
+        int newlimit;
+        MutRange_p newrange;
+        
+        newlimit = (count / 2) * 3 + 5;
+        Assert(pos + diff <= newlimit);
+            
+        *seqp = NewSequence(count, PickIntGetter(0),
+                                newlimit * sizeof(struct MutRange));
+
+        newrange = S_aux(*seqp, MutRange_p);
+        memcpy(newrange, range, count * sizeof(struct MutRange));
+        range = newrange;
+
+        LoseRef(map);
+        map = IncRefCount(*seqp);
+    }
+    
+    map->count += diff;
+    
+    if (diff > 0) {
+        for (i = count; --i >= pos; )
+            range[i+diff] = range[i];
+    } else if (diff < 0) {
+        for (i = pos; i < pos - diff; ++i)
+            LoseRef(range[i].added);
+        for (i = pos - diff; i < count; ++i)
+            range[i+diff] = range[i];
+    }
+    
+    return range;
+}
+
+static struct SeqType ST_Mutable = {
+    "mutable", MutableGetter, 011, MutableCleaner 
+};
+
+View_p MutableView (View_p view) {
+    int rows;
+    Seq_p seq;
+
+    rows = ViewSize(view);
+    seq = NewSequence(rows, &ST_Mutable, 0);            
+    /* data[0] is the parent view (may be changed to a settable one later) */
+    /* data[1] holds the mutable range map, as a sequence */
+    seq->MV_parent = IncRefCount(view);
+    seq->MV_mutmap = NULL;
+    
+    if (rows == 0)
+        MutResize(&seq->MV_mutmap, 0, 1);
+    else {
+        MutRange_p range = MutResize(&seq->MV_mutmap, 0, 2);
+        range[1].start = rows;
+    }
+    
+    return IndirectView(V_Meta(view), seq);
+}
+
+int IsMutable (View_p view) {
+    Seq_p seq = ViewCol(view, 0).seq;
+    return seq != NULL && seq->type == &ST_Mutable;
+}
+
+View_p ViewSet (View_p view, int row, int col, Item_p item) {
+    int index;
+    View_p *modview;
+    Seq_p mutseq;
+
+    if (!IsMutable(view))
+        view = MutableView(view);
+    
+    mutseq = ViewCol(view, 0).seq;
+    index = ChooseMutView(mutseq, &row);
+
+    if (row >= 0) {
+        MutRange_p range = S_aux(mutseq->MV_mutmap, MutRange_p);
+        modview = &range[row].added;
+    } else
+        modview = (View_p*) &mutseq->data[0].p;
+    
+    if (!IsSettable(*modview))
+        *modview = IncRefCount(SettableView(LoseRef(*modview)));
+        
+    SettableSetter(*modview, index, col, item);
+
+    return view;
+}
+
+View_p ViewReplace (View_p view, int offset, int count, View_p data) {
+    int drows, fend, fpos, fslot, tend, tpos, tslot, grow, diff;
+    Seq_p seq, map;
+    MutRange_p range;
+    View_p tailv;
+    
+    drows = data != NULL ? ViewSize(data) : 0;
+    fend = offset + count;
+    tend = offset + drows;
+
+    if (drows > 0 && !ViewCompat(view, data))
+        return NULL;
+
+    if (drows == 0 && count == 0)
+        return view;
+        
+    if (!IsMutable(view))
+        view = MutableView(view);
+
+    DumpRanges("before", view);
+
+    seq = ViewCol(view, 0).seq;
+    map = seq->MV_mutmap;
+    range = S_aux(map, MutRange_p);
+    
+    fslot = MutSlot(range, offset);
+    fpos = offset - range[fslot].start;
+    
+    tslot = MutSlot(range, fend);
+    tpos = fend - range[tslot].start;
+    
+    tailv = range[tslot].added;
+
+#if MUT_DEBUG
+printf("fslot %d fpos %d tslot %d tpos %d drows %d offset %d count %d fend %d tend %d\n", fslot,fpos,tslot,tpos,drows,offset,count,fend,tend);
+#endif
+
+    /* keep head of first range, if rows remain before offset */
+    if (fpos > 0)
+        ++fslot;
+    
+    grow = fslot - tslot;
+    if (drows > 0)
+        ++grow;
+
+    range = MutResize(&seq->MV_mutmap, fslot, grow);
+    tslot += grow;
+    
+    if (fpos > 0 && grow > 0)
+        range[tslot].shift = range[fslot-1].shift;
+    
+    if (drows > 0) {
+        range[fslot].start = offset;
+        range[fslot].shift = 0;
+        range[fslot].added = IncRefCount(data);
+    }
+        
+    /* keep tail of last range, if rows remain after offset */
+    if (tpos > 0) {
+        range[tslot].start = tend;
+        range[tslot].shift += tpos;
+        LoseRef(range[tslot].added);
+        range[tslot].added = IncRefCount(tailv);
+        ++tslot;
+    }
+    
+    diff = drows - count;
+    seq->count += diff;
+    
+    map = seq->MV_mutmap;
+    while (tslot < map->count)
+        range[tslot++].start += diff;
+
+    DumpRanges("after", view);
+    return view;
+}
+
+ItemTypes SetCmd_MIX (Item args[]) {
+    int i, col, row, objc;
+    const Object_p *objv;
+    View_p view;
+    Item item;
+    
+    view = ObjAsView(args[0].o);
+    row = args[1].i;
+    if (row < 0)
+        row += ViewSize(view);
+    
+    objv = (const Object_p *) args[2].u.ptr;
+    objc = args[2].u.len;
+
+    if (objc % 2 != 0) {
+        args->e = EC_wnoa;
+        return IT_error;
+    }
+
+    for (i = 0; i < objc; i += 2) {
+        col = ColumnByName(V_Meta(view), objv[i]);
+        if (col < 0)
+            return IT_unknown;
+
+        item.o = objv[i+1];
+        if (!ObjToItem(ViewColType(view, col), &item))
+            return IT_unknown;
+
+        view = ViewSet(view, row, col, &item);
+    }
+
+    args->v = view;
+    return IT_view;
+}
+
+Seq_p MutPrepare (View_p view) {
+    int i, j, k, cols, ranges, parows, delcnt, delpos, count, adjpos;
+    Seq_p result, *seqs, mutseq, mutmap;
+    MutRange_p range, rp;
+    View_p parent, insview;
+    Column column;
+    
+    Assert(IsMutable(view));
+    
+    mutseq = ViewCol(view, 0).seq;
+    parent = mutseq->MV_parent;
+    parows = ViewSize(parent);
+    mutmap = mutseq->MV_mutmap;
+    range = S_aux(mutmap, MutRange_p);
+    ranges = mutmap->count - 1;
+    
+    cols = ViewWidth(view);
+    result = NewSeqVec(IT_unknown, NULL, MP_limit);
+    
+    seqs = S_aux(result, Seq_p*);
+        
+    seqs[MP_delmap] = NewBitVec(parows);
+    seqs[MP_insmap] = NewBitVec(ViewSize(view));
+
+    delcnt = delpos = 0;
+    insview = CloneView(view);
+    
+    for (i = 0; i < ranges; ++i) {
+        rp = range + i;
+        count = (rp+1)->start - rp->start;
+        if (rp->added == NULL) {
+            delcnt += rp->shift - delpos;
+            SetBitRange(seqs[MP_delmap], delpos, rp->shift - delpos);
+            delpos = rp->shift + count;
+        } else {
+            View_p newdata = StepView(rp->added, count, rp->shift, 1, 1);
+            insview = ViewReplace(insview, ViewSize(insview), 0, newdata);
+            SetBitRange(seqs[MP_insmap], rp->start, count);
+        }
+    }
+    
+    delcnt += parows - delpos;
+    SetBitRange(seqs[MP_delmap], delpos, parows - delpos);
+    seqs[MP_insdat] = insview;
+
+    seqs[MP_adjmap] = NewBitVec(parows - delcnt);
+
+    if (IsSettable(parent)) {
+        Seq_p setseq, adjseq;
+        
+        setseq = ViewCol(parent, 0).seq;
+        adjseq = setseq->SV_bits;
+                
+        if (adjseq != NULL && adjseq->count > 0) {
+            int *revptr, *rowptr;
+            Seq_p revmap, rowmap, hash = setseq->SV_hash;
+            View_p bitmeta, bitview;
+        
+            revmap = NewIntVec(hash->count, &revptr);
+            rowmap = NewIntVec(hash->count, &rowptr);
+
+            k = adjpos = 0;
+            
+            for (i = 0; i < ranges; ++i) {
+                rp = range + i;
+                if (rp->added == NULL) {
+                    count = (rp+1)->start - rp->start;
+                    for (j = 0; j < count; ++j)
+                        if (TestBit(adjseq, rp->start + j)) {
+                            int index = HashMapLookup(hash, rp->start + j, -1);
+                            Assert(index >= 0);
+                            revptr[k] = index;
+                            rowptr[k++] = rp->start + j;
+                            SetBit(seqs+MP_adjmap, adjpos + j);
+                        }
+                    adjpos += count;
+                }
+            }
+            
+            Assert(adjpos == parows - delcnt);
+            
+            seqs[MP_adjdat] = RemapSubview(parent, SeqAsCol(rowmap), 0, -1);
+
+            bitmeta = StepView(MakeIntColMeta("_"), 1, 0, ViewWidth(parent), 1);
+            bitview = NewView(bitmeta); /* will become an N-intcol view */
+            
+            for (i = 0; i < cols; ++i) {
+                column.seq = SV_data(setseq)[cols+i];
+                column.pos = -1;
+                MinBitCount(&column.seq, hash->count);
+                SetViewCols(bitview, i, 1, column);
+            }
+
+            seqs[MP_revmap] = revmap;
+            seqs[MP_usemap] = RemapSubview(bitview, SeqAsCol(revmap), 0, -1);
+        }
+    } else {
+        seqs[MP_adjdat] = seqs[MP_usemap] = NoColumnView(0);
+        seqs[MP_revmap] = ViewCol(seqs[MP_usemap], 0).seq;
+    }
+    
+    for (i = 0; i < MP_limit; ++i)
+        IncRefCount(seqs[i]);       
+         
+    return result;
+}
+/* %include<sorted.c>% */
+/*
+ * sorted.c - Implementation of sorting functions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+static int ItemsEqual (ItemTypes type, Item a, Item b) {
+    switch (type) {
+
+        case IT_int:
+            return a.i == b.i;
+
+        case IT_wide:
+            return a.w == b.w;
+
+        case IT_float:
+            return a.f == b.f;
+
+        case IT_double:
+            return a.d == b.d;
+
+        case IT_string:
+            return strcmp(a.s, b.s) == 0;
+
+        case IT_bytes:
+            return a.u.len == b.u.len && memcmp(a.u.ptr, b.u.ptr, a.u.len) == 0;
+
+        case IT_view:
+            return ViewCompare(a.v, b.v) == 0;
+            
+        default: Assert(0); return -1;
+    }
+}
+
+int RowEqual (View_p v1, int r1, View_p v2, int r2) {
+    int c;
+    ItemTypes type;
+    Item item1, item2;
+
+    for (c = 0; c < ViewWidth(v1); ++c) {
+        type = ViewColType(v1, c);
+        item1 = GetViewItem(v1, r1, c, type);
+        item2 = GetViewItem(v2, r2, c, type);
+
+        if (!ItemsEqual(type, item1, item2))
+            return 0;
+    }
+
+    return 1;
+}
+
+/* TODO: UTF-8 comparisons, also case-sensitive & insensitive */
+
+static int ItemsCompare (ItemTypes type, Item a, Item b, int lower) {
+    switch (type) {
+
+        case IT_int:
+            return (a.i > b.i) - (a.i < b.i);
+
+        case IT_wide:
+            return (a.w > b.w) - (a.w < b.w);
+
+        case IT_float:
+            return (a.f > b.f) - (a.f < b.f);
+
+        case IT_double:
+            return (a.d > b.d) - (a.d < b.d);
+
+        case IT_string:
+            return (lower ? strcasecmp : strcmp)(a.s, b.s);
+
+        case IT_bytes: {
+            int f;
+
+            if (a.u.len == b.u.len)
+                return memcmp(a.u.ptr, b.u.ptr, a.u.len);
+
+            f = memcmp(a.u.ptr, b.u.ptr, a.u.len < b.u.len ? a.u.len : b.u.len);
+            return f != 0 ? f : a.u.len - b.u.len;
+        }
+        
+        case IT_view:
+            return ViewCompare(a.v, b.v);
+            
+        default: Assert(0); return -1;
+    }
+}
+
+int RowCompare (View_p v1, int r1, View_p v2, int r2) {
+    int c, f;
+    ItemTypes type;
+    Item item1, item2;
+
+    for (c = 0; c < ViewWidth(v1); ++c) {
+        type = ViewColType(v1, c);
+        item1 = GetViewItem(v1, r1, c, type);
+        item2 = GetViewItem(v2, r2, c, type);
+
+        f = ItemsCompare(type, item1, item2, 0);
+        if (f != 0)
+            return f < 0 ? -1 : 1;
+    }
+
+    return 0;
+}
+
+static int RowIsLess (View_p v, int a, int b) {
+    int c, f;
+    ItemTypes type;
+    Item va, vb;
+
+    if (a != b)
+        for (c = 0; c < ViewWidth(v); ++c) {
+            type = ViewColType(v, c);
+            va = GetViewItem(v, a, c, type);
+            vb = GetViewItem(v, b, c, type);
+
+            f = ItemsCompare(type, va, vb, 0);
+            if (f != 0)
+                return f < 0;
+        }
+
+    return a < b;
+}
+
+static int TestAndSwap (View_p v, int *a, int *b) {
+    if (RowIsLess(v, *b, *a)) {
+        int t = *a;
+        *a = *b;
+        *b = t;
+        return 1;
+    }
+    return 0;
+}
+
+static void MergeSort (View_p v, int *ar, int nr, int *scr) {
+    switch (nr) {
+        case 2:
+            TestAndSwap(v, ar, ar+1);
+            break;
+        case 3:
+            TestAndSwap(v, ar, ar+1);
+            if (TestAndSwap(v, ar+1, ar+2))
+                TestAndSwap(v, ar, ar+1);
+            break;
+        case 4: /* TODO: optimize with if's */
+            TestAndSwap(v, ar, ar+1);
+            TestAndSwap(v, ar+2, ar+3);
+            TestAndSwap(v, ar, ar+2);
+            TestAndSwap(v, ar+1, ar+3);
+            TestAndSwap(v, ar+1, ar+2);
+            break;
+            /* TODO: also special-case 5-item sort? */
+        default: {
+            int s1 = nr / 2, s2 = nr - s1;
+            int *f1 = scr, *f2 = scr + s1, *t1 = f1 + s1, *t2 = f2 + s2;
+            MergeSort(v, f1, s1, ar);
+            MergeSort(v, f2, s2, ar+s1);
+            for (;;)
+                if (RowIsLess(v, *f1, *f2)) {
+                    *ar++ = *f1++;
+                    if (f1 >= t1) {
+                        while (f2 < t2)
+                            *ar++ = *f2++;
+                        break;
+                    }
+                } else {
+                    *ar++ = *f2++;
+                    if (f2 >= t2) {
+                        while (f1 < t1)
+                            *ar++ = *f1++;
+                        break;
+                    }
+                }
+        }
+    }
+}
+
+Column SortMap (View_p view) {
+    int r, rows, *imap, *itmp;
+    Seq_p seq;
+
+    rows = ViewSize(view);
+
+    if (rows <= 1 || ViewWidth(view) == 0)
+        return NewIotaColumn(rows);
+
+    seq = NewIntVec(rows, &imap);
+    NewIntVec(rows, &itmp);
+    
+    for (r = 0; r < rows; ++r)
+        imap[r] = itmp[r] = r;
+
+    MergeSort(view, imap, rows, itmp);
+
+    return SeqAsCol(seq);
+}
+
+static ItemTypes AggregateMax (ItemTypes type, Column column, Item_p item) {
+    int r, rows;
+    Item temp;
+    
+    rows = column.seq->count;
+    if (rows == 0) {
+        item->e = EC_nalor;
+        return IT_error;
+    }
+    
+    *item = GetColItem(0, column, type);
+    for (r = 1; r < rows; ++r) {
+        temp = GetColItem(r, column, type);
+        if (ItemsCompare (type, temp, *item, 0) > 0)
+            *item = temp;
+    }
+    
+    return type;
+}
+
+ItemTypes MaxCmd_VN (Item args[]) {
+    Column column = ViewCol(args[0].v, args[1].i);
+    return AggregateMax(ViewColType(args[0].v, args[1].i), column, args);
+}
+
+static ItemTypes AggregateMin (ItemTypes type, Column column, Item_p item) {
+    int r, rows;
+    Item temp;
+    
+    rows = column.seq->count;
+    if (rows == 0) {
+        item->e = EC_nalor;
+        return IT_error;
+    }
+    
+    *item = GetColItem(0, column, type);
+    for (r = 1; r < rows; ++r) {
+        temp = GetColItem(r, column, type);
+        if (ItemsCompare (type, temp, *item, 0) < 0)
+            *item = temp;
+    }
+    
+    return type;
+}
+
+ItemTypes MinCmd_VN (Item args[]) {
+    Column column = ViewCol(args[0].v, args[1].i);
+    return AggregateMin(ViewColType(args[0].v, args[1].i), column, args);
+}
+
+static ItemTypes AggregateSum (ItemTypes type, Column column, Item_p item) {
+    int r, rows = column.seq->count;
+    
+    switch (type) {
+        
+        case IT_int:
+            item->w = 0; 
+            for (r = 0; r < rows; ++r)
+                item->w += GetColItem(r, column, IT_int).i;
+            return IT_wide;
+            
+        case IT_wide:
+            item->w = 0;
+            for (r = 0; r < rows; ++r)
+                item->w += GetColItem(r, column, IT_wide).w;
+            return IT_wide;
+            
+        case IT_float:
+            item->d = 0; 
+            for (r = 0; r < rows; ++r)
+                item->d += GetColItem(r, column, IT_float).f;
+            return IT_double;
+
+        case IT_double:     
+            item->d = 0; 
+            for (r = 0; r < rows; ++r)
+                item->d += GetColItem(r, column, IT_double).d;
+            return IT_double;
+            
+        default:
+            return IT_unknown;
+    }
+}
+
+ItemTypes SumCmd_VN (Item args[]) {
+    Column column = ViewCol(args[0].v, args[1].i);
+    return AggregateSum(ViewColType(args[0].v, args[1].i), column, &args[0]);
+}
+/* %include<view.c>% */
+/*
+ * view.c - Implementation of views.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+int ViewSize (View_p view) {
+    Seq_p seq = ViewCol(view, 0).seq;
+    return seq != NULL ? seq->count : 0;
+}
+
+char GetColType (View_p meta, int col) {
+    /* TODO: could be a #define */
+    return *GetViewItem(meta, col, MC_type, IT_string).s;
+}
+
+static void ViewCleaner (View_p view) {
+    int c;
+    for (c = 0; c <= ViewWidth(view); ++c)
+        DecRefCount(ViewCol(view, c).seq);
+}
+
+static ItemTypes ViewGetter (int row, Item_p item) {
+    item->c = ViewCol(item->c.seq, row);
+    return IT_column;
+}
+
+static struct SeqType ST_View = { "view", ViewGetter, 010, ViewCleaner };
+
+static View_p ForceMetaView(View_p meta) {
+    View_p newmeta;
+    Column orignames, names;
+    
+    /* this code is needed so we can always do a hash lookup on name column */
+    
+    orignames = ViewCol(meta, MC_name);
+    names = ForceStringColumn(orignames);
+    
+    if (names.seq == orignames.seq)
+        return meta;
+        
+    /* need to construct a new meta view with the adjusted names column */
+    newmeta = NewView(V_Meta(meta));
+
+    SetViewCols(newmeta, MC_name, 1, names);
+    SetViewCols(newmeta, MC_type, 1, ViewCol(meta, MC_type));
+    SetViewCols(newmeta, MC_subv, 1, ViewCol(meta, MC_subv));
+
+    return newmeta;
+}
+
+View_p NewView (View_p meta) {
+    int c, cols, bytes;
+    View_p view;
+
+    /* a view must always be able to store at least one column */
+    cols = ViewSize(meta);
+    bytes = (cols + 1) * (sizeof(Column) + 1);
+
+    view = NewSequence(cols, &ST_View, bytes);
+    /* data[0] points to types string (allocated inline after the columns) */
+    /* data[1] is the meta view */
+    V_Types(view) = (char*) (V_Cols(view) + cols + 1);
+    V_Meta(view) = IncRefCount(ForceMetaView(meta));
+
+    /* TODO: could optimize by storing the types with the meta view instead */
+    for (c = 0; c < cols; ++c)
+        V_Types(view)[c] = CharAsItemType(GetColType(meta, c));
+
+    return view;
+}
+
+void SetViewCols (View_p view, int first, int count, Column src) {
+    int c;
+
+    AdjustSeqRefs(src.seq, count);
+    for (c = first; c < first + count; ++c) {
+        DecRefCount(ViewCol(view, c).seq);
+        ViewCol(view, c) = src;
+    }
+}
+
+void SetViewSeqs (View_p view, int first, int count, Seq_p src) {
+    SetViewCols(view, first, count, SeqAsCol(src));
+}
+
+View_p IndirectView (View_p meta, Seq_p seq) {
+    int c, cols;
+    View_p result;
+
+    cols = ViewSize(meta);
+    if (cols == 0)
+        ++cols;
+        
+    result = NewView(meta);
+    SetViewSeqs(result, 0, cols, seq);
+
+    for (c = 0; c < cols; ++c)
+        ViewCol(result, c).pos = c;
+
+    return result;
+}
+
+View_p EmptyMetaView (void) {
+    Shared_p sh = GetShared();
+    
+    if (sh->empty == NULL) {
+        int bytes;
+        View_p meta, subs [MC_limit];
+        Seq_p tempseq;
+
+        /* meta is recursively defined, so we can't use NewView here */
+        bytes = (MC_limit + 1) * (sizeof(Column) + 1);
+        meta = NewSequence(MC_limit, &ST_View, bytes);
+        V_Meta(meta) = IncRefCount(meta); /* circular */
+    
+        V_Types(meta) = (char*) (V_Cols(meta) + MC_limit + 1);
+        V_Types(meta)[0] = V_Types(meta)[1] = IT_string;
+        V_Types(meta)[2] = IT_view;
+
+        /* initialize all but last columns of meta with static ptr contents */
+        tempseq = NewStrVec(1);
+        AppendToStrVec("name", -1, tempseq);
+        AppendToStrVec("type", -1, tempseq);
+        AppendToStrVec("subv", -1, tempseq);
+        SetViewSeqs(meta, MC_name, 1, FinishStrVec(tempseq));
+
+        tempseq = NewStrVec(1);
+        AppendToStrVec("S", -1, tempseq);
+        AppendToStrVec("S", -1, tempseq);
+        AppendToStrVec("V", -1, tempseq);
+        SetViewSeqs(meta, MC_type, 1, FinishStrVec(tempseq));
+
+        /* same structure as meta but no rows */
+        sh->empty = NewView(meta);
+
+        /* initialize last column of meta, now that empty exists */
+        subs[MC_name] = subs[MC_type] = subs[MC_subv] = sh->empty;
+        SetViewSeqs(meta, MC_subv, 1, NewSeqVec(IT_view, subs, MC_limit));
+    }
+    
+    return sh->empty;
+}
+
+View_p NoColumnView (int rows) {
+    View_p result = NewView(EmptyMetaView());
+    SetViewSeqs(result, 0, 1, NewSequence(rows, PickIntGetter(0), 0));
+    return result;
+}
+
+View_p ColMapView (View_p view, Column mapcol) {
+    int c, cols;
+    const int *map;
+    View_p result;
+
+    map = (const int*) mapcol.seq->data[0].p;
+    cols = mapcol.seq->count;
+
+    if (cols == 0)
+        return NoColumnView(ViewSize(view));
+
+    result = NewView(RemapSubview(V_Meta(view), mapcol, 0, cols));
+
+    for (c = 0; c < cols; ++c)
+        SetViewCols(result, c, 1, ViewCol(view, map[c]));
+
+    return result;
+}
+
+View_p ColOmitView (View_p view, Column omitcol) {
+    int c, d, *map;
+    Seq_p mapcol;
+    
+    mapcol = NewIntVec(ViewWidth(view), &map);
+
+    /* TODO: make this robust, may have to add bounds check */
+    for (c = 0; c < omitcol.seq->count; ++c)
+        map[GetColItem(c, omitcol, IT_int).i] = 1;
+    
+    for (c = d = 0; c < mapcol->count; ++c)
+        if (!map[c])
+            map[d++] = c;
+            
+    mapcol->count = d; /* TODO: truncate unused area */
+    return ColMapView(view, SeqAsCol(mapcol));
+}
+
+View_p OneColView (View_p view, int col) {
+    View_p result;
+
+    result = NewView(StepView(V_Meta(view), 1, col, 1, 1));
+    SetViewCols(result, 0, 1, ViewCol(view, col));
+
+    return result;
+}
+
+View_p FirstView (View_p view, int count) {
+    if (count >= ViewSize(view))
+        return view;
+    return StepView(view, count, 0, 1, 1);
+}
+
+View_p LastView (View_p view, int count) {
+    int rows = ViewSize(view);
+    if (count >= rows)
+        return view;
+    return StepView(view, count, rows - count, 1, 1);
+}
+
+View_p TakeView (View_p view, int count) {
+    if (count >= 0)
+        return StepView(view, count, 0, 1, 1);
+    else
+        return StepView(view, -count, -1, 1, -1);
+}
+
+View_p CloneView (View_p view) {
+    return NewView(V_Meta(view));
+}
+
+View_p PairView (View_p view1, View_p view2) {
+    int c, rows1 = ViewSize(view1), rows2 = ViewSize(view2);
+    View_p meta, result;
+
+    if (rows2 < rows1)
+        view1 = FirstView(view1, rows2);
+    else if (rows1 < rows2)
+        view2 = FirstView(view2, rows1);
+    else if (ViewWidth(view2) == 0)
+        return view1;
+    else if (ViewWidth(view1) == 0)
+        return view2;
+
+    meta = ConcatView(V_Meta(view1), V_Meta(view2));
+    result = NewView(meta);
+    
+    for (c = 0; c < ViewWidth(view1); ++c)
+        SetViewCols(result, c, 1, ViewCol(view1, c));
+    for (c = 0; c < ViewWidth(view2); ++c)
+        SetViewCols(result, ViewWidth(view1) + c, 1, ViewCol(view2, c));
+        
+    return result;
+}
+
+static void ViewStructure (View_p meta, Buffer_p buffer) {
+    int c, cols = ViewSize(meta);
+    
+    for (c = 0; c < cols; ++c) {
+        char type = GetColType(meta, c);
+        
+        if (type == 'V') {
+            View_p submeta = GetViewItem(meta, c, MC_subv, IT_view).v;
+            
+            if (ViewSize(submeta) > 0) {
+                AddToBuffer(buffer, "(", 1);
+                ViewStructure(submeta, buffer);
+                AddToBuffer(buffer, ")", 1);
+                continue;
+            }
+        }
+        AddToBuffer(buffer, &type, 1);
+    }
+}
+
+int MetaIsCompatible (View_p meta1, View_p meta2) {
+    if (meta1 != meta2) {
+        int c, cols = ViewSize(meta1);
+
+        if (cols != ViewSize(meta2))
+            return 0;
+        
+        for (c = 0; c < cols; ++c) {
+            char type = GetColType(meta1, c);
+        
+            if (type != GetColType(meta2, c))
+                return 0;
+            
+            if (type == 'V') {
+                View_p v1 = GetViewItem(meta1, c, MC_subv, IT_view).v;
+                View_p v2 = GetViewItem(meta2, c, MC_subv, IT_view).v;
+
+                if (!MetaIsCompatible(v1, v2))
+                    return 0;
+            }
+        }
+    }
+    
+    return 1;
+}
+
+int ViewCompare (View_p view1, View_p view2) {
+    int f, r, rows1, rows2;
+    
+    if (view1 == view2)
+        return 0;
+    
+    f = ViewCompare(V_Meta(view1), V_Meta(view2));
+    if (f != 0)
+        return f;
+        
+    rows1 = ViewSize(view1);
+    rows2 = ViewSize(view2);
+    
+    for (r = 0; r < rows1; ++r) {
+        if (r >= rows2)
+            return 1;
+    
+        f = RowCompare(view1, r, view2, r);
+        if (f != 0)
+            return f < 0 ? -1 : 1;
+    }
+        
+    return rows1 < rows2 ? -1 : 0;
+}
+
+View_p MakeIntColMeta (const char *name) {
+    View_p result, subv;
+    Seq_p names, types, subvs;
+    
+    names = NewStrVec(1);
+    AppendToStrVec(name, -1, names);
+
+    types = NewStrVec(1);
+    AppendToStrVec("I", -1, types);
+
+    subv = EmptyMetaView();
+    subvs = NewSeqVec(IT_view, &subv, 1);
+    
+    result = NewView(V_Meta(EmptyMetaView()));
+    SetViewSeqs(result, MC_name, 1, FinishStrVec(names));
+    SetViewSeqs(result, MC_type, 1, FinishStrVec(types));
+    SetViewSeqs(result, MC_subv, 1, subvs);
+    return result;
+}
+
+View_p TagView (View_p view, const char* name) {
+    View_p tagview;
+    
+    tagview = NewView(MakeIntColMeta(name));
+    SetViewCols(tagview, 0, 1, NewIotaColumn(ViewSize(view)));
+    
+    return PairView(view, tagview);
+}
+
+View_p DescAsMeta (const char** desc, const char* end) {
+    int c, len, cols = 0, namebytes = 0;
+    char sep, *buf, *ptr, **strings;
+    Seq_p *views, tempseq;
+    struct Buffer names, types, subvs;
+    View_p result, empty;
+
+    InitBuffer(&names);
+    InitBuffer(&types);
+    InitBuffer(&subvs);
+    
+    len = end - *desc;
+    buf = memcpy(malloc(len+1), *desc, len);
+    buf[len] = ',';
+    
+    empty = EmptyMetaView();
+    result = NewView(V_Meta(empty));
+    
+    for (ptr = buf; ptr < buf + len; ++ptr) {
+        const char *s = ptr;
+        while (strchr(":,[]", *ptr) == 0)
+            ++ptr;
+        sep = *ptr;
+        *ptr = 0;
+
+        ADD_PTR_TO_BUF(names, s);
+        namebytes += ptr - s + 1;
+         
+        switch (sep) {
+
+            case '[':
+                ADD_PTR_TO_BUF(types, "V");
+                ++ptr;
+                ADD_PTR_TO_BUF(subvs, DescAsMeta((const char**) &ptr, buf + len));
+                sep = *++ptr;
+                break;
+
+            case ':':
+                ptr += 2;
+                sep = *ptr;
+                *ptr = 0;
+                ADD_PTR_TO_BUF(types, ptr - 1);
+                ADD_PTR_TO_BUF(subvs, empty);
+                break;
+
+            default:
+                ADD_PTR_TO_BUF(types, "S");
+                ADD_PTR_TO_BUF(subvs, empty);
+                break;
+        }
+        
+        ++cols;
+        if (sep != ',')
+            break;
+    }
+
+    strings = BufferAsPtr(&names, 1);
+    tempseq = NewStrVec(1);
+    for (c = 0; c < cols; ++c)
+        AppendToStrVec(strings[c], -1, tempseq);
+    SetViewSeqs(result, MC_name, 1, FinishStrVec(tempseq));
+    ReleaseBuffer(&names, 0);
+    
+    strings = BufferAsPtr(&types, 1);
+    tempseq = NewStrVec(1);
+    for (c = 0; c < cols; ++c)
+        AppendToStrVec(strings[c], -1, tempseq);
+    SetViewSeqs(result, MC_type, 1, FinishStrVec(tempseq));
+    ReleaseBuffer(&types, 0);
+    
+    views = BufferAsPtr(&subvs, 1);
+    tempseq = NewSeqVec(IT_view, views, cols);
+    SetViewSeqs(result, MC_subv, 1, tempseq);
+    ReleaseBuffer(&subvs, 0);
+    
+    free(buf);
+    *desc += ptr - buf;
+    return result;
+}
+
+View_p DescToMeta (const char *desc) {
+    int len;
+    const char *end;
+    View_p meta;
+
+    len = strlen(desc);
+    end = desc + len;
+    
+    meta = DescAsMeta(&desc, end);
+    if (desc < end)
+        return NULL;
+
+    return meta;
+}
+
+ItemTypes DataCmd_VX (Item args[]) {
+    View_p meta, view;
+    int c, cols, objc;
+    const Object_p *objv;
+    Column column;
+
+    meta = args[0].v;
+    cols = ViewSize(meta);
+    
+    objv = (const Object_p *) args[1].u.ptr;
+    objc = args[1].u.len;
+
+    if (objc != cols) {
+        args->e = EC_wnoa;
+        return IT_error;
+    }
+
+    view = NewView(meta);
+    for (c = 0; c < cols; ++c) {
+        column = CoerceColumn(ViewColType(view, c), objv[c]);
+        if (column.seq == NULL)
+            return IT_unknown;
+            
+        SetViewCols(view, c, 1, column);
+    }
+
+    args->v = view;
+    return IT_view;
+}
+
+ItemTypes StructDescCmd_V (Item args[]) {
+    struct Buffer buffer;
+    Item item;
+    
+    InitBuffer(&buffer);
+    MetaAsDesc(V_Meta(args[0].v), &buffer);
+    AddToBuffer(&buffer, "", 1);
+    item.s = BufferAsPtr(&buffer, 1);
+    args->o = ItemAsObj(IT_string, &item);
+    ReleaseBuffer(&buffer, 0);
+    return IT_object;
+}
+
+ItemTypes StructureCmd_V (Item args[]) {
+    struct Buffer buffer;
+    Item item;
+    
+    InitBuffer(&buffer);
+    ViewStructure(V_Meta(args[0].v), &buffer);
+    AddToBuffer(&buffer, "", 1);
+    item.s = BufferAsPtr(&buffer, 1);
+    args->o = ItemAsObj(IT_string, &item);
+    ReleaseBuffer(&buffer, 0);
+    return IT_object;
+}
+/* %include<wrap_gen.c>% */
+/* wrap_gen.c - generated code, do not edit */
+
+#include <stdlib.h>
+
+  
+ItemTypes BlockedCmd_V (Item_p a) {
+  a[0].v = BlockedView(a[0].v);
+  return IT_view;
+}
+
+ItemTypes CloneCmd_V (Item_p a) {
+  a[0].v = CloneView(a[0].v);
+  return IT_view;
+}
+
+ItemTypes CoerceCmd_OS (Item_p a) {
+  a[0].c = CoerceCmd(a[0].o, a[1].s);
+  return IT_column;
+}
+
+ItemTypes ColMapCmd_Vn (Item_p a) {
+  a[0].v = ColMapView(a[0].v, a[1].c);
+  return IT_view;
+}
+
+ItemTypes ColOmitCmd_Vn (Item_p a) {
+  a[0].v = ColOmitView(a[0].v, a[1].c);
+  return IT_view;
+}
+
+ItemTypes CompareCmd_VV (Item_p a) {
+  a[0].i = ViewCompare(a[0].v, a[1].v);
+  return IT_int;
+}
+
+ItemTypes CompatCmd_VV (Item_p a) {
+  a[0].i = ViewCompat(a[0].v, a[1].v);
+  return IT_int;
+}
+
+ItemTypes ConcatCmd_VV (Item_p a) {
+  a[0].v = ConcatView(a[0].v, a[1].v);
+  return IT_view;
+}
+
+ItemTypes CountsColCmd_C (Item_p a) {
+  a[0].c = NewCountsColumn(a[0].c);
+  return IT_column;
+}
+
+ItemTypes CountViewCmd_I (Item_p a) {
+  a[0].v = NoColumnView(a[0].i);
+  return IT_view;
+}
+
+ItemTypes FirstCmd_VI (Item_p a) {
+  a[0].v = FirstView(a[0].v, a[1].i);
+  return IT_view;
+}
+
+ItemTypes GetColCmd_VN (Item_p a) {
+  a[0].c = ViewCol(a[0].v, a[1].i);
+  return IT_column;
+}
+
+ItemTypes GetInfoCmd_VVI (Item_p a) {
+  a[0].c = GetHashInfo(a[0].v, a[1].v, a[2].i);
+  return IT_column;
+}
+
+ItemTypes GroupCmd_VnS (Item_p a) {
+  a[0].v = GroupCol(a[0].v, a[1].c, a[2].s);
+  return IT_view;
+}
+
+ItemTypes GroupedCmd_ViiS (Item_p a) {
+  a[0].v = GroupedView(a[0].v, a[1].c, a[2].c, a[3].s);
+  return IT_view;
+}
+
+ItemTypes HashFindCmd_VIViii (Item_p a) {
+  a[0].i = HashDoFind(a[0].v, a[1].i, a[2].v, a[3].c, a[4].c, a[5].c);
+  return IT_int;
+}
+
+ItemTypes HashViewCmd_V (Item_p a) {
+  a[0].c = HashValues(a[0].v);
+  return IT_column;
+}
+
+ItemTypes IjoinCmd_VV (Item_p a) {
+  a[0].v = IjoinView(a[0].v, a[1].v);
+  return IT_view;
+}
+
+ItemTypes IotaCmd_I (Item_p a) {
+  a[0].c = NewIotaColumn(a[0].i);
+  return IT_column;
+}
+
+ItemTypes IsectMapCmd_VV (Item_p a) {
+  a[0].c = IntersectMap(a[0].v, a[1].v);
+  return IT_column;
+}
+
+ItemTypes JoinCmd_VVS (Item_p a) {
+  a[0].v = JoinView(a[0].v, a[1].v, a[2].s);
+  return IT_view;
+}
+
+ItemTypes LastCmd_VI (Item_p a) {
+  a[0].v = LastView(a[0].v, a[1].i);
+  return IT_view;
+}
+
+ItemTypes MdefCmd_O (Item_p a) {
+  a[0].v = ObjAsMetaView(a[0].o);
+  return IT_view;
+}
+
+ItemTypes MdescCmd_S (Item_p a) {
+  a[0].v = DescToMeta(a[0].s);
+  return IT_view;
+}
+
+ItemTypes MetaCmd_V (Item_p a) {
+  a[0].v = V_Meta(a[0].v);
+  return IT_view;
+}
+
+ItemTypes OmitMapCmd_iI (Item_p a) {
+  a[0].c = OmitColumn(a[0].c, a[1].i);
+  return IT_column;
+}
+
+ItemTypes OneColCmd_VN (Item_p a) {
+  a[0].v = OneColView(a[0].v, a[1].i);
+  return IT_view;
+}
+
+ItemTypes PairCmd_VV (Item_p a) {
+  a[0].v = PairView(a[0].v, a[1].v);
+  return IT_view;
+}
+
+ItemTypes RemapSubCmd_ViII (Item_p a) {
+  a[0].v = RemapSubview(a[0].v, a[1].c, a[2].i, a[3].i);
+  return IT_view;
+}
+
+ItemTypes ReplaceCmd_VIIV (Item_p a) {
+  a[0].v = ViewReplace(a[0].v, a[1].i, a[2].i, a[3].v);
+  return IT_view;
+}
+
+ItemTypes RowCmpCmd_VIVI (Item_p a) {
+  a[0].i = RowCompare(a[0].v, a[1].i, a[2].v, a[3].i);
+  return IT_int;
+}
+
+ItemTypes RowEqCmd_VIVI (Item_p a) {
+  a[0].i = RowEqual(a[0].v, a[1].i, a[2].v, a[3].i);
+  return IT_int;
+}
+
+ItemTypes RowHashCmd_VI (Item_p a) {
+  a[0].i = RowHash(a[0].v, a[1].i);
+  return IT_int;
+}
+
+ItemTypes SizeCmd_V (Item_p a) {
+  a[0].i = ViewSize(a[0].v);
+  return IT_int;
+}
+
+ItemTypes SortMapCmd_V (Item_p a) {
+  a[0].c = SortMap(a[0].v);
+  return IT_column;
+}
+
+ItemTypes StepCmd_VIIII (Item_p a) {
+  a[0].v = StepView(a[0].v, a[1].i, a[2].i, a[3].i, a[4].i);
+  return IT_view;
+}
+
+ItemTypes StrLookupCmd_Ss (Item_p a) {
+  a[0].i = StringLookup(a[0].s, a[1].c);
+  return IT_int;
+}
+
+ItemTypes TagCmd_VS (Item_p a) {
+  a[0].v = TagView(a[0].v, a[1].s);
+  return IT_view;
+}
+
+ItemTypes TakeCmd_VI (Item_p a) {
+  a[0].v = TakeView(a[0].v, a[1].i);
+  return IT_view;
+}
+
+ItemTypes UngroupCmd_VN (Item_p a) {
+  a[0].v = UngroupView(a[0].v, a[1].i);
+  return IT_view;
+}
+
+ItemTypes UniqueMapCmd_V (Item_p a) {
+  a[0].c = UniqMap(a[0].v);
+  return IT_column;
+}
+
+ItemTypes ViewAsColCmd_V (Item_p a) {
+  a[0].c = ViewAsCol(a[0].v);
+  return IT_column;
+}
+
+ItemTypes WidthCmd_V (Item_p a) {
+  a[0].i = ViewWidth(a[0].v);
+  return IT_int;
+}
+
+/* : append ( VV-V ) over size swap insert ; */
+ItemTypes AppendCmd_VV (Item_p a) {
+  ItemTypes t;
+  /* over 0 */ a[2] = a[0];
+  t = SizeCmd_V(a+2);
+  /* swap 1 */ a[3] = a[1]; a[1] = a[2]; a[2] = a[3];
+  t = InsertCmd_VIV(a);
+  return IT_view;
+}
+
+/* : colconv ( C-C )   ; */
+ItemTypes ColConvCmd_C (Item_p a) {
+  return IT_column;
+}
+
+/* : counts ( VN-C ) getcol countscol ; */
+ItemTypes CountsCmd_VN (Item_p a) {
+  ItemTypes t;
+  t = GetColCmd_VN(a);
+  t = CountsColCmd_C(a);
+  return IT_column;
+}
+
+/* : delete ( VII-V ) 0 countview replace ; */
+ItemTypes DeleteCmd_VII (Item_p a) {
+  ItemTypes t;
+  a[3].i = 0;
+  t = CountViewCmd_I(a+3);
+  t = ReplaceCmd_VIIV(a);
+  return IT_view;
+}
+
+/* : except ( VV-V ) over swap exceptmap remap ; */
+ItemTypes ExceptCmd_VV (Item_p a) {
+  ItemTypes t;
+  /* over 0 */ a[2] = a[0];
+  /* swap 1 */ a[3] = a[1]; a[1] = a[2]; a[2] = a[3];
+  t = ExceptMapCmd_VV(a+1);
+  t = RemapCmd_Vi(a);
+  return IT_view;
+}
+
+/* : exceptmap ( VV-C ) over swap isectmap swap size omitmap ; */
+ItemTypes ExceptMapCmd_VV (Item_p a) {
+  ItemTypes t;
+  /* over 0 */ a[2] = a[0];
+  /* swap 1 */ a[3] = a[1]; a[1] = a[2]; a[2] = a[3];
+  t = IsectMapCmd_VV(a+1);
+  /* swap 0 */ a[2] = a[0]; a[0] = a[1]; a[1] = a[2];
+  t = SizeCmd_V(a+1);
+  t = OmitMapCmd_iI(a);
+  return IT_column;
+}
+
+/* : insert ( VIV-V ) 0 swap replace ; */
+ItemTypes InsertCmd_VIV (Item_p a) {
+  ItemTypes t;
+  a[3].i = 0;
+  /* swap 2 */ a[4] = a[2]; a[2] = a[3]; a[3] = a[4];
+  t = ReplaceCmd_VIIV(a);
+  return IT_view;
+}
+
+/* : intersect ( VV-V ) over swap isectmap remap ; */
+ItemTypes IntersectCmd_VV (Item_p a) {
+  ItemTypes t;
+  /* over 0 */ a[2] = a[0];
+  /* swap 1 */ a[3] = a[1]; a[1] = a[2]; a[2] = a[3];
+  t = IsectMapCmd_VV(a+1);
+  t = RemapCmd_Vi(a);
+  return IT_view;
+}
+
+/* : namecol ( V-V ) meta 0 onecol ; */
+ItemTypes NameColCmd_V (Item_p a) {
+  ItemTypes t;
+  t = MetaCmd_V(a);
+  a[1].i = 0;
+  t = OneColCmd_VN(a);
+  return IT_view;
+}
+
+/* : names ( V-C ) meta 0 getcol ; */
+ItemTypes NamesCmd_V (Item_p a) {
+  ItemTypes t;
+  t = MetaCmd_V(a);
+  a[1].i = 0;
+  t = GetColCmd_VN(a);
+  return IT_column;
+}
+
+/* : product ( VV-V ) over over size spread rrot swap size repeat pair ; */
+ItemTypes ProductCmd_VV (Item_p a) {
+  ItemTypes t;
+  /* over 0 */ a[2] = a[0];
+  /* over 1 */ a[3] = a[1];
+  t = SizeCmd_V(a+3);
+  t = SpreadCmd_VI(a+2);
+  /* rrot 0 */ a[3] = a[2]; a[2] = a[1]; a[1] = a[0]; a[0] = a[3];
+  /* swap 1 */ a[3] = a[1]; a[1] = a[2]; a[2] = a[3];
+  t = SizeCmd_V(a+2);
+  t = RepeatCmd_VI(a+1);
+  t = PairCmd_VV(a);
+  return IT_view;
+}
+
+/* : remap ( Vi-V ) 0 -1 remapsub ; */
+ItemTypes RemapCmd_Vi (Item_p a) {
+  ItemTypes t;
+  a[2].i = 0;
+  a[3].i = -1;
+  t = RemapSubCmd_ViII(a);
+  return IT_view;
+}
+
+/* : repeat ( VI-V ) over size imul 0 1 1 step ; */
+ItemTypes RepeatCmd_VI (Item_p a) {
+  ItemTypes t;
+  /* over 0 */ a[2] = a[0];
+  t = SizeCmd_V(a+2);
+  /* imul 1 */ a[1].i *=  a[2].i;
+  a[2].i = 0;
+  a[3].i = 1;
+  a[4].i = 1;
+  t = StepCmd_VIIII(a);
+  return IT_view;
+}
+
+/* : reverse ( V-V ) dup size -1 1 -1 step ; */
+ItemTypes ReverseCmd_V (Item_p a) {
+  ItemTypes t;
+  /* dup 0 */ a[1] = a[0];
+  t = SizeCmd_V(a+1);
+  a[2].i = -1;
+  a[3].i = 1;
+  a[4].i = -1;
+  t = StepCmd_VIIII(a);
+  return IT_view;
+}
+
+/* : slice ( VIII-V ) rrot 1 swap step ; */
+ItemTypes SliceCmd_VIII (Item_p a) {
+  ItemTypes t;
+  /* rrot 1 */ a[4] = a[3]; a[3] = a[2]; a[2] = a[1]; a[1] = a[4];
+  a[4].i = 1;
+  /* swap 3 */ a[5] = a[3]; a[3] = a[4]; a[4] = a[5];
+  t = StepCmd_VIIII(a);
+  return IT_view;
+}
+
+/* : sort ( V-V ) dup sortmap remap ; */
+ItemTypes SortCmd_V (Item_p a) {
+  ItemTypes t;
+  /* dup 0 */ a[1] = a[0];
+  t = SortMapCmd_V(a+1);
+  t = RemapCmd_Vi(a);
+  return IT_view;
+}
+
+/* : spread ( VI-V ) over size 0 rot 1 step ; */
+ItemTypes SpreadCmd_VI (Item_p a) {
+  ItemTypes t;
+  /* over 0 */ a[2] = a[0];
+  t = SizeCmd_V(a+2);
+  a[3].i = 0;
+  /* rot 1 */ a[4] = a[1]; a[1] = a[2]; a[2] = a[3]; a[3] = a[4];
+  a[4].i = 1;
+  t = StepCmd_VIIII(a);
+  return IT_view;
+}
+
+/* : types ( V-C ) meta 1 getcol ; */
+ItemTypes TypesCmd_V (Item_p a) {
+  ItemTypes t;
+  t = MetaCmd_V(a);
+  a[1].i = 1;
+  t = GetColCmd_VN(a);
+  return IT_column;
+}
+
+/* : union ( VV-V ) over except concat ; */
+ItemTypes UnionCmd_VV (Item_p a) {
+  ItemTypes t;
+  /* over 0 */ a[2] = a[0];
+  t = ExceptCmd_VV(a+1);
+  t = ConcatCmd_VV(a);
+  return IT_view;
+}
+
+/* : unionmap ( VV-C ) swap exceptmap ; */
+ItemTypes UnionMapCmd_VV (Item_p a) {
+  ItemTypes t;
+  /* swap 0 */ a[2] = a[0]; a[0] = a[1]; a[1] = a[2];
+  t = ExceptMapCmd_VV(a);
+  return IT_column;
+}
+
+/* : unique ( V-V ) dup uniquemap remap ; */
+ItemTypes UniqueCmd_V (Item_p a) {
+  ItemTypes t;
+  /* dup 0 */ a[1] = a[0];
+  t = UniqueMapCmd_V(a+1);
+  t = RemapCmd_Vi(a);
+  return IT_view;
+}
+
+/* : viewconv ( V-V )   ; */
+ItemTypes ViewConvCmd_V (Item_p a) {
+  return IT_view;
+}
+
+/* end of generated code */
+
+/* %include<cmds.c>% */
+/*
+ * cmds.c - Implementation of Tcl-specific operators.
+ */
+
+/*
+ * ext_tcl.h - Definitions needed across the Tcl-specific code.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#include <tcl.h>
+
+#if 10 * TCL_MAJOR_VERSION + TCL_MINOR_VERSION < 86
+#define Tcl_GetErrorLine(interp) (interp)->errorLine
+#define CONST86
+#endif
+
+/* colobj.c */
+
+extern Tcl_ObjType f_colObjType;
+
+Object_p  (ColumnAsObj) (Column column);
+
+/* ext_tcl.c */
+
+typedef struct SharedInfo {
+    Tcl_Interp *interp;
+    const struct CmdDispatch *cmds;
+} SharedInfo;
+
+#define Interp() (GetShared()->info->interp)
+#define DecObjRef   Tcl_DecrRefCount
+
+Object_p  (BufferAsTclList) (Buffer_p bp);
+Object_p  (IncObjRef) (Object_p objPtr);
+
+/* viewobj.c */
+
+extern Tcl_ObjType f_viewObjType;
+
+int       (AdjustCmdDef) (Object_p cmd);
+Object_p  (ViewAsObj) (View_p view);
+
+ItemTypes DefCmd_OO (Item args[]) {
+    int argc, c, r, cols, rows;
+    View_p meta, result;
+    Object_p obj, *argv;
+    Column column;
+    struct Buffer buffer;
+    
+    if (MdefCmd_O(args) != IT_view)
+        return IT_error;
+    if (args[0].v == NULL)
+        return IT_view;
+    meta = args[0].v;
+        
+    if (Tcl_ListObjGetElements(Interp(), args[1].o, &argc, &argv) != TCL_OK)
+        return IT_unknown;
+        
+    cols = ViewSize(meta);
+    if (cols == 0) {
+        if (argc != 0) {
+            args->e = EC_cizwv;
+            return IT_error;
+        }
+        
+        args->v = NoColumnView(0);
+        return IT_view;
+    }
+    
+    if (argc % cols != 0) {
+        args->e = EC_nmcw;
+        return IT_error;
+    }
+
+    result = NewView(meta);
+    rows = argc / cols;
+    
+    for (c = 0; c < cols; ++c) {
+        InitBuffer(&buffer);
+
+        for (r = 0; r < rows; ++r)
+            ADD_PTR_TO_BUF(buffer, argv[c + cols * r]);
+
+        obj = BufferAsTclList(&buffer);
+        column = CoerceColumn(ViewColType(result, c), obj);
+        DecObjRef(obj);
+        
+        if (column.seq == NULL)
+            return IT_unknown;
+            
+        SetViewCols(result, c, 1, column);
+    }
+    
+    args->v = result;
+    return IT_view;
+}
+
+static Object_p GetViewRows (View_p view, int row, int rows, int tags) {
+    int r, c, cols;
+    View_p meta;
+    Item item;
+    struct Buffer buf;
+    
+    meta = V_Meta(view);
+    cols = ViewSize(meta);
+    InitBuffer(&buf);
+    
+    for (r = 0; r < rows; ++r)
+        for (c = 0; c < cols; ++c) {
+            if (tags) {
+                item.c = ViewCol(meta, 0);
+                ADD_PTR_TO_BUF(buf, ItemAsObj(GetItem(c, &item), &item));
+            }
+            item.c = ViewCol(view, c);
+            ADD_PTR_TO_BUF(buf, ItemAsObj(GetItem(r + row, &item), &item));
+        }
+        
+    return BufferAsTclList(&buf);
+}
+
+static int ColumnNumber(Object_p obj, View_p meta) {
+    int col;
+    const char *name = Tcl_GetString(obj);
+    
+    switch (*name) {
+
+        case '#': return -2;
+        case '*': return -1;
+        case '-': case '0': case '1': case '2': case '3': case '4':
+                  case '5': case '6': case '7': case '8': case '9':
+            if (Tcl_GetIntFromObj(Interp(), obj, &col) != TCL_OK)
+                return -3;
+
+            if (col < 0)
+                col += ViewSize(meta);
+                
+            if (col < 0 || col >= ViewSize(meta))
+                return -4;
+            break;
+
+        default:
+            col = StringLookup(name, ViewCol(meta, MC_name));
+            if (col < 0)
+                return -3;
+    }
+
+    return col;
+}
+
+ItemTypes GetCmd_VX (Item args[]) {
+    View_p view;
+    int i, objc, r, row, col, rows;
+    const Object_p *objv;
+    ItemTypes currtype;
+
+    view = args[0].v;
+    currtype = IT_view;
+    
+    objv = (const Object_p *) args[1].u.ptr;
+    objc = args[1].u.len;
+
+    if (objc == 0) {
+        args->o = GetViewRows(view, 0, ViewSize(view), 0);
+        return IT_object;
+    }
+    
+    for (i = 0; i < objc; ++i) {
+        if (currtype == IT_view)
+            view = args[0].v;
+        else /* TODO: make sure the object does not leak if newly created */
+            view = ObjAsView(ItemAsObj(currtype, args));
+        
+        if (view == NULL)
+            return IT_unknown;
+
+        rows = ViewSize(view);
+
+        if (Tcl_GetIntFromObj(0, objv[i], &row) != TCL_OK)
+            switch (*Tcl_GetString(objv[i])) {
+                case '@':   args->v = V_Meta(view);
+                            currtype = IT_view;
+                            continue;
+                case '#':   args->i = rows;
+                            currtype = IT_int;
+                            continue;
+                case '*':   row = -1;
+                            break;
+                default:    Tcl_GetIntFromObj(Interp(), objv[i], &row);
+                            return IT_unknown;
+            }
+        else if (row < 0) {
+            row += rows;
+            if (row < 0) {
+                args->e = EC_rioor;
+                return IT_error;
+            }
+        }
+
+        if (++i >= objc) {
+            if (row >= 0)
+                args->o = GetViewRows(view, row, 1, 1); /* one tagged row */
+            else {
+                struct Buffer buf;
+                InitBuffer(&buf);
+                for (r = 0; r < rows; ++r)
+                    ADD_PTR_TO_BUF(buf, GetViewRows(view, r, 1, 0));
+                args->o = BufferAsTclList(&buf);
+            }
+            return IT_object;
+        }
+
+        col = ColumnNumber(objv[i], V_Meta(view));
+
+        if (row >= 0)
+            switch (col) {
+                default:    args->c = ViewCol(view, col);
+                            currtype = GetItem(row, args);
+                            break;
+                case -1:    args->o = GetViewRows(view, row, 1, 0);
+                            currtype = IT_object;
+                            break;
+                case -2:    args->i = row;
+                            currtype = IT_int;
+                            break;
+                case -3:    return IT_unknown;
+                case -4:    args->e = EC_cioor;
+                            return IT_error;
+            }
+        else
+            switch (col) {
+                default:    args->c = ViewCol(view, col);
+                            currtype = IT_column;
+                            break;
+                case -1:    args->o = GetViewRows(view, 0, rows, 0);
+                            currtype = IT_object;
+                            break;
+                case -2:    args->c = NewIotaColumn(rows);
+                            currtype = IT_column;
+                            break;
+                case -3:    return IT_unknown;
+                case -4:    args->e = EC_cioor;
+                            return IT_error;
+            }
+    }
+    
+    return currtype;
+}
+
+ItemTypes MutInfoCmd_V (Item_p a) {
+    int i;
+    Seq_p mods, *seqs;
+    Object_p result;
+    
+    if (!IsMutable(a[0].v))
+        return IT_unknown;
+        
+    mods = MutPrepare(a[0].v);
+    seqs = (void*) (mods + 1);
+    
+    result = Tcl_NewListObj(0, NULL);
+
+    for (i = 0; i < MP_delmap; ++i)
+        Tcl_ListObjAppendElement(NULL, result, ViewAsObj(seqs[i]));
+    for (i = MP_delmap; i < MP_limit; ++i)
+        Tcl_ListObjAppendElement(NULL, result, ColumnAsObj(SeqAsCol(seqs[i])));
+    
+    a->o = result;
+    return IT_object;
+}
+
+ItemTypes RefsCmd_O (Item args[]) {
+    args->i = args[0].o->refCount;
+    return IT_int;
+}
+
+ItemTypes RenameCmd_VO (Item args[]) {
+    int i, c, objc;
+    View_p meta, view, newmeta, newview;
+    Object_p *objv;
+    Item item;
+
+    if (Tcl_ListObjGetElements(Interp(), args[1].o, &objc, &objv) != TCL_OK)
+        return IT_unknown;
+        
+    if (objc % 2) {
+        args->e = EC_rambe;
+        return IT_error;
+    }
+
+    view = args[0].v;
+    meta = V_Meta(view);
+    newmeta = meta;
+    
+    for (i = 0; i < objc; i += 2) {
+        c = ColumnByName(meta, objv[i]);
+        if (c < 0)
+            return IT_unknown;
+        item.s = Tcl_GetString(objv[i+1]);
+        newmeta = ViewSet(newmeta, c, MC_name, &item);
+    }
+    
+    newview = NewView(newmeta);
+    
+    for (c = 0; c < ViewWidth(view); ++c)
+        SetViewCols(newview, c, 1, ViewCol(view, c));
+
+    args->v = newview;
+    return IT_view;
+}
+
+ItemTypes ToCmd_OO (Item args[]) {
+    Object_p result;
+
+    result = Tcl_ObjSetVar2(Interp(), args[1].o, 0, args[0].o,
+                                                    TCL_LEAVE_ERR_MSG);
+    if (result == NULL)
+        return IT_unknown;
+
+    args->o = result;
+    return IT_object;
+}
+
+ItemTypes TypeCmd_O (Item args[]) {
+    args->s = args[0].o->typePtr != NULL ? args[0].o->typePtr->name : "";
+    return IT_string;
+}
+/* %include<colobj.c>% */
+/*
+ * colobj.c - Implementation of column objects in Tcl.
+ */
+
+
+static const char *ErrorMessage(ErrorCodes code) {
+       switch (code) {
+               case EC_cioor: return "column index out of range";
+               case EC_rioor: return "row index out of range";
+               case EC_cizwv: return "cannot insert in zero-width view";
+               case EC_nmcw:    return "item count not a multiple of column width";
+               case EC_rambe: return "rename arg count must be even";
+               case EC_nalor: return "nead at least one row";
+               case EC_wnoa:    return "wrong number of arguments";
+       }
+       return "?";
+}
+
+Object_p ItemAsObj (ItemTypes type, Item_p item) {
+       switch (type) {
+
+               case IT_int:
+                       return Tcl_NewIntObj(item->i);
+
+               case IT_wide:
+                       return Tcl_NewWideIntObj(item->w);
+
+               case IT_float:
+                       return Tcl_NewDoubleObj(item->f);
+
+               case IT_double:
+                       return Tcl_NewDoubleObj(item->d);
+
+               case IT_string:
+                       return Tcl_NewStringObj(item->s, -1);
+                       
+               case IT_bytes:
+                       return Tcl_NewByteArrayObj(item->u.ptr, item->u.len);
+
+               case IT_object:
+                       return item->o;
+
+               case IT_column:
+                       return ColumnAsObj(item->c);
+
+               case IT_view:
+                       if (item->v == NULL) {
+                               Tcl_SetResult(Interp(), "invalid view", TCL_STATIC);
+                               return NULL;
+                       }
+                       return ViewAsObj(item->v);
+
+               case IT_error:
+                       Tcl_SetResult(Interp(), (char*) ErrorMessage(item->e), TCL_STATIC);
+                       return NULL;
+
+               default:
+                       Assert(0);
+                       return NULL;
+       }
+}
+
+int ColumnByName (View_p meta, Object_p obj) {
+       int colnum;
+       const char *str = Tcl_GetString(obj);
+       
+       switch (*str) {
+
+               case '#':
+                       return -2;
+
+               case '*':
+                       return -3;
+
+               case '-': case '0': case '1': case '2': case '3': case '4':
+                                 case '5': case '6': case '7': case '8': case '9':
+                       if (Tcl_GetIntFromObj(NULL, obj, &colnum) != TCL_OK)
+                               return -4;
+                       if (colnum < 0)
+                               colnum += ViewSize(meta);
+                       if (colnum < 0 || colnum >= ViewSize(meta))
+                               return -5;
+                       return colnum;
+                       
+               default:
+                       return StringLookup(str, ViewCol(meta, MC_name));
+       }
+}
+
+int ObjToItem (ItemTypes type, Item_p item) {
+       switch (type) {
+               
+               case IT_int:
+                       return Tcl_GetIntFromObj(Interp(), item->o, &item->i) == TCL_OK;
+
+               case IT_wide:
+                       return Tcl_GetWideIntFromObj(Interp(), item->o,
+                                                                                       (Tcl_WideInt*) &item->w) == TCL_OK;
+
+               case IT_float:
+                       if (Tcl_GetDoubleFromObj(Interp(), item->o, &item->d) != TCL_OK)
+                               return 0;
+                       item->f = (float) item->d;
+                       break;
+
+               case IT_double:
+                       return Tcl_GetDoubleFromObj(Interp(), item->o, &item->d) == TCL_OK;
+
+               case IT_string:
+                       item->s = Tcl_GetString(item->o);
+                       break;
+
+               case IT_bytes:
+                       item->u.ptr = Tcl_GetByteArrayFromObj(item->o, &item->u.len);
+                       break;
+
+               case IT_object:
+                       break;
+
+               case IT_column:
+                       item->c = ObjAsColumn(item->o);
+                       return item->c.seq != NULL && item->c.seq->count >= 0;
+
+               case IT_view:
+                       item->v = ObjAsView(item->o);
+                       return item->v != NULL;
+
+               default:
+                       Assert(0);
+                       return 0;
+       }
+       
+       return 1;
+}
+
+#define OBJ_TO_COLUMN_P(o) ((Column*) &(o)->internalRep.twoPtrValue)
+
+static void FreeColIntRep (Tcl_Obj *obj) {
+       PUSH_KEEP_REFS
+       DecRefCount(OBJ_TO_COLUMN_P(obj)->seq);
+       POP_KEEP_REFS
+}
+
+static void DupColIntRep (Tcl_Obj *src, Tcl_Obj *dup) {
+       Column_p column = OBJ_TO_COLUMN_P(src);
+       IncRefCount(column->seq);
+       *OBJ_TO_COLUMN_P(dup) = *column;
+       dup->typePtr = &f_colObjType;
+}
+
+static void UpdateColStrRep (Tcl_Obj *obj) {
+       int r;
+       Object_p list;
+       Item item;
+       struct Buffer buf;
+       Column column;
+       PUSH_KEEP_REFS
+       
+       InitBuffer(&buf);
+       column = *OBJ_TO_COLUMN_P(obj);
+       
+       if (column.seq != NULL)
+               for (r = 0; r < column.seq->count; ++r) {
+                       item.c = column;
+                       ADD_PTR_TO_BUF(buf, ItemAsObj(GetItem(r, &item), &item));
+               }
+
+       list = BufferAsTclList(&buf);
+
+       /* this hack avoids creating a second copy of the string rep */
+       obj->bytes = Tcl_GetStringFromObj(list, &obj->length);
+       list->bytes = NULL;
+       list->length = 0;
+       
+       DecObjRef(list);
+       
+       POP_KEEP_REFS
+}
+
+#define LO_list                data[0].o
+#define LO_objv                data[1].p
+
+static void ListObjCleaner (Seq_p seq) {
+       DecObjRef(seq->LO_list);
+}
+
+static ItemTypes ListObjGetter (int row, Item_p item) {
+       const Object_p *objv = item->c.seq->LO_objv;
+       item->o = objv[row];
+       return IT_object;
+}
+
+static struct SeqType ST_ListObj = {
+       "listobj", ListObjGetter, 0, ListObjCleaner
+};
+
+static int SetColFromAnyRep (Tcl_Interp *interp, Tcl_Obj *obj) {
+       int objc;
+       Object_p dup, *objv;
+       Seq_p seq;
+
+       /* must duplicate the list because it'll be kept by ObjAsColumn */
+       dup = Tcl_DuplicateObj(obj);
+       
+       if (Tcl_ListObjGetElements(interp, dup, &objc, &objv) != TCL_OK) {
+               DecObjRef(dup);
+               return TCL_ERROR;
+       }
+
+       PUSH_KEEP_REFS
+       
+       seq = IncRefCount(NewSequence(objc, &ST_ListObj, 0));
+       seq->LO_list = IncObjRef(dup);
+       seq->LO_objv = objv;
+
+       if (obj->typePtr != NULL && obj->typePtr->freeIntRepProc != NULL)
+               obj->typePtr->freeIntRepProc(obj);
+
+       *OBJ_TO_COLUMN_P(obj) = SeqAsCol(seq);
+       obj->typePtr = &f_colObjType;
+       
+       POP_KEEP_REFS
+       return TCL_OK;
+}
+
+Tcl_ObjType f_colObjType = {
+       "column", FreeColIntRep, DupColIntRep, UpdateColStrRep, SetColFromAnyRep
+};
+
+Column ObjAsColumn (Object_p obj) {
+       if (Tcl_ConvertToType(Interp(), obj, &f_colObjType) != TCL_OK) {
+               Column column;
+               column.seq = NULL;
+               column.pos = -1;
+               return column;
+       }
+       
+       return *OBJ_TO_COLUMN_P(obj);
+}
+
+Object_p ColumnAsObj (Column column) {
+       Object_p result;
+
+       result = Tcl_NewObj();
+       Tcl_InvalidateStringRep(result);
+
+       IncRefCount(column.seq);
+       *OBJ_TO_COLUMN_P(result) = column;
+       result->typePtr = &f_colObjType;
+       return result;
+}
+/* %include<loop.c>% */
+/*
+ * loop.c - Implementation of the Tcl-specific "loop" operator.
+ */
+
+/* TODO: code was copied from v3, needs a lot of cleanup */
+
+
+    typedef struct LoopInfo {
+        int row;
+        Object_p view;
+        View_p v;
+        Object_p cursor;
+    } LoopInfo;
+
+    typedef struct ColTrace {
+        LoopInfo* lip;
+        int col;
+        Object_p name;
+        int lastRow;
+    } ColTrace;
+
+static char* cursor_tracer(ClientData cd, Tcl_Interp* ip, const char *name1, const char *name2, int flags) {
+    ColTrace* ct = (ColTrace*) cd;
+    int row = ct->lip->row;
+    if (row != ct->lastRow) {
+        Object_p o;
+        if (ct->col < 0)
+            o = Tcl_NewIntObj(row);
+        else {
+            Item item;
+            item.c = ViewCol(ct->lip->v, ct->col);
+            o = ItemAsObj(GetItem(row, &item), &item);
+        }
+        if (Tcl_ObjSetVar2(ip, ct->lip->cursor, ct->name, o, 0) == 0)
+            return "cursor_tracer?";
+        ct->lastRow = row;
+    }
+    return 0;
+}
+
+static int loop_vop(int oc, Tcl_Obj* const* ov) {
+    LoopInfo li;
+    const char *cur;
+    struct Buffer result;
+    int type, e = TCL_OK;
+    static const char *options[] = { "-where", "-index", "-collect", 0 };
+    enum { eLOOP = -1, eWHERE, eINDEX, eCOLLECT };
+
+    if (oc < 2 || oc > 4) {
+        Tcl_WrongNumArgs(Interp(), 1, ov, "view ?arrayName? ?-type? body");
+        return TCL_ERROR;
+    }
+
+    li.v = ObjAsView(ov[0]);
+    if (li.v == NULL)
+        return TCL_ERROR;
+
+    --oc; ++ov;
+    if (oc > 1 && *Tcl_GetString(*ov) != '-') {
+        li.cursor = *ov++; --oc;
+    } else
+        li.cursor = Tcl_NewObj();
+    cur = Tcl_GetString(IncObjRef(li.cursor));
+
+    if (Tcl_GetIndexFromObj(0, *ov, options, "", 0, &type) == TCL_OK) {
+        --oc; ++ov;
+    } else
+        type = eLOOP;
+
+    {
+        int i, nr = ViewSize(li.v), nc = ViewWidth(li.v);
+        ColTrace* ctab = (ColTrace*) ckalloc((nc + 1) * sizeof(ColTrace));
+        InitBuffer(&result);
+        for (i = 0; i <= nc; ++i) {
+            ColTrace* ctp = ctab + i;
+            ctp->lip = &li;
+            ctp->lastRow = -1;
+            if (i < nc) {
+                ctp->col = i;
+                ctp->name = Tcl_NewStringObj(GetColItem(i,
+                              ViewCol(V_Meta(li.v), MC_name), IT_string).s, -1);
+            } else {
+                ctp->col = -1;
+                ctp->name = Tcl_NewStringObj("#", -1);
+            }
+            e = Tcl_TraceVar2(Interp(), cur, Tcl_GetString(ctp->name),
+                              TCL_TRACE_READS, cursor_tracer, (ClientData) ctp);
+        }
+        if (e == TCL_OK)
+            switch (type) {
+                case eLOOP:
+                    for (li.row = 0; li.row < nr; ++li.row) {
+                        e = Tcl_EvalObj(Interp(), *ov);
+                        if (e == TCL_CONTINUE)
+                            e = TCL_OK;
+                        else if (e != TCL_OK) {
+                            if (e == TCL_BREAK)
+                                e = TCL_OK;
+                            else if (e == TCL_ERROR) {
+                                char msg[50];
+                                sprintf(msg, "\n    (\"loop\" body line %d)",
+                                   Tcl_GetErrorLine(Interp()));
+                                Tcl_AddObjErrorInfo(Interp(), msg, -1);
+                            }
+                            break;
+                        }
+                    }
+                    break;
+                case eWHERE:
+                case eINDEX:
+                    for (li.row = 0; li.row < nr; ++li.row) {
+                        int f;
+                        e = Tcl_ExprBooleanObj(Interp(), *ov, &f);
+                        if (e != TCL_OK)
+                            break;
+                        if (f)
+                            ADD_INT_TO_BUF(result, li.row);
+                    }
+                    break;
+                case eCOLLECT:
+                    for (li.row = 0; li.row < nr; ++li.row) {
+                        Object_p o;
+                        e = Tcl_ExprObj(Interp(), *ov, &o);
+                        if (e != TCL_OK)
+                            break;
+                        ADD_PTR_TO_BUF(result, o);
+                    }
+                    break;
+                default: Assert(0); return TCL_ERROR;
+            }
+        for (i = 0; i <= nc; ++i) {
+            ColTrace* ctp = ctab + i;
+            Tcl_UntraceVar2(Interp(), cur, Tcl_GetString(ctp->name),
+                            TCL_TRACE_READS, cursor_tracer, (ClientData) ctp);
+            DecObjRef(ctp->name);
+        }
+        ckfree((char*) ctab);
+        if (e == TCL_OK)
+            switch (type) {
+                case eWHERE: case eINDEX: {
+                    Column map = SeqAsCol(BufferAsIntVec(&result));
+                    if (type == eWHERE)
+                        Tcl_SetObjResult(Interp(), 
+                                ViewAsObj(RemapSubview(li.v, map, 0, -1)));
+                    else
+                        Tcl_SetObjResult(Interp(), ColumnAsObj(map));
+                    break;
+                }
+                case eCOLLECT: {
+                    Tcl_SetObjResult(Interp(), BufferAsTclList(&result));
+                    break;
+                }
+                default:
+                    ReleaseBuffer(&result, 0);
+            }
+    }
+    
+    DecObjRef(li.cursor);
+    return e;
+}
+
+ItemTypes LoopCmd_X (Item args[]) {
+    int objc;
+    const Object_p *objv;
+
+    objv = (const Object_p *) args[0].u.ptr;
+    objc = args[0].u.len;
+
+    if (loop_vop(objc, objv) != TCL_OK)
+        return IT_unknown;
+        
+    args->o = Tcl_GetObjResult(Interp());
+    return IT_object;
+}
+/* %include<viewobj.c>% */
+/*
+ * viewobj.c - Implementation of view objects in Tcl.
+ */
+
+
+#define DEP_DEBUG 0
+
+#define OBJ_TO_VIEW_P(o) ((o)->internalRep.twoPtrValue.ptr1)
+#define OBJ_TO_ORIG_P(o) ((o)->internalRep.twoPtrValue.ptr2)
+
+#define OBJ_TO_ORIG_CNT(o)  (((Seq_p) OBJ_TO_ORIG_P(o))->OR_objc)
+#define OBJ_TO_ORIG_VEC(o)  ((Object_p*) ((Seq_p) OBJ_TO_ORIG_P(o) + 1))
+
+#define OR_depx     data[0].o
+#define OR_objc     data[1].i
+#define OR_depc     data[2].i
+#define OR_depv     data[3].p
+
+/* forward */
+static void SetupViewObj (Object_p, View_p, int objc, Object_p *objv, Object_p);
+static void ClearViewObj (Object_p obj);
+
+static void FreeViewIntRep (Tcl_Obj *obj) {
+    PUSH_KEEP_REFS
+
+    Assert(((Seq_p) OBJ_TO_ORIG_P(obj))->refs == 1);
+    ClearViewObj(obj);
+    
+    DecRefCount(OBJ_TO_VIEW_P(obj));
+    DecRefCount(OBJ_TO_ORIG_P(obj));
+    
+    POP_KEEP_REFS
+}
+
+static void DupViewIntRep (Tcl_Obj *src, Tcl_Obj *dup) {
+    Assert(0);
+}
+
+static void UpdateViewStrRep (Tcl_Obj *obj) {
+    int length;
+    const char *string;
+    Object_p origobj;
+    PUSH_KEEP_REFS
+    
+    /* TODO: avoid creating a Tcl list and copying the string, use a buffer */
+    origobj = Tcl_NewListObj(OBJ_TO_ORIG_CNT(obj), OBJ_TO_ORIG_VEC(obj));
+    string = Tcl_GetStringFromObj(origobj, &length);
+
+    obj->bytes = strcpy(ckalloc(length+1), string);
+    obj->length = length;
+
+    DecObjRef(origobj);
+
+    POP_KEEP_REFS
+}
+
+static char *RefTracer (ClientData cd, Tcl_Interp *interp, const char *name1, const char *name2, int flags) {
+    Object_p obj = (Object_p) cd;
+    
+#if DEBUG+0
+    DbgIf(DBG_trace) printf("       rt %p var: %s\n", (void*) obj, name1);
+#endif
+
+    if (flags && TCL_TRACE_WRITES) {
+        Tcl_UntraceVar2(Interp(), name1, name2,
+                        TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY,
+                        RefTracer, obj);
+    }
+
+    InvalidateView(obj);
+    DecObjRef(obj);
+    return NULL;
+}
+
+static int SetViewFromAnyRep (Tcl_Interp *interp, Tcl_Obj *obj) {
+    int e = TCL_ERROR, objc, rows;
+    Object_p *objv;
+    View_p view;
+    
+    if (Tcl_ListObjGetElements(interp, obj, &objc, &objv) != TCL_OK)
+        return TCL_ERROR;
+
+    PUSH_KEEP_REFS
+
+    switch (objc) {
+
+        case 0:
+            view = EmptyMetaView();
+            SetupViewObj(obj, view, objc, objv, NULL);
+            break;
+
+        case 1:
+            if (Tcl_GetIntFromObj(interp, objv[0], &rows) == TCL_OK &&
+                                                                rows >= 0) {
+                view = NoColumnView(rows);
+                SetupViewObj(obj, view, objc, objv, NULL);
+            } else {
+                Object_p o;
+                const char *var = Tcl_GetString(objv[0]) + 1;
+                
+                if (var[-1] != '@')
+                    goto FAIL;
+                    
+#if DEBUG+0
+                DbgIf(DBG_trace) printf("svfar %p var: %s\n", (void*) obj, var);
+#endif
+                o = (Object_p) Tcl_VarTraceInfo(Interp(), var, TCL_GLOBAL_ONLY,
+                                                            RefTracer, NULL);
+                if (o == NULL) {
+                    o = Tcl_GetVar2Ex(interp, var, NULL,
+                                        TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+                    if (o == NULL)
+                        goto FAIL;
+
+                    o = NeedMutable(o);
+                    Assert(o != NULL);
+                    
+                    if (Tcl_TraceVar2(interp, var, 0,
+                            TCL_TRACE_WRITES|TCL_TRACE_UNSETS|TCL_GLOBAL_ONLY,
+                                            RefTracer, IncObjRef(o)) != TCL_OK)
+                        goto FAIL;
+                }
+                
+                view = ObjAsView(o);
+                Assert(view != NULL);
+
+                SetupViewObj(obj, view, objc, objv, /*o*/ NULL);
+            }
+            
+            break;
+
+        default: {
+            Object_p cmd;
+            Tcl_SavedResult state;
+
+            Assert(interp != NULL);
+            Tcl_SaveResult(interp, &state);
+
+            cmd = IncObjRef(Tcl_DuplicateObj(obj));
+            view = NULL;
+
+            /* def -> cmd namespace name conv can prob be avoided in Tcl 8.5 */
+            if (AdjustCmdDef(cmd) == TCL_OK) {
+                int ac;
+                Object_p *av;
+                Tcl_ListObjGetElements(NULL, cmd, &ac, &av);
+                /* don't use Tcl_EvalObjEx, it forces a string conversion */
+                if (Tcl_EvalObjv(interp, ac, av, TCL_EVAL_GLOBAL) == TCL_OK) {
+                    /* result to view, may call EvalIndirectView recursively */
+                    view = ObjAsView(Tcl_GetObjResult(interp));
+                }
+            }
+
+            DecObjRef(cmd);
+
+            if (view == NULL) {
+                Tcl_DiscardResult(&state);
+                goto FAIL;
+            }
+
+            SetupViewObj(obj, view, objc, objv, NULL);
+            Tcl_RestoreResult(interp, &state);
+        }
+    }
+
+    e = TCL_OK;
+
+FAIL:
+    POP_KEEP_REFS
+    return e;
+}
+
+Tcl_ObjType f_viewObjType = {
+    "view", FreeViewIntRep, DupViewIntRep, UpdateViewStrRep, SetViewFromAnyRep
+};
+
+View_p ObjAsView (Object_p obj) {
+    if (Tcl_ConvertToType(Interp(), obj, &f_viewObjType) != TCL_OK)
+        return NULL;
+    return OBJ_TO_VIEW_P(obj);
+}
+
+static void AddDependency (Object_p obj, Object_p child) { 
+    Object_p *deps;
+    Seq_p origin = OBJ_TO_ORIG_P(obj);
+    
+#if DEBUG+0
+    DbgIf(DBG_deps) printf(" +dep %p %p\n", (void*) obj, (void*) child);
+#endif
+
+    if (origin->OR_depv == NULL) 
+        origin->OR_depv = calloc(10, sizeof(Object_p));
+    
+    Assert(origin->OR_depc < 10);
+    deps = origin->OR_depv;
+    deps[origin->OR_depc++] = child;
+}
+
+static void RemoveDependency (Object_p obj, Object_p child) {    
+    Object_p *deps;
+    Seq_p origin = OBJ_TO_ORIG_P(obj);
+    
+#if DEBUG+0
+    DbgIf(DBG_deps) printf(" -dep %p %p\n", (void*) obj, (void*) child);
+#endif
+
+    deps = origin->OR_depv;
+    Assert(deps != NULL);
+    
+    if (deps != NULL) {
+        int i;
+
+        /* removed from end in case we're called from the invalidation loop */
+        for (i = origin->OR_depc; --i >= 0; )
+            if (deps[i] == child)
+                break;
+        /*printf("  -> i %d n %d\n", i, origin->OR_depc);*/
+        
+        Assert(i < origin->OR_depc);
+        deps[i] = deps[--origin->OR_depc];
+            
+        if (origin->OR_depc == 0) {
+            free(deps);
+            origin->OR_depv = NULL;
+        }
+    }
+}
+
+void InvalidateView (Object_p obj) {
+    Object_p *deps;
+    Seq_p origin = OBJ_TO_ORIG_P(obj);
+    
+#if DEP_DEBUG+0
+    printf("inval %p deps %d refs %d\n",
+                    (void*) obj, origin->OR_depc, obj->refCount);
+#endif
+
+    if (obj->typePtr != &f_viewObjType)
+        return;
+    
+    deps = origin->OR_depv;
+    if (deps != NULL) {
+        /* careful, RemoveDependency will remove the item during iteration */
+        while (origin->OR_depc > 0) {
+            int last = origin->OR_depc - 1;
+            InvalidateView(deps[last]);
+            Assert(origin->OR_depc <= last); /* make sure count went down */
+        }
+        Assert(origin->OR_depv == NULL);
+    }
+
+#if 1
+    Assert(obj->typePtr == &f_viewObjType);
+    Tcl_GetString(obj);
+    FreeViewIntRep(obj);
+    obj->typePtr = NULL;
+#else
+    /* FIXME: hack to allow changes to list, even when the object is shared! */
+    { Object_p nobj = Tcl_NewListObj(OBJ_TO_ORIG_CNT(obj),
+                                        OBJ_TO_ORIG_VEC(obj));
+        DecRefCount(OBJ_TO_VIEW_P(obj));
+        DecRefCount(origin);
+        obj->typePtr = nobj->typePtr;
+        obj->internalRep = nobj->internalRep;
+        nobj->typePtr = NULL;
+        DecObjRef(nobj);
+        /*Tcl_InvalidateStringRep(obj);*/
+    }
+#endif
+}
+
+#if 0
+static void OriginCleaner (Seq_p seq) {
+    int i, items = seq->OR_objc;
+    const Object_p *objv = (const void*) (seq + 1);
+
+    for (i = 0; i < items; ++i)
+        DecObjRef(objv[i]);
+
+    Assert(seq->OR_depc == 0);
+    Assert(seq->OR_depv == NULL);
+}
+
+static ItemTypes OriginGetter (int row, Item_p item) {
+    const Object_p *objv = (const void*) (item->c.seq + 1);
+    item->o = objv[row];
+    return IT_object;
+}
+#endif
+
+static struct SeqType ST_Origin = { "origin", NULL, 0, NULL };
+
+static void SetupViewObj (Object_p obj, View_p view, int objc, Object_p *objv, Object_p extradep) {
+    int i;
+    Object_p *vals;
+    Seq_p origin;
+    
+    origin = NewSequenceNoRef(objc, &ST_Origin, objc * sizeof(Object_p));
+    /* data[0] is a pointer to the reference for "@..." references */
+    /* data[1] has the number of extra bytes, i.e. objc * sizeof (Seq_p) */
+    /* data[2] is the dependency count */
+    /* data[3] is the dependency vector if data[2].i > 0 */
+    origin->OR_depx = extradep;
+    origin->OR_objc = objc;
+    vals = (void*) (origin + 1);
+    
+    for (i = 0; i < objc; ++i)
+        vals[i] = IncObjRef(objv[i]);
+
+    if (obj->typePtr != NULL && obj->typePtr->freeIntRepProc != NULL)
+        obj->typePtr->freeIntRepProc(obj);
+    
+    OBJ_TO_VIEW_P(obj) = IncRefCount(view);
+    OBJ_TO_ORIG_P(obj) = IncRefCount(origin);
+    obj->typePtr = &f_viewObjType;
+    
+    for (i = 0; i < objc; ++i)
+        if (vals[i]->typePtr == &f_viewObjType)
+            AddDependency(vals[i], obj);
+            
+    if (extradep != NULL)
+        AddDependency(extradep, obj);
+}
+
+static void ClearViewObj (Object_p obj) {
+    int i, objc;
+    Object_p *objv;
+    Seq_p origin = OBJ_TO_ORIG_P(obj);
+    
+    /* can't have any child dependencies at this stage */
+    Assert(origin->OR_depc == 0);
+    Assert(origin->OR_depv == NULL);
+
+    objc = OBJ_TO_ORIG_CNT(obj);
+    objv = OBJ_TO_ORIG_VEC(obj);
+    
+    for (i = 0; i < objc; ++i) {
+        if (objv[i]->typePtr == &f_viewObjType)
+            RemoveDependency(objv[i], obj);
+        DecObjRef(objv[i]);
+    }
+        
+    if (origin->OR_depx != NULL)
+        RemoveDependency(origin->OR_depx, obj);
+}
+
+static Object_p MetaViewAsObj (View_p meta) {
+    char typeCh;
+    int width, rowNum;
+    Object_p result, fieldobj;
+    View_p subv;
+    Column names, types, subvs;
+
+    names = ViewCol(meta, MC_name);
+    types = ViewCol(meta, MC_type);
+    subvs = ViewCol(meta, MC_subv);
+
+    result = Tcl_NewListObj(0, NULL);
+
+    width = ViewSize(meta);
+    for (rowNum = 0; rowNum < width; ++rowNum) {
+        fieldobj = Tcl_NewStringObj(GetColItem(rowNum, names, IT_string).s, -1);
+
+        /* this ignores all but the first character of the type */
+        typeCh = *GetColItem(rowNum, types, IT_string).s;
+
+        switch (typeCh) {
+
+            case 'S':
+                break;
+
+            case 'V':
+                subv = GetColItem(rowNum, subvs, IT_view).v;
+                fieldobj = Tcl_NewListObj(1, &fieldobj);
+                Tcl_ListObjAppendElement(NULL, fieldobj, MetaViewAsObj(subv));
+                break;
+
+            default:
+                Tcl_AppendToObj(fieldobj, ":", 1);
+                Tcl_AppendToObj(fieldobj, &typeCh, 1);
+                break;
+        }
+
+        Tcl_ListObjAppendElement(NULL, result, fieldobj);
+    }
+
+    return result;
+}
+
+Object_p ViewAsObj (View_p view) {
+    View_p meta = V_Meta(view);
+    int c, rows = ViewSize(view), cols = ViewSize(meta);
+    Object_p result;
+    struct Buffer buffer;
+    
+    InitBuffer(&buffer);
+
+    if (meta == V_Meta(meta)) {
+        if (rows > 0) {
+            ADD_PTR_TO_BUF(buffer, Tcl_NewStringObj("mdef", 4));
+            ADD_PTR_TO_BUF(buffer, MetaViewAsObj(view));
+        }
+    } else {
+        if (cols == 0) {
+            ADD_PTR_TO_BUF(buffer, Tcl_NewIntObj(rows));
+        } else {
+            ADD_PTR_TO_BUF(buffer, Tcl_NewStringObj("data", 4));
+            ADD_PTR_TO_BUF(buffer, ViewAsObj(meta));
+            for (c = 0; c < cols; ++c)
+                ADD_PTR_TO_BUF(buffer, ColumnAsObj(ViewCol(view, c)));
+        }
+    }
+
+    result = Tcl_NewObj();
+    Tcl_InvalidateStringRep(result);
+    
+    SetupViewObj(result, view, BufferFill(&buffer) / sizeof(Object_p),
+                                            BufferAsPtr(&buffer, 1), NULL);
+    
+    ReleaseBuffer(&buffer, 0);
+    return result;
+}
+
+View_p ObjAsMetaView (Object_p obj) {
+    int r, rows, objc;
+    Object_p names, types, subvs, *objv, entry, nameobj, subvobj;
+    const char *name, *sep, *type;
+    View_p view = NULL;
+
+    if (Tcl_ListObjLength(Interp(), obj, &rows) != TCL_OK)
+        return NULL;
+
+    names = Tcl_NewListObj(0, 0);
+    types = Tcl_NewListObj(0, 0);
+    subvs = Tcl_NewListObj(0, 0);
+
+    for (r = 0; r < rows; ++r) {
+        Tcl_ListObjIndex(NULL, obj, r, &entry);
+        if (Tcl_ListObjGetElements(Interp(), entry, &objc, &objv) != TCL_OK ||
+                objc < 1 || objc > 2)
+            goto DONE;
+
+        name = Tcl_GetString(objv[0]);
+        sep = strchr(name, ':');
+        type = objc > 1 ? "V" : "S";
+
+        if (sep != NULL) {
+            if (sep[1] != 0) {
+                if (strchr("BDFLISV", sep[1]) == NULL)
+                    goto DONE;
+                type = sep+1;
+            }
+            nameobj= Tcl_NewStringObj(name, sep - name);
+        } else
+            nameobj = objv[0];
+
+        if (objc > 1) {
+            view = ObjAsMetaView(objv[1]);
+            if (view == NULL)
+                goto DONE;
+            subvobj = ViewAsObj(view);
+        } else
+            subvobj = Tcl_NewObj();
+
+        Tcl_ListObjAppendElement(NULL, names, nameobj);
+        Tcl_ListObjAppendElement(NULL, types, Tcl_NewStringObj(type, -1));
+        Tcl_ListObjAppendElement(NULL, subvs, subvobj);
+    }
+
+    view = NewView(V_Meta(EmptyMetaView()));
+    SetViewCols(view, MC_name, 1, CoerceColumn(IT_string, names));
+    SetViewCols(view, MC_type, 1, CoerceColumn(IT_string, types));
+    SetViewCols(view, MC_subv, 1, CoerceColumn(IT_view, subvs));
+    
+DONE:
+    DecObjRef(names);
+    DecObjRef(types);
+    DecObjRef(subvs);
+    return view;
+}
+
+Object_p NeedMutable (Object_p obj) {
+    int objc;
+    Object_p *objv;
+    View_p view;
+
+    view = ObjAsView(obj);
+    if (view == NULL)
+        return NULL;
+    
+    if (IsMutable(view))
+        return obj;
+    
+    objc = OBJ_TO_ORIG_CNT(obj);
+    objv = OBJ_TO_ORIG_VEC(obj);
+    
+    if (objc == 1 && *Tcl_GetString(objv[0]) == '@') {
+        const char *var = Tcl_GetString(objv[0]) + 1;
+        Object_p o = (Object_p) Tcl_VarTraceInfo(Interp(), var,
+                                            TCL_GLOBAL_ONLY, RefTracer, NULL);
+        Assert(o != NULL);
+        return o;
+    }
+    
+    if (objc > 1 && strcmp(Tcl_GetString(objv[0]), "get") == 0) {
+        Object_p origdef, tmp = NeedMutable(objv[1]); /* recursive */
+        Assert(tmp != NULL);
+        
+        origdef = Tcl_NewListObj(objc, objv);
+        Tcl_ListObjReplace(NULL, origdef, 1, 1, 1, &tmp);
+        return origdef;
+    }
+    
+    return obj;
+}
+
+static void ListOneDep (Buffer_p buf, Object_p obj) {
+    Object_p o, vec[3];
+    
+    if (obj->typePtr == &f_viewObjType) {
+        View_p view = OBJ_TO_VIEW_P(obj);
+        Seq_p seq = ViewCol(view, 0).seq;
+        vec[0] = Tcl_NewStringObj(seq != NULL ? seq->type->name : "", -1);
+        vec[1] = MetaViewAsObj(V_Meta(view));
+        vec[2] = Tcl_NewIntObj(ViewSize(view));
+        o = Tcl_NewListObj(3, vec);
+    } else if (Tcl_ListObjIndex(NULL, obj, 0, &o) != TCL_OK)
+        o = Tcl_NewStringObj("?", 1);
+
+    ADD_PTR_TO_BUF(*buf, o);
+}
+
+ItemTypes DepsCmd_O (Item_p a) {
+    int i;
+    Object_p obj, *objv;
+    Seq_p origin;
+    struct Buffer buffer;
+
+    obj = a[0].o;
+    ObjAsView(obj);
+    
+    if (obj->typePtr != &f_viewObjType)
+        return IT_unknown;
+    
+    InitBuffer(&buffer);
+    
+    origin = OBJ_TO_ORIG_P(obj);
+    objv = OBJ_TO_ORIG_VEC(obj);
+    
+    if (origin->OR_depx != NULL)
+        ListOneDep(&buffer, origin->OR_depx);
+    else
+        ADD_PTR_TO_BUF(buffer, Tcl_NewStringObj("-", 1));
+    
+    for (i = 0; i < origin->OR_depc; ++i)
+        ListOneDep(&buffer, objv[i]);
+    
+    a->o = BufferAsTclList(&buffer);
+    return IT_object;
+}
+/* %include<ext_tcl.c>% */
+/*
+ * ext_tcl.c - Interface to the Tcl scripting language.
+ */
+
+
+#ifndef PACKAGE_VERSION
+#define PACKAGE_VERSION "4"
+#endif
+
+/* stub interface code, removes the need to link with libtclstub*.a */
+#if STATIC_BUILD+0
+#define MyInitStubs(x) 1
+#else
+#ifdef FAKE_TCL_STUBS
+/*
+ * stubs.h - Internal stub code, adapted from CritLib
+ */
+
+CONST86 TclStubs               *tclStubsPtr        = NULL;
+CONST86 TclPlatStubs           *tclPlatStubsPtr    = NULL;
+struct TclIntStubs     *tclIntStubsPtr     = NULL;
+struct TclIntPlatStubs *tclIntPlatStubsPtr = NULL;
+
+static int MyInitStubs (Tcl_Interp *ip) {
+
+    typedef struct HeadOfInterp {
+        char                 *result;
+        Tcl_FreeProc *freeProc;
+        int                     errorLine;
+        TclStubs         *stubTable;
+    } HeadOfInterp;
+
+    HeadOfInterp *hoi = (HeadOfInterp*) ip;
+
+    if (hoi->stubTable == NULL || hoi->stubTable->magic != TCL_STUB_MAGIC) {
+        ip->result = "This extension requires stubs-support.";
+        ip->freeProc = TCL_STATIC;
+        return 0;
+    }
+
+    tclStubsPtr = hoi->stubTable;
+
+    if (Tcl_PkgRequire(ip, "Tcl", "8.1", 0) == NULL) {
+        tclStubsPtr = NULL;
+        return 0;
+    }
+
+    if (tclStubsPtr->hooks != NULL) {
+            tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
+            tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs;
+            tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;
+    }
+
+    return 1;
+}
+#else /* !FAKE_TCL_STUBS */
+#define MyInitStubs(ip) Tcl_InitStubs((ip), "8.4", 0)
+#endif /* FAKE_TCL_STUBS */
+#endif /* !STATIC_BUILD */
+
+#if NO_THREAD_CALLS+0
+Shared_p GetShared (void) {
+    static struct Shared data;
+    return &data;
+}
+#define UngetShared Tcl_CreateExitHandler
+#else
+static Tcl_ThreadDataKey tls_data;
+Shared_p GetShared (void) {
+    return (Shared_p) Tcl_GetThreadData(&tls_data, sizeof(struct Shared));
+}
+#define UngetShared Tcl_CreateThreadExitHandler
+#endif
+
+typedef struct CmdDispatch {
+    const char *name, *args;
+    ItemTypes (*proc) (Item_p);
+} CmdDispatch;
+
+static CmdDispatch f_commands[] = {
+/* opdefs_gen.h - generated code, do not edit */
+
+/* 94 definitions generated for Tcl:
+
+  # name       in     out    inline-code
+  : drop       U      {}     {}
+  : dup        U      UU     {$1 = $0;}
+  : imul       II     I      {$0.i *=  $1.i;}
+  : nip        UU     U      {$0 = $1;}
+  : over       UU     UUU    {$2 = $0;}
+  : rot        UUU    UUU    {$3 = $0; $0 = $1; $1 = $2; $2 = $3;}
+  : rrot       UUU    UUU    {$3 = $2; $2 = $1; $1 = $0; $0 = $3;}
+  : swap       UU     UU     {$2 = $0; $0 = $1; $1 = $2;}
+  : tuck       UU     UUU    {$1 = $2; $0 = $1; $2 = $0;}
+  
+  tcl {
+    # name       in    out
+    : Def        OO     V
+    : Deps       O      O
+    : Emit       V      O
+    : EmitMods   V      O
+    : Get        VX     U
+    : Load       O      V
+    : LoadMods   OV     V
+    : Loop       X      O
+    : MutInfo    V      O
+    : Ref        OX     O
+    : Refs       O      I
+    : Rename     VO     V
+    : Save       VS     I
+    : To         OO     O
+    : Type       O      O
+    : View       X      O
+  }
+  
+  python {
+    # name       in    out
+  }
+  
+  ruby {
+    # name       in    out
+    : AtRow      OI     O
+  }
+  
+  lua {
+    # name       in    out
+  }
+  
+  objc {
+    # name       in    out
+    : At         VIO    O
+  }
+  
+  # name       in    out
+  : BitRuns    i      C
+  : Data       VX     V
+  : Debug      I      I
+  : HashCol    SO     C
+  : Max        VN     O
+  : Min        VN     O
+  : Open       S      V
+  : ResizeCol  iII    C
+  : Set        MIX    V
+  : StructDesc V      S
+  : Structure  V      S
+  : Sum        VN     O
+  : Write      VO     I
+
+  # name       in    out  internal-name
+  : Blocked    V      V   BlockedView
+  : Clone      V      V   CloneView
+  : ColMap     Vn     V   ColMapView
+  : ColOmit    Vn     V   ColOmitView
+  : Coerce     OS     C   CoerceCmd
+  : Compare    VV     I   ViewCompare
+  : Compat     VV     I   ViewCompat
+  : Concat     VV     V   ConcatView
+  : CountsCol  C      C   NewCountsColumn
+  : CountView  I      V   NoColumnView
+  : First      VI     V   FirstView
+  : GetCol     VN     C   ViewCol
+  : Group      VnS    V   GroupCol
+  : HashFind   VIViii I   HashDoFind
+  : Ijoin      VV     V   IjoinView
+  : GetInfo    VVI    C   GetHashInfo
+  : Grouped    ViiS   V   GroupedView
+  : HashView   V      C   HashValues
+  : IsectMap   VV     C   IntersectMap
+  : Iota       I      C   NewIotaColumn
+  : Join       VVS    V   JoinView
+  : Last       VI     V   LastView
+  : Mdef       O      V   ObjAsMetaView
+  : Mdesc      S      V   DescToMeta
+  : Meta       V      V   V_Meta
+  : OmitMap    iI     C   OmitColumn
+  : OneCol     VN     V   OneColView
+  : Pair       VV     V   PairView
+  : RemapSub   ViII   V   RemapSubview
+  : Replace    VIIV   V   ViewReplace
+  : RowCmp     VIVI   I   RowCompare
+  : RowEq      VIVI   I   RowEqual
+  : RowHash    VI     I   RowHash
+  : Size       V      I   ViewSize
+  : SortMap    V      C   SortMap
+  : Step       VIIII  V   StepView
+  : StrLookup  Ss     I   StringLookup
+  : Tag        VS     V   TagView
+  : Take       VI     V   TakeView
+  : Ungroup    VN     V   UngroupView
+  : UniqueMap  V      C   UniqMap
+  : ViewAsCol  V      C   ViewAsCol
+  : Width      V      I   ViewWidth
+               
+  # name       in    out  compound-definition
+  : Append     VV     V   {over size swap insert}
+  : ColConv    C      C   { }
+  : Counts     VN     C   {getcol countscol}
+  : Delete     VII    V   {0 countview replace}
+  : Except     VV     V   {over swap exceptmap remap}
+  : ExceptMap  VV     C   {over swap isectmap swap size omitmap}
+  : Insert     VIV    V   {0 swap replace}
+  : Intersect  VV     V   {over swap isectmap remap}
+  : NameCol    V      V   {meta 0 onecol}
+  : Names      V      C   {meta 0 getcol}
+  : Product    VV     V   {over over size spread rrot swap size repeat pair}
+  : Repeat     VI     V   {over size imul 0 1 1 step}
+  : Remap      Vi     V   {0 -1 remapsub}
+  : Reverse    V      V   {dup size -1 1 -1 step}
+  : Slice      VIII   V   {rrot 1 swap step}
+  : Sort       V      V   {dup sortmap remap}
+  : Spread     VI     V   {over size 0 rot 1 step}
+  : Types      V      C   {meta 1 getcol}
+  : Unique     V      V   {dup uniquemap remap}
+  : Union      VV     V   {over except concat}
+  : UnionMap   VV     C   {swap exceptmap}
+  : ViewConv   V      V   { }
+  
+  # some operators are omitted from restricted execution environments
+  unsafe Open Save
+*/
+
+  { "open",       "V:S",      OpenCmd_S          },
+  { "save",       "I:VS",     SaveCmd_VS         },
+#define UNSAFE 2
+  { "append",     "V:VV",     AppendCmd_VV       },
+  { "bitruns",    "C:i",      BitRunsCmd_i       },
+  { "blocked",    "V:V",      BlockedCmd_V       },
+  { "clone",      "V:V",      CloneCmd_V         },
+  { "coerce",     "C:OS",     CoerceCmd_OS       },
+  { "colconv",    "C:C",      ColConvCmd_C       },
+  { "colmap",     "V:Vn",     ColMapCmd_Vn       },
+  { "colomit",    "V:Vn",     ColOmitCmd_Vn      },
+  { "compare",    "I:VV",     CompareCmd_VV      },
+  { "compat",     "I:VV",     CompatCmd_VV       },
+  { "concat",     "V:VV",     ConcatCmd_VV       },
+  { "counts",     "C:VN",     CountsCmd_VN       },
+  { "countscol",  "C:C",      CountsColCmd_C     },
+  { "countview",  "V:I",      CountViewCmd_I     },
+  { "data",       "V:VX",     DataCmd_VX         },
+  { "debug",      "I:I",      DebugCmd_I         },
+  { "def",        "V:OO",     DefCmd_OO          },
+  { "delete",     "V:VII",    DeleteCmd_VII      },
+  { "deps",       "O:O",      DepsCmd_O          },
+  { "emit",       "O:V",      EmitCmd_V          },
+  { "emitmods",   "O:V",      EmitModsCmd_V      },
+  { "except",     "V:VV",     ExceptCmd_VV       },
+  { "exceptmap",  "C:VV",     ExceptMapCmd_VV    },
+  { "first",      "V:VI",     FirstCmd_VI        },
+  { "get",        "U:VX",     GetCmd_VX          },
+  { "getcol",     "C:VN",     GetColCmd_VN       },
+  { "getinfo",    "C:VVI",    GetInfoCmd_VVI     },
+  { "group",      "V:VnS",    GroupCmd_VnS       },
+  { "grouped",    "V:ViiS",   GroupedCmd_ViiS    },
+  { "hashcol",    "C:SO",     HashColCmd_SO      },
+  { "hashfind",   "I:VIViii", HashFindCmd_VIViii },
+  { "hashview",   "C:V",      HashViewCmd_V      },
+  { "ijoin",      "V:VV",     IjoinCmd_VV        },
+  { "insert",     "V:VIV",    InsertCmd_VIV      },
+  { "intersect",  "V:VV",     IntersectCmd_VV    },
+  { "iota",       "C:I",      IotaCmd_I          },
+  { "isectmap",   "C:VV",     IsectMapCmd_VV     },
+  { "join",       "V:VVS",    JoinCmd_VVS        },
+  { "last",       "V:VI",     LastCmd_VI         },
+  { "load",       "V:O",      LoadCmd_O          },
+  { "loadmods",   "V:OV",     LoadModsCmd_OV     },
+  { "loop",       "O:X",      LoopCmd_X          },
+  { "max",        "O:VN",     MaxCmd_VN          },
+  { "mdef",       "V:O",      MdefCmd_O          },
+  { "mdesc",      "V:S",      MdescCmd_S         },
+  { "meta",       "V:V",      MetaCmd_V          },
+  { "min",        "O:VN",     MinCmd_VN          },
+  { "mutinfo",    "O:V",      MutInfoCmd_V       },
+  { "namecol",    "V:V",      NameColCmd_V       },
+  { "names",      "C:V",      NamesCmd_V         },
+  { "omitmap",    "C:iI",     OmitMapCmd_iI      },
+  { "onecol",     "V:VN",     OneColCmd_VN       },
+  { "pair",       "V:VV",     PairCmd_VV         },
+  { "product",    "V:VV",     ProductCmd_VV      },
+  { "ref",        "O:OX",     RefCmd_OX          },
+  { "refs",       "I:O",      RefsCmd_O          },
+  { "remap",      "V:Vi",     RemapCmd_Vi        },
+  { "remapsub",   "V:ViII",   RemapSubCmd_ViII   },
+  { "rename",     "V:VO",     RenameCmd_VO       },
+  { "repeat",     "V:VI",     RepeatCmd_VI       },
+  { "replace",    "V:VIIV",   ReplaceCmd_VIIV    },
+  { "resizecol",  "C:iII",    ResizeColCmd_iII   },
+  { "reverse",    "V:V",      ReverseCmd_V       },
+  { "rowcmp",     "I:VIVI",   RowCmpCmd_VIVI     },
+  { "roweq",      "I:VIVI",   RowEqCmd_VIVI      },
+  { "rowhash",    "I:VI",     RowHashCmd_VI      },
+  { "set",        "V:MIX",    SetCmd_MIX         },
+  { "size",       "I:V",      SizeCmd_V          },
+  { "slice",      "V:VIII",   SliceCmd_VIII      },
+  { "sort",       "V:V",      SortCmd_V          },
+  { "sortmap",    "C:V",      SortMapCmd_V       },
+  { "spread",     "V:VI",     SpreadCmd_VI       },
+  { "step",       "V:VIIII",  StepCmd_VIIII      },
+  { "strlookup",  "I:Ss",     StrLookupCmd_Ss    },
+  { "structdesc", "S:V",      StructDescCmd_V    },
+  { "structure",  "S:V",      StructureCmd_V     },
+  { "sum",        "O:VN",     SumCmd_VN          },
+  { "tag",        "V:VS",     TagCmd_VS          },
+  { "take",       "V:VI",     TakeCmd_VI         },
+  { "to",         "O:OO",     ToCmd_OO           },
+  { "type",       "O:O",      TypeCmd_O          },
+  { "types",      "C:V",      TypesCmd_V         },
+  { "ungroup",    "V:VN",     UngroupCmd_VN      },
+  { "union",      "V:VV",     UnionCmd_VV        },
+  { "unionmap",   "C:VV",     UnionMapCmd_VV     },
+  { "unique",     "V:V",      UniqueCmd_V        },
+  { "uniquemap",  "C:V",      UniqueMapCmd_V     },
+  { "view",       "O:X",      ViewCmd_X          },
+  { "viewascol",  "C:V",      ViewAsColCmd_V     },
+  { "viewconv",   "V:V",      ViewConvCmd_V      },
+  { "width",      "I:V",      WidthCmd_V         },
+  { "write",      "I:VO",     WriteCmd_VO        },
+
+/* end of generated code */
+    { NULL, NULL, NULL }
+};
+
+Object_p IncObjRef (Object_p objPtr) {
+    Tcl_IncrRefCount(objPtr);
+    return objPtr;
+}
+
+Object_p BufferAsTclList (Buffer_p bp) {
+    int argc;
+    Object_p result;
+    
+    argc = BufferFill(bp) / sizeof(Object_p);
+    result = Tcl_NewListObj(argc, BufferAsPtr(bp, 1));
+    ReleaseBuffer(bp, 0);
+    return result;
+}
+
+void FailedAssert (const char *msg, const char *file, int line) {
+    Tcl_Panic("Failed assertion at %s, line %d: %s\n", file, line, msg);
+}
+
+ItemTypes RefCmd_OX (Item args[]) {
+    int objc;
+    const Object_p *objv;
+    
+    objv = (const Object_p *) args[1].u.ptr;
+    objc = args[1].u.len;
+
+    args->o = Tcl_ObjGetVar2(Interp(), args[0].o, 0,
+                                TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG);
+    return IT_object;
+}
+
+ItemTypes OpenCmd_S (Item args[]) {
+    View_p result;
+    Tcl_DString ds;
+    char *native;
+
+    /*
+     * When providing a database for a tclkit, we have here a "chicken
+     * and egg" problem with encodings: a call to this code will
+     * result from invoking the "open" script-level Vlerq command, and
+     * thus it will be passed an UTF-8 encoded filename.  In the case
+     * of tclkits this filename is obtained via a call to [info
+     * nameofexecutable], and at the time of that call [encoding
+     * system] is "identity" because the encodings subsystem can be
+     * initialized only after the tclkit VFS is mounted, and its
+     * mounting is what this very function is called for.
+     *
+     * On Windows, when converting between "system native" characters
+     * and UTF-8 (and vice-versa) two encodings may be used:
+     * - [encoding system] on Win9x/ME
+     * - "unicode" encoding on Windows NT.
+     * The "unicode" encoding is built-in, and [encoding system] will
+     * only have correct value on Latin-1 and UTF-8 systems,
+     * on others it will be "identity".
+     *
+     * This means when the tclkit is started from a folder whose name
+     * contains non-latin-1 characters, on Windows NT this function
+     * will receive correct UTF-8 string and the call to
+     * Tcl_WinUtfToTChar() below will return proper array of WCHARs.
+     * On Win95/ME and Unices the behaviour depends on whether the
+     * system encoding happens to be UTF-8 or any variant of Latin-1;
+     * if it is, this function will receive a proper UTF-8 string and
+     * the call to Tcl_WinUtfToTChar()/Tcl_UtfToExternalDString()
+     * below will produce a proper "native" string back. Otherwise,
+     * [encoding system] will be "identity" and due to the way it
+     * works this function will receive a string containing exactly
+     * the bytes returned by some relevant system call, which [info
+     * nameofexecutable] performed and the call to
+     * Tcl_WinUtfToTChar()/Tcl_UtfToExternalDString() will produce an
+     * array of char with the same bytes.  It this case startup from a
+     * folder containing non-latin-1 characters will fail.
+     */
+
+#if WIN32+0
+    native = Tcl_WinUtfToTChar(args[0].s, strlen(args[0].s), &ds);
+#else
+    native = Tcl_UtfToExternalDString(NULL,
+         args[0].s, strlen(args[0].s), &ds);
+#endif
+    result = OpenDataFile(native);
+    Tcl_DStringFree(&ds);
+    if (result == NULL) {
+        Tcl_AppendResult(Interp(), "cannot open file: ", args[0].s, NULL);
+        return IT_unknown;
+    }
+    
+    args->v = result;
+    return IT_view;
+}
+
+static void LoadedStringCleaner (MappedFile_p map) {
+    DecObjRef((Object_p) map->data[3].p);
+}
+
+ItemTypes LoadCmd_O (Item args[]) {
+    int len;
+    const char *ptr;
+    View_p view;
+    MappedFile_p map;
+    
+    ptr = (const char*) Tcl_GetByteArrayFromObj(args[0].o, &len);
+
+    map = InitMappedFile(ptr, len, LoadedStringCleaner);
+    map->data[3].p = IncObjRef(args[0].o);
+    
+    view = MappedToView(map, NULL);
+    if (view == NULL)
+        return IT_unknown;
+        
+    args->v = view;
+    return IT_view;
+}
+
+ItemTypes LoadModsCmd_OV (Item args[]) {
+    int len;
+    const char *ptr;
+    View_p view;
+    MappedFile_p map;
+    
+    ptr = (const char*) Tcl_GetByteArrayFromObj(args[0].o, &len);
+
+    map = InitMappedFile(ptr, len, LoadedStringCleaner);
+    map->data[3].p = IncObjRef(args[0].o);
+    
+    view = MappedToView(map, args[1].v);
+    if (view == NULL)
+        return IT_unknown;
+        
+    args->v = view;
+    return IT_view;
+}
+
+    static void *WriteDataFun(void *chan, const void *ptr, Int_t len) {
+        Tcl_Write(chan, ptr, len);
+        return chan;
+    }
+
+ItemTypes SaveCmd_VS (Item args[]) {
+    Int_t bytes;
+    Tcl_Channel chan;
+    
+    chan = Tcl_OpenFileChannel(Interp(), args[1].s, "w", 0666);
+    if (chan == NULL || Tcl_SetChannelOption(Interp(), chan,
+                                            "-translation", "binary") != TCL_OK)
+        return IT_unknown;
+        
+    bytes = ViewSave(args[0].v, chan, NULL, WriteDataFun, 0);
+
+    Tcl_Close(Interp(), chan);
+
+    if (bytes < 0)
+        return IT_unknown;
+        
+    args->w = bytes;
+    return IT_wide;
+}
+
+ItemTypes WriteCmd_VO (Item args[]) {
+    Int_t bytes;
+    Tcl_Channel chan;
+    
+    chan = Tcl_GetChannel(Interp(), Tcl_GetString(args[1].o), NULL);
+    if (chan == NULL || Tcl_SetChannelOption(Interp(), chan,
+                                            "-translation", "binary") != TCL_OK)
+        return IT_unknown;
+        
+    bytes = ViewSave(args[0].v, chan, NULL, WriteDataFun, 0);
+    
+    if (bytes < 0)
+        return IT_unknown;
+        
+    args->w = bytes;
+    return IT_wide;
+}
+
+#define EmitInitFun ((SaveInitFun) Tcl_SetByteArrayLength)
+
+    static void *EmitDataFun(void *data, const void *ptr, Int_t len) {
+        memcpy(data, ptr, len);
+        return (char*) data + len;
+    }
+
+ItemTypes EmitCmd_V (Item args[]) {
+    Object_p result = Tcl_NewByteArrayObj(NULL, 0);
+        
+    if (ViewSave(args[0].v, result, EmitInitFun, EmitDataFun, 0) < 0) {
+        DecObjRef(result);
+        return IT_unknown;
+    }
+        
+    args->o = result;
+    return IT_object;
+}
+
+ItemTypes EmitModsCmd_V (Item args[]) {
+    Object_p result = Tcl_NewByteArrayObj(NULL, 0);
+        
+    if (ViewSave(args[0].v, result, EmitInitFun, EmitDataFun, 1) < 0) {
+        DecObjRef(result);
+        return IT_unknown;
+    }
+        
+    args->o = result;
+    return IT_object;
+}
+
+int AdjustCmdDef (Object_p cmd) {
+    Object_p origname, newname;
+    Tcl_CmdInfo cmdinfo;
+
+    /* Use "::vlerq::blah ..." if it exists, else use "vlerq blah ...". */
+    /* Could perhaps be simplified (optimized?) by using 8.5 ensembles. */
+     
+    if (Tcl_ListObjIndex(Interp(), cmd, 0, &origname) != TCL_OK)
+        return TCL_ERROR;
+
+    /* insert "::vlerq::" before the first list element */
+    newname = Tcl_NewStringObj("::vlerq::", -1);
+    Tcl_AppendObjToObj(newname, origname);
+    
+    if (Tcl_GetCommandInfo(Interp(), Tcl_GetString(newname), &cmdinfo))
+        Tcl_ListObjReplace(NULL, cmd, 0, 1, 1, &newname);
+    else {
+        Object_p buf[2];
+        DecObjRef(newname);
+        buf[0] = Tcl_NewStringObj("vlerq", -1);
+        buf[1] = origname;
+        Tcl_ListObjReplace(NULL, cmd, 0, 1, 2, buf);
+    }
+    return TCL_OK;
+}
+
+ItemTypes ViewCmd_X (Item args[]) {
+    int e = TCL_OK, i, n, index, objc;
+    const Object_p *objv;
+    Object_p result, buf[10], *cvec;
+    Tcl_Interp *interp = Interp();
+    const CmdDispatch *cmds = GetShared()->info->cmds;
+
+    objv = (const Object_p *) args[0].u.ptr;
+    objc = args[0].u.len;
+
+    if (objc < 1) {
+        Tcl_WrongNumArgs(interp, 0, objv, "view arg ?op ...? ?| ...?");
+        return IT_unknown;
+    }
+    
+    Tcl_SetObjResult(interp, objv[0]); --objc; ++objv;
+    
+    while (e == TCL_OK && objc > 0) {
+        for (n = 0; n < objc; ++n)
+            if (objv[n]->bytes != 0 && *objv[n]->bytes == '|' && 
+                    objv[n]->length == 1)
+                break;
+
+        if (n > 0) {
+            cvec = n > 8 ? malloc((n+2) * sizeof(Object_p)) : buf;
+                
+            if (Tcl_GetIndexFromObjStruct(NULL, *objv, cmds, sizeof *cmds, 
+                                            "", TCL_EXACT, &index) != TCL_OK)
+                index = -1;
+
+            cvec[0] = Tcl_NewStringObj("vlerq", -1);
+            cvec[1] = objv[0];
+            cvec[2] = IncObjRef(Tcl_GetObjResult(interp));
+            for (i = 1; i < n; ++i)
+                cvec[i+2] = objv[i];
+            
+            result = Tcl_NewListObj(n+1, cvec+1);
+
+            if (index < 0 || *cmds[index].args != 'V') {
+                e = AdjustCmdDef(result);
+                if (e == TCL_OK) {
+                    int ac;
+                    Object_p *av;
+                    Tcl_ListObjGetElements(NULL, result, &ac, &av);
+                    /* don't use Tcl_EvalObjEx, it forces a string conversion */
+                    e = Tcl_EvalObjv(interp, ac, av, 0);
+                }
+                DecObjRef(result);
+            } else
+                Tcl_SetObjResult(interp, result);
+            
+            DecObjRef(cvec[2]);
+            if (n > 8)
+                free(cvec);
+        }
+        
+        objc -= n+1; objv += n+1; /*++k;*/
+    }
+
+    if (e != TCL_OK) {
+#if 0
+        char msg[50];
+        sprintf(msg, "\n        (\"view\" step %d)", k);
+        Tcl_AddObjErrorInfo(interp, msg, -1);
+#endif
+        return IT_unknown;
+    }
+    
+    args->o = Tcl_GetObjResult(interp);
+    return IT_object;
+}
+
+#define MAX_STACK 20
+
+static int VlerqObjCmd (ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
+    int i, index, ok = TCL_ERROR;
+    ItemTypes type;
+    Object_p result;
+    Item stack [MAX_STACK];
+    const char *args;
+    const CmdDispatch *cmdtable;
+    PUSH_KEEP_REFS
+    
+    Interp() = interp;
+    
+    if (objc <= 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, "command ...");
+        goto FAIL;
+    }
+
+    cmdtable = (const CmdDispatch*) data;
+    if (Tcl_GetIndexFromObjStruct(interp, objv[1], cmdtable, sizeof *cmdtable, 
+                                    "command", TCL_EXACT, &index) != TCL_OK)
+        goto FAIL;
+
+    objv += 2; objc -= 2;
+    args = cmdtable[index].args + 2; /* skip return type and ':' */
+
+    for (i = 0; args[i] != 0; ++i) {
+        Assert(i < MAX_STACK);
+        if (args[i] == 'X') {
+            Assert(args[i+1] == 0);
+            stack[i].u.ptr = (const void*) (objv+i);
+            stack[i].u.len = objc-i;
+            break;
+        }
+        if ((args[i] == 0 && i != objc) || (args[i] != 0 && i >= objc)) {
+            char buf [10*MAX_STACK];
+            const char* s;
+            *buf = 0;
+            for (i = 0; args[i] != 0; ++i) {
+                if (*buf != 0)
+                    strcat(buf, " ");
+                switch (args[i] & ~0x20) {
+                    case 'C': s = "list"; break;
+                    case 'I': s = "int"; break;
+                    case 'N': s = "col"; break;
+                    case 'O': s = "any"; break;
+                    case 'S': s = "string"; break;
+                    case 'V': s = "view"; break;
+                    case 'X': s = "..."; break;
+                    default: Assert(0); s = "?"; break;
+                }
+                strcat(buf, s);
+                if (args[i] & 0x20)
+                    strcat(buf, "*");
+            }
+            Tcl_WrongNumArgs(interp, 2, objv-2, buf);
+            goto FAIL;
+        }
+        stack[i].o = objv[i];
+        if (!CastObjToItem(args[i], stack+i)) {
+            if (*Tcl_GetStringResult(interp) == 0) {
+                const char* s = "?";
+                switch (args[i] & ~0x20) {
+                    case 'C': s = "list"; break;
+                    case 'I': s = "integer"; break;
+                    case 'N': s = "column name"; break;
+                    case 'V': s = "view"; break;
+                }
+                Tcl_AppendResult(interp, cmdtable[index].name, ": invalid ", s,
+                                                                        NULL);
+            }
+            goto FAIL; /* TODO: append info about which arg is bad */
+        }
+    }
+    
+    GetShared()->info->cmds = cmdtable; /* for ViewCmd_X */
+    
+    type = cmdtable[index].proc(stack);
+    if (type == IT_unknown)
+        goto FAIL;
+
+    result = ItemAsObj(type, stack);
+    if (result == NULL)
+        goto FAIL;
+
+    Tcl_SetObjResult(interp, result);
+    ok = TCL_OK;
+
+FAIL:
+    POP_KEEP_REFS
+    return ok;
+}
+
+static void DoneShared (ClientData cd) {
+    Shared_p sh = (Shared_p) cd;
+    if (--sh->refs == 0)
+        free(sh->info);
+}
+
+static void InitShared (void) {
+    Shared_p sh = GetShared();
+    if (sh->refs++ == 0)
+        sh->info = calloc(1, sizeof(SharedInfo));
+    UngetShared(DoneShared, (ClientData) sh);
+}
+
+DLLEXPORT int Vlerq_Init (Tcl_Interp *interp) {
+    if (!MyInitStubs(interp) || Tcl_PkgRequire(interp, "Tcl", "8.4", 0) == NULL)
+        return TCL_ERROR;
+
+    Tcl_CreateObjCommand(interp, "vlerq", VlerqObjCmd, f_commands, NULL);
+    InitShared();
+    return Tcl_PkgProvide(interp, "vlerq", PACKAGE_VERSION);
+}
+
+DLLEXPORT int Vlerq_SafeInit (Tcl_Interp *interp) {
+    if (!MyInitStubs(interp) || Tcl_PkgRequire(interp, "Tcl", "8.4", 0) == NULL)
+        return TCL_ERROR;
+
+    /* UNSAFE is defined in the "opdefs_gen.h" file included above */
+    Tcl_CreateObjCommand(interp, "vlerq", VlerqObjCmd, f_commands + UNSAFE,
+                                                                        NULL);
+    InitShared();
+    return Tcl_PkgProvide(interp, "vlerq", PACKAGE_VERSION);
+}
+
+/* end of generated code */
diff --git a/8.x/vqtcl/library/m2mvfs.tcl b/8.x/vqtcl/library/m2mvfs.tcl
new file mode 100644 (file)
index 0000000..2d59df6
--- /dev/null
@@ -0,0 +1,236 @@
+# m2mvfs.tcl -- In-memory VFS which appends its data as a MK starkit when done.
+
+# This VFS driver collects data in memory which then gets saved to a Metakit
+# data file when unmounted, using vlerq calls.  Does not support deletions,
+# renames, and such.  Can only be used with a single mountpoint at a time.
+#
+# 1.4 adjusted for vlerq 3
+# 1.5 fixed to actually work
+# 1.6 minor cleanup
+# 1.7 adjusted for vlerq 4
+# 1.8 allow overwriting files
+
+package provide vfs::m2m 1.8
+
+package require vfs
+package require vlerq
+
+namespace eval vfs::m2m {
+    namespace eval v {
+        variable outfn   ;# output file name
+        # following lists are all indexed by the same directory ordinal number
+        variable dname   ;# list of directory names
+        variable prows   ;# list of parent row numbers
+        variable files   ;# list of list of (name size date contents) tuples
+    }
+
+# public
+
+    proc Mount {mkfile local args} {
+        set v::outfn [file normalize $mkfile]
+        set v::dname [list <root>]
+        set v::prows [list -1]
+        set v::files [list {}]
+        ::vfs::filesystem mount $local [list ::vfs::m2m::handler -]
+        ::vfs::RegisterMount $local [list ::vfs::m2m::Unmount -]
+        return m2m
+    }
+
+    proc Unmount {db local} {
+        ::vfs::filesystem unmount $local
+        if {$v::outfn ne ""} {
+            set fd [::open $v::outfn a]
+            vlerq write [makeDirsView] $fd
+            ::close $fd
+        }
+        unset v::outfn v::dname v::prows v::files
+    }
+
+# private
+
+    proc makeDirsView {} {
+        set d {}
+        foreach f $v::files {
+            set x [lsort -index 0 -unique $f]
+            lappend d [vlerq def {name size:I date:I contents:B} \
+                        [eval concat $x]]
+        }
+        set desc {name parent:I {files {name size:I date:I contents:B}}}
+        set dirs [vlerq data [vlerq mdef $desc] $v::dname $v::prows $d]
+        vlerq group $dirs {} dirs
+    }
+
+    proc handler {db cmd root path actual args} {
+        #puts [list M2M $db <$cmd> r: $root p: $path a: $actual $args]
+        switch $cmd {
+            matchindirectory { eval [linsert $args 0 $cmd $db $path $actual] }
+            fileattributes   { eval [linsert $args 0 $cmd $db $root $path] } 
+            default          { eval [linsert $args 0 $cmd $db $path] }
+        }
+    }
+
+    proc fail {code} {
+        ::vfs::filesystem posixerror $::vfs::posix($code)
+    }
+
+    proc lookUp {db path} {
+        set parent 0
+        if {$path ne "."} {
+            set elems [file split $path]
+            set remain [llength $elems]
+            foreach e $elems {
+                set r ""
+                foreach r [lsearch -exact -int -all $v::prows $parent] {
+                    if {$e eq [lindex $v::dname $r]} {
+                        set parent $r
+                        incr remain -1
+                        break
+                    }
+                }
+                if {$parent != $r} {
+                    if {$remain == 1} {
+                        set i [lsearch -exact \
+                                        [subFileNames [list ? ? $parent]] $e]
+                        if {$i >= 0} {
+                            # eval this 4-item result returns info about a file
+                            return [list lindex $v::files $parent $i]
+                        }
+                    }
+                    fail ENOENT
+                }
+            }
+        }
+        # evaluating this 3-item result returns the files subview
+        return [list lindex $v::files $parent]
+    }
+
+    proc isDir {tag} {
+        return [expr {[llength $tag] == 3}]
+    }
+
+    proc subDirNums {tag} {
+        lsearch -exact -int -all $v::prows [lindex $tag 2]
+    }
+
+    proc subFileNames {tag} {
+        set r {}
+        foreach x [lindex $v::files [lindex $tag 2]] { lappend r [lindex $x 0] }
+        return $r
+    }
+
+# methods
+
+    proc matchindirectory {db path actual pattern type} {
+        set o {}
+        if {$type == 0} { set type 20 }
+        set tag [lookUp $db $path]
+        if {$pattern ne ""} {
+            set c {}
+            if {[isDir $tag]} {
+                if {$type & 16} {
+                    set c [subFileNames $tag]
+                }
+                if {$type & 4} {
+                    foreach r [subDirNums $tag] {
+                        lappend c [lindex $v::dname $r]
+                    }
+                }
+            }
+            foreach x $c {
+                if {[string match $pattern $x]} {
+                    lappend o [file join $actual $x]
+                }
+            }
+        } elseif {$type & ([isDir $tag]?4:16)} {
+            set o [list $actual]
+        }
+        return $o
+    }
+
+    proc fileattributes {db root path args} {
+        switch -- [llength $args] {
+            0 { return [::vfs::listAttributes] }
+            1 { return [eval [linsert $args 0 \
+                                        ::vfs::attributesGet $root $path]] }
+            2 { return [eval [linsert $args 0 \
+                                        ::vfs::attributesSet $root $path]] }
+        }
+    }
+
+    proc open {db file mode permissions} {
+        switch -- $mode {
+            "" - r {
+                set tag [lookUp $db $file]
+                if {[isDir $tag]} { fail ENOENT }
+                foreach {name size date contents} [eval $tag] break
+                if {[string length $contents] != $size} {
+                    set contents [vfs::zip -mode decompress $contents]
+                }
+                set fd [vfs::memchan]
+                fconfigure $fd -translation binary
+                puts -nonewline $fd $contents
+                fconfigure $fd -translation auto
+                seek $fd 0
+                return [list $fd]
+            }
+            w { ;# make sure the parent dir exists and create empty
+                set tag [lookUp $db [file dirname $file]]
+                set dpos [lindex $tag 2]
+                set curr [lindex $v::files $dpos]
+                set fpos [llength $curr]
+                lappend curr [list [file tail $file] 0 [clock seconds] ""]
+                lset v::files $dpos $curr
+                set fd [vfs::memchan]
+                return [list $fd [list ::vfs::m2m::doClose $db $dpos $fpos $fd]]
+            }
+            default { error "unsupported access mode: $mode" }
+        }
+    }
+
+    proc doClose {db dpos fpos fd} {
+        fconfigure $fd -translation binary
+        seek $fd 0
+        set d [read $fd]
+        set n [string length $d]
+        set z [vfs::zip -mode compress $d]
+        if {[string length $z] < $n} { set d $z }
+        lset v::files $dpos $fpos 1 $n
+        lset v::files $dpos $fpos 3 $d
+    }
+
+    proc access {db path mode} {
+        lookUp $db $path
+    }
+
+    proc stat {db path} {
+        set tag [lookUp $db $path]
+        set l 1
+        if {[isDir $tag]} {
+            set t directory
+            set s 0
+            set d 0
+            set c ""
+            incr l [llength [subFileNames $tag]]
+            incr l [llength [subDirNums $tag]]
+        } else {
+            set t file
+            foreach {n s d c} [eval $tag] break
+        }
+        return [list type $t size $s atime $d ctime $d mtime $d nlink $l \
+            csize [string length $c] gid 0 uid 0 ino 0 mode 0777]
+    }
+
+    proc createdirectory {db path} {
+        set tag [lookUp $db [file dirname $path]]
+        lappend v::dname [file tail $path]
+        lappend v::prows [lindex $tag 2]
+        lappend v::files {}
+    }
+
+    proc utime {db path atime mtime} {
+        set tag [lookUp $db $path]
+        if {![isDir $tag]} {
+            lset v::files [lindex $tag 2] [lindex $tag 3] 2 $mtime
+        }
+    }
+}
diff --git a/8.x/vqtcl/library/mkclvfs.tcl b/8.x/vqtcl/library/mkclvfs.tcl
new file mode 100644 (file)
index 0000000..467bcba
--- /dev/null
@@ -0,0 +1,181 @@
+# mkclvfs.tcl -- Metakit Compatibility Layer Virtual File System driver
+# Rewritten from mk4vfs.tcl, orig by Matt Newman and Jean-Claude Wippler 
+
+# 1.0 initial release
+# 1.1 view size renamed to count
+# 1.2 replace view calls by vget (simpler and faster)
+# 1.3 modified to use the vlerq extension i.s.o. thrive
+# 1.4 minor cleanup
+# 1.5 adjusted for vlerq 4
+
+package provide vfs::mkcl 1.5
+
+package require vfs
+package require vlerq
+
+namespace eval ::vfs::mkcl {
+    interp alias {} ::vfs::mkcl::vopen {} ::vlerq open
+    interp alias {} ::vfs::mkcl::vget {} ::vlerq get
+        
+    namespace eval v {
+        variable seq 0  ;# used to generate a unique db handle
+        variable rootv  ;# maps handle to the "dirs" root view
+        variable dname  ;# maps handle to cached list of directory names
+        variable prows  ;# maps handle to cached list of parent row numbers
+    }
+
+# public
+
+    proc Mount {mkfile local args} {
+        set db mkclvfs[incr v::seq]
+        set v::rootv($db) [vget [vopen $mkfile] 0 dirs]
+        set v::dname($db) [vget $v::rootv($db) * name]
+        set v::prows($db) [vget $v::rootv($db) * parent]
+        #parray v::dname
+        #parray v::prows
+        ::vfs::filesystem mount $local [list ::vfs::mkcl::handler $db]
+        ::vfs::RegisterMount $local [list ::vfs::mkcl::Unmount $db]
+        return $db
+    }
+    
+    proc Unmount {db local} {
+        ::vfs::filesystem unmount $local
+        unset v::rootv($db) v::dname($db) v::prows($db)
+    }
+    
+# private
+
+    proc handler {db cmd root path actual args} {
+        #puts [list MKCL $db <$cmd> r: $root p: $path a: $actual $args]
+        switch $cmd {
+            matchindirectory { eval [linsert $args 0 $cmd $db $path $actual] }
+            fileattributes   { eval [linsert $args 0 $cmd $db $root $path] } 
+            default          { eval [linsert $args 0 $cmd $db $path] }
+        }
+    }
+    
+    proc fail {code} {
+        ::vfs::filesystem posixerror $::vfs::posix($code)
+    }
+    
+    proc lookUp {db path} {
+        set dirs $v::rootv($db)
+        set parent 0
+        set elems [file split $path]
+        set remain [llength $elems]
+        foreach e $elems {
+            set r ""
+            foreach r [lsearch -exact -int -all $v::prows($db) $parent] {
+                if {$e eq [lindex $v::dname($db) $r]} {
+                    set parent $r
+                    incr remain -1
+                    break
+                }
+            }
+            if {$parent != $r} {
+                if {$remain == 1} {
+                    set files [vget $dirs $parent files]
+                    set i [lsearch -exact [vget $files * name] $e]
+                    if {$i >= 0} {
+                        # eval this 3-item result returns the info about 1 file
+                        return [list vget $files $i]
+                    }
+                }
+                fail ENOENT
+            }
+        }
+        # evaluating this 4-item result returns the files subview
+        list vget $dirs $parent files
+    }
+    
+    proc isDir {tag} {
+        expr {[llength $tag] == 4}
+    }
+    
+    if {$::tcl_version eq "8.4"} {
+            proc apply {cmd args} { eval [concat $cmd $args] }
+    } else {
+            proc apply {cmd args} { {*}$cmd {*}$args }
+    }
+    
+# methods
+
+    proc matchindirectory {db path actual pattern type} {
+        set o {}
+        if {$type == 0} { set type 20 }
+        if {[catch {set tag [lookUp $db $path]} err]} { return {} }
+        if {$pattern ne ""} {
+            set c {}
+            if {[isDir $tag]} {
+                # collect file names
+                if {$type & 16} {
+                    set c [apply $tag * 0]
+                }
+                # collect directory names
+                if {$type & 4} {
+                    foreach r [lsearch -exact -int -all $v::prows($db) \
+                                                            [lindex $tag 2]] {
+                        lappend c [lindex $v::dname($db) $r]
+                    }
+                }
+            }
+            foreach x $c {
+                if {[string match $pattern $x]} {
+                    lappend o [file join $actual $x]
+                }
+            }
+        } elseif {$type & ([isDir $tag]?4:16)} {
+            set o [list $actual]
+        }
+        return $o
+    }
+    
+    proc fileattributes {db root path args} {
+        switch -- [llength $args] {
+            0 { return [::vfs::listAttributes] }
+            1 { set index [lindex $args 0]
+                    return [::vfs::attributesGet $root $path $index] }
+            2 { fail EROFS }
+        }
+    }
+    
+    proc open {db file mode permissions} {
+        if {$mode ne "" && $mode ne "r"} { fail EROFS }
+        set tag [lookUp $db $file]
+        if {[isDir $tag]} { fail ENOENT }
+        foreach {name size date contents} [apply $tag *] break
+        if {[string length $contents] != $size} {
+            set contents [::vfs::zip -mode decompress $contents]
+        }
+        set fd [::vfs::memchan]
+        fconfigure $fd -translation binary
+        puts -nonewline $fd $contents
+        fconfigure $fd -translation auto -encoding [encoding system]
+        seek $fd 0
+        list $fd
+    }
+    
+    proc access {db path mode} {
+        if {$mode & 2} { fail EROFS }
+        lookUp $db $path
+    }
+    
+    proc stat {db path} {
+        set tag [lookUp $db $path]
+        set l 1
+        if {[isDir $tag]} {
+            set t directory
+            set s 0
+            set d 0
+            set c ""
+            incr l [apply $tag #]
+            incr l [llength [lsearch -exact -int -all $v::prows($db) \
+                                                        [lindex $tag 2]]]
+        } else {
+            set t file
+            foreach {n s d c} [apply $tag *] break
+        }
+        list type $t size $s atime $d ctime $d mtime $d nlink $l \
+                    csize [string length $c] gid 0 uid 0 ino 0 mode 0777
+    }
+}
diff --git a/8.x/vqtcl/library/mklite.tcl b/8.x/vqtcl/library/mklite.tcl
new file mode 100644 (file)
index 0000000..4c09f70
--- /dev/null
@@ -0,0 +1,271 @@
+# mklite.tcl -- Compatibility layer for Metakit
+
+# 0.3 modified to use the vlerq extension i.s.o. thrive
+# 0.4 adjusted for vlerq 4
+# 0.5 support "mk::file open" (no other args) and more mk::select options
+
+package provide mklite 0.5
+
+package require vlerq
+
+namespace eval mklite {
+    variable mkdb   ;# the mkdb array maps open db handles to view references
+
+# call emulateMk4tcl to define compatibility aliases in a specific namespace
+# if the MKLITE_DEBUG env var is defined, all calls and returns will be traced
+
+    proc emulateMk4tcl {{ns ::mk}} {
+        foreach x {channel cursor file get loop select view} {
+            # NOTE: clobbers existing mk::* cmds, may want to rename 'em first?
+            if {[info exists ::env(MKLITE_DEBUG)]} {
+                interp alias {} ${ns}::$x {} ::mklite::debug ::mklite::$x
+            } else {
+                interp alias {} ${ns}::$x {} ::mklite::$x
+            }
+        }
+    }
+
+    proc debug {args} {
+        puts ">>> [list $args]"
+        set r [uplevel 1 $args]
+        set s [regsub -all {[^ -~]} $r ?]
+        puts " << [string length $r]: [string range $s 0 49]"
+        return $r
+    }
+
+    proc mk_obj {path} {
+        variable mkdb
+        # memoize last result (without row number), it's likely to be used again
+        set pre [regsub {!\d+$} $path {}]
+        if {$mkdb(?) eq $pre} { return $mkdb(:) }
+        set n 0
+        foreach {x y} [regsub -all {[:.!]} :$path { & }] {
+            switch -- $x {
+                : { set r $mkdb($y) }
+                ! { set n $y }
+                . { if {[catch { vlerq get $r $n $y } r]} { return 0 } }
+            }
+        }
+        set mkdb(?) $pre
+        set mkdb(:) $r
+        return $r
+    }
+
+# partial emulation of the mk::* commands
+
+    proc file {cmd args} {
+        variable mkdb
+        variable mkpath
+        set db [lindex $args 0]
+        if {$db eq ""} { return [array get mkpath] }
+        set file [lindex $args 1]
+        switch $cmd {
+            open {
+                set mkdb(?) ""
+                if {$file ne ""} {
+                    set mkdb($db) [vlerq open $file]
+                } else {
+                    set mkdb($db) 0
+                }
+                set mkpath($db) $file
+                return $db 
+            }
+            load {
+                fconfigure $file -translation binary
+                set mkdb($db) [vlerq load [read $file]]
+                return $db 
+            }
+            close {
+                set mkdb(?) ""
+                unset mkdb($db) mkpath($db)
+                return 
+            }
+            views {
+                return [vlerq get $mkdb($db) @ * 0]
+            }
+        }
+        error "mkfile $cmd?"
+    }
+
+    proc view {cmd path args} {
+        set a1 [lindex $args 0]
+        switch $cmd {
+            info {
+                return [vlerq get [mk_obj $path] @ * 0]
+            }
+            layout {
+                set layout "NOTYET"
+                if {[llength $args] > 0 && $layout != $a1} {
+                    #error "view restructuring not supported"
+                }
+                return $layout
+            }
+            size {
+                set len [vlerq get [mk_obj $path] #]
+                if {[llength $args] > 0 && $len != $a1} {
+                    error "view resizing not supported"
+                }
+                return $len
+            }
+            default { error "mkview $cmd?" }
+        }
+    }
+
+    proc cursor {cmd cursor args} {
+        upvar $cursor v
+        switch $cmd {
+            create {
+                NOTYET
+            }
+            incr {
+                NOTYET
+            }
+            pos -
+            position {
+                if {$args != ""} {
+                    unset v
+                    regsub {!-?\d+$} $v {} v
+                    append v !$args
+                    return $args
+                }
+                if {![regexp {\d+$} $v n]} {
+                    set n -1
+                }
+                return $n
+            }
+            default { error "mkcursor $cmd?" }
+        }
+    }
+
+    proc get {path args} {
+        set vw [mk_obj $path]
+        set row [regsub {^.*!} $path {}]
+        set sized 0
+        if {[lindex $args 0] eq "-size"} {
+            incr sized
+            set args [lrange $args 1 end]
+        }
+        set ids 0
+        if {[llength $args] == 0} {
+            incr ids
+            set args [vlerq get $vw @ * 0]
+        }
+        set r {}
+        foreach x $args {
+            if {$ids} { lappend r $x }
+            set v [vlerq get $vw $row $x]
+            if {$sized} { set v [string length $v] }
+            lappend r $v
+        }
+        if {[llength $args] == 1} { set r [lindex $r 0] }
+        return $r
+    }
+
+    proc loop {cursor path args} {
+        upvar $cursor v
+        #unset -nocomplain v ;# avoids errors if v already exists as array
+        if {[llength $args] == 0} {
+            set args [list $path]
+            set path $v
+            regsub {!-?\d+$} $path {} path
+        }
+        set first [lindex $args 0]
+        set last [lindex $args 1]
+        switch [llength $args] {
+            1 { set first 0
+                    set limit [vlerq get [mk_obj $path] #]
+                    set step 1 }
+            2 { set limit [vlerq get [mk_obj $path] #]
+                    set step 1 }
+            3 { set step 1 }
+            4 { set step [lindex $args 2] }
+            default { error "mkloop arg count?" }
+        }
+        set body [lindex $args end]
+        set code 0
+        for {set i $first} {$i < $limit} {incr i $step} {
+            set v $path!$i
+            set code [catch [list uplevel 1 $body] err]
+            switch $code {
+                1 -
+                2 { return -code $code $err }
+                3 { break }
+            }
+        }
+    }
+
+    # from http://wiki.tcl.tk/43
+    proc _lreverse L {
+         set res {}
+         set i [llength $L]
+         #while {[incr i -1]>=0} {lappend res [lindex $L $i]}
+         while {$i} {lappend res [lindex $L [incr i -1]]} ;# rmax
+         set res
+    } ;# RS, tuned 10% faster by [rmax]
+
+    proc select {path args} {
+        set vw [mk_obj $path]
+        set n [vlerq get $vw #]
+        set r {}
+        for {set i 0} {$i < $n} {incr i} { lappend r $i }
+        set n [llength $args]
+        set sorts {}
+        for {set i 0} {$i < $n} {incr i} {
+            set match std
+            switch -- [lindex $args $i] {
+                -sort    { lappend sorts [lindex $args [incr i]]; continue }
+                -rsort   { lappend sorts - [lindex $args [incr i]]; continue }
+                -first   { set first [lindex $args [incr i]]; continue }
+                -count   { set count [lindex $args [incr i]]; continue }
+                -glob    { set match glob; incr i }
+                -globnc  { set match globnc; incr i }
+                -keyword { set match keyword; incr i }
+            }
+            set cols [lindex $args $i]
+            set k [lindex $args [incr i]]
+            set kwre "\\m$k"
+            # could use loop -collect, might be faster
+            set r2 {}
+            foreach x $r {
+                foreach c $cols {
+                    set v [vlerq get $vw $x $c]
+                    switch $match {
+                        glob    { set ok [string match $k $v] }
+                        globnc  { set ok [string match -nocase $k $v] }
+                        keyword { set ok [regexp -nocase $kwre $v] }
+                        default { set ok [expr {$k eq $v}] }
+                    }
+                    if {$ok} { lappend r2 $x; break }
+                }
+            }
+            set r $r2
+        }
+        if {[llength $sorts]} {
+            foreach x [_lreverse $sorts] {
+                if {$x eq "-"} {
+                    set r [_lreverse $r]
+                } else {
+                    set v [vlerq remap [vlerq tag [vlerq colmap $vw $x] N] $r]
+                    set r [vlerq get [vlerq sort $v] * N]
+                }
+            }
+        }
+        if {[info exists first]} {
+            set r [lrange $r $first end]
+        }
+        if {[info exists count]} {
+            set r [lrange $r 0 [incr count -1]]
+        }
+        return $r
+    }
+
+    proc channel {path name mode} {
+        package require vfs ;# TODO: needs vfs, could use "chan create" in 8.5
+        if {$mode ne "r"} { error "mkchannel? mode $mode" }
+        set fd [vfs::memchan]
+        fconfigure $fd -translation binary
+        puts -nonewline $fd [get $path $name]
+        seek $fd 0
+        return $fd
+    }
+}
diff --git a/8.x/vqtcl/library/ratcl.tcl b/8.x/vqtcl/library/ratcl.tcl
new file mode 100644 (file)
index 0000000..f6b3cd5
--- /dev/null
@@ -0,0 +1,230 @@
+# ratcl.tcl -- Relational algebra ond other utility operators for vlerq
+
+package provide ratcl 4
+package require vlerq 4
+
+namespace eval vlerq {}
+interp alias {} view {} vlerq view
+
+namespace eval ratcl {
+    namespace export vopdef
+    
+    proc vopdef {name params body} {
+        proc ::vlerq::$name $params $body
+    }
+
+    vopdef as        {v cmd}  { interp alias {} $cmd {} view $v; return $cmd }
+    vopdef asview    {l args} { vlerq def $args $l }
+    vopdef collect   {v expr} { uplevel 1 [list view $v loop -collect $expr] }
+    vopdef freeze    {v}      { view $v emit | load }
+    vopdef index     {v cond} { uplevel 1 [list view $v loop -index $cond] }
+    vopdef pick      {v n}    { view $v where {[lindex $n $(#)] != 0} }
+    vopdef project   {v args} { view $v colmap $args | unique }
+    vopdef use       {v w}    { return $w }
+    vopdef where     {v cond} { uplevel 1 [list view $v loop -where $cond] }
+
+    vopdef do {w cmds} {
+        upvar 1 _v v
+        set v $w
+        set x ""
+        foreach c [split $cmds \n] {
+            append x $c "\n                     "
+            if {![info complete $x]} continue
+            set x [string trim $x]
+            regsub {^#.*} $x {} x
+            if {$x eq ""} continue
+            set cm "view \$_v $x"
+            set v [uplevel 1 $cm]
+            set x ""
+        }
+        set w $v
+        unset v
+        return $w
+    }
+
+    vopdef debug {w cmds} {
+        upvar 1 _v v
+        set v $w
+        puts " rows-in  col  msec  view-operation"
+        puts " -------  ---  ----  --------------"
+        set x ""
+        set w "                                   "
+        foreach c [split $cmds \n] {
+            append x $c \n $w
+            if {![info complete $x]} continue
+            set x [string trim $x]
+            if {[regexp {^#} $x]} {
+                puts [format {%20s %.58s} "" $x]
+                set x ""
+            }
+            switch -- $x {
+                "" { }
+                ?    { puts "$w ?\n[view $v dump]" }
+                default {
+                    if {[catch { view $v size } nr]} { set nr "" }
+                    if {[catch { view $v width } nc]} { set nc "" }
+                    set cm "view \$_v $x"
+                    set us [lindex [time {
+                        set v [uplevel 1 $cm]
+                        catch {view $v size}
+                    }] 0]
+                    puts [format {%8s %4s %5.0f  %s} \
+                                    $nr $nc [expr {$us/1000.0}] $x]
+                }
+            }
+            set x ""
+        }
+        if {[catch { view $v size } nr]} { set nr " -------" }
+        if {[catch { view $v width } nc]} { set nc " ---" }
+        puts [format {%8s %4s  ----  --------------} $nr $nc]
+        set w $v
+        unset v
+        return $w
+    }
+
+    vopdef dump {vid {maxrows 20}} {
+        set n [view $vid size]
+        if {[view $vid width] == 0} { return "  ($n rows, no columns)" }
+        set i -1
+        if {$n > $maxrows} { set vid [view $vid first $maxrows] }
+        foreach x [view $vid names] y [view $vid types] {
+            set v2 [view $vid onecol [incr i]]
+            switch $y {
+                B       { set s { "[string length $($x)]b" } }
+                V       { set s { "#[view $($x) size]" } }
+                default { set s { $($x) } }
+            }
+            set c [view $v2 collect $s]
+            set w [string length $x]
+            foreach z $c {
+                if {[string length $z] > $w} { set w [string length $z] }
+            }
+            if {$w > 50} { set w 50 }
+            switch $y {
+                B - I - L - F - D - V   { append fmt "  " %${w}s }
+                default                 { append fmt "  " %-$w.${w}s }
+            }
+            append hdr "  " [format %-${w}s $x]
+            append bar "  " [string repeat - $w]
+            lappend d $c
+        }
+        set r [list $hdr $bar]
+        for {set i 0} {$i < $n} {incr i} {
+            if {$i >= $maxrows} break
+            set cmd [list format $fmt]
+            foreach x $d { lappend cmd [regsub -all {[^ -~]} [lindex $x $i] .] }
+            lappend r [eval $cmd]
+        }
+        if {$i < $n} { lappend r [string map {- .} $bar] }
+        ::join $r \n
+    }
+
+    vopdef html {vid} {
+        set names [view $vid names]
+        set types [view $vid types]
+        set o <table>
+        append o {<style type="text/css"><!--\
+            tt table, pre table { border-spacing: 0; border: 1px solid #aaaaaa;\
+                                    margin: 0 0 2px 0 }\
+            th { background-color: #eeeeee; font-weight:normal }\
+            td { vertical-align: top }\
+            th, td { padding: 0 5px }\
+            th.row,td.row { color: #cccccc; font-size: 75% }\
+        --></style>}
+        append o \n {<tr><th class="row"></th>}
+        foreach x $names { append o <th><i> $x </i></th> }
+        append o </tr>\n
+        view $vid loop c {
+            append o {<tr><td align="right" class="row">} $c(#) </td>
+            set i -1
+            foreach x $names y $types val [view $vid get $c(#) *] {
+                switch $y {
+                    b - B   { set z [string length $val]b }
+                    v - V   { set z [view $val html] }
+                    default { 
+                        set z [string map {& &amp\; < &lt\; > &gt\;} $val] 
+                    }
+                }
+                switch $y {
+                    s - S - v - V { append o {<td>} }
+                    default { append o {<td align="right">} }
+                }
+                append o $z </td>
+            }
+            append o </tr>\n
+        }
+        append o </table>\n
+    }
+
+    vopdef transpose {v {p x}} {
+        set n [vlerq size $v]
+        foreach {pn pt} [split ${p}:S :] break
+        set m [view $v size | collect { "$pn$(#):$pt" }]
+        set c [view $v get @ | collect { [vlerq get $v * $(#)] }]
+        view $m def [eval [linsert $c 0 concat]]
+    }
+
+    vopdef freq {v i} {
+        set n [vlerq iota [vlerq width $v]]
+        llength $n ;# force $n to list, avoids assert in CastObjToItem, case 'n'
+        set g [vlerq group $v $n _]
+        view [vlerq colmap $g $n] pair [view ${i}:I def [vlerq counts $g _]]
+    }
+
+    vopdef sorton {v args} {
+        set n [view $v size]
+        if {[incr n -1] > 0} {
+            set dir +
+            set cols {}
+            # TODO: optimize, i.e. sort more at once and use faster reverse sort
+            foreach x $args {
+                switch -- $x {
+                    + - -       { set dir $x }
+                    default { set cols [linsert $cols 0 $dir $x ]}
+                }
+            }
+            foreach {dir col} $cols {
+                set c [view $v onecol $col]
+                if {$dir eq "-"} {
+                    set map [view $v onecol $col | reverse | sortmap | \
+                                    asview N:I | reverse | collect {$n-$(N)}]
+                } else {
+                    set map [view $c sortmap]
+                }
+                set v [view $v remap $map]
+            }
+        }
+        return $v
+    }
+
+    vopdef read {fd {data ""}} {
+        fconfigure $fd -translation binary
+        while {[string length $data] < 8} {
+            append data [::read $fd [expr {8 - [string length $data]}]]
+        }
+        binary scan $data a3cI hdr ext siz
+        switch -- $hdr {
+            "JL\x1A" - "LJ\x1A" {
+                if {$ext < 0} {
+                    set siz [expr {(($ext & 0x3F) << 36) + \
+                                    (($siz & 0xFFFFFFFF) << 4)}]
+                }
+            }
+            default { set siz -1 }
+        }
+        if {$siz < 0} {
+            while {![eof $fd]} {
+                append data [::read $fd]
+            }
+        } else {
+            incr siz -[string length $data]
+            while {$siz > 0} {
+                set more [::read $fd $siz]
+                append data $more
+                incr siz -[string length $more]
+            }
+            set more ""
+        }
+        vlerq load $data
+    }
+}
diff --git a/8.x/vqtcl/license.terms b/8.x/vqtcl/license.terms
new file mode 100644 (file)
index 0000000..9bd444f
--- /dev/null
@@ -0,0 +1,26 @@
+This software is copyrighted by Jean-Claude Wippler and Equi4 Software and others.
+The following terms apply to all files associated with the software
+unless explicitly disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
diff --git a/8.x/vqtcl/pkgIndex.tcl.in b/8.x/vqtcl/pkgIndex.tcl.in
new file mode 100644 (file)
index 0000000..cfc6e6f
--- /dev/null
@@ -0,0 +1,9 @@
+package ifneeded vlerq @PACKAGE_VERSION@ \
+  [list load [file join $dir lib@PACKAGE_NAME@@PACKAGE_VERSION@[info sharedlibext]] vlerq]
+
+package ifneeded ratcl @PACKAGE_VERSION@ \
+  [list source [file join $dir ratcl.tcl]]
+
+package ifneeded mklite    0.5 [list source [file join $dir mklite.tcl]]
+package ifneeded vfs::m2m  1.8 [list source [file join $dir m2mvfs.tcl]]
+package ifneeded vfs::mkcl 1.5 [list source [file join $dir mkclvfs.tcl]]
diff --git a/8.x/vqtcl/tclconfig/install-sh b/8.x/vqtcl/tclconfig/install-sh
new file mode 100755 (executable)
index 0000000..0ff4b6a
--- /dev/null
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+       echo "install:  no destination specified"
+       exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+       dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
diff --git a/8.x/vqtcl/tclconfig/tcl.m4 b/8.x/vqtcl/tclconfig/tcl.m4
new file mode 100644 (file)
index 0000000..175d86d
--- /dev/null
@@ -0,0 +1,4000 @@
+# tcl.m4 --
+#
+#      This file provides a set of autoconf macros to help TEA-enable
+#      a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: tcl.m4 7 2009-02-20 14:00:31Z patthoyts $
+
+AC_PREREQ(2.50)
+
+dnl TEA extensions pass us the version of TEA they think they
+dnl are compatible with (must be set in TEA_INIT below)
+dnl TEA_VERSION="3.5"
+
+# Possible values for key variables defined:
+#
+# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
+# TEA_PLATFORM        - windows unix
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+#      Locate the tclConfig.sh file and perform a sanity check on
+#      the Tcl compile flags
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tcl=...
+#
+#      Defines the following vars:
+#              TCL_BIN_DIR     Full path to the directory containing
+#                              the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+    #
+    # Ok, lets find the tcl configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tcl
+    #
+
+    if test x"${no_tcl}" = x ; then
+       # we reset no_tcl in case something fails here
+       no_tcl=true
+       AC_ARG_WITH(tcl,
+           AC_HELP_STRING([--with-tcl],
+               [directory containing tcl configuration (tclConfig.sh)]),
+           with_tclconfig=${withval})
+       AC_MSG_CHECKING([for Tcl configuration])
+       AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+           # First check to see if --with-tcl was specified.
+           if test x"${with_tclconfig}" != x ; then
+               case ${with_tclconfig} in
+                   */tclConfig.sh )
+                       if test -f ${with_tclconfig}; then
+                           AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+                           with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tclconfig}/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tcl installation
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ../tcl \
+                       `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tcl \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tcl \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tclConfig.sh" ; then
+                       ac_cv_c_tclconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tclconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tcl \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tclConfig.sh" ; then
+                   ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+                   break
+               fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tclconfig}" = x ; then
+           TCL_BIN_DIR="# no Tcl configs found"
+           AC_MSG_WARN([Can't find Tcl configuration definitions])
+           exit 0
+       else
+           no_tcl=
+           TCL_BIN_DIR=${ac_cv_c_tclconfig}
+           AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+#      Locate the tkConfig.sh file
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-tk=...
+#
+#      Defines the following vars:
+#              TK_BIN_DIR      Full path to the directory containing
+#                              the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+    #
+    # Ok, lets find the tk configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-tk
+    #
+
+    if test x"${no_tk}" = x ; then
+       # we reset no_tk in case something fails here
+       no_tk=true
+       AC_ARG_WITH(tk,
+           AC_HELP_STRING([--with-tk],
+               [directory containing tk configuration (tkConfig.sh)]),
+           with_tkconfig=${withval})
+       AC_MSG_CHECKING([for Tk configuration])
+       AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+           # First check to see if --with-tkconfig was specified.
+           if test x"${with_tkconfig}" != x ; then
+               case ${with_tkconfig} in
+                   */tkConfig.sh )
+                       if test -f ${with_tkconfig}; then
+                           AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+                           with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'`
+                       fi ;;
+               esac
+               if test -f "${with_tkconfig}/tkConfig.sh" ; then
+                   ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+               fi
+           fi
+
+           # then check for a private Tk library
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ../tk \
+                       `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../tk \
+                       `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../tk \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Darwin, check in Framework installation locations
+           if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+                       `ls -d /Library/Frameworks 2>/dev/null` \
+                       `ls -d /Network/Library/Frameworks 2>/dev/null` \
+                       `ls -d /System/Library/Frameworks 2>/dev/null` \
+                       ; do
+                   if test -f "$i/Tk.framework/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # on Windows, check in common installation locations
+           if test "${TEA_PLATFORM}" = "windows" \
+               -a x"${ac_cv_c_tkconfig}" = x ; then
+               for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+                       `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few other private locations
+           if test x"${ac_cv_c_tkconfig}" = x ; then
+               for i in \
+                       ${srcdir}/../tk \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+                   if test -f "$i/unix/tkConfig.sh" ; then
+                       ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_tkconfig}" = x ; then
+           TK_BIN_DIR="# no Tk configs found"
+           AC_MSG_WARN([Can't find Tk configuration definitions])
+           exit 0
+       else
+           no_tk=
+           TK_BIN_DIR=${ac_cv_c_tkconfig}
+           AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+#      Load the tclConfig.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              TCL_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              TCL_BIN_DIR
+#              TCL_SRC_DIR
+#              TCL_LIB_FILE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . ${TCL_BIN_DIR}/tclConfig.sh
+    else
+        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+    # If the TCL_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TCL_LIB_SPEC will be set to the value
+    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f ${TCL_BIN_DIR}/Makefile ; then
+        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
+        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
+        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tcl was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tcl.framework installed in an arbitary location.
+       case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -f ${TCL_BIN_DIR}/${TCL_LIB_FILE}; then
+                   for i in "`cd ${TCL_BIN_DIR}; pwd`" \
+                            "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+                           TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}; then
+                   TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
+                   TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TCL_DBGX substitution
+    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+    AC_SUBST(TCL_VERSION)
+    AC_SUBST(TCL_BIN_DIR)
+    AC_SUBST(TCL_SRC_DIR)
+
+    AC_SUBST(TCL_LIB_FILE)
+    AC_SUBST(TCL_LIB_FLAG)
+    AC_SUBST(TCL_LIB_SPEC)
+
+    AC_SUBST(TCL_STUB_LIB_FILE)
+    AC_SUBST(TCL_STUB_LIB_FLAG)
+    AC_SUBST(TCL_STUB_LIB_SPEC)
+
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(TCL_DEFS)
+    AC_SUBST(TCL_EXTRA_CFLAGS)
+    AC_SUBST(TCL_LD_FLAGS)
+    AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+#      Load the tkConfig.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              TK_BIN_DIR
+#
+# Results:
+#
+#      Sets the following vars that should be in tkConfig.sh:
+#              TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+        AC_MSG_RESULT([loading])
+       . ${TK_BIN_DIR}/tkConfig.sh
+    else
+        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+    # If the TK_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable TK_LIB_SPEC will be set to the value
+    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+    # instead of TK_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    if test -f ${TK_BIN_DIR}/Makefile ; then
+        TK_LIB_SPEC=${TK_BUILD_LIB_SPEC}
+        TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC}
+        TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH}
+    elif test "`uname -s`" = "Darwin"; then
+       # If Tk was built as a framework, attempt to use the libraries
+       # from the framework at the given location so that linking works
+       # against Tk.framework installed in an arbitary location.
+       case ${TK_DEFS} in
+           *TK_FRAMEWORK*)
+               if test -f ${TK_BIN_DIR}/${TK_LIB_FILE}; then
+                   for i in "`cd ${TK_BIN_DIR}; pwd`" \
+                            "`cd ${TK_BIN_DIR}/../..; pwd`"; do
+                       if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+                           TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}"
+                           break
+                       fi
+                   done
+               fi
+               if test -f ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}; then
+                   TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}"
+                   TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+               fi
+               ;;
+       esac
+    fi
+
+    # eval is required to do the TK_DBGX substitution
+    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+    # Ensure windowingsystem is defined
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       case ${TK_DEFS} in
+           *MAC_OSX_TK*)
+               AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+               TEA_WINDOWINGSYSTEM="aqua"
+               ;;
+           *)
+               TEA_WINDOWINGSYSTEM="x11"
+               ;;
+       esac
+    elif test "${TEA_PLATFORM}" = "windows" ; then
+       TEA_WINDOWINGSYSTEM="win32"
+    fi
+
+    AC_SUBST(TK_VERSION)
+    AC_SUBST(TK_BIN_DIR)
+    AC_SUBST(TK_SRC_DIR)
+
+    AC_SUBST(TK_LIB_FILE)
+    AC_SUBST(TK_LIB_FLAG)
+    AC_SUBST(TK_LIB_SPEC)
+
+    AC_SUBST(TK_STUB_LIB_FILE)
+    AC_SUBST(TK_STUB_LIB_FLAG)
+    AC_SUBST(TK_STUB_LIB_SPEC)
+
+    AC_SUBST(TK_LIBS)
+    AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+#      Allows the building of shared libraries
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-shared=yes|no
+#
+#      Defines the following vars:
+#              STATIC_BUILD    Used for building import/export libraries
+#                              on Windows.
+#
+#      Sets the following vars:
+#              SHARED_BUILD    Value of 1 or 0
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SHARED], [
+    AC_MSG_CHECKING([how to build libraries])
+    AC_ARG_ENABLE(shared,
+       AC_HELP_STRING([--enable-shared],
+           [build and link with shared libraries (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_shared+set}" = set; then
+       enableval="$enable_shared"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" ; then
+       AC_MSG_RESULT([shared])
+       SHARED_BUILD=1
+    else
+       AC_MSG_RESULT([static])
+       SHARED_BUILD=0
+       AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
+    fi
+    AC_SUBST(SHARED_BUILD)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+#      Specify if thread support should be enabled.  If "yes" is specified
+#      as an arg (optional), threads are enabled by default, "no" means
+#      threads are disabled.  "yes" is the default.
+#
+#      TCL_THREADS is checked so that if you are compiling an extension
+#      against a threaded core, your extension must be compiled threaded
+#      as well.
+#
+#      Note that it is legal to have a thread enabled extension run in a
+#      threaded or non-threaded Tcl core, but a non-threaded extension may
+#      only run in a non-threaded Tcl core.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-threads
+#
+#      Sets the following vars:
+#              THREADS_LIBS    Thread library(s)
+#
+#      Defines the following vars:
+#              TCL_THREADS
+#              _REENTRANT
+#              _THREAD_SAFE
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+    AC_ARG_ENABLE(threads,
+       AC_HELP_STRING([--enable-threads],
+           [build with threads]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+
+    if test "${enable_threads+set}" = set; then
+       enableval="$enable_threads"
+       tcl_ok=$enableval
+    else
+       tcl_ok=yes
+    fi
+
+    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+       TCL_THREADS=1
+
+       if test "${TEA_PLATFORM}" != "windows" ; then
+           # We are always OK on Windows, so check what this platform wants:
+    
+           # USE_THREAD_ALLOC tells us to try the special thread-based
+           # allocator that significantly reduces lock contention
+           AC_DEFINE(USE_THREAD_ALLOC, 1,
+               [Do we want to use the threaded memory allocator?])
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           if test "`uname -s`" = "SunOS" ; then
+               AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+                       [Do we really want to follow the standard? Yes we do!])
+           fi
+           AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+           AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+           if test "$tcl_ok" = "no"; then
+               # Check a little harder for __pthread_mutex_init in the same
+               # library, as some systems hide it there until pthread.h is
+               # defined.  We could alternatively do an AC_TRY_COMPILE with
+               # pthread.h, but that will work with libpthread really doesn't
+               # exist, like AIX 4.2.  [Bug: 4359]
+               AC_CHECK_LIB(pthread, __pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+           fi
+
+           if test "$tcl_ok" = "yes"; then
+               # The space is needed
+               THREADS_LIBS=" -lpthread"
+           else
+               AC_CHECK_LIB(pthreads, pthread_mutex_init,
+                   tcl_ok=yes, tcl_ok=no)
+               if test "$tcl_ok" = "yes"; then
+                   # The space is needed
+                   THREADS_LIBS=" -lpthreads"
+               else
+                   AC_CHECK_LIB(c, pthread_mutex_init,
+                       tcl_ok=yes, tcl_ok=no)
+                   if test "$tcl_ok" = "no"; then
+                       AC_CHECK_LIB(c_r, pthread_mutex_init,
+                           tcl_ok=yes, tcl_ok=no)
+                       if test "$tcl_ok" = "yes"; then
+                           # The space is needed
+                           THREADS_LIBS=" -pthread"
+                       else
+                           TCL_THREADS=0
+                           AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+                       fi
+                   fi
+               fi
+           fi
+       fi
+    else
+       TCL_THREADS=0
+    fi
+    # Do checking message here to not mess up interleaved configure output
+    AC_MSG_CHECKING([for building with threads])
+    if test "${TCL_THREADS}" = 1; then
+       AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+       AC_MSG_RESULT([yes (default)])
+    else
+       AC_MSG_RESULT([no])
+    fi
+    # TCL_THREADS sanity checking.  See if our request for building with
+    # threads is the same as the way Tcl was built.  If not, warn the user.
+    case ${TCL_DEFS} in
+       *THREADS=1*)
+           if test "${TCL_THREADS}" = "0"; then
+               AC_MSG_WARN([
+    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+    that IS thread-enabled.  It is recommended to use --enable-threads.])
+           fi
+           ;;
+       *)
+           if test "${TCL_THREADS}" = "1"; then
+               AC_MSG_WARN([
+    --enable-threads requested, but building against a Tcl that is NOT
+    thread-enabled.  This is an OK configuration that will also run in
+    a thread-enabled core.])
+           fi
+           ;;
+    esac
+    AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+#      Specify if debugging symbols should be used.
+#      Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+#      none
+#      
+#      TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+#      the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+#      Requires the following vars to be set in the Makefile:
+#              CFLAGS_DEFAULT
+#              LDFLAGS_DEFAULT
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-symbols
+#
+#      Defines the following vars:
+#              CFLAGS_DEFAULT  Sets to $(CFLAGS_DEBUG) if true
+#                              Sets to $(CFLAGS_OPTIMIZE) if false
+#              LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+#                              Sets to $(LDFLAGS_OPTIMIZE) if false
+#              DBGX            Formerly used as debug library extension;
+#                              always blank now.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_CONFIG_CFLAGS])
+    AC_MSG_CHECKING([for build with symbols])
+    AC_ARG_ENABLE(symbols,
+       AC_HELP_STRING([--enable-symbols],
+           [build with debugging symbols (default: off)]),
+       [tcl_ok=$enableval], [tcl_ok=no])
+    DBGX=""
+    if test "$tcl_ok" = "no"; then
+       CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
+       LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+       AC_MSG_RESULT([no])
+    else
+       CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+       LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+       if test "$tcl_ok" = "yes"; then
+           AC_MSG_RESULT([yes (standard debugging)])
+       fi
+    fi
+    if test "${TEA_PLATFORM}" != "windows" ; then
+       LDFLAGS_DEFAULT="${LDFLAGS}"
+    fi
+
+    AC_SUBST(TCL_DBGX)
+    AC_SUBST(CFLAGS_DEFAULT)
+    AC_SUBST(LDFLAGS_DEFAULT)
+
+    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+       AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+    fi
+
+    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+       if test "$tcl_ok" = "all"; then
+           AC_MSG_RESULT([enabled symbols mem debugging])
+       else
+           AC_MSG_RESULT([enabled $tcl_ok debugging])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+#      Allows use of modern nl_langinfo check for better l10n.
+#      This is only relevant for Unix.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --enable-langinfo=yes|no (default is yes)
+#
+#      Defines the following vars:
+#              HAVE_LANGINFO   Triggers use of nl_langinfo if defined.
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+    AC_ARG_ENABLE(langinfo,
+       AC_HELP_STRING([--enable-langinfo],
+           [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+       [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+    HAVE_LANGINFO=0
+    if test "$langinfo_ok" = "yes"; then
+       AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+    fi
+    AC_MSG_CHECKING([whether to use nl_langinfo])
+    if test "$langinfo_ok" = "yes"; then
+       AC_CACHE_VAL(tcl_cv_langinfo_h, [
+           AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+                   [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+       AC_MSG_RESULT([$tcl_cv_langinfo_h])
+       if test $tcl_cv_langinfo_h = yes; then
+           AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+       fi
+    else 
+       AC_MSG_RESULT([$langinfo_ok])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+#      Determine what the system is (some things cannot be easily checked
+#      on a feature-driven basis, alas). This can usually be done via the
+#      "uname" command, but there are a few systems, like Next, where
+#      this doesn't work.
+#
+# Arguments:
+#      none
+#
+# Results:
+#      Defines the following var:
+#
+#      system -        System/platform/version identification code.
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+       if test "${TEA_PLATFORM}" = "windows" ; then
+           tcl_cv_sys_version=windows
+       elif test -f /usr/lib/NextStep/software_version; then
+           tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+       else
+           tcl_cv_sys_version=`uname -s`-`uname -r`
+           if test "$?" -ne 0 ; then
+               AC_MSG_WARN([can't find uname command])
+               tcl_cv_sys_version=unknown
+           else
+               # Special check for weird MP-RAS system (uname returns weird
+               # results, and the version is kept in special file).
+
+               if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+                   tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
+               fi
+               if test "`uname -s`" = "AIX" ; then
+                   tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+               fi
+           fi
+       fi
+    ])
+    system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+#      Try to determine the proper flags to pass to the compiler
+#      for building shared libraries and other such nonsense.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substitutes the following vars:
+#
+#       DL_OBJS -       Name of the object file that implements dynamic
+#                       loading for Tcl on this system.
+#       DL_LIBS -       Library file(s) to include in tclsh and other base
+#                       applications in order for the "load" command to work.
+#       LDFLAGS -      Flags to pass to the compiler when linking object
+#                       files into an executable application binary such
+#                       as tclsh.
+#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
+#                       be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+#       CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+#                       that tell the run-time dynamic linker where to look
+#                       for shared libraries such as libtcl.so.  Depends on
+#                       the variable LIB_RUNTIME_DIR in the Makefile.
+#       SHLIB_CFLAGS -  Flags to pass to cc when compiling the components
+#                       of a shared library (may request position-independent
+#                       code, among other things).
+#       SHLIB_LD -      Base command to use for combining object files
+#                       into a shared library.
+#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+#                       creating shared libraries.  This symbol typically
+#                       goes at the end of the "ld" commands that build
+#                       shared libraries. The value of the symbol is
+#                       "${LIBS}" if all of the dependent libraries should
+#                       be specified when creating a shared library.  If
+#                       dependent libraries should not be specified (as on
+#                       SunOS 4.x, where they cause the link to fail, or in
+#                       general if Tcl and Tk aren't themselves shared
+#                       libraries), then this symbol has an empty string
+#                       as its value.
+#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
+#                       extensions.  An empty string means we don't know how
+#                       to use shared libraries on this platform.
+#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
+#                       in a static or shared library name, using the $VERSION variable
+#                       to put the version in the right place.  This is used
+#                       by platforms that need non-standard library names.
+#                       Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
+#                       to have a version after the .so, and ${VERSION}.a
+#                       on AIX, since a shared library needs to have
+#                       a .a extension whereas shared objects for loadable
+#                       extensions have a .so extension.  Defaults to
+#                       ${VERSION}${SHLIB_SUFFIX}.
+#       TCL_NEEDS_EXP_FILE -
+#                       1 means that an export file is needed to link to a
+#                       shared library.
+#       TCL_EXP_FILE -  The name of the installed export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#       TCL_BUILD_EXP_FILE -
+#                       The name of the built export / import file which
+#                       should be used to link to the Tcl shared library.
+#                       Empty if Tcl is unshared.
+#      CFLAGS_DEBUG -
+#                      Flags used when running the compiler in debug mode
+#      CFLAGS_OPTIMIZE -
+#                      Flags used when running the compiler in optimize mode
+#      CFLAGS -        Additional CFLAGS added as necessary (usually 64-bit)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+    dnl Make sure we are initialized
+    AC_REQUIRE([TEA_INIT])
+
+    # Step 0.a: Enable 64 bit support?
+
+    AC_MSG_CHECKING([if 64bit support is requested])
+    AC_ARG_ENABLE(64bit,
+       AC_HELP_STRING([--enable-64bit],
+           [enable 64bit support (default: off)]),
+       [do64bit=$enableval], [do64bit=no])
+    AC_MSG_RESULT([$do64bit])
+
+    # Step 0.b: Enable Solaris 64 bit VIS support?
+
+    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+    AC_ARG_ENABLE(64bit-vis,
+       AC_HELP_STRING([--enable-64bit-vis],
+           [enable 64bit Sparc VIS support (default: off)]),
+       [do64bitVIS=$enableval], [do64bitVIS=no])
+    AC_MSG_RESULT([$do64bitVIS])
+
+    if test "$do64bitVIS" = "yes"; then
+       # Force 64bit on with VIS
+       do64bit=yes
+    fi
+
+    # Step 0.c: Cross-compiling options for Windows/CE builds?
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       AC_MSG_CHECKING([if Windows/CE build is requested])
+       AC_ARG_ENABLE(wince,[  --enable-wince          enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no])
+       AC_MSG_RESULT([$doWince])
+    fi
+
+    # Step 1: set the variable "system" to hold the name and version number
+    # for the system.
+
+    TEA_CONFIG_SYSTEM
+
+    # Step 2: check for existence of -ldl library.  This is needed because
+    # Linux can use either -ldl or -ldld for dynamic loading.
+
+    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
+
+    # Require ranlib early so we can override it in special cases below.
+
+    AC_REQUIRE([AC_PROG_RANLIB])
+
+    # Step 3: set configuration options based on system name and version.
+    # This is similar to Tcl's unix/tcl.m4 except that we've added a
+    # "windows" case.
+
+    do64bit_ok=no
+    LDFLAGS_ORIG="$LDFLAGS"
+    # When ld needs options to work in 64-bit mode, put them in
+    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+    # is disabled by the user. [Bug 1016796]
+    LDFLAGS_ARCH=""
+    TCL_EXPORT_FILE_SUFFIX=""
+    UNSHARED_LIB_SUFFIX=""
+    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+    TCL_LIB_VERSIONS_OK=ok
+    CFLAGS_DEBUG=-g
+    CFLAGS_OPTIMIZE=-O
+    if test "$GCC" = "yes" ; then
+       CFLAGS_OPTIMIZE=-O2
+       CFLAGS_WARNING="-Wall -Wno-implicit-int"
+    else
+       CFLAGS_WARNING=""
+    fi
+    TCL_NEEDS_EXP_FILE=0
+    TCL_BUILD_EXP_FILE=""
+    TCL_EXP_FILE=""
+dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
+dnl AC_CHECK_TOOL(AR, ar)
+    AC_CHECK_PROG(AR, ar, ar)
+    STLIB_LD='${AR} cr'
+    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+    case $system in
+       windows)
+           # This is a 2-stage check to make sure we have the 64-bit SDK
+           # We have to know where the SDK is installed.
+           # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+           # MACHINE is IX86 for LINK, but this is used by the manifest,
+           # which requires x86|amd64|ia64.
+           MACHINE="X86"
+           if test "$do64bit" != "no" ; then
+               if test "x${MSSDK}x" = "xx" ; then
+                   MSSDK="C:/Progra~1/Microsoft Platform SDK"
+               fi
+               MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
+               PATH64=""
+               case "$do64bit" in
+                   amd64|x64|yes)
+                       MACHINE="AMD64" ; # default to AMD64 64-bit build
+                       PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+                       ;;
+                   ia64)
+                       MACHINE="IA64"
+                       PATH64="${MSSDK}/Bin/Win64"
+                       ;;
+               esac
+               if test ! -d "${PATH64}" ; then
+                   AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+                   AC_MSG_WARN([Ensure latest Platform SDK is installed])
+                   do64bit="no"
+               else
+                   AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
+                   do64bit_ok="yes"
+               fi
+           fi
+
+           if test "$doWince" != "no" ; then
+               if test "$do64bit" != "no" ; then
+                   AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+               fi
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+               fi
+               TEA_PATH_CELIB
+               # Set defaults for common evc4/PPC2003 setup
+               # Currently Tcl requires 300+, possibly 420+ for sockets
+               CEVERSION=420;          # could be 211 300 301 400 420 ...
+               TARGETCPU=ARMV4;        # could be ARMV4 ARM MIPS SH3 X86 ...
+               ARCH=ARM;               # could be ARM MIPS X86EM ...
+               PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+               if test "$doWince" != "yes"; then
+                   # If !yes then the user specified something
+                   # Reset ARCH to allow user to skip specifying it
+                   ARCH=
+                   eval `echo $doWince | awk -F, '{ \
+           if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+           if ([$]1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+           if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+           if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+           if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+                   }'`
+                   if test "x${ARCH}" = "x" ; then
+                       ARCH=$TARGETCPU;
+                   fi
+               fi
+               OSVERSION=WCE$CEVERSION;
+               if test "x${WCEROOT}" = "x" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+                   if test ! -d "${WCEROOT}" ; then
+                       WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+                   fi
+               fi
+               if test "x${SDKROOT}" = "x" ; then
+                   SDKROOT="C:/Program Files/Windows CE Tools"
+                   if test ! -d "${SDKROOT}" ; then
+                       SDKROOT="C:/Windows CE Tools"
+                   fi
+               fi
+               WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+               SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+               if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+                   -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+                   AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+                   doWince="no"
+               else
+                   # We could PATH_NOSPACE these, but that's not important,
+                   # as long as we quote them when used.
+                   CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+                   if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+                       CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+                   fi
+                   CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+               fi
+           fi
+
+           if test "$GCC" != "yes" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
+                   runtime=-MT
+               else
+                   runtime=-MD
+               fi
+
+                if test "$do64bit" != "no" ; then
+                   # All this magic is necessary for the Win64 SDK RC1 - hobbs
+                   CC="\"${PATH64}/cl.exe\""
+                   CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+                   RC="\"${MSSDK}/bin/rc.exe\""
+                   lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+                   LINKBIN="\"${PATH64}/link.exe\""
+                   CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+                   # Avoid 'unresolved external symbol __security_cookie'
+                   # errors, c.f. http://support.microsoft.com/?id=894573
+                   TEA_ADD_LIBS([bufferoverflowU.lib])
+               elif test "$doWince" != "no" ; then
+                   CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+                   if test "${TARGETCPU}" = "X86"; then
+                       CC="\"${CEBINROOT}/cl.exe\""
+                   else
+                       CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+                   fi
+                   CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+                   RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+                   arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+                   defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+                   if test "${SHARED_BUILD}" = "1" ; then
+                       # Static CE builds require static celib as well
+                       defs="${defs} _DLL"
+                   fi
+                   for i in $defs ; do
+                       AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+                   done
+                   AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+                   AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+                   CFLAGS_DEBUG="-nologo -Zi -Od"
+                   CFLAGS_OPTIMIZE="-nologo -Ox"
+                   lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+                   lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+                   LINKBIN="\"${CEBINROOT}/link.exe\""
+                   AC_SUBST(CELIB_DIR)
+               else
+                   RC="rc"
+                   lflags="-nologo"
+                   LINKBIN="link"
+                   CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+                   CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+               fi
+           fi
+
+           if test "$GCC" = "yes"; then
+               # mingw gcc mode
+               RC="windres"
+               CFLAGS_DEBUG="-g"
+               CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+               SHLIB_LD="$CC -shared"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+               LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+           else
+               SHLIB_LD="${LINKBIN} -dll ${lflags}"
+               # link -lib only works when -lib is the first arg
+               STLIB_LD="${LINKBIN} -lib ${lflags}"
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+               PATHTYPE=-w
+               # For information on what debugtype is most useful, see:
+               # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+               # This essentially turns it all on.
+               LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
+               LDFLAGS_OPTIMIZE="-release"
+               if test "$doWince" != "no" ; then
+                   LDFLAGS_CONSOLE="-link ${lflags}"
+                   LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+               else
+                   LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+                   LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+               fi
+           fi
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dll"
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+           TCL_LIB_VERSIONS_OK=nodots
+           # Bogus to avoid getting this turned off
+           DL_OBJS="tclLoadNone.obj"
+           ;;
+       AIX-*)
+           if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
+               # AIX requires the _r compiler when gcc isn't being used
+               case "${CC}" in
+                   *_r)
+                       # ok ...
+                       ;;
+                   *)
+                       CC=${CC}_r
+                       ;;
+               esac
+               AC_MSG_RESULT([Using $CC for compiling with threads])
+           fi
+           LIBS="$LIBS -lc"
+           SHLIB_CFLAGS=""
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           DL_OBJS="tclLoadDl.o"
+           LD_LIBRARY_PATH_VAR="LIBPATH"
+
+           # Check to enable 64-bit flags for compiler/linker on AIX 4+
+           if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_WARN([64bit mode not supported with GCC on $system])
+               else 
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS -q64"
+                   LDFLAGS_ARCH="-q64"
+                   RANLIB="${RANLIB} -X64"
+                   AR="${AR} -X64"
+                   SHLIB_LD_FLAGS="-b64"
+               fi
+           fi
+
+           if test "`uname -m`" = "ia64" ; then
+               # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               # AIX-5 has dl* in libc.so
+               DL_LIBS=""
+               if test "$GCC" = "yes" ; then
+                   CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               else
+                   CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+               fi
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           else
+               if test "$GCC" = "yes" ; then
+                   SHLIB_LD="gcc -shared"
+               else
+                   SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+               fi
+               SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+               DL_LIBS="-ldl"
+               CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               TCL_NEEDS_EXP_FILE=1
+               TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
+           fi
+
+           # AIX v<=4.1 has some different flags than 4.2+
+           if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
+               AC_LIBOBJ([tclLoadAix])
+               DL_LIBS="-lld"
+           fi
+
+           # On AIX <=v4 systems, libbsd.a has to be linked in to support
+           # non-blocking file IO.  This library has to be linked in after
+           # the MATH_LIBS or it breaks the pow() function.  The way to
+           # insure proper sequencing, is to add it to the tail of MATH_LIBS.
+           # This library also supplies gettimeofday.
+           #
+           # AIX does not have a timezone field in struct tm. When the AIX
+           # bsd library is used, the timezone global and the gettimeofday
+           # methods are to be avoided for timezone deduction instead, we
+           # deduce the timezone by comparing the localtime result on a
+           # known GMT value.
+
+           AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
+           if test $libbsd = yes; then
+               MATH_LIBS="$MATH_LIBS -lbsd"
+               AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
+           fi
+           ;;
+       BeOS*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="${CC} -nostart"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+
+           #-----------------------------------------------------------
+           # Check for inet_ntoa in -lbind, for BeOS (which also needs
+           # -lsocket, even if the network functions are in -lnet which
+           # is always linked to, for compatibility.
+           #-----------------------------------------------------------
+           AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+           ;;
+       BSD/OS-2.1*|BSD/OS-3*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="shlicc -r"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       BSD/OS-4.*)
+           SHLIB_CFLAGS="-export-dynamic -fPIC"
+           SHLIB_LD="cc -shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       dgux*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       HP-UX-*.11.*)
+           # Use updated header definitions where possible
+           AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+           # Needed by Tcl, but not most extensions
+           #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+           #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
+
+           SHLIB_SUFFIX=".sl"
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS='${LIBS}'
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="gcc -shared"
+               SHLIB_LD_LIBS='${LIBS}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+
+           # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+           #CFLAGS="$CFLAGS +DAportable"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   hpux_arch=`${CC} -dumpmachine`
+                   case $hpux_arch in
+                       hppa64*)
+                           # 64-bit gcc in use.  Fix flags for GNU ld.
+                           do64bit_ok=yes
+                           SHLIB_LD="${CC} -shared"
+                           SHLIB_LD_LIBS='${LIBS}'
+                           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+                           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+                           ;;
+                       *)
+                           AC_MSG_WARN([64bit mode not supported with GCC on $system])
+                           ;;
+                   esac
+               else
+                   do64bit_ok=yes
+                   CFLAGS="$CFLAGS +DD64"
+                   LDFLAGS_ARCH="+DD64"
+               fi
+           fi
+           ;;
+       HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+           SHLIB_SUFFIX=".sl"
+           AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+           if test "$tcl_ok" = yes; then
+               SHLIB_CFLAGS="+z"
+               SHLIB_LD="ld -b"
+               SHLIB_LD_LIBS=""
+               DL_OBJS="tclLoadShl.o"
+               DL_LIBS="-ldld"
+               LDFLAGS="$LDFLAGS -Wl,-E"
+               CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+               LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+               LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+           fi
+           ;;
+       IRIX-5.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           ;;
+       IRIX-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mabi=n32"
+               LDFLAGS="$LDFLAGS -mabi=n32"
+           else
+               case $system in
+                   IRIX-6.3)
+                       # Use to build 6.2 compatible binaries on 6.3.
+                       CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+                       ;;
+                   *)
+                       CFLAGS="$CFLAGS -n32"
+                       ;;
+               esac
+               LDFLAGS="$LDFLAGS -n32"
+           fi
+           ;;
+       IRIX64-6.*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="ld -n32 -shared -rdata_shared"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+
+           # Check to enable 64-bit flags for compiler/linker
+
+           if test "$do64bit" = "yes" ; then
+               if test "$GCC" = "yes" ; then
+                   AC_MSG_WARN([64bit mode not supported by gcc])
+               else
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               fi
+           fi
+           ;;
+       Linux*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+           # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
+           # when you inline the string and math operations.  Turn this off to
+           # get rid of the warnings.
+           #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
+
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           if test $do64bit = yes; then
+               AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+                   hold_cflags=$CFLAGS
+                   CFLAGS="$CFLAGS -m64"
+                   AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+                   CFLAGS=$hold_cflags])
+               if test $tcl_cv_cc_m64 = yes; then
+                   CFLAGS="$CFLAGS -m64"
+                   do64bit_ok=yes
+               fi
+           fi
+
+           # The combo of gcc + glibc has a bug related
+           # to inlining of functions like strtod(). The
+           # -fno-builtin flag should address this problem
+           # but it does not work. The -fno-inline flag
+           # is kind of overkill but it works.
+           # Disable inlining only when one of the
+           # files in compat/*.c is being linked in.
+           if test x"${USE_COMPAT}" != x ; then
+               CFLAGS="$CFLAGS -fno-inline"
+           fi
+
+           ;;
+       GNU*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+
+           SHLIB_LD="${CC} -shared"
+           DL_OBJS=""
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           if test "`uname -m`" = "alpha" ; then
+               CFLAGS="$CFLAGS -mieee"
+           fi
+           ;;
+       Lynx*)
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           CFLAGS_OPTIMIZE=-02
+           SHLIB_LD="${CC} -shared "
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-mshared -ldl"
+           LD_FLAGS="-Wl,--export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           ;;
+       MP-RAS-02*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       MP-RAS-*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       NetBSD-*|FreeBSD-[[1-2]].*)
+           # NetBSD/SPARC needs -fPIC, -fpic will not do.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           if test $tcl_cv_ld_elf = yes; then
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+           else
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           fi
+
+           # Ancient FreeBSD doesn't handle version numbers with dots.
+
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       OpenBSD-*)
+           # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
+           case `machine` in
+           sparc|sparc64)
+               SHLIB_CFLAGS="-fPIC";;
+           *)
+               SHLIB_CFLAGS="-fpic";;
+           esac
+           SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
+               AC_EGREP_CPP(yes, [
+#ifdef __ELF__
+       yes
+#endif
+               ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
+           if test $tcl_cv_ld_elf = yes; then
+               LDFLAGS=-Wl,-export-dynamic
+           else
+               LDFLAGS=""
+           fi
+
+           # OpenBSD doesn't do version numbers with dots.
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       FreeBSD-*)
+           # FreeBSD 3.* and greater have ELF.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           LDFLAGS="$LDFLAGS -export-dynamic"
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "${TCL_THREADS}" = "1" ; then
+               # The -pthread needs to go in the CFLAGS, not LIBS
+               LIBS=`echo $LIBS | sed s/-pthread//`
+               CFLAGS="$CFLAGS -pthread"
+               LDFLAGS="$LDFLAGS -pthread"
+           fi
+           case $system in
+           FreeBSD-3.*)
+               # FreeBSD-3 doesn't handle version numbers with dots.
+               UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+               SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+               TCL_LIB_VERSIONS_OK=nodots
+               ;;
+           esac
+           ;;
+       Darwin-*)
+           CFLAGS_OPTIMIZE="-Os"
+           SHLIB_CFLAGS="-fno-common"
+           if test $do64bit = yes; then
+               case `arch` in
+                   ppc)
+                       AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+                               tcl_cv_cc_arch_ppc64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+                                   tcl_cv_cc_arch_ppc64=no)
+                           CFLAGS=$hold_cflags])
+                       if test $tcl_cv_cc_arch_ppc64 = yes; then
+                           CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+                           do64bit_ok=yes
+                       fi;;
+                   i386)
+                       AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+                               tcl_cv_cc_arch_x86_64, [
+                           hold_cflags=$CFLAGS
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+                                   tcl_cv_cc_arch_x86_64=no)
+                           CFLAGS=$hold_cflags])
+                       if test $tcl_cv_cc_arch_x86_64 = yes; then
+                           CFLAGS="$CFLAGS -arch x86_64"
+                           do64bit_ok=yes
+                       fi;;
+                   *)
+                       AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+               esac
+           else
+               # Check for combined 32-bit and 64-bit fat build
+               echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
+                   echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
+                   fat_32_64=yes
+           fi
+           # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
+           SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+           AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_single_module = yes; then
+               SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+           fi
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".dylib"
+           DL_OBJS="tclLoadDyld.o"
+           DL_LIBS=""
+           # Don't use -prebind when building for Mac OS X 10.4 or later only:
+           test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+               "`echo "${CFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4 && \
+               LDFLAGS="$LDFLAGS -prebind"
+           LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+           AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_search_paths_first = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+
+           # TEA specific: for Tk extensions, remove 64-bit arch flags from
+           # CFLAGS for combined 32-bit and 64-bit fat builds as neither TkAqua
+           # nor TkX11 can be built for 64-bit at present.
+           test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}" && \
+               CFLAGS="`echo "$CFLAGS " | sed -e 's/-arch ppc64 / /g' -e 's/-arch x86_64 / /g'`"
+           ;;
+       NEXTSTEP-*)
+           SHLIB_CFLAGS=""
+           SHLIB_LD="cc -nostdlib -r"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadNext.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OS/390-*)
+           CFLAGS_OPTIMIZE=""          # Optimizer is buggy
+           AC_DEFINE(_OE_SOCKETS, 1,   # needed in sys/socket.h
+               [Should OS/390 do the right thing with sockets?])
+           ;;      
+       OSF1-1.0|OSF1-1.1|OSF1-1.2)
+           # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+           SHLIB_CFLAGS=""
+           # Hack: make package name same as library name
+           SHLIB_LD='ld -R -export $@:'
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadOSF.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-1.*)
+           # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+           SHLIB_CFLAGS="-fPIC"
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD="ld -shared"
+           else
+               SHLIB_LD="ld -non_shared"
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       OSF1-V*)
+           # Digital OSF/1
+           SHLIB_CFLAGS=""
+           if test "$SHARED_BUILD" = "1" ; then
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
+           else
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+           fi
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+           if test "$GCC" = "yes" ; then
+               CFLAGS="$CFLAGS -mieee"
+            else
+               CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+           fi
+           # see pthread_intro(3) for pthread support on osf1, k.furukawa
+           if test "${TCL_THREADS}" = "1" ; then
+               CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+               CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+               LIBS=`echo $LIBS | sed s/-lpthreads//`
+               if test "$GCC" = "yes" ; then
+                   LIBS="$LIBS -lpthread -lmach -lexc"
+               else
+                   CFLAGS="$CFLAGS -pthread"
+                   LDFLAGS="$LDFLAGS -pthread"
+               fi
+           fi
+
+           ;;
+       QNX-6*)
+           # QNX RTP
+           # This may work for all QNX, but it was only reported for v6.
+           SHLIB_CFLAGS="-fPIC"
+           SHLIB_LD="ld -Bshareable -x"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           # dlopen is in -lc on QNX
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SCO_SV-3.2*)
+           # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+           # this test works, since "uname -s" was non-standard in 3.2.4 and
+           # below.
+           if test "$GCC" = "yes" ; then
+               SHLIB_CFLAGS="-fPIC -melf"
+               LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+           else
+               SHLIB_CFLAGS="-Kpic -belf"
+               LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+           fi
+           SHLIB_LD="ld -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS=""
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SINIX*5.4*)
+           SHLIB_CFLAGS="-K PIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+       SunOS-4*)
+           SHLIB_CFLAGS="-PIC"
+           SHLIB_LD="ld"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+           LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+           # SunOS can't handle version numbers with dots in them in library
+           # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
+           # requires an extra version number at the end of .so file names.
+           # So, the library has to have a name like libtcl75.so.1.0
+
+           SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
+           UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+           TCL_LIB_VERSIONS_OK=nodots
+           ;;
+       SunOS-5.[[0-6]])
+           # Careful to not let 5.10+ fall into this case
+
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+           fi
+           ;;
+       SunOS-5*)
+           # Note: If _REENTRANT isn't defined, then Solaris
+           # won't define thread-safe library routines.
+
+           AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+           AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+               [Do we really want to follow the standard? Yes we do!])
+
+           SHLIB_CFLAGS="-KPIC"
+
+           # Check to enable 64-bit flags for compiler/linker
+           if test "$do64bit" = "yes" ; then
+               arch=`isainfo`
+               if test "$arch" = "sparcv9 sparc" ; then
+                       if test "$GCC" = "yes" ; then
+                           if test "`gcc -dumpversion | awk -F. '{print [$]1}'`" -lt "3" ; then
+                               AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+                           else
+                               do64bit_ok=yes
+                               CFLAGS="$CFLAGS -m64 -mcpu=v9"
+                               LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+                               SHLIB_CFLAGS="-fPIC"
+                           fi
+                       else
+                           do64bit_ok=yes
+                           if test "$do64bitVIS" = "yes" ; then
+                               CFLAGS="$CFLAGS -xarch=v9a"
+                               LDFLAGS_ARCH="-xarch=v9a"
+                           else
+                               CFLAGS="$CFLAGS -xarch=v9"
+                               LDFLAGS_ARCH="-xarch=v9"
+                           fi
+                           # Solaris 64 uses this as well
+                           #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+                       fi
+               elif test "$arch" = "amd64 i386" ; then
+                   if test "$GCC" = "yes" ; then
+                       AC_MSG_WARN([64bit mode not supported with GCC on $system])
+                   else
+                       do64bit_ok=yes
+                       CFLAGS="$CFLAGS -xarch=amd64"
+                       LDFLAGS="$LDFLAGS -xarch=amd64"
+                   fi
+               else
+                   AC_MSG_WARN([64bit mode not supported for $arch])
+               fi
+           fi
+           
+           # Note: need the LIBS below, otherwise Tk won't find Tcl's
+           # symbols when dynamically loaded into tclsh.
+
+           SHLIB_LD_LIBS='${LIBS}'
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           if test "$GCC" = "yes" ; then
+               SHLIB_LD="$CC -shared"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+               if test "$do64bit_ok" = "yes" ; then
+                   # We need to specify -static-libgcc or we need to
+                   # add the path to the sparv9 libgcc.
+                   # JH: static-libgcc is necessary for core Tcl, but may
+                   # not be necessary for extensions.
+                   SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+                   # for finding sparcv9 libgcc, get the regular libgcc
+                   # path, remove so name and append 'sparcv9'
+                   #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+                   #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+               fi
+           else
+               SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+               CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+               LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+           fi
+           ;;
+       UNIX_SV* | UnixWare-5*)
+           SHLIB_CFLAGS="-KPIC"
+           SHLIB_LD="cc -G"
+           SHLIB_LD_LIBS=""
+           SHLIB_SUFFIX=".so"
+           DL_OBJS="tclLoadDl.o"
+           DL_LIBS="-ldl"
+           # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+           # that don't grok the -Bexport option.  Test that it does.
+           AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+               hold_ldflags=$LDFLAGS
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+               AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+               LDFLAGS=$hold_ldflags])
+           if test $tcl_cv_ld_Bexport = yes; then
+               LDFLAGS="$LDFLAGS -Wl,-Bexport"
+           fi
+           CC_SEARCH_FLAGS=""
+           LD_SEARCH_FLAGS=""
+           ;;
+    esac
+
+    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
+       AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+    fi
+
+    # Step 4: disable dynamic loading if requested via a command-line switch.
+
+    AC_ARG_ENABLE(load,
+       AC_HELP_STRING([--enable-load],
+           [allow dynamic loading and "load" command (default: on)]),
+       [tcl_ok=$enableval], [tcl_ok=yes])
+    if test "$tcl_ok" = "no"; then
+       DL_OBJS=""
+    fi
+
+    if test "x$DL_OBJS" != "x" ; then
+       BUILD_DLTEST="\$(DLTEST_TARGETS)"
+    else
+       echo "Can't figure out how to do dynamic loading or shared libraries"
+       echo "on this system."
+       SHLIB_CFLAGS=""
+       SHLIB_LD=""
+       SHLIB_SUFFIX=""
+       DL_OBJS="tclLoadNone.o"
+       DL_LIBS=""
+       LDFLAGS="$LDFLAGS_ORIG"
+       CC_SEARCH_FLAGS=""
+       LD_SEARCH_FLAGS=""
+       BUILD_DLTEST=""
+    fi
+    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+    # If we're running gcc, then change the C flags for compiling shared
+    # libraries to the right flags for gcc, instead of those for the
+    # standard manufacturer compiler.
+
+    if test "$DL_OBJS" != "tclLoadNone.o" ; then
+       if test "$GCC" = "yes" ; then
+           case $system in
+               AIX-*)
+                   ;;
+               BSD/OS*)
+                   ;;
+               IRIX*)
+                   ;;
+               NetBSD-*|FreeBSD-*)
+                   ;;
+               Darwin-*)
+                   ;;
+               SCO_SV-3.2*)
+                   ;;
+               windows)
+                   ;;
+               *)
+                   SHLIB_CFLAGS="-fPIC"
+                   ;;
+           esac
+       fi
+    fi
+
+    if test "$SHARED_LIB_SUFFIX" = "" ; then
+       SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+    fi
+    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
+       UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+    fi
+
+    AC_SUBST(DL_LIBS)
+
+    AC_SUBST(CFLAGS_DEBUG)
+    AC_SUBST(CFLAGS_OPTIMIZE)
+    AC_SUBST(CFLAGS_WARNING)
+
+    AC_SUBST(STLIB_LD)
+    AC_SUBST(SHLIB_LD)
+
+    AC_SUBST(SHLIB_LD_LIBS)
+    AC_SUBST(SHLIB_CFLAGS)
+
+    AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+    # These must be called after we do the basic CFLAGS checks and
+    # verify any possible 64-bit or similar switches are necessary
+    TEA_TCL_EARLY_FLAGS
+    TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+#      Determine which interface to use to talk to the serial port.
+#      Note that #include lines must begin in leftmost column for
+#      some compilers to recognize them as preprocessor directives,
+#      and some build environments have stdin not pointing at a
+#      pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines only one of the following vars:
+#              HAVE_SYS_MODEM_H
+#              USE_TERMIOS
+#              USE_TERMIO
+#              USE_SGTTY
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+    AC_CHECK_HEADERS(sys/modem.h)
+    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+    AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no ; then
+       AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+    struct termios t;
+    if (tcgetattr(0, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       cfsetospeed(&t, 0);
+       t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+    struct termio t;
+    if (ioctl(0, TCGETA, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+       return 0;
+    }
+    return 1;
+    }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+    fi
+    if test $tcl_cv_api_serial = no; then
+       AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+    struct sgttyb t;
+    if (ioctl(0, TIOCGETP, &t) == 0
+       || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+       t.sg_ospeed = 0;
+       t.sg_flags |= ODDP | EVENP | RAW;
+       return 0;
+    }
+    return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+    fi])
+    case $tcl_cv_api_serial in
+       termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+       termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+       sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_MISSING_POSIX_HEADERS
+#
+#      Supply substitutes for missing POSIX header files.  Special
+#      notes:
+#          - stdlib.h doesn't define strtol, strtoul, or
+#            strtod insome versions of SunOS
+#          - some versions of string.h don't declare procedures such
+#            as strstr
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              NO_DIRENT_H
+#              NO_ERRNO_H
+#              NO_VALUES_H
+#              HAVE_LIMITS_H or NO_LIMITS_H
+#              NO_STDLIB_H
+#              NO_STRING_H
+#              NO_SYS_WAIT_H
+#              NO_DLFCN_H
+#              HAVE_SYS_PARAM_H
+#
+#              HAVE_STRING_H ?
+#
+# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+# CHECK on limits.h
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
+    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
+    AC_TRY_LINK([#include <sys/types.h>
+#include <dirent.h>], [
+#ifndef _POSIX_SOURCE
+#   ifdef __Lynx__
+       /*
+        * Generate compilation error to make the test fail:  Lynx headers
+        * are only valid if really in the POSIX environment.
+        */
+
+       missing_procedure();
+#   endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
+
+    if test $tcl_cv_dirent_h = no; then
+       AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
+    fi
+
+    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
+    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
+    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
+    AC_CHECK_HEADER(limits.h,
+       [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
+       [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
+    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
+    fi
+    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+
+    # See also memmove check below for a place where NO_STRING_H can be
+    # set and why.
+
+    if test $tcl_ok = 0; then
+       AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
+    fi
+
+    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
+    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
+
+    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+    AC_HAVE_HEADERS(sys/param.h)
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+#      Locate the X11 header files and the X11 library archive.  Try
+#      the ac_path_x macro first, but if it doesn't find the X stuff
+#      (e.g. because there's no xmkmf program) then check through
+#      a list of possible directories.  Under some conditions the
+#      autoconf macro will return an include directory that contains
+#      no include files, so double-check its result just to be safe.
+#
+#      This should be called after TEA_CONFIG_CFLAGS as setting the
+#      LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Sets the following vars:
+#              XINCLUDES
+#              XLIBSW
+#              PKG_LIBS (appends to)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+       TEA_PATH_UNIX_X
+    fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+    AC_PATH_X
+    not_really_there=""
+    if test "$no_x" = ""; then
+       if test "$x_includes" = ""; then
+           AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
+       else
+           if test ! -r $x_includes/X11/Intrinsic.h; then
+               not_really_there="yes"
+           fi
+       fi
+    fi
+    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+       AC_MSG_CHECKING([for X11 header files])
+       found_xincludes="no"
+       AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
+       if test "$found_xincludes" = "no"; then
+           dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+           for i in $dirs ; do
+               if test -r $i/X11/Intrinsic.h; then
+                   AC_MSG_RESULT([$i])
+                   XINCLUDES=" -I$i"
+                   found_xincludes="yes"
+                   break
+               fi
+           done
+       fi
+    else
+       if test "$x_includes" != ""; then
+           XINCLUDES="-I$x_includes"
+           found_xincludes="yes"
+       fi
+    fi
+    if test found_xincludes = "no"; then
+       AC_MSG_RESULT([couldn't find any!])
+    fi
+
+    if test "$no_x" = yes; then
+       AC_MSG_CHECKING([for X11 libraries])
+       XLIBSW=nope
+       dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+       for i in $dirs ; do
+           if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then
+               AC_MSG_RESULT([$i])
+               XLIBSW="-L$i -lX11"
+               x_libraries="$i"
+               break
+           fi
+       done
+    else
+       if test "$x_libraries" = ""; then
+           XLIBSW=-lX11
+       else
+           XLIBSW="-L$x_libraries -lX11"
+       fi
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+    fi
+    if test "$XLIBSW" = nope ; then
+       AC_MSG_RESULT([could not find any!  Using -lX11.])
+       XLIBSW=-lX11
+    fi
+    if test x"${XLIBSW}" != x ; then
+       PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+#      The statements below check for systems where POSIX-style
+#      non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
+#      On these systems (mostly older ones), use the old BSD-style
+#      FIONBIO approach instead.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              HAVE_SYS_IOCTL_H
+#              HAVE_SYS_FILIO_H
+#              USE_FIONBIO
+#              O_NONBLOCK
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+    AC_CHECK_HEADERS(sys/ioctl.h)
+    AC_CHECK_HEADERS(sys/filio.h)
+    TEA_CONFIG_SYSTEM
+    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+    case $system in
+       # There used to be code here to use FIONBIO under AIX.  However, it
+       # was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
+       # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
+       # code (JO, 5/31/97).
+
+       OSF*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       SunOS-4*)
+           AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+           AC_MSG_RESULT([FIONBIO])
+           ;;
+       *)
+           AC_MSG_RESULT([O_NONBLOCK])
+           ;;
+    esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANLDER
+#
+#      Checks how the system deals with time.h, what time structures
+#      are used on the system, and what fields the structures have.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Defines some of the following vars:
+#              USE_DELTA_FOR_TZ
+#              HAVE_TM_GMTOFF
+#              HAVE_TM_TZADJ
+#              HAVE_TIMEZONE_VAR
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+    AC_CHECK_HEADERS(sys/time.h)
+    AC_HEADER_TIME
+    AC_STRUCT_TIMEZONE
+
+    AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+           tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+    if test $tcl_cv_member_tm_tzadj = yes ; then
+       AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+    fi
+
+    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+       AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+           tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+    if test $tcl_cv_member_tm_gmtoff = yes ; then
+       AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+    fi
+
+    #
+    # Its important to include time.h in this check, as some systems
+    # (like convex) have timezone functions, etc.
+    #
+    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+       AC_TRY_COMPILE([#include <time.h>],
+           [extern long timezone;
+           timezone += 1;
+           exit (0);],
+           tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+    if test $tcl_cv_timezone_long = yes ; then
+       AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+    else
+       #
+       # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+       #
+       AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+           AC_TRY_COMPILE([#include <time.h>],
+               [extern time_t timezone;
+               timezone += 1;
+               exit (0);],
+               tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+       if test $tcl_cv_timezone_time = yes ; then
+           AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+#      Under Solaris 2.4, strtod returns the wrong value for the
+#      terminating character under some conditions.  Check for this
+#      and if the problem exists use a substitute procedure
+#      "fixstrtod" (provided by Tcl) that corrects the error.
+#      Also, on Compaq's Tru64 Unix 5.0,
+#      strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+#      none
+#      
+# Results:
+#
+#      Might defines some of the following vars:
+#              strtod (=fixstrtod)
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+    if test "$tcl_strtod" = 1; then
+       AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+           AC_TRY_RUN([
+               extern double strtod();
+               int main() {
+                   char *infString="Inf", *nanString="NaN", *spaceString=" ";
+                   char *term;
+                   double value;
+                   value = strtod(infString, &term);
+                   if ((term != infString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(nanString, &term);
+                   if ((term != nanString) && (term[-1] == 0)) {
+                       exit(1);
+                   }
+                   value = strtod(spaceString, &term);
+                   if (term == (spaceString+1)) {
+                       exit(1);
+                   }
+                   exit(0);
+               }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+                   tcl_cv_strtod_buggy=buggy)])
+       if test "$tcl_cv_strtod_buggy" = buggy; then
+           AC_LIBOBJ([fixstrtod])
+           USE_COMPAT=1
+           AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+       fi
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_LINK_LIBS
+#
+#      Search for the libraries needed to link the Tcl shell.
+#      Things like the math library (-lm) and socket stuff (-lsocket vs.
+#      -lnsl) are dealt with here.
+#
+# Arguments:
+#      Requires the following vars to be set in the Makefile:
+#              DL_LIBS
+#              LIBS
+#              MATH_LIBS
+#      
+# Results:
+#
+#      Subst's the following var:
+#              TCL_LIBS
+#              MATH_LIBS
+#
+#      Might append to the following vars:
+#              LIBS
+#
+#      Might define the following vars:
+#              HAVE_NET_ERRNO_H
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_LINK_LIBS], [
+    #--------------------------------------------------------------------
+    # On a few very rare systems, all of the libm.a stuff is
+    # already in libc.a.  Set compiler flags accordingly.
+    # Also, Linux requires the "ieee" library for math to work
+    # right (and it must appear before "-lm").
+    #--------------------------------------------------------------------
+
+    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+    #--------------------------------------------------------------------
+    # Interactive UNIX requires -linet instead of -lsocket, plus it
+    # needs net/errno.h to define the socket-related error codes.
+    #--------------------------------------------------------------------
+
+    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+    AC_CHECK_HEADER(net/errno.h, [
+       AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
+
+    #--------------------------------------------------------------------
+    #  Check for the existence of the -lsocket and -lnsl libraries.
+    #  The order here is important, so that they end up in the right
+    #  order in the command line generated by make.  Here are some
+    #  special considerations:
+    #  1. Use "connect" and "accept" to check for -lsocket, and
+    #     "gethostbyname" to check for -lnsl.
+    #  2. Use each function name only once:  can't redo a check because
+    #     autoconf caches the results of the last check and won't redo it.
+    #  3. Use -lnsl and -lsocket only if they supply procedures that
+    #     aren't already present in the normal libraries.  This is because
+    #     IRIX 5.2 has libraries, but they aren't needed and they're
+    #     bogus:  they goof up name resolution if used.
+    #  4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+    #     To get around this problem, check for both libraries together
+    #     if -lsocket doesn't work by itself.
+    #--------------------------------------------------------------------
+
+    tcl_checkBoth=0
+    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+    if test "$tcl_checkSocket" = 1; then
+       AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
+           LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
+    fi
+    if test "$tcl_checkBoth" = 1; then
+       tk_oldLibs=$LIBS
+       LIBS="$LIBS -lsocket -lnsl"
+       AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
+    fi
+    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
+           [LIBS="$LIBS -lnsl"])])
+    
+    # Don't perform the eval of the libraries here because DL_LIBS
+    # won't be set until we call TEA_CONFIG_CFLAGS
+
+    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+    AC_SUBST(TCL_LIBS)
+    AC_SUBST(MATH_LIBS)
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+#      Check for what flags are needed to be passed so the correct OS
+#      features are available.
+#
+# Arguments:
+#      None
+#      
+# Results:
+#
+#      Might define the following vars:
+#              _ISOC99_SOURCE
+#              _LARGEFILE64_SOURCE
+#              _LARGEFILE_SOURCE64
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+       AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+           AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+               [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+       AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+       tcl_flags="$tcl_flags $1"
+    fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+    AC_MSG_CHECKING([for required early compiler flags])
+    tcl_flags=""
+    TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+       [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+       [struct stat64 buf; int i = stat64("/", &buf);])
+    TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+       [char *p = (char *)open64;])
+    if test "x${tcl_flags}" = "x" ; then
+       AC_MSG_RESULT([none])
+    else
+       AC_MSG_RESULT([${tcl_flags}])
+    fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+#      Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+#      None
+#      
+# Results:
+#
+#      Might define the following vars:
+#              TCL_WIDE_INT_IS_LONG
+#              TCL_WIDE_INT_TYPE
+#              HAVE_STRUCT_DIRENT64
+#              HAVE_STRUCT_STAT64
+#              HAVE_TYPE_OFF64_T
+#
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+    AC_MSG_CHECKING([for 64-bit integer type])
+    AC_CACHE_VAL(tcl_cv_type_64bit,[
+       tcl_cv_type_64bit=none
+       # See if the compiler knows natively about __int64
+       AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+           tcl_type_64bit=__int64, tcl_type_64bit="long long")
+       # See if we should use long anyway  Note that we substitute in the
+       # type that is our current guess for a 64-bit type inside this check
+       # program, so it should be modified only carefully...
+        AC_TRY_COMPILE(,[switch (0) { 
+            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; 
+        }],tcl_cv_type_64bit=${tcl_type_64bit})])
+    if test "${tcl_cv_type_64bit}" = none ; then
+       AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+       AC_MSG_RESULT([using long])
+    elif test "${tcl_cv_type_64bit}" = "__int64" \
+               -a "${TEA_PLATFORM}" = "windows" ; then
+       # We actually want to use the default tcl.h checks in this
+       # case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+       AC_MSG_RESULT([using Tcl header defaults])
+    else
+       AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+           [What type should be used to define wide integers?])
+       AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+       # Now check for auxiliary declarations
+       AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+           AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/dirent.h>],[struct dirent64 p;],
+               tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+       if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+       fi
+
+       AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+           AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+               tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+       if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+           AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+       fi
+
+       AC_CHECK_FUNCS(open64 lseek64)
+       AC_MSG_CHECKING([for off64_t])
+       AC_CACHE_VAL(tcl_cv_type_off64_t,[
+           AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+               tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+       dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+       dnl functions lseek64 and open64 are defined.
+       if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
+           AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+           AC_MSG_RESULT([yes])
+       else
+           AC_MSG_RESULT([no])
+       fi
+    fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+#      Init various Tcl Extension Architecture (TEA) variables.
+#      This should be the first called TEA_* macro.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              CYGPATH
+#              EXEEXT
+#      Defines only:
+#              TEA_VERSION
+#              TEA_INITED
+#              TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+#      Select the executable extension based on the host type.  This
+#      is a lightweight replacement for AC_EXEEXT that doesn't require
+#      a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+    # TEA extensions pass this us the version of TEA they think they
+    # are compatible with.
+    TEA_VERSION="3.5"
+
+    AC_MSG_CHECKING([for correct TEA configuration])
+    if test x"${PACKAGE_NAME}" = x ; then
+       AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.in])
+    fi
+    if test x"$1" = x ; then
+       AC_MSG_ERROR([
+TEA version not specified.])
+    elif test "$1" != "${TEA_VERSION}" ; then
+       AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
+    else
+       AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+    fi
+    case "`uname -s`" in
+       *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
+           AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
+           EXEEXT=".exe"
+           TEA_PLATFORM="windows"
+           ;;
+       *)
+           CYGPATH=echo
+           EXEEXT=""
+           TEA_PLATFORM="unix"
+           ;;
+    esac
+
+    # Check if exec_prefix is set. If not use fall back to prefix.
+    # Note when adjusted, so that TEA_PREFIX can correct for this.
+    # This is needed for recursive configures, since autoconf propagates
+    # $prefix, but not $exec_prefix (doh!).
+    if test x$exec_prefix = xNONE ; then
+       exec_prefix_default=yes
+       exec_prefix=$prefix
+    fi
+
+    AC_SUBST(EXEEXT)
+    AC_SUBST(CYGPATH)
+
+    # This package name must be replaced statically for AC_SUBST to work
+    AC_SUBST(PKG_LIB_FILE)
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+    AC_SUBST(PKG_STUB_LIB_FILE)
+
+    # We AC_SUBST these here to ensure they are subst'ed,
+    # in case the user doesn't call TEA_ADD_...
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+    AC_SUBST(PKG_TCL_SOURCES)
+    AC_SUBST(PKG_HEADERS)
+    AC_SUBST(PKG_INCLUDES)
+    AC_SUBST(PKG_LIBS)
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_SOURCES
+#              PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       case $i in
+           [\$]*)
+               # allow $-var names
+               PKG_SOURCES="$PKG_SOURCES $i"
+               PKG_OBJECTS="$PKG_OBJECTS $i"
+               ;;
+           *)
+               # check for existence - allows for generic/win/unix VPATH
+               if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+                   -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+                   ; then
+                   AC_MSG_ERROR([could not find source file '$i'])
+               fi
+               PKG_SOURCES="$PKG_SOURCES $i"
+               # this assumes it is in a VPATH dir
+               i=`basename $i`
+               # handle user calling this before or after TEA_SETUP_COMPILER
+               if test x"${OBJEXT}" != x ; then
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+               else
+                   j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+               fi
+               PKG_OBJECTS="$PKG_OBJECTS $j"
+               ;;
+       esac
+    done
+    AC_SUBST(PKG_SOURCES)
+    AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+#      Specify one or more source files.  Users should check for
+#      the right platform before adding to their list.
+#      It is not important to specify the directory, as long as it is
+#      in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_STUB_SOURCES
+#              PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence - allows for generic/win/unix VPATH
+       if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+           -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+           ; then
+           AC_MSG_ERROR([could not find stub source file '$i'])
+       fi
+       PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+       # this assumes it is in a VPATH dir
+       i=`basename $i`
+       # handle user calling this before or after TEA_SETUP_COMPILER
+       if test x"${OBJEXT}" != x ; then
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+       else
+           j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+       fi
+       PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+    done
+    AC_SUBST(PKG_STUB_SOURCES)
+    AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+#      Specify one or more Tcl source files.  These should be platform
+#      independent runtime files.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+       fi
+       PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+    done
+    AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+#      Specify one or more source headers.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+    vars="$@"
+    for i in $vars; do
+       # check for existence, be strict because it is installed
+       if test ! -f "${srcdir}/$i" ; then
+           AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+       fi
+       PKG_HEADERS="$PKG_HEADERS $i"
+    done
+    AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+#      Specify one or more include dirs.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+    vars="$@"
+    for i in $vars; do
+       PKG_INCLUDES="$PKG_INCLUDES $i"
+    done
+    AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+#      Specify one or more libraries.  Users should check for
+#      the right platform before adding to their list.  For Windows,
+#      libraries provided in "foo.lib" format will be converted to
+#      "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+    vars="$@"
+    for i in $vars; do
+       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+           # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
+           i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+       fi
+       PKG_LIBS="$PKG_LIBS $i"
+    done
+    AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+#      Specify one or more CFLAGS.  Users should check for
+#      the right platform before adding to their list.
+#
+# Arguments:
+#      one or more file names
+#
+# Results:
+#
+#      Defines and substs the following vars:
+#              PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+    PKG_CFLAGS="$PKG_CFLAGS $@"
+    AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+#      Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      If --prefix or --exec-prefix was not specified, $prefix and
+#      $exec_prefix will be set to the values given to Tcl when it was
+#      configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+    if test "${prefix}" = "NONE"; then
+       prefix_default=yes
+       if test x"${TCL_PREFIX}" != x; then
+           AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+           prefix=${TCL_PREFIX}
+       else
+           AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+           prefix=/usr/local
+       fi
+    fi
+    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+       -o x"${exec_prefix_default}" = x"yes" ; then
+       if test x"${TCL_EXEC_PREFIX}" != x; then
+           AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+           exec_prefix=${TCL_EXEC_PREFIX}
+       else
+           AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+           exec_prefix=$prefix
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+#      Do compiler checks the way we want.  This is just a replacement
+#      for AC_PROG_CC in TEA configure.in files to make them cleaner.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+    # If the user did not set CFLAGS, set it now to keep
+    # the AC_PROG_CC macro from adding "-g -O2".
+    if test "${CFLAGS+set}" != "set" ; then
+       CFLAGS=""
+    fi
+
+    AC_PROG_CC
+    AC_PROG_CPP
+
+    AC_PROG_INSTALL
+
+    #--------------------------------------------------------------------
+    # Checks to see if the make program sets the $MAKE variable.
+    #--------------------------------------------------------------------
+
+    AC_PROG_MAKE_SET
+
+    #--------------------------------------------------------------------
+    # Find ranlib
+    #--------------------------------------------------------------------
+
+    AC_PROG_RANLIB
+
+    #--------------------------------------------------------------------
+    # Determines the correct binary file extension (.o, .obj, .exe etc.)
+    #--------------------------------------------------------------------
+
+    AC_OBJEXT
+    AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+#      Do compiler checks that use the compiler.  This must go after
+#      TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+    AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+    #------------------------------------------------------------------------
+    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+    # It makes compiling go faster.  (This is only a performance feature.)
+    #------------------------------------------------------------------------
+
+    if test -z "$no_pipe" -a -n "$GCC"; then
+       AC_MSG_CHECKING([if the compiler understands -pipe])
+       OLDCC="$CC"
+       CC="$CC -pipe"
+       AC_TRY_COMPILE(,, AC_MSG_RESULT([yes]), CC="$OLDCC"
+           AC_MSG_RESULT([no]))
+    fi
+
+    #--------------------------------------------------------------------
+    # Common compiler flag setup
+    #--------------------------------------------------------------------
+
+    AC_C_BIGENDIAN
+    if test "${TEA_PLATFORM}" = "unix" ; then
+       TEA_TCL_LINK_LIBS
+       TEA_MISSING_POSIX_HEADERS
+       # Let the user call this, because if it triggers, they will
+       # need a compat/strtod.c that is correct.  Users can also
+       # use Tcl_GetDouble(FromObj) instead.
+       #TEA_BUGGY_STRTOD
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+#      Generate a line that can be used to build a shared/unshared library
+#      in a platform independent manner.
+#
+# Arguments:
+#      none
+#
+#      Requires:
+#
+# Results:
+#
+#      Defines the following vars:
+#      CFLAGS -        Done late here to note disturb other AC macros
+#       MAKE_LIB -      Command to execute to build the Tcl library;
+#                       differs depending on whether or not Tcl is being
+#                       compiled as a shared library.
+#      MAKE_SHARED_LIB Makefile rule for building a shared library
+#      MAKE_STATIC_LIB Makefile rule for building a static library
+#      MAKE_STUB_LIB   Makefile rule for building a stub library
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+       MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+       MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
+    else
+       MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
+       MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+       MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
+    fi
+
+    if test "${SHARED_BUILD}" = "1" ; then
+       MAKE_LIB="${MAKE_SHARED_LIB} "
+    else
+       MAKE_LIB="${MAKE_STATIC_LIB} "
+    fi
+
+    #--------------------------------------------------------------------
+    # Shared libraries and static libraries have different names.
+    # Use the double eval to make sure any variables in the suffix is
+    # substituted. (@@@ Might not be necessary anymore)
+    #--------------------------------------------------------------------
+
+    if test "${TEA_PLATFORM}" = "windows" ; then
+       if test "${SHARED_BUILD}" = "1" ; then
+           # We force the unresolved linking of symbols that are really in
+           # the private libraries of Tcl and Tk.
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+           fi
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+       else
+           eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "$GCC" = "yes"; then
+           PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+       fi
+       # These aren't needed on Windows (either MSVC or gcc)
+       RANLIB=:
+       RANLIB_STUB=:
+    else
+       RANLIB_STUB="${RANLIB}"
+       if test "${SHARED_BUILD}" = "1" ; then
+           SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+           if test x"${TK_BIN_DIR}" != x ; then
+               SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+           fi
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+           RANLIB=:
+       else
+           eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+       fi
+       # Some packages build their own stubs libraries
+       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+    fi
+
+    # These are escaped so that only CFLAGS is picked up at configure time.
+    # The other values will be substituted at make time.
+    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+    if test "${SHARED_BUILD}" = "1" ; then
+       CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+    fi
+
+    AC_SUBST(MAKE_LIB)
+    AC_SUBST(MAKE_SHARED_LIB)
+    AC_SUBST(MAKE_STATIC_LIB)
+    AC_SUBST(MAKE_STUB_LIB)
+    AC_SUBST(RANLIB_STUB)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+#      Compute the name of an existing object library located in libdir
+#      from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+#      basename        The base name of the library without version
+#                      numbers, extensions, or "lib" prefixes.
+#      extra_dir       Extra directory in which to search for the
+#                      library.  This location is used first, then
+#                      $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+#      TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+#      Defines the following vars:
+#              ${basename}_LIB_NAME    The computed library name.
+#              ${basename}_LIB_SPEC    The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+    AC_MSG_CHECKING([for $1 library])
+
+    # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+    tea_lib_name_dir="${exec_prefix}/lib"
+
+    # Or in a user-specified location.
+
+    if test x"$2" != x ; then
+       tea_extra_lib_dir=$2
+    else
+       tea_extra_lib_dir=NONE
+    fi
+
+    for i in \
+           `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+           `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+           `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+       if test -f "$i" ; then
+           tea_lib_name_dir=`dirname $i`
+           $1_LIB_NAME=`basename $i`
+           $1_LIB_PATH_NAME=$i
+           break
+       fi
+    done
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+    else
+       # Strip off the leading "lib" and trailing ".a" or ".so"
+
+       tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+       $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+    fi
+
+    if test "x${$1_LIB_NAME}" = x ; then
+       AC_MSG_ERROR([not found])
+    else
+       AC_MSG_RESULT([${$1_LIB_SPEC}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+#      Locate the private Tcl include files
+#
+# Arguments:
+#
+#      Requires:
+#              TCL_SRC_DIR     Assumes that TEA_LOAD_TCLCONFIG has
+#                               already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TCL_TOP_DIR_NATIVE
+#              TCL_GENERIC_DIR_NATIVE
+#              TCL_UNIX_DIR_NATIVE
+#              TCL_WIN_DIR_NATIVE
+#              TCL_BMAP_DIR_NATIVE
+#              TCL_TOOL_DIR_NATIVE
+#              TCL_PLATFORM_DIR_NATIVE
+#              TCL_BIN_DIR_NATIVE
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl private include files])
+
+    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+    TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+    TCL_UNIX_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+    TCL_WIN_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+    TCL_BMAP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/bitmaps\"
+    TCL_TOOL_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/tools\"
+    TCL_COMPAT_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/compat\"
+
+    if test "${TEA_PLATFORM}" = "windows"; then
+       TCL_PLATFORM_DIR_NATIVE=${TCL_WIN_DIR_NATIVE}
+    else
+       TCL_PLATFORM_DIR_NATIVE=${TCL_UNIX_DIR_NATIVE}
+    fi
+    # We want to ensure these are substituted so as not to require
+    # any *_NATIVE vars be defined in the Makefile
+    TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+    if test "`uname -s`" = "Darwin"; then
+        # If Tcl was built as a framework, attempt to use
+        # the framework's Headers and PrivateHeaders directories
+        case ${TCL_DEFS} in
+           *TCL_FRAMEWORK*)
+               if test -d "${TCL_BIN_DIR}/Headers" -a -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+               TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"; else
+               TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"; fi
+               ;;
+       esac
+    fi
+
+    AC_SUBST(TCL_TOP_DIR_NATIVE)
+    AC_SUBST(TCL_GENERIC_DIR_NATIVE)
+    AC_SUBST(TCL_UNIX_DIR_NATIVE)
+    AC_SUBST(TCL_WIN_DIR_NATIVE)
+    AC_SUBST(TCL_BMAP_DIR_NATIVE)
+    AC_SUBST(TCL_TOOL_DIR_NATIVE)
+    AC_SUBST(TCL_PLATFORM_DIR_NATIVE)
+
+    AC_SUBST(TCL_INCLUDES)
+    AC_MSG_RESULT([Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+#      Locate the installed public Tcl header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tclinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+    AC_MSG_CHECKING([for Tcl public headers])
+
+    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tclh, [
+       # Use the value from --with-tclinclude, if it was given
+
+       if test x"${with_tclinclude}" != x ; then
+           if test -f "${with_tclinclude}/tcl.h" ; then
+               ac_cv_c_tclh=${with_tclinclude}
+           else
+               AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tcl was built as a framework, attempt to use
+               # the framework's Headers directory
+               case ${TCL_DEFS} in
+                   *TCL_FRAMEWORK*)
+                       list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tcl is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TCL_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tcl's --prefix location,
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+               if test x"${TCL_INCLUDE_SPEC}" != x ; then
+                   d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+                   list="$list `ls -d ${d} 2>/dev/null`"
+               fi
+           fi
+           for i in $list ; do
+               if test -f "$i/tcl.h" ; then
+                   ac_cv_c_tclh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tclh}" = x ; then
+       AC_MSG_ERROR([tcl.h not found.  Please specify its location with --with-tclinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tclh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+#      Locate the private Tk include files
+#
+# Arguments:
+#
+#      Requires:
+#              TK_SRC_DIR      Assumes that TEA_LOAD_TKCONFIG has
+#                               already been called.
+#
+# Results:
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk private include files])
+
+    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+    TK_UNIX_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+    TK_WIN_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+    TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+    TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+    if test "${TEA_PLATFORM}" = "windows"; then
+       TK_PLATFORM_DIR_NATIVE=${TK_WIN_DIR_NATIVE}
+    else
+       TK_PLATFORM_DIR_NATIVE=${TK_UNIX_DIR_NATIVE}
+    fi
+    # We want to ensure these are substituted so as not to require
+    # any *_NATIVE vars be defined in the Makefile
+    TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
+       -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       TK_INCLUDES="${TK_INCLUDES} -I${TK_XLIB_DIR_NATIVE}"
+    fi
+    if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       TK_INCLUDES="${TK_INCLUDES} -I${TK_SRC_DIR_NATIVE}/macosx"
+    fi
+    if test "`uname -s`" = "Darwin"; then
+        # If Tk was built as a framework, attempt to use
+        # the framework's Headers and PrivateHeaders directories
+        case ${TK_DEFS} in
+           *TK_FRAMEWORK*)
+               if test -d "${TK_BIN_DIR}/Headers" -a -d "${TK_BIN_DIR}/PrivateHeaders"; then
+               TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"; fi
+               ;;
+       esac
+    fi
+
+    AC_SUBST(TK_TOP_DIR_NATIVE)
+    AC_SUBST(TK_UNIX_DIR_NATIVE)
+    AC_SUBST(TK_WIN_DIR_NATIVE)
+    AC_SUBST(TK_GENERIC_DIR_NATIVE)
+    AC_SUBST(TK_XLIB_DIR_NATIVE)
+    AC_SUBST(TK_PLATFORM_DIR_NATIVE)
+
+    AC_SUBST(TK_INCLUDES)
+    AC_MSG_RESULT([Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+#      Locate the installed public Tk header files
+#
+# Arguments:
+#      None.
+#
+# Requires:
+#      CYGPATH must be set
+#
+# Results:
+#
+#      Adds a --with-tkinclude switch to configure.
+#      Result is cached.
+#
+#      Substs the following vars:
+#              TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+    AC_MSG_CHECKING([for Tk public headers])
+
+    AC_ARG_WITH(tkinclude, [  --with-tkinclude      directory containing the public Tk header files.], with_tkinclude=${withval})
+
+    AC_CACHE_VAL(ac_cv_c_tkh, [
+       # Use the value from --with-tkinclude, if it was given
+
+       if test x"${with_tkinclude}" != x ; then
+           if test -f "${with_tkinclude}/tk.h" ; then
+               ac_cv_c_tkh=${with_tkinclude}
+           else
+               AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+           fi
+       else
+           if test "`uname -s`" = "Darwin"; then
+               # If Tk was built as a framework, attempt to use
+               # the framework's Headers directory.
+               case ${TK_DEFS} in
+                   *TK_FRAMEWORK*)
+                       list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+                       ;;
+               esac
+           fi
+
+           # Look in the source dir only if Tk is not installed,
+           # and in that situation, look there before installed locations.
+           if test -f "${TK_BIN_DIR}/Makefile" ; then
+               list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+           fi
+
+           # Check order: pkg --prefix location, Tk's --prefix location,
+           # relative to directory of tkConfig.sh, Tcl's --prefix location, 
+           # relative to directory of tclConfig.sh.
+
+           eval "temp_includedir=${includedir}"
+           list="$list \
+               `ls -d ${temp_includedir}        2>/dev/null` \
+               `ls -d ${TK_PREFIX}/include      2>/dev/null` \
+               `ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
+               `ls -d ${TCL_PREFIX}/include     2>/dev/null` \
+               `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+           if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+               list="$list /usr/local/include /usr/include"
+           fi
+           for i in $list ; do
+               if test -f "$i/tk.h" ; then
+                   ac_cv_c_tkh=$i
+                   break
+               fi
+           done
+       fi
+    ])
+
+    # Print a message based on how we determined the include path
+
+    if test x"${ac_cv_c_tkh}" = x ; then
+       AC_MSG_ERROR([tk.h not found.  Please specify its location with --with-tkinclude])
+    else
+       AC_MSG_RESULT([${ac_cv_c_tkh}])
+    fi
+
+    # Convert to a native path and substitute into the output files.
+
+    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+    AC_SUBST(TK_INCLUDES)
+
+    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
+       -o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+       # On Windows and Aqua, we need the X compat headers
+       AC_MSG_CHECKING([for X11 header files])
+       if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+           INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+           TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+           AC_SUBST(TK_XINCLUDES)
+       fi
+       AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+#      Determine the fully qualified path name of the tclsh executable
+#      in the Tcl build directory or the tclsh installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the tclsh executable even if tclsh has not yet been
+#      built in the build directory. The tclsh found is always
+#      associated with a tclConfig.sh file. This tclsh should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+    AC_MSG_CHECKING([for tclsh])
+    if test -f "${TCL_BIN_DIR}/Makefile" ; then
+        # tclConfig.sh is in Tcl build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+        fi
+    else
+        # tclConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+        else
+            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+        fi
+        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${TCLSH_PROG}" ; then
+                REAL_TCL_BIN_DIR="`cd "$i"; pwd`"
+                break
+            fi
+        done
+        TCLSH_PROG="${REAL_TCL_BIN_DIR}/${TCLSH_PROG}"
+    fi
+    AC_MSG_RESULT([${TCLSH_PROG}])
+    AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+#      Determine the fully qualified path name of the wish executable
+#      in the Tk build directory or the wish installed in a bin
+#      directory. This macro will correctly determine the name
+#      of the wish executable even if wish has not yet been
+#      built in the build directory. The wish found is always
+#      associated with a tkConfig.sh file. This wish should be used
+#      only for running extension test cases. It should never be
+#      or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments
+#      none
+#
+# Results
+#      Subst's the following values:
+#              WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+    AC_MSG_CHECKING([for wish])
+    if test -f "${TK_BIN_DIR}/Makefile" ; then
+        # tkConfig.sh is in Tk build directory
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="${TK_BIN_DIR}/wish"
+        fi
+    else
+        # tkConfig.sh is in install location
+        if test "${TEA_PLATFORM}" = "windows"; then
+            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+        else
+            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+        fi
+        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
+              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
+        for i in $list ; do
+            if test -f "$i/${WISH_PROG}" ; then
+                REAL_TK_BIN_DIR="`cd "$i"; pwd`"
+                break
+            fi
+        done
+        WISH_PROG="${REAL_TK_BIN_DIR}/${WISH_PROG}"
+    fi
+    AC_MSG_RESULT([${WISH_PROG}])
+    AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+#      Locate the ${1}Config.sh file and perform a sanity check on
+#      the ${1} compile flags.  These are used by packages like
+#      [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-$1=...
+#
+#      Defines the following vars:
+#              $1_BIN_DIR      Full path to the directory containing
+#                              the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+    #
+    # Ok, lets find the $1 configuration
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-$1
+    #
+
+    if test x"${no_$1}" = x ; then
+       # we reset no_$1 in case something fails here
+       no_$1=true
+       AC_ARG_WITH($1, [  --with-$1              directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+       AC_MSG_CHECKING([for $1 configuration])
+       AC_CACHE_VAL(ac_cv_c_$1config,[
+
+           # First check to see if --with-$1 was specified.
+           if test x"${with_$1config}" != x ; then
+               case ${with_$1config} in
+                   */$1Config.sh )
+                       if test -f ${with_$1config}; then
+                           AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+                           with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+                       fi;;
+               esac
+               if test -f "${with_$1config}/$1Config.sh" ; then
+                   ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+               fi
+           fi
+
+           # then check for a private $1 installation
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in \
+                       ../$1 \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../$1 \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ../../../$1 \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../$1 \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+                       `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+                   if test -f "$i/unix/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i/unix; pwd)`
+                       break
+                   fi
+               done
+           fi
+
+           # check in a few common install locations
+           if test x"${ac_cv_c_$1config}" = x ; then
+               for i in `ls -d ${libdir} 2>/dev/null` \
+                       `ls -d ${exec_prefix}/lib 2>/dev/null` \
+                       `ls -d ${prefix}/lib 2>/dev/null` \
+                       `ls -d /usr/local/lib 2>/dev/null` \
+                       `ls -d /usr/contrib/lib 2>/dev/null` \
+                       `ls -d /usr/lib 2>/dev/null` \
+                       ; do
+                   if test -f "$i/$1Config.sh" ; then
+                       ac_cv_c_$1config=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+
+       if test x"${ac_cv_c_$1config}" = x ; then
+           $1_BIN_DIR="# no $1 configs found"
+           AC_MSG_WARN([Cannot find $1 configuration definitions])
+           exit 0
+       else
+           no_$1=
+           $1_BIN_DIR=${ac_cv_c_$1config}
+           AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+       fi
+    fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+#      Load the $1Config.sh file
+#
+# Arguments:
+#      
+#      Requires the following vars to be set:
+#              $1_BIN_DIR
+#
+# Results:
+#
+#      Subst the following vars:
+#              $1_SRC_DIR
+#              $1_LIB_FILE
+#              $1_LIB_SPEC
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+        AC_MSG_RESULT([loading])
+       . ${$1_BIN_DIR}/$1Config.sh
+    else
+        AC_MSG_RESULT([file not found])
+    fi
+
+    #
+    # If the $1_BIN_DIR is the build directory (not the install directory),
+    # then set the common variable name to the value of the build variables.
+    # For example, the variable $1_LIB_SPEC will be set to the value
+    # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+    # instead of $1_BUILD_LIB_SPEC since it will work with both an
+    # installed and uninstalled version of Tcl.
+    #
+
+    if test -f ${$1_BIN_DIR}/Makefile ; then
+       AC_MSG_WARN([Found Makefile - using build library specs for $1])
+        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+    fi
+
+    AC_SUBST($1_VERSION)
+    AC_SUBST($1_BIN_DIR)
+    AC_SUBST($1_SRC_DIR)
+
+    AC_SUBST($1_LIB_FILE)
+    AC_SUBST($1_LIB_SPEC)
+
+    AC_SUBST($1_STUB_LIB_FILE)
+    AC_SUBST($1_STUB_LIB_SPEC)
+    AC_SUBST($1_STUB_LIB_PATH)
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+#      Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+#      none
+#
+# Results:
+#
+#      Adds the following arguments to configure:
+#              --with-celib=...
+#
+#      Defines the following vars:
+#              CELIB_DIR       Full path to the directory containing
+#                              the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+    # First, look for one uninstalled.
+    # the alternative search directory is invoked by --with-celib
+
+    if test x"${no_celib}" = x ; then
+       # we reset no_celib in case something fails here
+       no_celib=true
+       AC_ARG_WITH(celib,[  --with-celib=DIR        use Windows/CE support library from DIR], with_celibconfig=${withval})
+       AC_MSG_CHECKING([for Windows/CE celib directory])
+       AC_CACHE_VAL(ac_cv_c_celibconfig,[
+           # First check to see if --with-celibconfig was specified.
+           if test x"${with_celibconfig}" != x ; then
+               if test -d "${with_celibconfig}/inc" ; then
+                   ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+               else
+                   AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+               fi
+           fi
+
+           # then check for a celib library
+           if test x"${ac_cv_c_celibconfig}" = x ; then
+               for i in \
+                       ../celib-palm-3.0 \
+                       ../celib \
+                       ../../celib-palm-3.0 \
+                       ../../celib \
+                       `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ${srcdir}/../celib-palm-3.0 \
+                       ${srcdir}/../celib \
+                       `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+                       ; do
+                   if test -d "$i/inc" ; then
+                       ac_cv_c_celibconfig=`(cd $i; pwd)`
+                       break
+                   fi
+               done
+           fi
+       ])
+       if test x"${ac_cv_c_celibconfig}" = x ; then
+           AC_MSG_ERROR([Cannot find celib support library directory])
+       else
+           no_celib=
+           CELIB_DIR=${ac_cv_c_celibconfig}
+           CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+           AC_MSG_RESULT([found $CELIB_DIR])
+       fi
+    fi
+])
+
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/8.x/vqtcl/tests/all.tcl b/8.x/vqtcl/tests/all.tcl
new file mode 100755 (executable)
index 0000000..af48c35
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env tclkit
+
+source [file join [file dir [info script]] initests.tcl]
+
+runAllTests
+
+eval unset [info vars ?]
+eval unset [info vars ??]
+#puts [info vars *]
\ No newline at end of file
diff --git a/8.x/vqtcl/tests/basic.test b/8.x/vqtcl/tests/basic.test
new file mode 100755 (executable)
index 0000000..cba22c1
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+#puts pwd-[pwd]
+#puts auto-$auto_path
+#puts loaded-[info loaded]
+
+test 1 {} {
+    vlerq type ""
+} {}
+
+test 2 {} {
+    vlerq type [list 1 2 3]
+} list
+
+test 3 {} {
+    vlerq refs [list 1 2 3]
+} 1
+
+test 4 {} -body {
+    set v [list 1 2 3]
+    vlerq refs $v
+} -result 2 -cleanup { unset v }
+
+test 5 {} {
+    vlerq viewconv [vlerq def A {a b c}]
+} {data {mdef A} {a b c}}
+
+test 6 {0-bit ints} {
+    vlerq def A:I {0 0 0}
+} {data {mdef A:I} {0 0 0}}
+
+test 7 {1-bit ints} {
+    vlerq def A:I {0 1 1 0 1 0 0 0 1}
+} {data {mdef A:I} {0 1 1 0 1 0 0 0 1}}
+
+test 8 {2-bit ints} {
+    vlerq def A:I {0 1 2 3 2 1 0}
+} {data {mdef A:I} {0 1 2 3 2 1 0}}
+
+test 9 {4-bit ints} {
+    vlerq def A:I {0 1 14 15 2 13}
+} {data {mdef A:I} {0 1 14 15 2 13}}
+
+test 10 {8-bit ints} {
+    vlerq def A:I {0 -1 100 -100}
+} {data {mdef A:I} {0 -1 100 -100}}
+
+test 11 {16-bit ints} {
+    vlerq def A:I {1234 2345 3456}
+} {data {mdef A:I} {1234 2345 3456}}
+
+test 12 {32-bit ints} {
+    vlerq def A:I {123456 0 -654321}
+} {data {mdef A:I} {123456 0 -654321}}
+
+test 13 {64-bit ints} {
+    vlerq def A:L {12345678901 23456789012}
+} {data {mdef A:L} {12345678901 23456789012}}
+
+test 14 {32-bit floats} {
+    vlerq def A:F {1.25 2.5 3.75}
+} {data {mdef A:F} {1.25 2.5 3.75}}
+
+test 15 {64-bit floats} {
+    vlerq def A:D {1234567.25 2345678.75}
+} {data {mdef A:D} {1234567.25 2345678.75}}
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/bits.test b/8.x/vqtcl/tests/bits.test
new file mode 100755 (executable)
index 0000000..ca54d24
--- /dev/null
@@ -0,0 +1,76 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    vlerq bitruns {}
+} {}
+
+test 2 {} {
+    vlerq bitruns {0 1 0 0 1 1 1 0}
+} {0 1 1 2 3 1}
+
+test 3 {} {
+    vlerq bitruns {1 0 1 1 0 0 0 1}
+} {1 1 1 2 3 1}
+
+test 4 {} {
+    vlerq bitruns [split [string repeat 0 20] ""]
+} {0 20}
+
+test 5 {} {
+    vlerq bitruns [split [string repeat 01 10] ""]
+} {0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1}
+
+test 6 {} {
+    vlerq bitruns [split [string repeat 001 10] ""]
+} {0 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1}
+
+test 7 {} {
+    vlerq bitruns [split [string repeat 00001 10] ""]
+} {0 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1}
+
+test 8 {} {
+    vlerq bitruns [split [string repeat 000000001 10] ""]
+} {0 8 1 8 1 8 1 8 1 8 1 8 1 8 1 8 1 8 1 8 1}
+
+test 9 {} {
+    vlerq bitruns [split [string repeat 0011 10] ""]
+} {0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2}
+
+test 10 {} {
+    vlerq bitruns [split [string repeat 0100111 5] ""]
+} {0 1 1 2 3 1 1 2 3 1 1 2 3 1 1 2 3 1 1 2 3}
+
+test 11 {} {
+    vlerq bitruns [split [string repeat 011000 10] ""]
+} {0 1 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 3}
+
+test 12 {} {
+    set z [string repeat 0 100]
+    vlerq bitruns [split ${z}1${z} ""]
+} {0 100 1 100}
+
+test 13 {} {
+    set z [string repeat 0 1000]
+    vlerq bitruns [split ${z}1${z} ""]
+} {0 1000 1 1000}
+
+test 14 {} {
+    set z [string repeat 0 10000]
+    vlerq bitruns [split ${z}1${z} ""]
+} {0 10000 1 10000}
+
+test 15 {} {
+    set z [string repeat 0 10000]
+    vlerq bitruns [split ${z}1${z}1${z} ""]
+} {0 10000 1 10000 1 10000}
+
+unset -nocomplain  z
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/blocked.test b/8.x/vqtcl/tests/blocked.test
new file mode 100755 (executable)
index 0000000..233f8ff
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+test 1 {structure of sample mkblk.db file} {
+    set bdb [vlerq open data/mkblk.db]
+    vlerq structure $bdb
+} ((II))
+
+test 2 {blocked view has 3 blocks} {
+    vlerq get $bdb 0 bv #
+} 4
+
+test 3 {blocked view structure and size} {
+    set v [vlerq blocked [vlerq get $bdb 0 bv]]
+    list [vlerq names $v] [vlerq structure $v] [vlerq size $v]
+} {{k1 k2} II 2500}
+
+test 4 {block sizes} {
+    vlerq counts [vlerq get $bdb 0 bv] _B
+} {999 999 500 2}
+
+test 5 {contents of last block} {
+    vlerq get $bdb 0 bv -1 _B *
+} {{999 -999} {1999 -1999}}
+
+test 6 {blocked view access} {
+    foreach x {0 1 998 999 1000 1998 1999 2000 2498 2499} {
+      lappend k1 [vlerq get $v $x k1]
+      lappend k2 [vlerq get $v $x k2]
+    }
+    list $k1 $k2
+} {{0 1 998 999 1000 1998 1999 2000 2498 2499}\
+     {0 -1 -998 -999 -1000 -1998 -1999 -2000 -2498 -2499}}
+
+unset -nocomplain v x k1 k2
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/column.test b/8.x/vqtcl/tests/column.test
new file mode 100755 (executable)
index 0000000..5c86f1a
--- /dev/null
@@ -0,0 +1,113 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    vlerq colconv {}
+} {}
+
+test 2 {} {
+    vlerq type [vlerq colconv {}]
+} column
+
+test 3 {} {
+    vlerq colconv {1 2 3}
+} {1 2 3}
+
+test 4 {} {
+    vlerq type [vlerq colconv {1 2 3}]
+} column
+
+test 5 {} {
+    vlerq coerce {} I
+} {}
+
+test 6 {} {
+    vlerq coerce {0 1 1000 -0 -1 -1000} I
+} {0 1 1000 0 -1 -1000}
+
+test 7 {} {
+    vlerq coerce {a aa "" 0 1 A AA "" -0 -1} S
+} {a aa {} 0 1 A AA {} -0 -1}
+
+test 8 {} {
+    vlerq iota 0
+} {}
+
+test 9 {} {
+    vlerq iota 5
+} {0 1 2 3 4}
+
+test 10 {} {
+    vlerq omitmap {2 3 7} 9
+} {0 1 4 5 6 8}
+
+test 11 {} {
+    # 2007-02-06 new, allow unsorted map
+    vlerq omitmap {2 7 3} 9
+} {0 1 4 5 6 8}
+
+test 12 {} {
+    vlerq getcol [vlerq def A {a b c}] 0
+} {a b c}
+    
+test 13 {} {
+    vlerq getcol [vlerq def A {a b c}] -1
+} {a b c}
+    
+test 14 {} {
+    vlerq getcol [vlerq def A {a b c}] A
+} {a b c}
+    
+test 15 {} {
+    vlerq getcol [vlerq def A:I {1 2 3}] A
+} {1 2 3}
+    
+test 16 {} {
+    vlerq getcol [vlerq def {A B} {a A b B c C}] 0
+} {a b c}
+    
+test 17 {} {
+    vlerq getcol [vlerq def {A B} {a A b B c C}] 1
+} {A B C}
+    
+test 18 {} {
+    vlerq getcol [vlerq def {A B} {a A b B c C}] -2
+} {a b c}
+    
+test 19 {} {
+    vlerq getcol [vlerq def {A B} {a A b B c C}] -1
+} {A B C}
+    
+test 20 {} {
+    vlerq getcol [vlerq def {A B} {a A b B c C}] A
+} {a b c}
+    
+test 21 {} {
+    vlerq getcol [vlerq def {A B} {a A b B c C}] B
+} {A B C}
+
+test 22 {} {
+    vlerq resizecol {0 11 22 33 44 55} 3 2
+} {0 11 22 0 0 33 44 55}
+
+test 23 {} {
+    set v [vlerq resizecol {0 11 22 33 44 55} 2 -3]
+} {0 11 55}
+
+test 24 {} {
+    set v [vlerq resizecol $v 2 7 ]
+} {0 11 0 0 0 0 0 0 0 55}
+
+test 25 {} {
+    set v [vlerq resizecol $v 1 -8]
+} {0 55}
+
+unset -nocomplain v
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/commit.test b/8.x/vqtcl/tests/commit.test
new file mode 100755 (executable)
index 0000000..3fd9c14
--- /dev/null
@@ -0,0 +1,250 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+set tmp [makeDirectory testfiles.tmp]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    set v [vlerq def A a]
+    set e [vlerq emit $v]
+    string length $e
+} 38
+
+test 2 {} {
+    binary scan $e H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 26 61 00 02 80 83 41 3a 53\
+     81 82 88 81 8a 80 80 00 00 00 00 00 00 16 80 00\
+     00 0b 00 00 00 0b }
+
+test 3 {} {
+    vlerq load $e
+} {data {mdef A} a}
+
+test 4 {} {
+    vlerq emitmods $v
+} ""
+
+test 5 {} {
+    set v [vlerq set $v 0 A x]
+} {data {mdef A} x}
+
+test 6 {} {
+    vlerq mutinfo $v
+} {{data {mdef A} {}}\
+     {data {mdef A} x}\
+     {data {mdef _:I} 1} 0 1 0 0}
+
+test 7 {} {
+    set d [vlerq emitmods $v]
+    string length $d
+} 43
+
+test 8 {} {
+    binary scan $d H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 2b 01 01 78 00 02 80 80 80\
+     81 88 81 81 89 82 8a 81 8c 80 80 80 00 00 00 00\
+     00 00 1b 90 00 00 0e 00 00 00 0d }
+
+test 9 {} {
+    vlerq loadmods $d [vlerq def A a]
+} {data {mdef A} x}
+
+test 10 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb 33 ccc}]
+    set e [vlerq emit $v]
+    string length $e
+} 55
+
+test 11 {} {
+    binary scan $e H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 37 0b 16 21 61 00 62 62 00\
+     63 63 63 00 32 04 80 87 41 3a 49 2c 42 3a 53 83\
+     83 88 89 8b 82 94 80 80 00 00 00 00 00 00 27 80\
+     00 00 11 00 00 00 16 }
+
+test 12 {} {
+    vlerq load $e
+} {data {mdef {A:I B}} {11 22 33} {a bb ccc}}
+
+test 13 {} {
+    vlerq emitmods $v
+} ""
+
+test 14 {} {
+    set v [vlerq set $v 1 A 44 B dd]
+} {data {mdef {A:I B}} {11 44 33} {a dd ccc}}
+
+test 15 {} {
+    vlerq mutinfo $v
+} {{data {mdef {A:I B}} {} {}}\
+     {data {mdef {A:I B}} 44 dd}\
+     {data {mdef {_:I _:I}} 1 1} {0 0 0} {0 1 0} {0 0 0} 0}
+
+test 16 {} {
+    set d [vlerq emitmods $v]
+    string length $d
+} 50
+
+test 17 {} {
+    binary scan $d H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 32 04 01 2c 01 64 64 00 03\
+     80 80 80 81 88 81 81 89 81 8a 81 8b 83 8c 81 8f\
+     80 80 80 00 00 00 00 00 00 22 90 00 00 12 00 00\
+     00 10 }
+
+test 18 {} {
+    vlerq loadmods $d [vlerq def {A:I B} {11 a 22 bb 33 ccc}]
+} {data {mdef {A:I B}} {11 44 33} {a dd ccc}}
+
+test 19 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb}]
+    set w [vlerq insert $v 1 [vlerq def {A:I B} {33 ccc 44 dddd}]]
+    set d [vlerq emitmods $w]
+    string length $d
+} 51
+
+test 20 {} {
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {33 44} {ccc dddd}} 0 0 {0 0} {0 0} {0 1 1 0} {}}
+
+test 21 {} {
+    binary scan $d H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 33 21 2c 63 63 63 00 64 64\
+     64 64 00 54 14 80 80 80 80 82 82 88 89 8a 81 93\
+     80 81 94 80 00 00 00 00 00 00 23 90 00 00 0e 00\
+     00 00 15 }
+
+test 22 {} {
+    vlerq loadmods $d $v
+} {data {mdef {A:I B}} {11 33 44 22} {a ccc dddd bb}}
+
+test 23 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb 33 ccc}]
+    set w [vlerq delete $v 1 1]
+    set d [vlerq emitmods $w]
+    string length $d
+} 31
+
+test 24 {} {
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {} {}} 0 0 {0 1 0} {0 0} {0 0} {}}
+
+test 25 {} {
+    binary scan $d H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 1f 04 80 80 81 88 80 80 80\
+     00 00 00 00 00 00 0f 90 00 00 06 00 00 00 09 }
+
+test 26 {} {
+    vlerq loadmods $d $v
+} {data {mdef {A:I B}} {11 33} {a ccc}}
+
+test 27 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb 33 ccc}]
+    set w [vlerq insert $v 1 [vlerq def {A:I B} {1 1 2 2}]]
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {1 2} {1 2}} 0 0 {0 0 0} {0 0 0} {0 1 1 0 0} {}}
+
+test 28 {} {
+    set w [vlerq insert $w 4 [vlerq def {A:I B} {3 3}]]
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {1 2 3} {1 2 3}} 0 0 {0 0 0} {0 0 0} {0 1 1 0 1 0} {}}
+
+test 29 {} {
+    vlerq loadmods [vlerq emitmods $w] $v
+} {data {mdef {A:I B}} {11 1 2 22 3 33} {a 1 2 bb 3 ccc}}
+
+test 30 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb}]
+    set w [vlerq insert $v 1 [vlerq def {A:I B} {1 c 2 d 3 e}]]
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {1 2 3} {c d e}} 0 0 {0 0} {0 0} {0 1 1 1 0} {}}
+
+test 31 {} {
+    set w [vlerq delete $w 2 1]
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {1 3} {c e}} 0 0 {0 0} {0 0} {0 1 1 0} {}}
+
+test 32 {} {
+    vlerq loadmods [vlerq emitmods $w] $v
+} {data {mdef {A:I B}} {11 1 3 22} {a c e bb}}
+
+test 33 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb 33 ccc 44 dddd 55 eeeee}]
+    set w [vlerq delete $v 1 1]
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {} {}} 0 0 {0 1 0 0 0} {0 0 0 0} {0 0 0 0} {}}
+
+test 34 {} {
+    set w [vlerq delete $w 2 1]
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {} {}} 0 0 {0 1 0 1 0} {0 0 0} {0 0 0} {}}
+
+test 35 {} {
+    vlerq loadmods [vlerq emitmods $w] $v
+} {data {mdef {A:I B}} {11 33 55} {a ccc eeeee}}
+
+test 36 {bitmaps are compressed} {
+    set v [vlerq tag 10000 A]
+    set w [vlerq set $v 5000 A -123]
+    set d [vlerq emitmods $w]
+    string length $d
+} 44 ;# would be 1292 uncompressed
+
+test 37 {} {
+    vlerq slice $w 4998 1 5
+} {data {mdef A:I} {4998 4999 -123 5001 5002}}
+
+test 38 {} {
+    lreplace [vlerq mutinfo $w] 3 5 ? ? ?
+} {{data {mdef A:I} {}} {data {mdef A:I} -123} {data {mdef _:I} 1} ? ? ? 0}
+
+test 39 {} {
+    binary scan $d H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 2c 00 04 e2 20 01 38 70 01\
+     85 80 80 80 87 88 81 81 8f 81 90 80 80 00 00 00\
+     00 00 00 1c 90 00 00 0b 00 00 00 11 }
+
+test 40 {} {
+    vlerq slice [vlerq loadmods $d $v] 4998 1 5
+} {data {mdef A:I} {4998 4999 -123 5001 5002}}
+
+test 41 {} {
+    set v [vlerq def {A B} {a A b B c C d D e E}]
+    set w [vlerq set [vlerq set $v 3 A 3] 1 B 1]
+    set d [vlerq emitmods $w]
+    string length $d
+} 54
+
+test 42 {set high row, then low row} {
+    vlerq mutinfo $w
+} {{data {mdef {A B}} {} {}}\
+     {data {mdef {A B}} {b 3} {1 D}}\
+     {data {mdef {_:I _:I}} {0 1} {1 0}}\
+     {0 0 0 0 0} {0 1 0 1 0} {0 0 0 0 0} {1 0}}
+
+test 43 {} {
+    binary scan $d H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 36 0a 10 33 00 02 01 31 00\
+     02 80 80 80 81 88 82 81 89 82 8a 81 8c 80 81 8d\
+     82 8e 81 90 80 80 80 00 00 00 00 00 00 26 90 00\
+     00 15 00 00 00 11 }
+
+test 44 {} {
+    vlerq loadmods $d $v
+} {data {mdef {A B}} {a b c 3 e} {A 1 C D E}}
+
+unset -nocomplain d e v w
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/emit.test b/8.x/vqtcl/tests/emit.test
new file mode 100755 (executable)
index 0000000..25958a3
--- /dev/null
@@ -0,0 +1,219 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+set tmp [makeDirectory testfiles.tmp]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    set v [vlerq emit 123]
+    string length $v
+} 27
+
+test 2 {} {
+    vlerq load $v
+} 123
+
+test 3 {} -body {
+    binary scan $v H* w
+    regsub -all {..} $w {& }
+} -match glob -result {4? 4? 1a 00 00 00 00 1b 80 80 fb 80 00 00 00 00\
+                         00 00 0b 80 00 00 03 00 00 00 08 }
+test 4 {} {
+    set fd [open $tmp/t1.db w]
+    fconfigure $fd -translation binary
+    set r [vlerq write 124 $fd]
+    close $fd
+    set r
+} 27
+    
+test 5 {} {
+    vlerq open $tmp/t1.db
+} 124
+    
+test 6 {} {
+    vlerq save 125 $tmp/t2.db
+} 27
+    
+test 7 {} {
+    vlerq open $tmp/t2.db
+} 125
+    
+test 8 {} {
+    set v [vlerq emit [vlerq def A {a b c}]]
+    string length $v
+} 42
+
+test 9 {} {
+    vlerq load $v
+} {data {mdef A} {a b c}}
+
+test 10 {} -body {
+    binary scan $v H* w
+    regsub -all {..} $w {& }
+} -match glob -result {4? 4? 1a 00 00 00 00 2a 61 00 62 00 63 00 2a 80\
+                         83 41 3a 53 83 86 88 81 8e 80 80 00 00 00 00 00\
+                         00 1a 80 00 00 0b 00 00 00 0f }
+test 11 {} {
+    set fd [open $tmp/t3.db w]
+    fconfigure $fd -translation binary
+    set r [vlerq write [vlerq def A {a b d}] $fd]
+    close $fd
+    set r
+} 42
+
+test 12 {} {
+    vlerq open $tmp/t3.db
+} {data {mdef A} {a b d}}
+    
+test 13 {} {
+    vlerq save [vlerq def A {a b e}] $tmp/t4.db
+} 42
+
+test 14 {} {
+    vlerq open $tmp/t4.db
+} {data {mdef A} {a b e}}
+
+test 15 {fix binary input conversion: used Tcl string i.s.o. bytearray} {
+    binary scan [vlerq emit [vlerq def A:B \xAB\xAC\xAD\xAE\xAF]] H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 29 ab ac ad ae af 05 80 83\
+     41 3a 42 81 85 88 81 8d 80 80 00 00 00 00 00 00\
+     19 80 00 00 0b 00 00 00 0e }
+    
+test 16 {fix to preserve null bytes inside B fields} {
+    binary scan [vlerq emit [vlerq def A:B \xAB\x00\xAC\x00\xAD]] H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 29 ab 00 ac 00 ad 05 80 83\
+     41 3a 42 81 85 88 81 8d 80 80 00 00 00 00 00 00\
+     19 80 00 00 0b 00 00 00 0e }
+
+test 17 {} {
+    set v [vlerq group [vlerq def A {a aa aaa}] {} v] 
+    set w [vlerq group 123 {} w] 
+    set x [vlerq group [vlerq def {B C} {b c bb cc}] {} x] 
+    set y [vlerq pair $v [vlerq pair $w $x]]
+} {data {mdef {{v A} {w {}} {x {B C}}}} {{data {mdef A} {a aa aaa}}}\
+                                          123\
+                                          {{data {mdef {B C}} {b bb} {c cc}}}}
+test 18 {} {
+    set z [vlerq emit $y]
+    binary scan $z H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 63 61 00 61 61 00 61 61 61\
+     00 32 04 80 83 89 88 82 91 80 80 80 fb 62 00 62\
+     62 00 32 63 00 63 63 00 32 80 82 85 9d 81 a2 80\
+     85 a3 81 a8 80 80 95 76 5b 41 3a 53 5d 2c 77 3a\
+     56 2c 78 5b 42 3a 53 2c 43 3a 53 5d 81 87 93 83\
+     9a 8c a9 80 00 00 00 00 00 00 53 80 00 00 1e 00\
+     00 00 35 }
+     
+test 19 {} {
+    vlerq load $z
+} {data {mdef {{v A} {w {}} {x {B C}}}} {{data {mdef A} {a aa aaa}}}\
+                                          123\
+                                          {{data {mdef {B C}} {b bb} {c cc}}}}
+test 20 {} {
+    set z [vlerq emit [vlerq def {{A B}} [list [vlerq def B {1 2}] \
+                                               [vlerq def B {3 4 5}]]]]
+    binary scan $z H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 3d 31 00 32 00 22 33 00 34\
+     00 35 00 2a 80 82 84 88 81 8c 80 80 83 86 8d 81\
+     93 80 80 86 41 5b 42 3a 53 5d 82 8e 94 80 00 00\
+     00 00 00 00 2d 80 00 00 0b 00 00 00 22 }
+
+test 21 {} {
+    set z [vlerq emit [vlerq def A:V [list [vlerq def B {1 2}] \
+                                           [vlerq def C {3 4 5}]]]]
+    binary scan $z H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 42 31 00 32 00 22 33 00 34\
+     00 35 00 2a 80 83 42 3a 53 82 84 88 81 8c 80 80\
+     83 43 3a 53 83 86 8d 81 93 80 80 83 41 3a 56 82\
+     96 94 80 00 00 00 00 00 00 32 80 00 00 08 00 00\
+     00 2a }
+                         
+test 22 {} {
+    vlerq load $z
+} {data {mdef {{A {}}}} {{data {mdef B} {1 2}} {data {mdef C} {3 4 5}}}}
+
+test 23 {0-bit ints} {
+    vlerq load [vlerq emit [vlerq def A:I {0 0 0}]]
+} {data {mdef A:I} {0 0 0}}
+
+test 24 {1-bit ints} {
+    vlerq load [vlerq emit [vlerq def A:I {0 1 1 0 1 0 0 0 1}]]
+} {data {mdef A:I} {0 1 1 0 1 0 0 0 1}}
+
+test 25 {2-bit ints} {
+    vlerq load [vlerq emit [vlerq def A:I {0 1 2 3 2 1 0}]]
+} {data {mdef A:I} {0 1 2 3 2 1 0}}
+
+test 26 {4-bit ints} {
+    vlerq load [vlerq emit [vlerq def A:I {0 1 14 15 2 13}]]
+} {data {mdef A:I} {0 1 14 15 2 13}}
+    
+test 27 {8-bit ints} {
+    vlerq load [vlerq emit [vlerq def A:I {0 -1 100 -100}]]
+} {data {mdef A:I} {0 -1 100 -100}}
+    
+test 28 {16-bit ints} {
+    vlerq load [vlerq emit [vlerq def A:I {1234 2345 3456}]]
+} {data {mdef A:I} {1234 2345 3456}}
+    
+test 29 {32-bit ints} {
+    vlerq load [vlerq emit [vlerq def A:I {123456 0 -654321}]]
+} {data {mdef A:I} {123456 0 -654321}}
+    
+test 30 {64-bit ints} {
+    vlerq load [vlerq emit [vlerq def A:L {12345678901 23456789012}]]
+} {data {mdef A:L} {12345678901 23456789012}}
+
+test 31 {32-bit floats} {
+    vlerq load [vlerq emit [vlerq def A:F {1.25 2.5 3.75}]]
+} {data {mdef A:F} {1.25 2.5 3.75}}
+
+test 32 {64-bit floats} {
+    vlerq load [vlerq emit [vlerq def A:D {1234567.25 2345678.75}]]
+} {data {mdef A:D} {1234567.25 2345678.75}}
+
+test 33 {} {
+    set v [vlerq tag 10000 A]
+    vlerq get [vlerq meta $v]
+} {A I {}}
+    
+test 34 {} {
+    string length [vlerq emit $v]
+} 20035
+
+test 35 {} {
+    vlerq def A {1 {}}
+} {data {mdef A} {1 {}}}
+    
+test 36 {F117, 2006-12-16} {
+    set z [vlerq emit [vlerq def A {1 {}}]]
+    binary scan $z H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 26 31 00 02 80 83 41 3a 53\
+     82 82 88 81 8a 80 80 00 00 00 00 00 00 16 80 00\
+     00 0b 00 00 00 0b }
+    
+test 37 {F117, 2006-12-16} {
+    vlerq load [vlerq emit [vlerq def A {1 {}}]]
+} {data {mdef A} {1 {}}}
+    
+test 38 {} {
+    vlerq def A {{} 1}
+} {data {mdef A} {{} 1}}
+    
+test 39 {} {
+    vlerq load [vlerq emit [vlerq def A {{} 1}]]
+} {data {mdef A} {{} 1}}
+
+unset -nocomplain r v w x y z fd
+    
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/error.test b/8.x/vqtcl/tests/error.test
new file mode 100755 (executable)
index 0000000..c0eaf9c
--- /dev/null
@@ -0,0 +1,208 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {vlerq without command name} -body {
+    vlerq
+} -returnCodes 1 -result {wrong # args: should be "vlerq command ..."}
+
+test 2 {vlerq with a bad command name} -body {
+    vlerq ?
+} -returnCodes 1 -result {bad command "?": must be open, save, append, bitruns, blocked, clone, coerce, colconv, colmap, colomit, compare, compat, concat, counts, countscol, countview, data, debug, def, delete, deps, emit, emitmods, except, exceptmap, first, get, getcol, getinfo, group, grouped, hashcol, hashfind, hashview, ijoin, insert, intersect, iota, isectmap, join, last, load, loadmods, loop, max, mdef, mdesc, meta, min, mutinfo, namecol, names, omitmap, onecol, pair, product, ref, refs, remap, remapsub, rename, repeat, replace, resizecol, reverse, rowcmp, roweq, rowhash, set, size, slice, sort, sortmap, spread, step, strlookup, structdesc, structure, sum, tag, take, to, type, types, ungroup, union, unionmap, unique, uniquemap, view, viewascol, viewconv, width, or write}
+
+test 3 {colconv without list} -body {
+    vlerq colconv
+} -returnCodes 1 -result {wrong # args: should be "vlerq colconv list"}
+
+test 4 {colconv with a non-list} -body {
+    vlerq colconv "\{"
+} -returnCodes 1 -result {unmatched open brace in list}
+
+test 5 {viewconv without value} -body {
+    vlerq viewconv
+} -returnCodes 1 -result {wrong # args: should be "vlerq viewconv view"}
+
+test 6 {type without value} -body {
+    vlerq type
+} -returnCodes 1 -result {wrong # args: should be "vlerq type any"}
+
+test 7 {refs without value} -body {
+    vlerq refs
+} -returnCodes 1 -result {wrong # args: should be "vlerq refs any"}
+
+test 8 {meta without view} -body {
+    vlerq meta
+} -returnCodes 1 -result {wrong # args: should be "vlerq meta view"}
+
+test 9 {size without view} -body {
+    vlerq size
+} -returnCodes 1 -result {wrong # args: should be "vlerq size view"}
+
+test 10 {negative size} {
+    catch { vlerq size -123 } ;# TODO: return proper error message
+} 1
+
+test 11 {bad variable reference} -body {
+    vlerq size @?
+} -returnCodes 1 -result {can't read "?": no such variable}
+
+test 12 {ref without varname} -body {
+    vlerq ref
+} -returnCodes 1 -result {wrong # args: should be "vlerq ref any ..."}
+
+test 13 {to with too few args} -body {
+    vlerq to ?
+} -returnCodes 1 -result {wrong # args: should be "vlerq to any any"}
+
+test 14 {non-existent view operation} -body {
+    vlerq viewconv {foo bar}
+} -returnCodes 1 -match glob -result {bad command "foo": must be open, *}
+
+test 15 {locate the load path of the vlerq extension} -body {
+    foreach x [info loaded] {
+      foreach {path name} $x break
+      if {$name eq "Vlerq"} break
+    }
+    set path
+    # match either a reasonable real path or the empty string if statically linked
+} -match regexp -result {^(.*/(?:(?:libvlerq)|(?:vqtcl)).*\..*|)$}
+
+test 16 {open is not allowed in safe interpreters} -body {
+    set i [interp create -safe]
+    load $path Vlerq $i
+    catch { $i eval {vlerq open} } msg
+    interp delete $i
+    set msg
+} -match glob -result {bad command "open": must be append, *}
+    
+test 17 {open should be supported in normal interpreters} {
+    catch { vlerq open } msg
+    set msg
+} {wrong # args: should be "vlerq open string"}
+
+test 18 {open file which does not exist} -body {
+    vlerq open blah-blah-blah
+} -returnCodes 1 -result {cannot open file: blah-blah-blah}
+
+test 19 {define zero-width view with data} -body {
+    vlerq def {} {1 2 3}
+} -returnCodes 1 -result {cannot insert in zero-width view}
+    
+test 20 {define with incorrect number of items} -body {
+    vlerq def {A B} {1 2 3}
+} -returnCodes 1 -result {item count not a multiple of column width}
+
+test 21 {view cmd without args} -body {
+    vlerq view
+} -returnCodes 1 -result {wrong # args: should be "view arg ?op ...? ?| ...?"}
+
+test 22 {} -body {
+    vlerq view 3 | ?
+} -returnCodes 1 -match glob -result {bad command "?": must be open, *}
+
+test 23 {untyped sum} -body {
+    set x [vlerq sum [vlerq def A {1 2 3 4}] A]
+} -returnCodes 1 -result {} ;# TODO: sum should return an error message
+
+test 24 {} -body {
+    vlerq def A:I [list ""]
+} -returnCodes 1 -result {expected integer but got ""}
+    
+test 25 {} -body {
+    vlerq def A:I 1.2
+} -returnCodes 1 -result {expected integer but got "1.2"}
+    
+test 26 {} -body {
+    vlerq def A:L 2.3
+} -returnCodes 1 -result {expected integer but got "2.3"}
+    
+test 27 {} -body {
+    vlerq def A:F a
+} -returnCodes 1 -result {expected floating-point number but got "a"}
+    
+test 28 {} -body {
+    vlerq def A:D b
+} -returnCodes 1 -result {expected floating-point number but got "b"}
+
+test 29 {} -body {
+    vlerq def A { {}? }
+} -returnCodes 1 -result \
+    {list element in braces followed by "?" instead of space}
+
+test 30 {} -body {
+    vlerq data [vlerq mdef A] { {}? }
+} -returnCodes 1 -result \
+    {list element in braces followed by "?" instead of space}
+
+test 31 {F118, 2006-12-16} -body {
+    vlerq get [vlerq def a {1 2 3 4}] 4 a
+} -returnCodes 1 -result {row index out of range}
+    
+test 32 {} -body {
+    vlerq get [vlerq def a {1 2 3 4}] -5 a
+} -returnCodes 1 -result {row index out of range}
+    
+test 33 {} -body {
+    vlerq get [vlerq def a {1 2 3 4}] 0 1
+} -returnCodes 1 -result {column index out of range}
+    
+test 34 {} -body {
+    vlerq get [vlerq def a {1 2 3 4}] 0 -2
+} -returnCodes 1 -result {column index out of range}
+    
+test 35 {} -body {
+    vlerq get [vlerq def a {1 2 3 4}] -5 -2
+} -returnCodes 1 -result {row index out of range}
+
+test 36 {} -body {
+    vlerq mdesc {a]b[,}
+} -returnCodes 1 -result {invalid view}
+
+test 37 {} -body {
+    vlerq mdef {{a b c}}
+} -returnCodes 1 -result {invalid view}
+
+test 38 {} -body {
+    vlerq rename
+} -returnCodes 1 -result {wrong # args: should be "vlerq rename view any"}
+
+test 39 {} -body {
+    vlerq getcol
+} -returnCodes 1 -result {wrong # args: should be "vlerq getcol view col"}
+
+test 40 {} -body {
+    vlerq group
+} -returnCodes 1 \
+    -result {wrong # args: should be "vlerq group view col* string"}
+
+test 41 {} -body {
+    # F142, 2007-03-02
+    vlerq def a:0 1
+} -returnCodes 1 -result {invalid view}
+
+test 42 {F150} -body {
+    vlerq colmap [vlerq def A {}] B
+} -returnCodes 1 -result {colmap: invalid column name}
+
+test 43 {F151 concat} -body {
+    set v [vlerq def {A B} {}]
+    set w [vlerq def A {}]
+    vlerq concat $v $w
+} -returnCodes 1 -result {invalid view}
+      
+test 44 {F151 union} -body {
+    vlerq union $v $w
+} -returnCodes 1 -result {invalid view}
+      
+test 45 {incompatible intersect} -body {
+    vlerq intersect $v $w
+} -returnCodes 1 -result {invalid view}
+      
+unset -nocomplain v w x i
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/file.test b/8.x/vqtcl/tests/file.test
new file mode 100755 (executable)
index 0000000..0f6970b
--- /dev/null
@@ -0,0 +1,190 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    vlerq meta [vlerq open data/lkit-le.db]
+} {mdef {{dirs {name parent:I {files {name size:I date:I contents:B}}}}}}
+
+test 2 {} {
+    vlerq meta [vlerq open data/lkit-be.db]
+} {mdef {{dirs {name parent:I {files {name size:I date:I contents:B}}}}}}
+
+test 3 {} -body {
+    set v [vlerq get [vlerq open data/lkit-le.db] 0 0]
+} -match glob -result {data *\
+    {<root> lib app-listk cgi1.6} {-1 0 1 1}\
+    {{data * {main.tcl ChangeLog} {67 167} {1039266154 1046092593} {* *}}\
+     {data * {} {} {} {}}\
+     {data * {pkgIndex.tcl listk.tcl tcl2html.tcl} {72 2452 5801}\
+              {1039266186 1046093102 1046093789} {* * *}}\
+     {data * {pkgIndex.tcl cgi.tcl} {532 65885} {1020940611 1020940611} {* *}}}}
+
+test 4 {} {
+    list [string length [vlerq get $v 0 2 0 3]] \
+         [string length [vlerq get $v 0 2 1 3]] \
+         [string length [vlerq get $v 2 2 0 3]] \
+         [string length [vlerq get $v 2 2 1 3]] \
+         [string length [vlerq get $v 2 2 2 3]] \
+         [string length [vlerq get $v 3 2 0 3]] \
+         [string length [vlerq get $v 3 2 1 3]]
+} {54 130 72 1132 2434 317 15621}
+    
+test 5 {} -body {
+    set w [vlerq get [vlerq open data/lkit-be.db] 0 0]
+} -match glob -result {data *\
+    {<root> lib app-listk cgi1.6} {-1 0 1 1}\
+    {{data * {ChangeLog main.tcl} {167 67} {1046092593 1039266154} {* *}}\
+     {data * {} {} {} {}}\
+     {data * {listk.tcl pkgIndex.tcl tcl2html.tcl} {2452 72 5801}\
+              {1046093102 1039266186 1046093789} {* * *}}\
+     {data * {cgi.tcl pkgIndex.tcl} {65885 532} {1020940611 1020940611} {* *}}}}
+
+test 6 {} {
+    list [string length [vlerq get $w 0 2 0 3]] \
+         [string length [vlerq get $w 0 2 1 3]] \
+         [string length [vlerq get $w 2 2 0 3]] \
+         [string length [vlerq get $w 2 2 1 3]] \
+         [string length [vlerq get $w 2 2 2 3]] \
+         [string length [vlerq get $w 3 2 0 3]] \
+         [string length [vlerq get $w 3 2 1 3]]
+} {130 54 1132 72 2434 15621 317}
+    
+test 7 {} -body {
+    set fd [open data/lkit-le.db]
+    fconfigure $fd -translation binary
+    set data [read $fd]
+    close $fd
+    vlerq get [vlerq load $data] 0 0
+} -match glob -result {data *\
+    {<root> lib app-listk cgi1.6} {-1 0 1 1}\
+    {{data * {main.tcl ChangeLog} {67 167} {1039266154 1046092593} {* *}}\
+     {data * {} {} {} {}}\
+     {data * {pkgIndex.tcl listk.tcl tcl2html.tcl} {72 2452 5801}\
+              {1039266186 1046093102 1046093789} {* * *}}\
+     {data * {pkgIndex.tcl cgi.tcl} {532 65885} {1020940611 1020940611} {* *}}}}
+
+test 8 {} -body {
+    set fd [open data/lkit-be.db]
+    fconfigure $fd -translation binary
+    set data [read $fd]
+    close $fd
+    vlerq get [vlerq load $data] 0 0
+} -match glob -result {data *\
+    {<root> lib app-listk cgi1.6} {-1 0 1 1}\
+    {{data * {ChangeLog main.tcl} {167 67} {1046092593 1039266154} {* *}}\
+     {data * {} {} {} {}}\
+     {data * {listk.tcl pkgIndex.tcl tcl2html.tcl} {2452 72 5801}\
+              {1046093102 1039266186 1046093789} {* * *}}\
+     {data * {cgi.tcl pkgIndex.tcl} {65885 532} {1020940611 1020940611} {* *}}}}
+
+test 9 {} {
+    vlerq structure $v
+} SI(SIIB)
+    
+test 10 {} {
+    vlerq structdesc $v
+} {name:S,parent:I,files[name:S,size:I,date:I,contents:B]}
+    
+test 11 {} {
+    vlerq compat $v $w
+} 1
+    
+test 12 {} {
+    vlerq compare $v $w
+} 1
+    
+test 13 {} {
+    vlerq compare $w $v
+} -1
+    
+test 14 {} {
+    set r {}
+    foreach i {0 1 2 3} {
+      lappend r [vlerq compare [vlerq get $v $i 2] [vlerq get $w $i 2]]
+    }
+    set r
+} {1 0 1 1}
+    
+test 15 {} {
+    set r {}
+    foreach i {0 1 2 3} {
+      lappend r [vlerq compare [vlerq get $w $i 2] [vlerq get $v $i 2]]
+    }
+    set r
+} {-1 0 -1 -1}
+    
+test 16 {} {
+    set r {}
+    foreach i {0 1 2 3} {
+      lappend r [vlerq compare [vlerq sort [vlerq get $v $i 2]] \
+                               [vlerq sort [vlerq get $w $i 2]]]
+    }
+    set r
+} {0 0 0 0}
+
+test 17 {} {
+    vlerq open data/gtest.db
+} {data {mdef {{frequents {drinker bar perweek:I}}\
+                 {likes {drinker beer perday:I}}\
+                 {serves {bar beer quantity:I}}}}\
+      {{data {mdef {drinker bar perweek:I}}\
+         {adam woody sam norm wilt norm lola norm woody pierre}\
+         {lolas cheers cheers cheers joes joes lolas lolas lolas frankies}\
+         {1 5 5 3 2 1 6 2 1 0}}}\
+      {{data {mdef {drinker beer perday:I}}\
+         {adam wilt sam norm norm nan woody lola}\
+         {bud rollingrock bud rollingrock bud sierranevada pabst mickies}\
+         {2 1 2 3 2 1 2 5}}}\
+      {{data {mdef {bar beer quantity:I}}\
+         {cheers cheers joes joes joes lolas lolas winkos frankies}\
+         {bud samaddams bud samaddams mickies mickies pabst rollingrock snafu}\
+         {500 255 217 13 2222 1515 333 432 5}}}}
+    
+test 18 {} {
+    set v [vlerq def {A {B C}} [list a [vlerq def C {1 2 3}] \
+                                     b [vlerq def C {4 5 6 7}]]]
+    vlerq get $v
+} {a {data {mdef C} {1 2 3}} b {data {mdef C} {4 5 6 7}}}
+
+test 19 {} {
+    vlerq get [vlerq load [vlerq emit $v]]
+} {a {data {mdef C} {1 2 3}} b {data {mdef C} {4 5 6 7}}}
+    
+test 20 {} {
+    set v [vlerq def {A B:V} [list a [vlerq def C {1 2 3}] \
+                                   b [vlerq def {D E} {4 5 6 7}]]]
+    vlerq get $v
+} {a {data {mdef C} {1 2 3}} b {data {mdef {D E}} {4 6} {5 7}}}
+
+test 21 {} {
+    vlerq meta [vlerq load [vlerq emit $v]]
+} {mdef {A {B {}}}}
+    
+test 22 {} {
+    set z [vlerq emit $v]
+    binary scan $z H* w
+    regsub -all {..} [string replace $w 0 3 4?4?] {& }
+} {4? 4? 1a 00 00 00 00 5e 61 00 62 00 22 31 00 32\
+     00 33 00 2a 34 00 36 00 22 35 00 37 00 22 80 83\
+     43 3a 53 83 86 8d 81 93 80 80 87 44 3a 53 2c 45\
+     3a 53 82 84 94 81 98 80 84 99 81 9d 80 80 87 41\
+     3a 53 2c 42 3a 56 82 84 88 81 8c 80 9f 9e 80 00\
+     00 00 00 00 00 4e 80 00 00 11 00 00 00 3d }
+                         
+test 23 {} {
+    vlerq get [vlerq load [vlerq emit $v]] 0 *
+} {a {data {mdef C} {1 2 3}}}
+
+test 24 {} {
+    vlerq get [vlerq load [vlerq emit $v]] 1 *
+} {b {data {mdef {D E}} {4 6} {5 7}}}
+
+unset -nocomplain r v w i z fd
+    
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/get.test b/8.x/vqtcl/tests/get.test
new file mode 100755 (executable)
index 0000000..0347fb3
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    set v [vlerq data [vlerq mdef {A B}] {a b c} {d e f}]
+    vlerq get $v
+} {a d b e c f}
+    
+test 2 {}  { vlerq get 5 #         } 5 
+test 3 {}  { vlerq get 5 *         } {{} {} {} {} {}} 
+test 4 {}  { vlerq get 5 * *       } {} 
+test 5 {}  { vlerq get 5 * #       } {0 1 2 3 4} 
+
+test 6 {}  { vlerq get 5 @ #       } 0 
+test 7 {}  { vlerq get 5 @ * 0     } {} 
+test 8 {}  { vlerq get 5 @ *       } {} 
+test 9 {}  { vlerq get 5 @ * *     } {} 
+test 10 {} { vlerq get 5 @ * #     } {} 
+                                    
+test 11 {} { vlerq get 5 @ @ #     } 3
+test 12 {} { vlerq get 5 @ @ * 0   } {name type subv} 
+test 13 {} { vlerq get 5 @ @ * 1   } {S S V} 
+test 14 {} { vlerq get 5 @ @ * 2   } {{} {} {}} 
+test 15 {} { vlerq get 5 @ @ * -1  } {{} {} {}} 
+test 16 {} { vlerq get 5 @ @ * -2  } {S S V} 
+test 17 {} { vlerq get 5 @ @ * -3  } {name type subv} 
+test 18 {} { vlerq get 5 @ @ *     } {{name S {}} {type S {}} {subv V {}}} 
+test 19 {} { vlerq get 5 @ @ * *   } {name S {} type S {} subv V {}} 
+test 20 {} { vlerq get 5 @ @ * #   } {0 1 2} 
+
+test 21 {} { vlerq get "" #        } 0
+test 22 {} { vlerq get "" * 0      } {} 
+test 23 {} { vlerq get "" *        } {} 
+test 24 {} { vlerq get "" * *      } {} 
+test 25 {} { vlerq get "" * #      } {} 
+    
+test 26 {} { vlerq get "" @ #      } 3
+test 27 {} { vlerq get "" @ * 0    } {name type subv} 
+test 28 {} { vlerq get "" @ * 1    } {S S V} 
+test 29 {} { vlerq get "" @ * 2    } {{} {} {}} 
+test 30 {} { vlerq get "" @ * -1   } {{} {} {}} 
+test 31 {} { vlerq get "" @ * -2   } {S S V} 
+test 32 {} { vlerq get "" @ * -3   } {name type subv} 
+test 33 {} { vlerq get "" @ *      } {{name S {}} {type S {}} {subv V {}}} 
+test 34 {} { vlerq get "" @ * *    } {name S {} type S {} subv V {}} 
+test 35 {} { vlerq get "" @ * #    } {0 1 2} 
+
+test 36 {} { vlerq get "" @ * name } {name type subv} 
+test 37 {} { vlerq get "" @ * type } {S S V} 
+test 38 {} { vlerq get "" @ * subv } {{} {} {}} 
+    
+test 39 {} { vlerq get "" @ 0      } {name name type S subv {}} 
+test 40 {} { vlerq get "" @ 1      } {name type type S subv {}} 
+test 41 {} { vlerq get "" @ 2      } {name subv type V subv {}} 
+    
+test 42 {} { vlerq get "" @ # * #  } {0 1 2} 
+
+test 43 {} {
+    vlerq get [vlerq def A {a b c}] * #
+} {0 1 2}
+    
+test 43 {} {
+    vlerq get [vlerq def A {a b c}] -2 #
+} 1
+    
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/hash.test b/8.x/vqtcl/tests/hash.test
new file mode 100755 (executable)
index 0000000..a368165
--- /dev/null
@@ -0,0 +1,431 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    vlerq hashcol I {}
+} {}
+
+test 2 {} {
+    vlerq hashcol I {0 1 10 -0 -1 -10}
+} {0 1 10 0 -1 -10}
+
+test 3 {} {
+    vlerq hashcol L {0 -0 123456789 12345678901 12345678902}
+} {0 0 123456789 -539222985 -539222988}
+
+test 4 {} tcl8.4 {
+    vlerq hashcol D {0 -0 12345.6789 12345.678901 12345.678902}
+} {0 -2147483648 -1493572489 -1494073142 -1500863666}
+
+test 5 {} tcl8.4 {
+    vlerq hashcol F {0 -0 12345.6789 12345.678901 12345.678902}
+} {0 -2147483648 1178658487 1178658487 1178658487}
+
+test 6 {} {
+    vlerq hashcol S {"" a aa A 0 1 -0}
+} {0 698601184 1080305280 -107479360 -938362831 1636964016 1298176885}
+
+test 7 {} {
+    vlerq hashcol B {"" a aa A 0 1 -0}
+} {3166080 698601184 1080305280 -107479360 -938362831 1636964016 1298176885}
+
+test 8 {} {
+    vlerq hashview {}
+} {}
+
+test 9 {} {
+    vlerq hashview [vlerq meta ""]
+} {-236896329 -54087954 589683543}
+
+test 10 {} {
+    vlerq rowhash [vlerq meta ""] 1
+} -54087954
+
+test 11 {} {
+    vlerq rowhash [vlerq def A:B abc] 0
+} -307079773
+
+test 12 {} {
+    vlerq getinfo {} {} 0
+} {{} {0 0 0 0} {}}
+
+test 13 {} {
+    set v [vlerq def A:I {1 2 1 2 1 3}]
+    vlerq getinfo $v $v 0
+} {{0 1 5} {0 0 0 2 0 3 0 1} {1 2 1 2 1 3}}
+
+test 14 {} {
+    set v [vlerq def A {a b a b a c}]
+    set h [vlerq getinfo $v $v 0]
+} {{0 1 5} {2 0 3 1 0 0 0 0}\
+     {698601184 -1021039261 698601184 -1021039261 698601184 1554287586}}
+
+test 15 {} {
+    eval [linsert $h 0 vlerq hashfind $v 1 $v]
+} 1
+
+test 16 {} {
+    eval [linsert $h 0 vlerq hashfind [vlerq def A x] 0 $v]
+} -1
+
+test 17 {} {
+    vlerq getinfo {} {} 1
+} {{} {} {}}
+
+test 18 {} {
+    set v [vlerq def A:I {1 2 1 2 1 3}]
+    vlerq getinfo $v $v 1
+} {{0 1 5} {3 5 6} {0 2 4 1 3 5}}
+
+test 19 {} {
+    set v [vlerq def A {a b a b a c}]
+    vlerq getinfo $v $v 1
+} {{0 1 5} {3 5 6} {0 2 4 1 3 5}}
+
+test 20 {} {
+    vlerq uniquemap {}
+} {}
+
+test 21 {} {
+    vlerq uniquemap [vlerq def A:I {1 2 1 2 1 3}]
+} {0 1 5}
+
+test 22 {} {
+    vlerq uniquemap [vlerq def A:I {1 2 3 4 5 6}]
+} {0 1 2 3 4 5}
+
+test 23 {} {
+    vlerq uniquemap [vlerq def A {a b a b a c}]
+} {0 1 5}
+
+test 24 {} {
+    vlerq uniquemap [vlerq def A {a a a a a a}]
+} {0}
+
+test 25 {} {
+    vlerq uniquemap [vlerq data [vlerq mdef {A B:I}] {a 0 a 0 a -0} \
+                                                     {1 0 0 0 -0 0}]
+} {0 1 2 5}
+
+test 26 {} {
+    vlerq unique [vlerq def A {a b a b a c}]
+} {data {mdef A} {a b c}}
+
+test 27 {} {
+    vlerq isectmap [vlerq def A {d b a}] [vlerq def A {a b c}]
+} {1 2}
+    
+test 28 {} {
+    vlerq intersect [vlerq def A {a b c}] [vlerq def A {d b a}]
+} {data {mdef A} {a b}}
+    
+test 29 {} {
+    vlerq except [vlerq def A {a b c d e}] [vlerq def A {d b a}]
+} {data {mdef A} {c e}}
+    
+test 30 {} {
+    vlerq union [vlerq def A {a b c}] [vlerq def A {e b a d}]
+} {data {mdef A} {a b c e d}}
+    
+test 31 {} {
+    set v [vlerq def A {a b c d e}]
+    vlerq getinfo $v $v 1
+} {{0 1 2 3 4} {1 2 3 4 5} {0 1 2 3 4}}
+
+test 32 {} {
+    set v [vlerq def A {a b b c c c}]
+    vlerq getinfo $v $v 1
+} {{0 1 3} {1 3 6} {0 1 2 3 4 5}}
+
+test 33 {} {
+    set v [vlerq def A {a b a b a c}]
+    vlerq getinfo $v $v 1
+} {{0 1 5} {3 5 6} {0 2 4 1 3 5}}
+
+test 34 {} {
+    set v [vlerq def A {a b c d d}]
+    vlerq getinfo $v $v 1
+} {{0 1 2 3} {1 2 3 5} {0 1 2 3 4}}
+
+test 35 {} {
+    vlerq group [vlerq def A {a b c d e}] 0 G
+} {data {mdef {A {G {}}}} {a b c d e} {1 1 1 1 1}}
+
+test 36 {} {
+    vlerq group [vlerq def A {a b b c c c}] 0 G
+} {data {mdef {A {G {}}}} {a b c} {1 2 3}}
+
+test 37 {} {
+    vlerq group [vlerq def A {a b b c c c}] {} G
+} {data {mdef {{G A}}} {{data {mdef A} {a b b c c c}}}}
+    
+test 38 {} {
+    vlerq group [vlerq def A {a b a b a c}] 0 G
+} {data {mdef {A {G {}}}} {a b c} {3 2 1}}
+
+test 39 {} {
+    vlerq group [vlerq def A {a b a b a c}] A G
+} {data {mdef {A {G {}}}} {a b c} {3 2 1}}
+
+test 40 {} {
+    set v [vlerq group [vlerq def {A B:I} {a 0 b 1 c 1 d 1 d 0}] 0 G]
+} {data {mdef {A {G B:I}}} {a b c d} {{data {mdef B:I} 0}\
+                                        {data {mdef B:I} 1}\
+                                        {data {mdef B:I} 1}\
+                                        {data {mdef B:I} {1 0}}}}
+test 41 {} {
+    vlerq hashcol V [vlerq getcol $v 1]
+} {1 0 0 3}
+    
+test 42 {} {
+    vlerq hashcol V [vlerq getcol $v G]
+} {1 0 0 3}
+    
+test 43 {} {
+    vlerq getinfo [vlerq def A {a b c}] [vlerq def A {a b c d e a b c d e}] 2
+} {{0 1 2} {2 4 6} {0 5 1 6 2 7}}
+
+test 44 {} {
+    vlerq getinfo [vlerq def A {a b c}] [vlerq def A {a c a c}] 2
+} {{0 1 2} {2 2 4} {0 2 1 3}}
+
+test 45 {} {
+    vlerq getinfo [vlerq def A {a b c d}] [vlerq def A {a b c e a b c e}] 2
+} {{0 1 2 3} {2 4 6 6} {0 4 1 5 2 6}}
+
+test 46 {} {
+    vlerq getinfo [vlerq def A {a b c}] [vlerq def A {d e f}] 2
+} {{0 1 2} {0 0 0} {}}
+
+test 47 {} {
+    vlerq getinfo [vlerq def A a] [vlerq def A {a b a b a b}] 2
+} {0 3 {0 2 4}}
+
+test 48 {} {
+    vlerq getinfo [vlerq def A {a a a}] [vlerq def A {a b a b a b}] 2
+} {{0 0 0} 3 {0 2 4}}
+
+test 49 {} {
+    set v [vlerq def {B C} {c d e f c d d e}]
+    set w [vlerq def {B C} {c d c d d e}]
+    vlerq getinfo $v $w 2
+} {{0 1 0 2} {2 2 3} {0 1 2}}
+
+test 50 {} {
+    set v [vlerq def {A B} {}]
+    set w [vlerq def {B C} {}]
+    vlerq isectmap [vlerq namecol $v] [vlerq namecol $w]
+} 1
+
+test 51 {} {
+    vlerq isectmap [vlerq namecol $w] [vlerq namecol $v]
+} 0
+
+test 52 {} {
+    vlerq join [vlerq def A {a b c}] [vlerq def A {a b c d e a b c d e}] J
+} {data {mdef {A {J {}}}} {a b c} {2 2 2}}
+
+test 53 {} {
+    vlerq join [vlerq def A {a b c}] [vlerq def A {a c a c}] J
+} {data {mdef {A {J {}}}} {a b c} {2 0 2}}
+
+test 54 {} {
+    vlerq join [vlerq def A {a b c d}] [vlerq def A {a b c e a b c e}] J
+} {data {mdef {A {J {}}}} {a b c d} {2 2 2 0}}
+
+test 55 {} {
+    vlerq join [vlerq def A {a b c}] [vlerq def A {d e f}] J
+} {data {mdef {A {J {}}}} {a b c} {0 0 0}}
+
+test 56 {} {
+    vlerq join [vlerq def A a] [vlerq def A {a b a b a b}] J
+} {data {mdef {A {J {}}}} a 3}
+
+test 57 {} {
+    vlerq join [vlerq def A {a a a}] [vlerq def A {a b a b a b}] J
+} {data {mdef {A {J {}}}} {a a a} {3 3 3}}
+
+test 58 {} {
+    set v [vlerq data [vlerq mdef {A B}] {a b c} {A B C}]
+    set w [vlerq data [vlerq mdef {A C}] {a c a c} {1 3 1 3}]
+    vlerq join $v $w J
+} {data {mdef {A B {J C}}} {a b c} {A B C} {{data {mdef C} {1 1}}\
+                                              {data {mdef C} {}}\
+                                              {data {mdef C} {3 3}}}}
+test 59 {} {
+    vlerq ungroup [vlerq join $v $w J] -1
+} {data {mdef {A B C}} {a a c c} {A A C C} {1 1 3 3}}
+    
+test 60 {} {
+    vlerq ungroup [vlerq join $v $w J] J
+} {data {mdef {A B C}} {a a c c} {A A C C} {1 1 3 3}}
+    
+test 61 {} {
+    vlerq ijoin $v $w
+} {data {mdef {A B C}} {a a c c} {A A C C} {1 1 3 3}}
+    
+test 62 {} {
+    set v [vlerq def {A B C} {a c d a e f e c d a d e}]
+    set w [vlerq def {B C D} {c d e c d f d e f}]
+    vlerq ijoin $v $w
+} {data {mdef {A B C D}} {a a e e a} {c c c c d} {d d d d e} {e f e f f}}
+
+test 63 {} {
+    vlerq join [vlerq def A {a b c}] [vlerq def B {A B C}] J
+} {data {mdef {A {J B}}} {a b c} {{data {mdef B} {A B C}}\
+                                    {data {mdef B} {A B C}}\
+                                    {data {mdef B} {A B C}}}}
+test 64 {} {
+    set v [vlerq data [vlerq mdef {A B}] {a b c} {A B C}]
+    vlerq join $v $v J
+} {data {mdef {A B {J {}}}} {a b c} {A B C} {1 1 1}}
+
+test 65 {} {
+    set v [vlerq def {A B C} {a c d a e f e c d a d e}]
+    set w [vlerq def {B C D} {c d e c d f d e f}]
+    vlerq join $v $w J
+} {data {mdef {A B C {J D}}} {a a e a} {c e c d} {d f d e}\
+                               {{data {mdef D} {e f}}\
+                                {data {mdef D} {}}\
+                                {data {mdef D} {e f}}\
+                                {data {mdef D} f}}}
+test 66 {} {
+    set r {}
+    foreach x {a b c d e f g} {
+      lappend r [vlerq strlookup $x {b c d e f}]
+    }
+    set r
+} {-1 0 1 2 3 4 -1}
+
+test 67 {} {
+    # vlerq cvstrac #38
+    vlerq except [vlerq def {a b} {1 2 3 4 1 2}] [vlerq def {a b} {3 4}]
+} {data {mdef {a b}} {1 1} {2 2}}
+    
+test 68 {} {
+    vlerq except [vlerq def {a b} {1 2 3 4}] [vlerq def {a b} {3 4}]
+} {data {mdef {a b}} 1 2}
+
+set v [vlerq group [vlerq def {a b} {1 2 3 4 5 6 7 8}] a g]
+
+test 69 {} {
+    vlerq loop $v -collect { [vlerq rowhash $v $(#)] }
+} {-1702861950 -1165893242 -1501528190 1853940110}
+     
+test 70 {} {
+    vlerq getinfo $v $v 0
+} {{0 1 2 3} {4 0 0 3 0 0 2 1} {-1702861950 -1165893242 -1501528190 1853940110}}
+
+test 71 {} {
+    # bt: failed on 2006-12-02
+    set v [vlerq group [vlerq def {a b} {1 2 3 4 5 6 7 8}] a g]
+    vlerq get [vlerq except $v [vlerq slice $v 2 2 2]]
+} {3 {data {mdef b} 4} 7 {data {mdef b} 8}}
+
+test 72 {} {
+    set v [vlerq def {a b} {1 {2 3 4} 2 {3 4 5} 3 4}]
+    set w [vlerq loop $v -collect { [vlerq def d $(b)] }]
+    set w [vlerq def {{c d}} $w]
+    set v [vlerq pair $v $w]
+} {data {mdef {a b {c d}}} {1 2 3}\
+                             {{2 3 4} {3 4 5} 4}\
+                             {{data {mdef d} {2 3 4}}\
+                              {data {mdef d} {3 4 5}}\
+                              {data {mdef d} 4}}}
+test 73 {} {
+    vlerq ungroup $v c
+} {data {mdef {a b d}} {1 1 1 2 2 2 3}\
+                         {{2 3 4} {2 3 4} {2 3 4} {3 4 5} {3 4 5} {3 4 5} 4}\
+                         {2 3 4 3 4 5 4}}
+
+test 74 {join ok} {
+    vlerq join [vlerq def a {1 3}] [vlerq def {a b} {1 2 3 4}] J
+} {data {mdef {a {J b}}} {1 3} {{data {mdef b} 2} {data {mdef b} 4}}}
+    
+test 75 {join bad: F115} {
+    vlerq join [vlerq def a:I {1 3}] [vlerq def {a:I b} {1 2 3 4}] J
+} {data {mdef {a:I {J b}}} {1 3} {{data {mdef b} 2} {data {mdef b} 4}}}
+
+test 76 {} {
+    set v [vlerq def A {1 2 3 4 5}]
+    set w [vlerq def A {4 2 2 6 4}]
+    vlerq exceptmap $v $w
+} {0 2 4}
+    
+test 77 {} {
+    set v [vlerq def A {4 2 2 6 4}]
+    set w [vlerq def A {1 2 3 4 5}]
+    vlerq unionmap $v $w
+} {0 2 4}
+
+test 78 {} {
+    set v [vlerq def {a b c} {1 a b 2 c d}]
+    vlerq group $v {a c} g
+} {data {mdef {a c {g b}}} {1 2} {b d} {{data {mdef b} a} {data {mdef b} c}}}
+
+test 79 {} {
+    # bt: failed on 2007-02-05, see fff/138
+    vlerq group $v {c a} g
+} {data {mdef {c a {g b}}} {b d} {1 2} {{data {mdef b} a} {data {mdef b} c}}}
+
+test 80 {} {
+    vlerq getinfo $v $v 1
+} {{0 1} {1 2} {0 1}}
+
+test 81 {} {
+    vlerq grouped [vlerq colmap $v b] {1 2} {0 1} g
+} {data {mdef {{g b}}} {{data {mdef b} a} {data {mdef b} c}}}
+
+test 82 {} {
+    set v [vlerq def {A B C} {a c d a e f e c d a d e}]
+    set w [vlerq def {B C D} {c d e c d f d e f}]
+    vlerq ijoin $v $w
+} {data {mdef {A B C D}} {a a e e a} {c c c c d} {d d d d e} {e f e f f}}
+
+test 83 {} {
+    vlerq join $v $w J
+} {data {mdef {A B C {J D}}} {a a e a} {c e c d} {d f d e}\
+                               {{data {mdef D} {e f}}\
+                                {data {mdef D} {}}\
+                                {data {mdef D} {e f}}\
+                                {data {mdef D} f}}}
+
+test 84 {} {
+    vlerq isectmap [vlerq meta $v] [vlerq meta $w]
+} {1 2}
+
+test 85 {} {
+    vlerq isectmap [vlerq meta $w] [vlerq meta $v]
+} {0 1}
+
+test 86 {} {
+    # bt: failed on 2007-02-10, see fff/140
+    set x [vlerq colmap $v {C A B}]
+    vlerq ijoin $x $w
+} {data {mdef {C A B D}} {d d d d e} {a a e e a} {c c c c d} {e f e f f}}
+
+test 87 {} {
+    vlerq join $x $w J
+} {data {mdef {C A B {J D}}} {d f d e} {a a e a} {c e c d}\
+                               {{data {mdef D} {e f}}\
+                                {data {mdef D} {}}\
+                                {data {mdef D} {e f}}\
+                                {data {mdef D} f}}}
+
+test 88 {} {
+    vlerq isectmap [vlerq meta $x] [vlerq meta $w]
+} {0 2}
+
+test 89 {} {
+    vlerq isectmap [vlerq meta $w] [vlerq meta $x]
+} {0 1}
+
+unset -nocomplain r v w x h
+    
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/indirect.test b/8.x/vqtcl/tests/indirect.test
new file mode 100755 (executable)
index 0000000..be9d5c2
--- /dev/null
@@ -0,0 +1,91 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    set v [vlerq def A {a b c d e f}]
+    vlerq remap $v {}
+} {data {mdef A} {}}
+
+test 2 {} {
+    vlerq remap $v {1 3 5}
+} {data {mdef A} {b d f}}
+
+test 3 {} {
+    vlerq remap $v {5 3 1 0 2 4}
+} {data {mdef A} {f d b a c e}}
+
+test 4 {} {
+    vlerq remap $v {1 -1 -2 4 3 -1 5}
+} {data {mdef A} {b b b e d d f}}
+
+test 5 {} {
+    vlerq step $v 6 0 1 1
+} {data {mdef A} {a b c d e f}}
+
+test 6 {} {
+    vlerq step 0 1 1 1 1
+} 0
+
+test 7 {} {
+    vlerq step $v 5 1 1 1
+} {data {mdef A} {b c d e f}}
+
+test 8 {} {
+    vlerq step $v 3 0 2 1
+} {data {mdef A} {a a b b c c}}
+
+test 9 {} {
+    vlerq step $v 6 0 1 2
+} {data {mdef A} {a c e a c e}}
+
+test 10 {} {
+    vlerq step $v 6 -1 1 -1
+
+} {data {mdef A} {f e d c b a}}
+
+test 11 {} {
+    vlerq step $v 12 3 1 1
+} {data {mdef A} {d e f a b c d e f a b c}}
+
+test 12 {} {
+    vlerq step $v 12 3 1 -1
+} {data {mdef A} {d c b a f e d c b a f e}}
+
+test 13 {} {
+    vlerq concat [vlerq def A {}] [vlerq def A {1 2 3}]
+} {data {mdef A} {1 2 3}}
+
+test 14 {} {
+    vlerq concat [vlerq def A {a b c}] [vlerq def A {1 2 3}]
+} {data {mdef A} {a b c 1 2 3}}
+
+test 15 {} {
+    set v [vlerq data [vlerq mdef {A B}] {a b c} {1 2 3}]
+    vlerq meta [vlerq grouped $v {1 2 3} {0 1 2} G]
+} {mdef {{G {A B}}}}
+
+test 16 {} {
+    vlerq grouped $v {1 2 3} {0 1 2} G
+} {data {mdef {{G {A B}}}} {{data {mdef {A B}} a 1}\
+                               {data {mdef {A B}} b 2}\
+                               {data {mdef {A B}} c 3}}}
+test 17 {} {
+    set v [vlerq data [vlerq mdef {A B}] {a b c d e f} {1 2 3 4 5 6}]
+    vlerq grouped $v {1 3 6} {0 1 2 3 4 5} G
+} {data {mdef {{G {A B}}}} {{data {mdef {A B}} a 1}\
+                               {data {mdef {A B}} {b c} {2 3}}\
+                               {data {mdef {A B}} {d e f} {4 5 6}}}}
+test 18 {} {
+    vlerq grouped $v {1 3 6} {5 3 4 0 1 2} G
+} {data {mdef {{G {A B}}}} {{data {mdef {A B}} f 6}\
+                               {data {mdef {A B}} {d e} {4 5}}\
+                               {data {mdef {A B}} {a b c} {1 2 3}}}}
+unset -nocomplain v
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/initests.tcl b/8.x/vqtcl/tests/initests.tcl
new file mode 100644 (file)
index 0000000..d896feb
--- /dev/null
@@ -0,0 +1,57 @@
+# common test setup script
+
+#puts "vars: [info vars ?] [info vars ??]"
+
+if {[info exists testsInited]} return
+
+package require Tcl 8.4
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+  package require tcltest 2.2
+  namespace import tcltest::*
+}
+
+singleProcess true ;# run without forking
+
+testsDirectory [file dirname [info script]]
+
+# if run from the tests directory, move one level up
+if {[pwd] eq [testsDirectory]} {
+  cd ..
+}
+
+temporaryDirectory [pwd]
+workingDirectory [file dirname [testsDirectory]]
+
+# TextMate support on Mac OS X: run make before running any test from editor
+if {[info exists env(TM_FILENAME)]} {
+  if {[catch { exec make } msg]} {
+    puts stderr $msg
+    exit 1
+  }
+}
+
+proc readfile {filename} {                                                      
+  set fd [open $filename]                                                       
+  set data [read $fd]                                                           
+  close $fd                                                                     
+  return $data                                                                  
+}
+
+# extract version number from configure.in
+regexp {AC_INIT\(\[vqtcl\],\s*\[([.\d]+)\]\)} [readfile configure.in] - version
+unset -
+
+# make sure the pkgIndex.tcl is found
+if {[lsearch $auto_path [workingDirectory]] < 0} {
+  lappend auto_path [workingDirectory]
+}
+
+testConstraint 64bit            [expr {$tcl_platform(wordSize) == 8}]
+testConstraint bigendian        [expr {$tcl_platform(byteOrder) eq "bigEndian"}]
+testConstraint kitten           [file exists [temporaryDirectory]/kitten.kit]
+testConstraint metakit          [expr {![catch { package require Mk4tcl }]}]
+testConstraint tcl$tcl_version  1
+testConstraint vfs              [expr {![catch { package require vfs }]}]
+
+set testsInited 1
diff --git a/8.x/vqtcl/tests/kitten.test b/8.x/vqtcl/tests/kitten.test
new file mode 100755 (executable)
index 0000000..2f1bc6c
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {load mkclvfs package} vfs {
+    if {[file exists src_tcl/mkclvfs.tcl]} {
+      source src_tcl/mkclvfs.tcl
+    } else {
+      source library/mkclvfs.tcl
+    }
+    package require vfs::mkcl
+} 1.5
+
+test 2 {} -constraints {vfs kitten} -body {
+    set fs [vfs::mkcl::Mount [temporaryDirectory]/kitten.kit /kitten]
+} -match glob -result mkclvfs*
+
+test 3 {} {vfs kitten} {
+    lsort -dict [glob -directory /kitten -tails -types f *]
+} {ChangeLog main.tcl}
+
+test 4 {} {vfs kitten} {
+    lsort -dict [glob -directory /kitten -tails -types d *]
+} {doc lib}
+
+test 5 {} -constraints {vfs kitten} -body {
+    lsort -dict [glob -directory /kitten/lib -tails -types f *]
+} -match glob -result {httpdist.tcl * md5.tcl}
+
+test 6 {} -constraints {vfs kitten} -body {
+    lsort -dict [glob -directory /kitten/lib -tails -types d *]
+} -match glob -result {ascenc-0.11 autoproxy * tls-1.4 wcb2.8 wikit yeti-0.4}
+
+test 7 {} {vfs kitten} {
+    vfs::unmount /kitten
+} {}
+
+unset -nocomplain fs
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/l.large.test b/8.x/vqtcl/tests/l.large.test
new file mode 100755 (executable)
index 0000000..aaa2b66
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+# large file tests, skipped by default because they take a lot of time
+
+source [file join [file dir [info script]] initests.tcl]
+set tmp [makeDirectory testfiles.tmp]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+proc bigview {n} {
+    vlerq repeat [vlerq group [vlerq def A [vlerq iota $n]] {} _B] $n
+}
+
+test 1 {} {
+    set v [bigview 10]
+    vlerq structdesc $v
+} {_B[A:S]}
+
+test 2 {} {
+    vlerq size [vlerq blocked $v]
+} 100
+
+test 3 {} {
+    vlerq save $v $tmp/b1.db
+} 346
+
+test 4 {} -body {
+    vlerq size [vlerq blocked [vlerq open $tmp/b1.db]]
+} -result 100 -cleanup { file delete $tmp/b1.db }
+
+test 5 {} {
+    # correct: gives same result on 32b- and 64b on 2006-12-13
+    string length [vlerq emit [bigview 7088]]
+} 268571360
+
+test 6 {} {
+    # wrong: gave different result (268651792) on 32b and 64b on 2006-12-13
+    # diff = 16 bytes less
+    string length [vlerq emit [bigview 7089]]
+} 268651808
+
+test 7 {} {
+    set v [bigview 10000]
+    vlerq size [vlerq blocked $v]
+} 100000000
+
+test 8 {} {
+    # wrong: gave different result (539080016) on 32b and 64b on 2006-12-13
+    # diff 40160 bytes = 2510x 16 bytes less
+    vlerq save $v $tmp/b2.db
+} 539120176
+
+test 9 {} -body {
+    vlerq size [vlerq blocked [vlerq open $tmp/b2.db]]
+} -result 100000000 -cleanup { file delete $tmp/b2.db }
+
+test 10 {} {
+    set v [bigview 20000]
+    vlerq size [vlerq blocked $v]
+} 400000000
+
+test 11 {} 64bit {
+    vlerq save $v $tmp/b3.db
+} 2378195504
+
+test 12 {} -constraints 64bit -body {
+    vlerq size [vlerq blocked [vlerq open $tmp/b3.db]]
+} -result 400000000 -cleanup { file delete $tmp/b3.db }
+
+test 13 {} {
+    vlerq size [vlerq blocked [bigview 40000]]
+} 1600000000
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/l.leaks.test b/8.x/vqtcl/tests/l.leaks.test
new file mode 100644 (file)
index 0000000..8db3886
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+# memory leaks tests, skipped by default because this may take a lot of time
+
+source [file join [file dir [info script]] initests.tcl]
+
+set cmd {vlerq open data/mkblk.db}
+set cmd {vlerq def {A B C} {1 2 3 4 5 6 7 8 9}}
+set cmd {vlerq loop [vlerq def A {1 2}] { append a $(A) }; unset a "" }
+
+proc memuse {} {
+  set out [exec ps l -p [pid]]
+  lindex [split $out \n] 1 [lsearch $out RSS]
+}
+
+test 0 {} {
+    package require vlerq
+} $version
+
+memuse
+
+test 1 {} {
+    memuse
+} [memuse]
+
+test 2 {} {
+    eval $cmd
+    return
+} {}
+
+test 3 {} {
+    eval $cmd
+    memuse
+} [memuse]
+
+test 4 {} {
+    for {set i 0} {$i < 10000} {incr i} {
+      eval $cmd
+    }
+    memuse
+} [memuse]
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/loop.test b/8.x/vqtcl/tests/loop.test
new file mode 100755 (executable)
index 0000000..996d33a
--- /dev/null
@@ -0,0 +1,123 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+set v [vlerq def {A B C} {1 2 3 11 22 33 111 222 333}]
+
+test 1 {} {
+    set i 0
+    vlerq loop $v c { incr i }
+    set i
+} 3
+
+test 2 {} {
+    set r {}
+    vlerq loop $v c { lappend r $c(#) }
+    set r
+} {0 1 2}
+    
+test 3 {} {
+    set r {}
+    vlerq loop $v c { lappend r $c(B) $c(A) }
+    set r
+} {2 1 22 11 222 111}
+
+set w [vlerq def A {1 2 3 4 5 6 7 8 9}]
+
+test 4 {} {
+    vlerq loop $w c -index 1
+} {0 1 2 3 4 5 6 7 8}
+
+test 5 {} {
+    vlerq loop $w c -index { $c(A) % 2 }
+} {0 2 4 6 8}
+
+test 6 {} {
+    vlerq loop $w c -index { $c(A) > 3 && $c(A) < 6 }
+} {3 4}
+
+test 7 {} {
+    vlerq loop $w c -index { $c(A) == $c(#) + 1 }
+} {0 1 2 3 4 5 6 7 8}
+
+test 8 {} {
+    vlerq get [vlerq loop $w c -where 1]
+} {1 2 3 4 5 6 7 8 9}
+    
+test 9 {} {
+    vlerq get [vlerq loop $w c -where { $c(A) % 2 }]
+} {1 3 5 7 9}
+    
+test 10 {} {
+    vlerq get [vlerq loop $w c -where { $c(A) > 3 && $c(A) < 6 }]
+} {4 5}
+    
+test 11 {} {
+    vlerq get [vlerq loop $w c -where { $c(A) == $c(#) + 1 }]
+} {1 2 3 4 5 6 7 8 9}
+
+test 12 {loop var must end up in current namespace} {
+    namespace eval t1 { vlerq loop $w c1 -index { $c1(A) % 2 } }
+    list [info exists c1] [array get t1::c1]
+} {0 {A 9}}
+namespace forget t1
+
+unset c
+test 13 {loop with parray} -body {
+    vlerq loop [vlerq def {A B C} {1 2 3 11 22 33 111 222 333}] c {parray c}
+} -output {}
+
+test 14 {loop on single column} {
+    set r {}
+    vlerq loop [vlerq def A {1 2 3}] c { lappend r $c(A) }
+    set r
+} {1 2 3}
+unset c
+
+test 15 {try to loop on non-array} {
+    set c 1
+    catch { vlerq loop [vlerq def A {1 2 3}] c { lappend r $c(A) } } r
+    unset c
+    set r
+} {can't trace "c(#)": variable isn't array}
+
+test 16 {} {
+    set r {}
+    vlerq loop [vlerq def A {1 2 3}] {
+      lappend r x$(A)
+      if {$(A) >= 2} break
+      lappend r y$(A)
+    }
+    set r
+} {x1 y1 x2}
+
+test 17 {} {
+    set r {}
+    vlerq loop [vlerq def A {1 2 3}] {
+      lappend r x$(A)
+      if {$(A) >= 2} continue
+      lappend r y$(A)
+    }
+    set r
+} {x1 y1 x2 x3}
+
+test 18 {} {
+    set r {}
+    set c [catch {
+      vlerq loop [vlerq def A {1 2 3}] {
+        lappend r x$(A)
+        if {$(A) >= 2} { error booh! }
+        lappend r y$(A)
+      }
+    } e]
+    lappend r $c $e
+} {x1 y1 x2 1 booh!}
+
+unset -nocomplain r c e v w i
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/m2m.test b/8.x/vqtcl/tests/m2m.test
new file mode 100755 (executable)
index 0000000..26b3a76
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {load m2mvfs package} vfs {
+    if {[file exists src_tcl/m2mvfs.tcl]} {
+      source src_tcl/m2mvfs.tcl
+    } else {
+      source library/m2mvfs.tcl
+    }
+    package require vfs::m2m
+} 1.8
+
+test 2 {} vfs {
+    vfs::m2m::Mount "" mem
+} {m2m}
+
+test 3 {} vfs {
+    ::vfs::filesystem unmount mem
+    # TODO: detect repeated mounts, should probably be an error
+    vfs::m2m::Mount m2m.tmp mem
+} {m2m}
+
+test 4 {} vfs {
+    glob -nocomplain mem/*
+} {}
+
+test 5 {} -constraints vfs -body {
+    set fd [open mem/aa w]
+} -match regexp -result {^(rechan\d+|mem\d+)$}
+
+test 6 {} vfs {
+    glob -nocomplain mem/*
+} mem/aa
+
+test 7 {} vfs {
+    file size mem/aa
+} 0
+
+test 8 {} vfs {
+    puts -nonewline $fd haha
+    close $fd
+    file size mem/aa
+} 4
+
+test 9 {} vfs {
+    file mkdir mem/d
+} {}
+
+test 10 {} vfs {
+    set fd [open mem/d/ff w]
+    puts -nonewline $fd wow
+    close $fd
+    file size mem/d/ff
+} 3
+
+test 11 {} vfs {
+    set fd [open mem/d/eee w]
+    puts -nonewline $fd "Hello world!"
+    close $fd
+    file size mem/d/eee
+} 12
+
+test 12 {} vfs {
+    glob mem/*
+} {mem/aa mem/d}
+
+test 13 {} vfs {
+    glob mem/d/*
+} {mem/d/ff mem/d/eee}
+
+test 14 {} vfs {
+    file delete m2m.tmp
+    vfs::unmount mem
+} {}
+
+test 15 {} vfs {
+    file size m2m.tmp
+} 191
+
+test 16 {} vfs {
+    #puts [exec xxd m2m.tmp]
+    file delete m2m.tmp
+} {}
+
+unset -nocomplain fd
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/mkcl.test b/8.x/vqtcl/tests/mkcl.test
new file mode 100755 (executable)
index 0000000..6b7d9da
--- /dev/null
@@ -0,0 +1,133 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {load mkclvfs package} vfs {
+    if {[file exists src_tcl/mkclvfs.tcl]} {
+      source src_tcl/mkclvfs.tcl
+    } else {
+      source library/mkclvfs.tcl
+    }
+    package require vfs::mkcl
+} 1.5
+
+test 2 {} -constraints vfs -body {
+    set fs [vfs::mkcl::Mount data/lkit-le.db /try1]
+} -match glob -result mkclvfs*
+
+test 3 {} vfs {
+    glob -directory /try1 *
+} {/try1/main.tcl /try1/ChangeLog /try1/lib}
+
+test 4 {} -constraints vfs -body {
+    file stat /try1/lib sb
+    puts ""
+    parray sb
+} -match glob -output {
+sb(atime) = 0
+sb(ctime) = 0
+sb(dev)   = *
+sb(gid)   = 0
+sb(ino)   = 0
+sb(mode)  = 16895
+sb(mtime) = 0
+sb(nlink) = 3
+sb(size)  = 0
+sb(type)  = directory
+sb(uid)   = 0
+}
+
+test 5 {} -constraints vfs -body {
+    file stat /try1/ChangeLog sb
+    puts ""
+    parray sb
+} -match glob -output {
+sb(atime) = 1046092593
+sb(ctime) = 1046092593
+sb(dev)   = *
+sb(gid)   = 0
+sb(ino)   = 0
+sb(mode)  = 33279
+sb(mtime) = 1046092593
+sb(nlink) = 1
+sb(size)  = 167
+sb(type)  = file
+sb(uid)   = 0
+}
+
+test 6 {} vfs {
+    set fd [open /try1/ChangeLog]
+    set data \n
+    append data [read $fd]
+    close $fd
+    set data
+} {
+2003-02-24  jcw
+   * tcl2html.tcl: added Jeff Hobb's code to show tcl file nicely
+   * listk.tcl: adjusted to use the above for *.tcl files
+   * all: added change log
+}
+
+test 7 {} vfs {
+    file size /try1/lib/cgi1.6/cgi.tcl
+} 65885
+
+test 8 {} vfs {
+    vfs::unmount /try1
+} {}
+    
+test 9 {} -constraints vfs -body {
+    set fs [vfs::mkcl::Mount data/lkit-be.db /try2]
+} -match glob -result mkclvfs*
+
+test 10 {} vfs {
+    glob -directory /try2 *
+} {/try2/ChangeLog /try2/main.tcl /try2/lib}
+
+test 11 {} -constraints vfs -body {
+    file stat /try2/ChangeLog sb
+    puts ""
+    parray sb
+} -match glob -output {
+sb(atime) = 1046092593
+sb(ctime) = 1046092593
+sb(dev)   = *
+sb(gid)   = 0
+sb(ino)   = 0
+sb(mode)  = 33279
+sb(mtime) = 1046092593
+sb(nlink) = 1
+sb(size)  = 167
+sb(type)  = file
+sb(uid)   = 0
+}
+
+test 12 {} vfs {
+    set fd [open /try2/ChangeLog]
+    set data \n
+    append data [read $fd]
+    close $fd
+    set data
+} {
+2003-02-24  jcw
+   * tcl2html.tcl: added Jeff Hobb's code to show tcl file nicely
+   * listk.tcl: adjusted to use the above for *.tcl files
+   * all: added change log
+}
+
+test 13 {} vfs {
+    file size /try2/lib/cgi1.6/cgi.tcl
+} 65885
+
+test 14 {} vfs {
+    vfs::unmount /try2
+} {}
+
+unset -nocomplain fs fd sb
+    
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/mklite.test b/8.x/vqtcl/tests/mklite.test
new file mode 100755 (executable)
index 0000000..af46336
--- /dev/null
@@ -0,0 +1,204 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {load mkclvfs package} {
+    if {[file exists src_tcl/mklite.tcl]} {
+      source src_tcl/mklite.tcl
+    } else {
+      source library/mklite.tcl
+    }
+    package require mklite
+} 0.5
+
+test 2 {open mk file} {
+    mklite::file open db data/gtest.db -readonly
+} db
+
+test 3 {root names via vlerq} {
+    vlerq names [vlerq open data/gtest.db]
+} {frequents likes serves}
+
+test 4 {root names} {
+    mklite::file views db
+} {frequents likes serves}
+
+test 5 {mk compatibility layer} {
+    mklite::emulateMk4tcl
+} {}
+
+test 6 {view sizes} {
+    set F db.frequents
+    set L db.likes
+    set S db.serves
+    list [mk::view size $F] [mk::view size $L] [mk::view size $S]
+} {10 8 9}
+
+test 7 {view names} {
+    list [mk::view info $F] [mk::view info $L] [mk::view info $S]
+} {{drinker bar perweek} {drinker beer perday} {bar beer quantity}}
+
+test 8 {get all cols} {
+    mk::get $F!2
+} {drinker sam bar cheers perweek 5}
+
+test 9 {get all cols sizes} {
+    mk::get $F!2 -size
+} {drinker 3 bar 6 perweek 1}
+
+test 10 {get one col} {
+    mk::get $F!2 bar
+} cheers
+
+test 11 {get one col size} {
+    mk::get $F!2 -size bar
+} 6
+
+test 12 {get several cols} {
+    mk::get $F!2 bar drinker
+} {cheers sam}
+
+test 13 {get several cols sizes} {
+    mk::get $F!2 -size bar drinker
+} {6 3}
+
+test 14 {frequents data} {
+    set r ""
+    mk::loop c $F { append r "  " [mk::get $c drinker bar perweek] \n }
+    set r
+} { \
+  adam lolas 1
+  woody cheers 5
+  sam cheers 5
+  norm cheers 3
+  wilt joes 2
+  norm joes 1
+  lola lolas 6
+  norm lolas 2
+  woody lolas 1
+  pierre frankies 0
+}
+
+test 15 {likes data} {
+    set r ""
+    mk::loop c $L { append r "  " [mk::get $c drinker beer perday] \n }
+    set r
+} { \
+  adam bud 2
+  wilt rollingrock 1
+  sam bud 2
+  norm rollingrock 3
+  norm bud 2
+  nan sierranevada 1
+  woody pabst 2
+  lola mickies 5
+}
+
+test 16 {serves data} {
+    set r ""
+    mk::loop c $S { append r "  " [mk::get $c bar beer quantity] \n }
+    set r
+} { \
+  cheers bud 500
+  cheers samaddams 255
+  joes bud 217
+  joes samaddams 13
+  joes mickies 2222
+  lolas mickies 1515
+  lolas pabst 333
+  winkos rollingrock 432
+  frankies snafu 5
+}
+
+test 17 {select} {
+    mk::select $F drinker norm
+} {3 5 7}
+
+test 18 {select bar} {
+    mk::select $F bar lolas
+} {0 6 7 8}
+
+test 19 {select glob} {
+    mk::select $F -glob bar *e*
+} {1 2 3 4 5 9}
+
+test 20 {select globnc} {
+    mk::select $F -globnc bar *E*
+} {1 2 3 4 5 9}
+
+test 21 {select keyword} {
+    mk::select $S -keyword beer M
+} {4 5}
+
+test 22 {select multiple or} {
+    mk::select $S -glob {bar beer} *e*
+} {0 1 2 3 4 5 8}
+
+test 23 {select sort} {
+    mk::select $S -sort beer
+} {0 2 4 5 6 7 1 3 8}
+
+test 24 {select rsort} {
+    mk::select $S -rsort beer
+} {8 3 1 7 6 5 4 2 0}
+
+test 25 {select count} {
+    mk::select $F -count 2 drinker norm
+} {3 5}
+
+test 26 {select first} {
+    mk::select $F -first 2 drinker norm
+} 7
+
+test 27 {select glob and count} {
+    mk::select $F -glob bar *e* -count 3
+} {1 2 3}
+
+test 28 {select multiple criteria} {
+    mk::select $F bar lolas drinker norm
+} 7
+
+test 29 {select nothing} {
+    mk::select $F bar maid
+} {}
+
+test 30 {select multiple criteria empty} {
+    mk::select $F drinker woody bar joes
+} {}
+
+test 31 {list of open files} {
+    mk::file open
+} {db data/gtest.db}
+
+test 32 {} {
+    mk::file close db
+} {}
+    
+test 33 {} {
+    catch { mk::file close db }
+} 1
+    
+test 34 {} {
+    catch { mklite::file views db }
+} 1
+    
+test 35 {load mk file} {
+    mklite::file open db
+    set fd [open data/gtest.db]
+    mklite::file load db $fd
+    close $fd
+    mklite::file views db
+} {frequents likes serves}
+
+test 36 {} {
+    mk::file close db
+} {}
+    
+unset -nocomplain c r S F L fd
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/mutable.test b/8.x/vqtcl/tests/mutable.test
new file mode 100755 (executable)
index 0000000..585a7a6
--- /dev/null
@@ -0,0 +1,324 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    vlerq set [vlerq def A {a b c}] 1 A XYZ
+} {data {mdef A} {a XYZ c}}
+
+test 2 {} {
+    vlerq set [vlerq def A:B {d e f}] 1 A ABC
+} {data {mdef A:B} {d ABC f}}
+
+test 3 {} {
+    vlerq set [vlerq def A:I {1 2 3}] 1 A 22
+} {data {mdef A:I} {1 22 3}}
+
+test 4 {} {
+    vlerq set [vlerq def A:L {1 2 3}] 1 A 112233445566
+} {data {mdef A:L} {1 112233445566 3}}
+
+test 5 {} {
+    vlerq set [vlerq def A:F {1.5 2.5 3.5}] 1 A 4.5
+} {data {mdef A:F} {1.5 4.5 3.5}}
+
+test 6 {} {
+    vlerq set [vlerq def A:D {1.1 2.2 3.3}] 1 A 4.567890123
+} {data {mdef A:D} {1.1 4.567890123 3.3}}
+
+test 7 {} {
+    set v [vlerq group [vlerq def {A B} {a A1 a A2 b B1 b B2}] A G]
+} {data {mdef {A {G B}}} {a b} {{data {mdef B} {A1 A2}}\
+                                  {data {mdef B} {B1 B2}}}}
+test 8 {} {
+    vlerq set $v 1 G [vlerq def B {1 2 3}]
+} {data {mdef {A {G B}}} {a b} {{data {mdef B} {A1 A2}}\
+                                  {data {mdef B} {1 2 3}}}}
+test 9 {} {
+    set v [vlerq def A {a b c d e}]
+    vlerq size [vlerq delete $v 1 3]
+} 2
+
+test 10 {} {
+    vlerq delete $v 1 3
+} {data {mdef A} {a e}}
+
+test 11 {} {
+    vlerq mutinfo [vlerq delete $v 1 3]
+} {{data {mdef A} {}} 0 0 {0 1 1 1 0} {0 0} {0 0} {}}
+
+test 12 {} {
+    vlerq delete $v 0 3
+} {data {mdef A} {d e}}
+
+test 13 {} {
+    vlerq delete $v 2 3
+} {data {mdef A} {a b}}
+
+test 14 {} {
+    vlerq replace $v 1 3 [vlerq def A {1 2 3}]
+} {data {mdef A} {a 1 2 3 e}}
+
+test 15 {} {
+    vlerq mutinfo [vlerq replace $v 1 3 [vlerq def A {1 2 3}]]
+} {{data {mdef A} {1 2 3}} 0 0 {0 1 1 1 0} {0 0} {0 1 1 1 0} {}}
+
+test 16 {} {
+    vlerq append $v [vlerq def A {1 2 3}]
+} {data {mdef A} {a b c d e 1 2 3}}
+
+test 17 {} {
+    vlerq mutinfo [vlerq append $v [vlerq def A {1 2 3}]]
+} {{data {mdef A} {1 2 3}} 0 0 {0 0 0 0 0} {0 0 0 0 0} {0 0 0 0 0 1 1 1} {}}
+
+test 18 {} {
+    set v [vlerq insert $v 2 [vlerq def A {1 2 3}]]
+} {data {mdef A} {a b 1 2 3 c d e}}
+
+test 19 {} {
+    vlerq mutinfo $v
+} {{data {mdef A} {1 2 3}} 0 0 {0 0 0 0 0} {0 0 0 0 0} {0 0 1 1 1 0 0 0} {}}
+
+test 20 {} {
+    vlerq set $v 3 A zz
+} {data {mdef A} {a b 1 zz 3 c d e}}
+
+set v [vlerq def {A B C} {1 2 3 11 22 33 111 222 333}]
+
+test 21 {} {
+    set w [vlerq set $v 1 B x22]
+} {data {mdef {A B C}} {1 11 111} {2 x22 222} {3 33 333}}
+
+test 22 {} {
+    vlerq mutinfo $w
+} {{data {mdef {A B C}} {} {} {}}\
+     {data {mdef {A B C}} 11 x22 33}\
+     {data {mdef {_:I _:I _:I}} 0 1 0} {0 0 0} {0 1 0} {0 0 0} 0}
+
+test 23 {check row count is still 3} {
+    vlerq size $w
+} 3
+    
+test 24 {verify new contents} {
+    vlerq get $w
+} {1 2 3 11 x22 33 111 222 333}
+    
+test 25 {check v has not changed} {
+    vlerq get $v
+} {1 2 3 11 22 33 111 222 333}
+    
+test 26 {insert one row} {
+    set w [vlerq insert $v 1 [vlerq def {A B C} {x y z}]]
+} {data {mdef {A B C}} {1 x 11 111} {2 y 22 222} {3 z 33 333}}
+    
+test 27 {} {
+    vlerq size $w
+} 4
+    
+test 28 {verify new contents} {
+    vlerq get $w
+} {1 2 3 x y z 11 22 33 111 222 333}
+    
+test 29 {check v has not changed} {
+    vlerq get $v
+} {1 2 3 11 22 33 111 222 333}
+    
+test 30 {delete one row} {
+    set w [vlerq delete $v 1 1]
+} {data {mdef {A B C}} {1 111} {2 222} {3 333}}
+    
+test 31 {} {
+    vlerq get $w #
+} 2
+
+test 32 {verify new contents} {
+    vlerq get $w
+} {1 2 3 111 222 333}
+    
+test 33 {check v has not changed} {
+    vlerq get $v
+} {1 2 3 11 22 33 111 222 333}
+
+test 34 {} {
+    set w [vlerq group $v A G]
+    vlerq get $w 0 G
+} {data {mdef {B C}} 2 3}
+
+test 35 {set one item in subview} {
+    vlerq set [vlerq get $w 0 G] 0 B bb
+} {data {mdef {B C}} bb 3}
+
+test 36 {set one item in subview} {
+    set w [vlerq group [vlerq set $v 2 A 1] A G]
+    vlerq set [vlerq get $w 0 G] 1 B bb
+} {data {mdef {B C}} {2 bb} {3 333}}
+
+test 37 {} {
+    set v [vlerq def {A B C} {a b c aa bb cc aaa bbb ccc}]
+    vlerq set $v 1 A x B y C z
+} {data {mdef {A B C}} {a x aaa} {b y bbb} {c z ccc}}
+
+test 38 {} {
+    vlerq set [vlerq def {A B C} {a b c aa bb cc}] -1 A xx
+} {data {mdef {A B C}} {a xx} {b bb} {c cc}}
+
+test 39 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+} {data {mdef A} {1 a b 2}}
+
+test 40 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq append $v [vlerq def A {x y}]
+} {data {mdef A} {1 a b 2 x y}}
+
+test 41 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq insert $v 0 [vlerq def A {x y}]
+} {data {mdef A} {x y 1 a b 2}}
+
+test 42 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq insert $v 1 [vlerq def A {x y}]
+} {data {mdef A} {1 x y a b 2}}
+
+test 43 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq insert $v 2 [vlerq def A {x y}]
+} {data {mdef A} {1 a x y b 2}}
+
+test 44 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq insert $v 3 [vlerq def A {x y}]
+} {data {mdef A} {1 a b x y 2}}
+
+test 45 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq insert $v 4 [vlerq def A {x y}]
+} {data {mdef A} {1 a b 2 x y}}
+
+test 46 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 0 1
+} {data {mdef A} {a b 2}}
+
+test 47 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 1 1
+} {data {mdef A} {1 b 2}}
+
+test 48 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 2 1
+} {data {mdef A} {1 a 2}}
+
+test 49 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 3 1
+} {data {mdef A} {1 a b}}
+
+test 50 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 0 2
+} {data {mdef A} {b 2}}
+
+test 51 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 1 2
+} {data {mdef A} {1 2}}
+
+test 52 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 2 2
+} {data {mdef A} {1 a}}
+
+test 53 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 0 3
+} {data {mdef A} 2}
+
+test 54 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 1 3
+} {data {mdef A} 1}
+
+test 55 {} {
+    set v [vlerq insert [vlerq def A {1 2}] 1 [vlerq def A {a b}]]
+    vlerq delete $v 0 4
+} {data {mdef A} {}}
+
+test 56 {insertion when there are no columns} {
+    vlerq insert 3 0 5
+} 8
+
+test 57 {} {
+    set v [vlerq def A {a b c d e f g h i j k l m n o p q r s t u v w x y z}]
+    for {set i 1} {$i < 25} {incr i 2} {
+      set v [vlerq set $v $i A $i]
+    }
+    set v
+} {data {mdef A} {a 1 c 3 e 5 g 7 i 9 k 11 m 13 o 15 q 17 s 19 u 21 w 23 y z}}
+
+test 58 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb 33 ccc}]
+    set w [vlerq insert $v 2 [vlerq def {A:I B} {1 1 2 2}]]
+} {data {mdef {A:I B}} {11 22 1 2 33} {a bb 1 2 ccc}}
+
+test 59 {2nd insert before} {
+    set w [vlerq insert $w 1 [vlerq def {A:I B} {3 3}]]
+} {data {mdef {A:I B}} {11 3 22 1 2 33} {a 3 bb 1 2 ccc}}
+
+test 60 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb 33 ccc}]
+    set w [vlerq insert $v 1 [vlerq def {A:I B} {1 1 2 2}]]
+} {data {mdef {A:I B}} {11 1 2 22 33} {a 1 2 bb ccc}}
+
+test 61 {2nd insert after} {
+    set w [vlerq insert $w 4 [vlerq def {A:I B} {3 3}]]
+} {data {mdef {A:I B}} {11 1 2 22 3 33} {a 1 2 bb 3 ccc}}
+
+test 62 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb}]
+    set w [vlerq insert $v 1 [vlerq def {A:I B} {1 c 2 d 3 e}]]
+} {data {mdef {A:I B}} {11 1 2 3 22} {a c d e bb}}
+
+test 63 {delete inside insert} {
+    set w [vlerq delete $w 2 1]
+} {data {mdef {A:I B}} {11 1 3 22} {a c e bb}}
+
+test 64 {} {
+    vlerq mutinfo $w
+} {{data {mdef {A:I B}} {1 3} {c e}} 0 0 {0 0} {0 0} {0 1 1 0} {}}
+
+test 65 {} {
+    set v [vlerq def {A:I B} {11 a 22 bb 33 ccc 44 dddd 55 eeeee}]
+    set w [vlerq delete $v 1 1]
+} {data {mdef {A:I B}} {11 33 44 55} {a ccc dddd eeeee}}
+
+test 66 {two independent deletes} {
+    vlerq delete $w 2 1
+} {data {mdef {A:I B}} {11 33 55} {a ccc eeeee}}
+
+test 67 {set high row, then low row} {
+    set v [vlerq def {A B} {a A b B c C d D e E}]
+    set w [vlerq set [vlerq set $v 3 A 3] 1 B 1]
+} {data {mdef {A B}} {a b c 3 e} {A 1 C D E}}
+
+test 68 {} {
+    vlerq mutinfo $w
+} {{data {mdef {A B}} {} {}}\
+     {data {mdef {A B}} {b 3} {1 D}}\
+     {data {mdef {_:I _:I}} {0 1} {1 0}}\
+     {0 0 0 0 0} {0 1 0 1 0} {0 0 0 0 0} {1 0}}
+
+test 69 {} {
+    vlerq insert [vlerq def A {}] 0 [vlerq def A {1 2 3}]
+} {data {mdef A} {1 2 3}}
+
+unset -nocomplain v w i
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/ops.test b/8.x/vqtcl/tests/ops.test
new file mode 100755 (executable)
index 0000000..63fe88a
--- /dev/null
@@ -0,0 +1,464 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {view of empty string} {
+    vlerq viewconv {}
+} {}
+
+test 2 {view with no columns} {
+    vlerq viewconv 5
+} 5
+
+test 3 {view type of empty meta view} {
+    vlerq type [vlerq viewconv {}]
+} view
+
+test 4 {view type of no-column view} {
+    vlerq type [vlerq viewconv 5]
+} view
+
+test 5 {refcount of empty meta view} {
+    vlerq refs [vlerq viewconv {}]
+} 1
+
+test 6 {refcount of no-column view} {
+    vlerq refs [vlerq viewconv 5]
+} 1
+
+test 7 {size of empty view} {
+    vlerq size ""
+} 0
+
+test 8 {size of no-column view} {
+    vlerq size 5
+} 5
+
+test 9 {width of empty view} {
+    vlerq size [vlerq meta ""]
+} 3
+
+test 10 {width of no-column view} {
+    vlerq size [vlerq meta 5]
+} 0
+
+test 11 {meta meta view} {
+    set m [vlerq meta ""]
+} {mdef {name type {subv {}}}}
+
+test 12 {size of meta meta view} {
+    vlerq size $m
+} 3
+
+test 13 {width of meta meta view} {
+    vlerq size [vlerq meta $m]
+} 3
+
+test 14 {meta meta meta view} {
+    vlerq meta $m
+} {mdef {name type {subv {}}}}
+
+test 15 {empty meta view} {
+    set e [vlerq get $m 2 2]
+} {}
+
+test 16 {size of empty meta view} {
+    vlerq size $e
+} 0
+
+test 17 {width of empty meta view} {
+    vlerq size [vlerq meta $e]
+} 3
+
+test 18 {meta empty meta view} {
+    vlerq meta $e
+} {mdef {name type {subv {}}}}
+
+test 19 {contents of meta meta view} {
+    vlerq get $m
+} {name S {} type S {} subv V {}}
+
+test 20 {empty meta view from list} {
+    # this could trigger a different code path, see updateViewStrRep
+    set v [lreplace x 0 0]
+    vlerq viewconv $v
+} {}
+
+test 21 {no-column view from list} {
+    # this could trigger a different code path, see updateViewStrRep
+    set v [list 7]
+    vlerq viewconv $v
+} 7
+
+test 22 {to operator} {
+    vlerq to 12 v
+    vlerq size $v
+} 12
+
+test 23 {to operator result} {
+    vlerq to 12 v
+} 12
+
+test 24 {to result use} {
+    vlerq size @v
+} 12
+
+test 25 {to must set local var} -body {
+    # bt: failed on 2006-12-02
+    unset -nocomplain a
+    proc a {} { vlerq to [vlerq def a {1 2 3 4}] a; set a }
+    a
+} -result {data {mdef a} {1 2 3 4}} -cleanup { rename a "" }
+
+test 26 {data with meta view} {
+    set v [vlerq data [vlerq meta ""] {A B} {S I} {"" ""}]
+} {mdef {A B:I}}
+
+test 27 {mdef operator} {
+    vlerq mdef {A:S B:I}
+} {mdef {A B:I}}
+
+test 28 {mdesc operator} {
+    vlerq mdesc {A,B:I,C[D:L,E:F],F:V}
+} {mdef {A B:I {C {D:L E:F}} {F {}}}}
+
+test 29 {data operator} {
+    set v [vlerq data [vlerq mdef {A:S B:I}] {a b} {1 2}]
+} {data {mdef {A B:I}} {a b} {1 2}}
+
+test 30 {} {
+    set v [vlerq data [vlerq mdef {A B}] {a b c} {d e f}]
+    vlerq colmap $v {}
+} 3
+
+test 31 {} {
+    vlerq colmap $v 1
+} {data {mdef B} {d e f}}
+
+test 32 {} {
+    vlerq colmap $v {1 0}
+} {data {mdef {B A}} {d e f} {a b c}}
+
+test 33 {} {
+    vlerq colmap $v {0 1 0}
+} {data {mdef {A B A}} {a b c} {d e f} {a b c}}
+
+test 34 {} {
+    vlerq colmap $v B
+} {data {mdef B} {d e f}}
+
+test 35 {} {
+    vlerq colmap $v {B A}
+} {data {mdef {B A}} {d e f} {a b c}}
+
+test 36 {} {
+    vlerq colmap $v {A B A}
+} {data {mdef {A B A}} {a b c} {d e f} {a b c}}
+
+test 37 {} {
+    vlerq colmap $v {-1 -2}
+} {data {mdef {B A}} {d e f} {a b c}}
+
+test 38 {} {
+    vlerq repeat [vlerq def A {a b c}] 2
+} {data {mdef A} {a b c a b c}}
+
+test 39 {} {
+    vlerq spread [vlerq def A {a b c}] 2
+} {data {mdef A} {a a b b c c}}
+
+test 40 {} {
+    set v [vlerq data [vlerq mdef {A B}] {a b} {c d}]
+    set w [vlerq data [vlerq mdef {C D}] {1 2} {3 4}]
+    vlerq product $v $w
+} {data {mdef {A B C D}} {a a b b} {c c d d} {1 2 1 2} {3 4 3 4}}
+
+test 41 {} {
+    vlerq clone [vlerq def A {a b c}]
+} {data {mdef A} {}}
+
+test 42 {} {
+    vlerq reverse [vlerq def A {a b c}]
+} {data {mdef A} {c b a}}
+
+test 43 {} {
+    vlerq first [vlerq def A {a b c}] 0
+} {data {mdef A} {}}
+
+test 44 {} {
+    vlerq first [vlerq def A {a b c}] 2
+} {data {mdef A} {a b}}
+
+test 45 {} {
+    vlerq first [vlerq def A {a b c}] 4
+} {data {mdef A} {a b c}}
+
+test 46 {} {
+    vlerq last [vlerq def A {a b c}] 0
+} {data {mdef A} {}}
+
+test 47 {} {
+    vlerq last [vlerq def A {a b c}] 2
+} {data {mdef A} {b c}}
+
+test 48 {} {
+    vlerq last [vlerq def A {a b c}] 4
+} {data {mdef A} {a b c}}
+
+test 49 {} {
+    vlerq slice [vlerq def A {a b c d e f g h i}] 1 2 3
+} {data {mdef A} {b d f}}
+
+test 50 {} {
+    vlerq slice [vlerq def A {a b c d e f g h i}] 7 -2 3
+} {data {mdef A} {h f d}}
+
+test 51 {} {
+    vlerq names ""
+} {name type subv}
+    
+test 52 {} {
+    vlerq names [vlerq meta ""]
+} {name type subv}
+
+test 53 {} {
+    vlerq types ""
+} {S S V}
+    
+test 54 {} {
+    vlerq types [vlerq meta ""]
+} {S S V}
+
+test 55 {} {
+    vlerq take [vlerq def A {a b c}] 2
+} {data {mdef A} {a b}}
+
+test 56 {} {
+    vlerq take [vlerq def A {a b c}] 7
+} {data {mdef A} {a b c a b c a}}
+
+test 57 {} {
+    vlerq take [vlerq def A {a b c}] -2
+} {data {mdef A} {c b}}
+
+test 58 {} {
+    vlerq take [vlerq def A {a b c}] -7
+} {data {mdef A} {c b a c b a c}}
+
+test 59 {} {
+    vlerq namecol ""
+} {data {mdef name} {name type subv}}
+
+test 60 {} {
+    vlerq structure 123
+} {}
+    
+test 61 {} {
+    vlerq structure ""
+} SSV
+    
+test 62 {} {
+    vlerq structdesc 123
+} {}
+    
+test 63 {} {
+    vlerq structdesc ""
+} {name:S,type:S,subv:V}
+    
+test 64 {} {
+    vlerq compat 12 34
+} 1
+    
+test 65 {} {
+    vlerq compat "" ""
+} 1
+    
+test 66 {} {
+    vlerq compat 12 ""
+} 0
+    
+test 67 {} {
+    vlerq compat "" 34
+} 0
+    
+test 68 {} {
+    vlerq compat "" [vlerq meta ""]
+} 1
+
+test 69 {} {
+    vlerq compat [vlerq def A {1 2 3}] [vlerq def B {1 2 3}]
+} 1
+
+test 70 {} {
+    vlerq compat [vlerq def A {1 2 3}] [vlerq def A:I {1 2 3}]
+} 0
+
+test 71 {} {
+    vlerq compat [vlerq def {{A {B C}}} {}] [vlerq def {{D {E F}}} {}]
+} 1
+
+test 72 {} {
+    vlerq compat [vlerq def {{A {B C}}} {}] [vlerq def {{A {B C:I}}} {}]
+} 0
+
+test 73 {} {
+    vlerq def A ""
+} {data {mdef A} {}}
+    
+test 74 {} {
+    vlerq def A {a b c}
+} {data {mdef A} {a b c}}
+    
+test 75 {} {
+    vlerq def {A B} ""
+} {data {mdef {A B}} {} {}}
+    
+test 76 {} {
+    vlerq def {A B} {a b c d}
+} {data {mdef {A B}} {a c} {b d}}
+    
+test 77 {} {
+    vlerq def {A B:I} {a 1 b 02 c -03}
+} {data {mdef {A B:I}} {a b c} {1 2 -3}}
+
+test 78 {} {
+    vlerq tag 0 T
+} {data {mdef T:I} {}}
+
+test 79 {} {
+    vlerq tag 5 T
+} {data {mdef T:I} {0 1 2 3 4}}
+
+test 80 {} {
+    vlerq tag [vlerq def A {a b c}] T
+} {data {mdef {A T:I}} {a b c} {0 1 2}}
+
+test 81 {} {
+    vlerq tag [vlerq def {A B} {a A b B c C}] T
+} {data {mdef {A B T:I}} {a b c} {A B C} {0 1 2}}
+
+test 82 {} {
+    set v [vlerq def {A B C} {1 2 3 4 5 6 7 8 9}]
+    vlerq rename $v {B X}
+} {data {mdef {A X C}} {1 4 7} {2 5 8} {3 6 9}}
+
+test 83 {} {
+    vlerq rename $v {B X -1 Y}
+} {data {mdef {A X Y}} {1 4 7} {2 5 8} {3 6 9}}
+
+test 84 {} {
+    vlerq rename $v {A B B C C A}
+} {data {mdef {B C A}} {1 4 7} {2 5 8} {3 6 9}}
+
+test 85 {omit} {
+    set T [vlerq def {A B C D} {a b c d a b e f b c e f e d c d e d e f a b d e}]
+    vlerq colomit $T {2 3} 
+} {data {mdef {A B}} {a a b e e a} {b b c d d b}}
+
+test 86 {omit reorder} {
+    vlerq colomit $T {3 2} 
+} {data {mdef {A B}} {a a b e e a} {b b c d d b}}
+
+test 87 {omit named} {
+    set T [vlerq def {A B C D} {a b c d a b e f b c e f e d c d e d e f a b d e}]
+    vlerq colomit $T {C D} 
+} {data {mdef {A B}} {a a b e e a} {b b c d d b}}
+
+test 88 {omit named reorder} {
+    vlerq colomit $T {D C} 
+} {data {mdef {A B}} {a a b e e a} {b b c d d b}}
+
+test 89 {} {
+    set v [vlerq def {A B C} {1 2 3 4 5 6}]
+    vlerq colomit $v {C B} 
+} {data {mdef A} {1 4}}
+
+test 90 {} {
+    vlerq colomit $v {A A} 
+} {data {mdef {B C}} {2 5} {3 6}}
+
+test 91 {} {
+    vlerq colomit $v {} 
+} {data {mdef {A B C}} {1 4} {2 5} {3 6}}
+
+test 92 {} {
+    vlerq viewascol [vlerq def {A B:I C} {1 2 3 4 5 6 7 8 9}]
+} {{1 4 7} {2 5 8} {3 6 9}}
+
+test 93 {} {
+    set v [vlerq def {A B} {1 2 3 4 1 2}]
+    vlerq rowcmp $v 0 $v 1
+} -1
+    
+test 94 {} {
+    set v [vlerq def {A B} {1 2 3 4 1 2}]
+    vlerq rowcmp $v 0 $v 2
+} 0
+
+test 95 {} {
+    vlerq def {} {}
+} 0
+
+test 96 {} {
+    set v [vlerq def {A B} {a b c d e f}]
+    vlerq onecol $v A
+} {data {mdef A} {a c e}}
+    
+test 97 {} {
+    set v [vlerq def {A B} {a b c d e f}]
+    vlerq onecol $v -1
+} {data {mdef B} {b d f}}
+
+test 98 {empty string col} {
+    vlerq load [vlerq emit [vlerq def A {"" "" ""}]]
+} {data {mdef A} {{} {} {}}}
+     
+test 99 {16-bit getter} {
+    vlerq load [vlerq emit [vlerq def A:I {123 456 789}]]
+} {data {mdef A:I} {123 456 789}}
+
+test 100 {} {
+    vlerq pair [vlerq def A {a b c}] [vlerq def B {1 2 3}]
+} {data {mdef {A B}} {a b c} {1 2 3}}
+
+test 101 {} {
+    vlerq pair [vlerq def A {a b c}] 2
+} {data {mdef A} {a b}}
+
+test 102 {} {
+    vlerq pair [vlerq def A {a b c}] 3
+} {data {mdef A} {a b c}}
+
+test 103 {} {
+    vlerq pair [vlerq def A {a b c}] 4
+} {data {mdef A} {a b c}}
+
+test 104 {} {
+    vlerq pair 2 [vlerq def A {a b c}]
+} {data {mdef A} {a b}}
+
+test 105 {} {
+    vlerq pair 3 [vlerq def A {a b c}]
+} {data {mdef A} {a b c}}
+
+test 106 {} {
+    vlerq pair 4 [vlerq def A {a b c}]
+} {data {mdef A} {a b c}}
+
+test 107 {} {
+    # bt: crashed on 2007-02-10, see fff/139
+    vlerq pair [vlerq def A {a b c}] [vlerq def B {1 2}]
+} {data {mdef {A B}} {a b} {1 2}}
+
+test 108 {} {
+    vlerq pair [vlerq def A {a b}] [vlerq def B {1 2 3}]
+} {data {mdef {A B}} {a b} {1 2}}
+
+unset -nocomplain T e v w m
+     
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/ratcl.test b/8.x/vqtcl/tests/ratcl.test
new file mode 100755 (executable)
index 0000000..7a6466d
--- /dev/null
@@ -0,0 +1,376 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load ratcl package} {
+    if {[file exists src_tcl/ratcl.tcl]} {
+      source src_tcl/ratcl.tcl
+    } else {
+      source library/ratcl.tcl
+    }
+    package require ratcl
+} 4
+
+test 1 {} {
+    view {A B} def {1 2 11 22 111 222} | reverse | get
+} {111 222 11 22 1 2}
+
+test 2 {} {
+    view {A B} def {1 2 11 22 111 222} | reverse | dump
+} { \
+  A    B  
+  ---  ---
+  111  222
+  11   22 
+  1    2  }
+
+test 3 {} {
+    view 3 | dump
+} {  (3 rows, no columns)}
+    
+test 4 {} {
+    view "" | dump
+} { \
+  name  type  subv
+  ----  ----  ----}
+
+# tests copied from v3
+set v [view {A B C} def {1 2 3 11 22 33 111 222 333}]
+
+test 5 {} {
+    view $v names
+} {A B C}
+
+test 6 {} {
+    view $v types
+} {S S S}
+    
+test 7 {} {
+    view $v width
+} 3
+
+test 8 {} {
+    vlerq get $v *
+} {{1 2 3} {11 22 33} {111 222 333}}
+
+test 9 {} {
+    view $v first 2 | get *
+} {{1 2 3} {11 22 33}}
+
+test 10 {} {
+    view $v last 2 | get *
+} {{11 22 33} {111 222 333}}
+
+test 11 {} {
+    view $v reverse | get *
+} {{111 222 333} {11 22 33} {1 2 3}}
+
+test 12 {} {
+    view $v repeat 2 | get *
+} {{1 2 3} {11 22 33} {111 222 333} {1 2 3} {11 22 33} {111 222 333}}
+
+test 13 {} {
+    view $v spread 2 | get *
+} {{1 2 3} {1 2 3} {11 22 33} {11 22 33} {111 222 333} {111 222 333}}
+
+test 14 {} {
+    view $v dump
+} { \
+  A    B    C  
+  ---  ---  ---
+  1    2    3  
+  11   22   33 
+  111  222  333}
+
+test 15 {} -body {
+    view $v html
+} -match glob -result {<table><style type="text/css"><!--*--></style>
+<tr><th class="row"></th><th><i>A</i></th><th><i>B</i></th><th><i>C</i></th></tr>
+<tr><td align="right" class="row">0</td><td>1</td><td>2</td><td>3</td></tr>
+<tr><td align="right" class="row">1</td><td>11</td><td>22</td><td>33</td></tr>
+<tr><td align="right" class="row">2</td><td>111</td><td>222</td><td>333</td></tr>
+</table>
+}
+
+test 16 {} {
+    namespace eval blah {
+      namespace import ::ratcl::vopdef
+      vopdef haha {v} { return abc }
+    }
+    view - haha
+} {abc}
+
+namespace forget blah
+
+test 17 {transpose} {
+    set v [view {A B C} def {1 2 3 4 5 6 7 8 9} | transpose]
+    list [view $v names] [view $v structure] [view $v get]
+} {{x0 x1 x2} SSS {1 4 7 2 5 8 3 6 9}}
+
+test 18 {transpose ints} {
+    set v [view {A:I B:I C:I} def {1 2 3 4 5 6 7 8 9} | transpose X:I]
+    list [view $v names] [view $v structure] [view $v get]
+} {{X0 X1 X2} III {1 4 7 2 5 8 3 6 9}}
+
+test 19 {use vop} {
+    view 1 use 2
+} 2
+
+test 20 {do vop} {
+    set T [view {A B C D} def {a b c d a b e f b c e f e d c d e d e f a b d e}]
+    view $T do {
+      transpose 
+      get 
+    }
+} {a a b e e a b b c d d b c e e c e d d f f d f e}
+
+test 21 {debug vop} -body {
+    set T [view {A B C D} def {a b c d a b e f b c e f e d c d e d e f a b d e}]
+    view $T debug transpose | get
+} -match glob -output {\
+ rows-in  col  msec  view-operation
+ -------  ---  ----  --------------
+       6    4    ??  transpose
+       4    6  ----  --------------
+} -result {a a b e e a b b c d d b c e e c e d d f f d f e}
+
+test 22 {use and debug vops} -body {
+    view - debug {
+      use {A B}
+      def {1 2 3 4 5 6}
+      transpose
+      get
+    }
+} -result {1 3 5 2 4 6} -match glob -output {\
+ rows-in  col  msec  view-operation
+ -------  ---  ----  --------------
+                 ??  use {A B}
+                 ??  def {1 2 3 4 5 6}
+       3    2    ??  transpose
+       2    3    ??  get
+ -------  ---  ----  --------------
+}
+
+test 23 {debug comments} -body {
+    view $T debug {
+      # start
+      transpose
+      # empty lines are not shown
+      
+      structure
+      # end
+    }
+} -result SSSSSS -match glob -output {\
+ rows-in  col  msec  view-operation
+ -------  ---  ----  --------------
+                     # start
+       6    4    ??  transpose
+                     # empty lines are not shown
+       4    6    ??  structure
+                     # end
+ -------  ---  ----  --------------
+}
+
+test 24 {frequency table} {
+    view A def {a b a b b c} | freq N | get
+} {a 2 b 3 c 1}
+
+test 25 {frequency table on unique values} {
+    view A def {b a c} | freq N | get
+} {b 1 a 1 c 1}
+
+test 26 {frequency table on a single value} {
+    view A def {a a a a} | freq N | get
+} {a 4}
+
+test 27 {} {
+    view {1 2 3} asview A:I | structdesc
+} A:I
+    
+test 28 {} {
+    view {1 2 3} asview A | structdesc
+} A:S
+
+test 29 {} {
+    view 10 asview len:I | get
+} 10
+    
+test 30 {} {
+    view [view 10 asview len:I] min len 50
+} 10
+
+test 31 {} {
+    set v [vlerq def {A B} {1 a 1 b 1 b 2 c 3 c}]
+    view $v project A | get
+} {1 2 3}
+
+test 32 {} {
+    view $v project B | get
+} {a b c}
+
+test 33 {} {
+    view $v project A B | get
+} {1 a 1 b 2 c 3 c}
+
+test 34 {} {
+    view $v project | get
+} {}
+
+test 35 {} {
+    view A:I def {1 2 3 4 5 6 9 10 11 12} | pick {1 1 0 1 1 0 0 1 1 0} | get
+} {1 2 4 5 10 11}
+
+test 36 {} {
+    set v [vlerq def {A B} {1 2 3 4}]
+    set w [vlerq reverse $v]
+} {data {mdef {A B}} {3 1} {4 2}}
+    
+test 37 {} {
+    set v [vlerq def {A B} {1 2 3 4}]
+    set w [vlerq reverse $v]
+    vlerq pair $v $w
+} {data {mdef {A B A B}} {1 3} {2 4} {3 1} {4 2}}
+    
+test 38 {} {
+    set v [vlerq def {A B} {1 2 3 4}]
+    set w [vlerq reverse $v]
+    view $v pair $w | get
+} {1 2 3 4 3 4 1 2}
+    
+test 39 {} {
+    set v [vlerq def {A B} {1 2 3 4}]
+    set w [vlerq reverse $v]
+    # 2006-12-08 failed because dump could not handle duplicate column names
+    view $v pair $w | dump
+} { \
+  A  B  A  B
+  -  -  -  -
+  1  2  3  4
+  3  4  1  2}
+
+test 40 {} -body {
+    set v [vlerq def {A B} {1 2 3 4}]
+    set w [vlerq reverse $v]
+    view $v pair $w | html
+} -match glob -result {<table><style*/style>
+<tr><th class="row"></th><th><i>A</i></th><th><i>B</i></th><th><i>A</i></th><th><i>B</i></th></tr>
+<tr><td align="right" class="row">0</td><td>1</td><td>2</td><td>3</td><td>4</td></tr>
+<tr><td align="right" class="row">1</td><td>3</td><td>4</td><td>1</td><td>2</td></tr>
+</table>
+}
+
+set T [vlerq def {X A B C D} {0 a b c d
+                              1 e d f d
+                              2 a b e f
+                              3 b c e d
+                              4 a b d e
+                              5 e d c f}]
+test 41 {} {
+    view $T sorton A | get * X
+} {0 2 4 3 1 5}
+
+test 42 {} {
+    view $T sorton - A | get * X
+} {1 5 3 0 2 4}
+
+test 43 {} {
+    view $T sorton B | get * X
+} {0 2 4 3 1 5}
+
+test 44 {} {
+    view $T sorton - B | get * X
+} {1 5 3 0 2 4}
+
+test 45 {} {
+    view $T sorton C | get * X
+} {0 5 4 2 3 1}
+
+test 46 {} {
+    view $T sorton - C | get * X
+} {1 2 3 4 0 5}
+
+test 47 {} {
+    view $T sorton D | get * X
+} {0 1 3 4 2 5}
+
+test 48 {} {
+    view $T sorton - D | get * X
+} {2 5 4 0 1 3}
+
+test 49 {} {
+    view $T sorton D C | get * X
+} {0 3 1 4 5 2}
+
+test 50 {} {
+    view $T sorton D - C | get * X
+} {1 3 0 4 2 5}
+
+test 51 {} {
+    view $T sorton - D C | get * X
+} {2 5 4 1 3 0}
+
+test 52 {} {
+    view $T sorton - D + C | get * X
+} {5 2 4 0 3 1}
+
+test 53 {} {
+    # exercises view args > 8 and total vlerq args > 20
+    view $T sorton - D + C - A + B - C + D - A + B - C + D | get * X
+} {5 2 4 0 3 1}
+
+test 54 {} {
+    # failed, see F119
+    set m [view {A,B:I} mdesc]
+    set v [view $m data {a bb ccc} {1 22 333}]
+    vlerq unique [vlerq colmap $v {B B}]
+} {data {mdef {B:I B:I}} {1 22 333} {1 22 333}}
+
+test 55 {} {
+    vlerq unique [vlerq colmap $v {B A}]
+} {data {mdef {B:I A}} {1 22 333} {a bb ccc}}
+
+test 56 {read without hitting eof} {
+    set fd [open data/gtest.db]
+    set v [view $fd read]
+    set r [eof $fd]
+    close $fd
+    set r
+} 0
+
+test 57 {} {
+    vlerq meta $v
+} {mdef {{frequents {drinker bar perweek:I}}\
+           {likes {drinker beer perday:I}}\
+           {serves {bar beer quantity:I}}}}
+    
+test 58 {read until eof} {
+    set fd [open data/gtest.db]
+    set w [view $fd read ########] ;# fake a non-header to force reading to eof
+    set r [eof $fd]
+    close $fd
+    set r
+} 1
+
+test 59 {} {
+    vlerq meta $w
+} {mdef {{frequents {drinker bar perweek:I}}\
+           {likes {drinker beer perday:I}}\
+           {serves {bar beer quantity:I}}}}
+
+test 60 {F146 - failed assertion, cannot reproduce} {
+    view {} size; view {} do {use 5} | dump
+} {  (5 rows, no columns)}
+
+test 61 {as result} {
+    view $T as tcmd
+} tcmd
+
+test 62 {as use} {
+    tcmd size
+} 6
+
+rename tcmd ""
+unset -nocomplain T r v w m fd
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/ref.test b/8.x/vqtcl/tests/ref.test
new file mode 100755 (executable)
index 0000000..4786651
--- /dev/null
@@ -0,0 +1,151 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+test 1 {ref command} {
+    set v ""
+    list [vlerq size @v] [vlerq width @v]
+} {0 3}
+
+test 2 {ref changed value} {
+    set v [vlerq meta ""]
+    list [vlerq size @v] [vlerq width @v]
+} {3 3}
+
+unset v
+
+test 3 {} {
+    proc foo {args} {
+      puts [list got: $args]
+      lindex $args 2
+    }
+    set v [vlerq def A {a b c}]
+    set t {ref v foo bar}
+    list [vlerq size $t] [vlerq size [vlerq meta $t]]
+} {3 1}
+
+test 4 {} -constraints x -body {
+    vlerq set $t 1 A X
+} -result {data {mdef A} {a X c}} \
+    -output "got: bar {data {mdef A} {a b c}} set 1 A X\n"
+
+test 5 {} {
+    set v [vlerq def A {a b c}]
+    vlerq load [vlerq emit @v]
+} {data {mdef A} {a b c}}
+
+test 6 {} {
+    vlerq set @v 1 A xyz
+} {data {mdef A} {a xyz c}}
+
+test 7 {} {
+    vlerq viewconv $v
+} {data {mdef A} {a b c}}
+
+test 8 {} x {
+    vlerq viewconv @v
+} {data {mdef A} {a xyz c}}
+
+test 9 {} x {
+    vlerq set $v 0 A abc
+} {data {mdef A} {abc xyz c}}
+
+test 10 {} x {
+    vlerq set @v 2 A def
+} {data {mdef A} {abc xyz def}}
+
+test 11 {} {
+    vlerq viewconv $v
+} {data {mdef A} {a b c}}
+
+test 12 {} x {
+    vlerq viewconv @v
+} {data {mdef A} {a xyz def}}
+
+test 13 {} {
+    set v [vlerq group [vlerq def {A B} {a 1 a 2 a 3}] A G]
+    set v [vlerq load [vlerq emit $v]]
+    vlerq load [vlerq emit @v]
+} {data {mdef {A {G B}}} a {{data {mdef B} {1 2 3}}}}
+
+test 14 {} {
+    vlerq get @v 0 G
+} {data {mdef B} {1 2 3}}
+
+test 15 {} {
+    vlerq set @v 0 A b
+} {data {mdef {A {G B}}} b {{data {mdef B} {1 2 3}}}}
+
+test 16 {} {
+    vlerq set {get @v 0 G} 1 B xyz
+} {data {mdef B} {1 xyz 3}}
+
+test 17 {if this works then subviews are mutable} x {
+    set v
+} {data {mdef {A {G B}}} b {{data {mdef B} {1 xyz 3}}}}
+
+#unset v
+#vlerq debug 3
+
+test 18 {} {
+    set v [vlerq def A {5 3 2 1 4}]
+    vlerq sort @v
+} {data {mdef A} {1 2 3 4 5}}
+
+test 19 {} {
+    vlerq set $v 2 A 6
+    vlerq sort @v
+} {data {mdef A} {1 2 3 4 5}}
+
+test 20 {} {
+    set v [vlerq set $v 3 A 7]
+    vlerq sort @v
+} {data {mdef A} {2 3 4 5 7}}
+
+test 21 {} {
+    vlerq set @v 2 A 8
+    set v
+} {data {mdef A} {5 3 8 7 4}}
+
+test 22 {} {
+    vlerq sort @v
+} {data {mdef A} {3 4 5 7 8}}
+
+test 23 {} {
+    set w {sort @v}
+    vlerq viewconv $w
+} {data {mdef A} {3 4 5 7 8}}
+
+test 24 {} {
+    vlerq set @v 2 A 0
+} {data {mdef A} {5 3 0 7 4}}
+
+test 25 {} {
+    vlerq deps $v
+} -
+
+test 26 {} {
+    set w [vlerq sort $v]
+    vlerq size $w
+} 5
+
+test 27 {} x {
+    vlerq deps $v
+} {- {sort A 5}}
+
+test 28 {} x {
+    vlerq deps @v
+} {}
+
+test 29 {} x {
+    vlerq viewconv $w
+} {data {mdef A} {0 3 4 5 7}}
+
+unset -nocomplain t v w
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/sorted.test b/8.x/vqtcl/tests/sorted.test
new file mode 100755 (executable)
index 0000000..854138e
--- /dev/null
@@ -0,0 +1,283 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {} {
+    package require vlerq
+} $version
+
+test 1 {} {
+    vlerq roweq [vlerq meta ""] 0 [vlerq meta ""] 0
+} 1
+
+test 2 {} {
+    vlerq roweq [vlerq meta ""] 0 [vlerq meta ""] 1
+} 0
+
+test 3 {} {
+    vlerq roweq [vlerq def {L:L F:F D:D B:B} {1 2 3 4}] 0 \
+                [vlerq def {L:L F:F D:D B:B} {1 2.0 3.0 4}] 0
+} 1
+
+test 4 {} {
+    vlerq sortmap [vlerq def A:I {1 2 1 2 1 3}]
+} {0 2 4 1 3 5}
+
+test 5 {} {
+    vlerq sortmap [vlerq def A {a b a b a c}]
+} {0 2 4 1 3 5}
+
+test 6 {} {
+    vlerq sort [vlerq def A {a b a b a c}]
+} {data {mdef A} {a a a b b c}}
+
+test 7 {} {
+    vlerq sort [vlerq def A {a b a c}]
+} {data {mdef A} {a a b c}}
+
+test 8 {} {
+    vlerq compare "" ""
+} 0
+    
+test 9 {} {
+    vlerq compare 0 0
+} 0
+    
+test 10 {} {
+    vlerq compare 12 12
+} 0
+    
+test 11 {} {
+    vlerq compare 12 23
+} -1
+    
+test 12 {} {
+    vlerq compare "" 12
+} 1
+    
+test 13 {} {
+    vlerq compare "" [vlerq meta ""]
+} -1
+    
+test 14 {} {
+    vlerq compare [vlerq meta ""] [vlerq meta ""]
+} 0
+    
+test 15 {} {
+    vlerq compare [vlerq def A {}] [vlerq def A {}]
+} 0
+    
+test 16 {} {
+    vlerq compare [vlerq def A a] [vlerq def A a]
+} 0
+    
+test 17 {} {
+    vlerq compare [vlerq def A a] [vlerq def A b]
+} -1
+    
+test 18 {} {
+    vlerq compare [vlerq def A a] [vlerq def A {a b}]
+} -1
+    
+test 19 {} {
+    vlerq compare [vlerq def A {}] [vlerq def A a]
+} -1
+    
+test 20 {} {
+    vlerq compare [vlerq def A b] [vlerq def A {a b}]
+} 1
+    
+test 21 {} {
+    vlerq compare [vlerq def A {}] [vlerq def B {}]
+} -1
+    
+test 22 {} {
+    vlerq compare [vlerq def A b] [vlerq def B a]
+} -1
+    
+test 23 {} {
+    vlerq compare [vlerq def A {}] [vlerq def {A B} {}]
+} -1
+    
+test 24 {} {
+    vlerq compare [vlerq def {A B} {}] [vlerq def {A B} {}]
+} 0
+    
+test 25 {} {
+    vlerq compare [vlerq def {A B} {a b}] [vlerq def {A B} {a b}]
+} 0
+    
+test 26 {} {
+    vlerq compare [vlerq def {A B} {a b aa bb}] [vlerq def {A B} {a b aa bb}]
+} 0
+    
+test 27 {} {
+    vlerq compare [vlerq def {A B} {a b}] [vlerq def {A B} {a b aa bb}]
+} -1
+    
+test 28 {} {
+    vlerq compare [vlerq def {A B} {a b aa bb}] [vlerq def {A B} {a b}]
+} 1
+    
+test 29 {} {
+    vlerq compare [vlerq def {A B} {a b aa bb}] [vlerq def {A B} {a b aaa bb}]
+} -1
+    
+test 30 {} {
+    vlerq compare [vlerq def {A B} {a b aaa bb}] [vlerq def {A B} {a b aa bb}]
+} 1
+    
+test 31 {} {
+    vlerq compare [vlerq def {A B} {a b aa bb}] [vlerq def {A B} {a b aa bbb}]
+} -1
+    
+test 32 {} {
+    vlerq compare [vlerq def {A B} {a b aa bbb}] [vlerq def {A B} {a b aa bb}]
+} 1
+    
+test 33 {} {
+    vlerq compare [vlerq def A {}] [vlerq def A:I {}]
+} 1
+    
+test 34 {} {
+    vlerq compare [vlerq def A {}] [vlerq def A:I {}]
+} 1
+    
+test 35 {} {
+    vlerq compare [vlerq def A:I 1] [vlerq def A:I 01]
+} 0
+    
+test 36 {} {
+    vlerq compare [vlerq def A:I 01] [vlerq def A:I 1]
+} 0
+
+test 37 {} {
+    vlerq compare [vlerq def A:I 19] [vlerq def A:I 2]
+} 1
+    
+test 38 {} {
+    vlerq compare [vlerq def A:I 2] [vlerq def A:I 19]
+} -1
+    
+test 39 {} {
+    vlerq compare [vlerq def A 19] [vlerq def A 2]
+} -1
+    
+test 40 {} {
+    vlerq compare [vlerq def A 2] [vlerq def A 19]
+} 1
+
+test 41 {} {
+    vlerq compare [vlerq def {L:L F:F D:D B:B} {1 2 3 4}] \
+                  [vlerq def {L:L F:F D:D B:B} {1 2.0 3.0 4}]
+} 0
+
+test 42 {} {
+    vlerq max [vlerq def A {a b c}] 0
+} c
+    
+test 43 {} {
+    vlerq max [vlerq def A {a b c}] 0
+} c
+    
+test 44 {} {
+    vlerq max [vlerq def A {a b c}] 0
+} c
+    
+test 45 {} {
+    vlerq max [vlerq def A:I {1 2 3}] 0
+} 3
+    
+test 46 {} {
+    vlerq max [vlerq def A:I {1 2 3}] 0
+} 3
+    
+test 47 {} {
+    vlerq max [vlerq def A:I {1 2 3}] A
+} 3
+    
+test 48 {} {
+    vlerq min [vlerq def A {a b c}] 0 d
+} a
+    
+test 49 {} {
+    vlerq min [vlerq def A {a b c}] 0
+} a
+    
+test 50 {} {
+    vlerq min [vlerq def A {a b c}] 0
+} a
+    
+test 51 {} {
+    vlerq min [vlerq def A {a b c ""}] 0
+} ""
+    
+test 52 {} {
+    vlerq min [vlerq def A:I {1 2 3}] 0 4
+} 1
+    
+test 53 {} {
+    vlerq min [vlerq def A:I {1 2 3}] 0
+} 1
+    
+test 54 {} {
+    vlerq min [vlerq def A:I {1 2 3}] A
+} 1
+    
+test 55 {} {
+    vlerq sum [vlerq def A:I {}] 0
+} 0
+    
+test 56 {} {
+    vlerq sum [vlerq def A:I {1 2 3}] 0
+} 6
+    
+test 57 {} {
+    vlerq sum [vlerq def A:I {0 1 -2}] 0
+} -1
+    
+test 58 {} {
+    vlerq sum [vlerq def A:I {0 1 -2}] A
+} -1
+    
+test 59 {} {
+    vlerq sum [vlerq def A:L {10000000000 20000000000 30000000000}] 0
+} 60000000000
+    
+test 60 {} {
+    vlerq sum [vlerq def A:F {1000000000.1 2000000000.2 3000000000.3}] 0
+} 6000000000.0
+    
+test 61 {} {
+    vlerq sum [vlerq def A:D {1000000000.1 2000000000.2 3000000000.3}] 0
+} 6000000000.6
+
+test 62 {see F147, this works} {
+    view {a b} def {1 a} | group a g | collect {[view $(g) get]}
+} {a}
+
+test 63 {F147 - this is ok} {
+    view {a b} def {1 a} | group a g | structdesc
+} {a:S,g[b:S]}
+
+test 64 {F147 - so is this} {
+    view {a b} def {1 a} | group a g | dump
+} { \
+  a  g 
+  -  --
+  1  #1}
+
+test 65 {F147 - this throws an error} -constraints x -body {
+    view {a b} def {1 a} | group a g | loop {puts [view $(g) sort | dump]}
+} -output {?}
+
+test 66 {F147 - this throws an assertion} -constraints x -body {
+    view {a b} def {1 a} | group a g | loop {puts [view $(g) sort | freeze | get]}
+} -output {?}
+
+test 67 {F147 - and this crashes!} x {
+    view {a b} def {1 a} | group a g | collect {[view $(g) sort | get]}
+} {a}
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/tests/view.test b/8.x/vqtcl/tests/view.test
new file mode 100755 (executable)
index 0000000..1b61d9b
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env tclkit
+# %renumber<^\s*test >%
+
+source [file join [file dir [info script]] initests.tcl]
+
+test 0 {load extension} {
+    package require vlerq
+} $version
+
+namespace eval ::vlerq {}
+
+test 1 {indirect view operation} -body {
+    proc ::vlerq::foo {n} { vlerq viewconv [expr {2*$n}] }
+    vlerq size {foo 123}
+} -result 246 -cleanup {
+    rename ::vlerq::foo ""
+}
+
+test 2 {recursive indirect view operation} -body {
+    proc ::vlerq::foo {n} { expr {3*$n} }
+    vlerq size {foo 123}
+} -result 369 -cleanup {
+    rename ::vlerq::foo ""
+}
+
+test 3 {} {
+    vlerq view [vlerq def A {a b c}] size
+} 3
+
+test 4 {} {
+    vlerq view A def {a b c} | repeat 3 | size
+} 9
+
+::tcltest::cleanupTests
diff --git a/8.x/vqtcl/win/makefile.vc b/8.x/vqtcl/win/makefile.vc
new file mode 100644 (file)
index 0000000..8197ad9
--- /dev/null
@@ -0,0 +1,460 @@
+# makefile.vc --                                               -*- Makefile -*-
+#
+# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
+#
+# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
+# make it suitable as a general package makefile. Look for the word EDIT
+# which marks sections that may need modification. As a minumum you will
+# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
+# relevant to your package.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+# Copyright (c) 2001 ActiveState Corporation.
+# Copyright (c) 2001-2002 David Gravereaux.
+# Copyright (c) 2003-2006 Pat Thoyts
+#
+#-------------------------------------------------------------------------
+
+# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
+# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
+# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
+MSG = ^
+You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
+Platform SDK first to setup the environment.  Jump to this line to read^
+the build instructions.
+!error $(MSG)
+!endif
+
+#------------------------------------------------------------------------------
+# HOW TO USE this makefile:
+#
+# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
+#     used  as a check to see if vcvars32.bat had been run prior to running
+#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
+#     been set globally and the PATH adjusted.  Either way is valid.
+#
+#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
+#     directory to setup the proper environment, if needed, for your current
+#     setup.  This is a needed bootstrap requirement and allows the swapping of
+#     different environments to be easier.
+#
+# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
+#     vcvars32.bat according to the instructions for it.  This can also turn on
+#     the 64-bit compiler, if your SDK has it.
+#
+# 3)  Targets are:
+#      all       -- Builds everything.
+#       <project> -- Builds the project (eg: nmake vlerq)
+#      test      -- Builds and runs the test suite.
+#      install   -- Installs the built binaries and libraries to $(INSTALLDIR)
+#                   in an appropriate subdirectory.
+#      clean/realclean/distclean -- varying levels of cleaning.
+#
+# 4)  Macros usable on the commandline:
+#      INSTALLDIR=<path>
+#              Sets where to install Tcl from the built binaries.
+#              C:\Progra~1\Tcl is assumed when not specified.
+#
+#      OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
+#              Sets special options for the core.  The default is for none.
+#              Any combination of the above may be used (comma separated).
+#              'none' will over-ride everything to nothing.
+#
+#              static  =  Builds a static library of the core instead of a
+#                         dll.  The shell will be static (and large), as well.
+#              msvcrt  =  Effects the static option only to switch it from
+#                         using libcmt(d) as the C runtime [by default] to
+#                         msvcrt(d). This is useful for static embedding
+#                         support.
+#              staticpkg = Effects the static option only to switch
+#                         tclshXX.exe to have the dde and reg extension linked
+#                         inside it.
+#              nothreads = Turns off multithreading support (not recommended)
+#              thrdalloc = Use the thread allocator (shared global free pool).
+#              symbols =  Adds symbols for step debugging.
+#              profile =  Adds profiling hooks.  Map file is assumed.
+#              loimpact =  Adds a flag for how NT treats the heap to keep memory
+#                         in use, low.  This is said to impact alloc performance.
+#
+#      STATS=memdbg,compdbg,none
+#              Sets optional memory and bytecode compiler debugging code added
+#              to the core.  The default is for none.  Any combination of the
+#              above may be used (comma separated).  'none' will over-ride
+#              everything to nothing.
+#
+#              memdbg   = Enables the debugging memory allocator.
+#              compdbg  = Enables byte compilation logging.
+#
+#      MACHINE=(IX86|IA64|ALPHA|AMD64)
+#              Set the machine type used for the compiler, linker, and
+#              resource compiler.  This hook is needed to tell the tools
+#              when alternate platforms are requested.  IX86 is the default
+#              when not specified. If the CPU environment variable has been
+#              set (ie: recent Platform SDK) then MACHINE is set from CPU.
+#
+#      TMP_DIR=<path>
+#      OUT_DIR=<path>
+#              Hooks to allow the intermediate and output directories to be
+#              changed.  $(OUT_DIR) is assumed to be 
+#              $(BINROOT)\(Release|Debug) based on if symbols are requested.
+#              $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
+#
+#      TESTPAT=<file>
+#              Reads the tests requested to be run from this file.
+#
+#      CFG_ENCODING=encoding
+#              name of encoding for configuration information. Defaults
+#              to cp1252
+#
+# 5)  Examples:
+#
+#      Basic syntax of calling nmake looks like this:
+#      nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
+#
+#                        Standard (no frills)
+#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+#       Setting environment for using Microsoft Visual C++ tools.
+#       c:\tcl_src\win\>nmake -f makefile.vc all
+#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
+#
+#                         Building for Win64
+#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
+#       Setting environment for using Microsoft Visual C++ tools.
+#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
+#       Targeting Windows pre64 RETAIL
+#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
+#
+#------------------------------------------------------------------------------
+#==============================================================================
+###############################################################################
+#------------------------------------------------------------------------------
+
+!if !exist("makefile.vc")
+MSG = ^
+You must run this makefile only from the directory it is in.^
+Please `cd` to its location first.
+!error $(MSG)
+!endif
+
+#-------------------------------------------------------------------------
+# Project specific information (EDIT)
+#
+# You should edit this with the name and version of your project. This
+# information is used to generate the name of the package library and
+# it's install location.
+#
+# For example, the vlerq extension is  going to build vlerq10.dll and
+# would install it into $(INSTALLDIR)\lib\vlerq10
+#
+# You need to specify the object files that need to be linked into your
+# binary here.
+#
+#-------------------------------------------------------------------------
+
+PROJECT = vlerq
+PRJNAME = vqtcl
+
+# Uncomment the following line if this is a Tk extension.
+#PROJECT_REQUIRES_TK=1
+!include "rules.vc"
+
+DOTVERSION      = 4.1
+VERSION         = $(DOTVERSION:.=)
+STUBPREFIX      = $(PROJECT)stub
+
+DLLOBJS = \
+       $(TMP_DIR)\vlerq.obj
+
+#-------------------------------------------------------------------------
+# Target names and paths ( shouldn't need changing )
+#-------------------------------------------------------------------------
+
+BINROOT                = .
+ROOT            = ..
+
+PRJIMPLIB      = $(OUT_DIR)\$(PRJNAME)$(VERSION)$(SUFX).lib
+PRJLIBNAME     = $(PRJNAME)$(VERSION)$(SUFX).$(EXT)
+PRJLIB         = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB     = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+### Make sure we use backslash only.
+PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PRJNAME)$(DOTVERSION)
+LIB_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR     = $(PRJ_INSTALL_DIR)
+INCLUDE_INSTALL_DIR    = $(_TCLDIR)\include
+
+### The following paths CANNOT have spaces in them.
+GENERICDIR     = $(ROOT)\generic
+WINDIR         = $(ROOT)\win
+LIBDIR          = $(ROOT)\library
+DOCDIR         = $(ROOT)\doc
+TOOLSDIR       = $(ROOT)\tools
+COMPATDIR      = $(ROOT)\compat
+
+#---------------------------------------------------------------------
+# Compile flags
+#---------------------------------------------------------------------
+
+!if !$(DEBUG)
+!if $(OPTIMIZING)
+### This cranks the optimization level to maximize speed
+cdebug = -Zi $(OPTIMIZATIONS)
+!else
+cdebug = -Zi
+!endif
+!else if "$(MACHINE)" == "IA64" #|| "$(MACHINE)" == "AMD64"
+### Warnings are too many, can't support warnings into errors.
+cdebug = -Zi -Od $(DEBUGFLAGS)
+!else
+cdebug = -Zi -W3 $(DEBUGFLAGS)
+!endif
+
+### Declarations common to all compiler options
+cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
+cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
+
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+!if !$(STATIC_BUILD)
+cflags = $(cflags) -DUSE_TCL_STUBS
+!if defined(TKSTUBLIB)
+cflags = $(cflags) -DUSE_TK_STUBS
+!endif
+!endif
+
+INCLUDES       = $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)"
+BASE_CFLAGS    = $(cflags) $(cdebug) $(crt) $(INCLUDES)
+CON_CFLAGS     = $(cflags) $(cdebug) $(crt) -DCONSOLE
+TCL_CFLAGS     = -DPACKAGE_NAME="\"$(PROJECT)\"" \
+                  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+                 -DBUILD_$(PROJECT) \
+                  $(BASE_CFLAGS) $(OPTDEFINES)
+
+#---------------------------------------------------------------------
+# Link flags
+#---------------------------------------------------------------------
+
+!if $(DEBUG)
+ldebug = -debug:full -debugtype:cv
+!if $(MSVCRT)
+ldebug = $(ldebug) -nodefaultlib:msvcrt
+!endif
+!else
+ldebug = -debug -opt:ref -opt:icf,3
+!endif
+
+### Declarations common to all linker options
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(PROFILE)
+lflags = $(lflags) -profile
+!endif
+
+!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
+### Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
+### Align sections for speed in loading by choosing the virtual page size.
+lflags = $(lflags) -align:4096
+!endif
+
+!if $(LOIMPACT)
+lflags = $(lflags) -ws:aggressive
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+!if !$(STATIC_BUILD)
+baselibs  = $(TCLSTUBLIB)
+!if defined(TKSTUBLIB)
+baselibs  = $(baselibs) $(TKSTUBLIB)
+!endif
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) >= 1400 && $(VCVERSION) < 1500
+baselibs   = $(baselibs) bufferoverflowU.lib
+!endif
+!endif
+
+#---------------------------------------------------------------------
+# TclTest flags
+#---------------------------------------------------------------------
+
+!IF "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!ENDIF
+
+#---------------------------------------------------------------------
+# Project specific targets (EDIT)
+#---------------------------------------------------------------------
+
+all:       setup $(PROJECT)
+$(PROJECT): setup pkgIndex $(PRJLIB)
+install:    install-binaries install-libraries install-docs
+pkgIndex:   $(OUT_DIR)\pkgIndex.tcl
+
+test: setup $(PROJECT)
+       @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+       @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+       @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+       @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+       @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
+       $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS)
+!else
+        @echo Please wait while the tests are collected...
+        $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) > tests.log
+       type tests.log | more
+!endif
+
+shell: setup $(PROJECT)
+       @set VLERQ_LIBRARY=$(LIBDIR:\=/)
+       @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+       @set TCLLIBPATH=$(OUT_DIR:\=/)
+       @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+       @set PATH=$(_TCLDIR)\bin;$(PATH)
+!else
+       @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+!endif
+       $(DEBUGGER) $(TCLSH) $(SCRIPT)
+
+setup:
+       @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+       @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+# See <tcl>/win/coffbase.txt for extension base addresses.
+$(PRJLIB): $(DLLOBJS)
+!if $(STATIC_BUILD)
+       $(lib32) -nologo -out:$@ @<<
+$**
+<<
+!else
+       $(link32) $(dlllflags) -base:0x10C00000 -out:$@ $(baselibs) @<<
+$**
+<<
+       $(_VC_MANIFEST_EMBED_DLL)
+       -@del $*.exp
+!endif
+
+$(PRJSTUBLIB): $(PRJSTUBOBJS)
+       $(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
+
+#---------------------------------------------------------------------
+# Implicit rules
+#---------------------------------------------------------------------
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+       $(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
+               -DCOMMAVERSION=$(DOTVERSION:.=,),0,0 \
+               -DDOTVERSION=\"$(DOTVERSION)\" \
+               -DVERSION=\"$(VERSION)$(SUFX)\" \
+!if $(DEBUG)
+       -d DEBUG \
+!endif
+!if $(TCL_THREADS)
+       -d TCL_THREADS \
+!endif
+!if $(STATIC_BUILD)
+       -d STATIC_BUILD \
+!endif
+       $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+#-------------------------------------------------------------------------
+# Explicit dependency rules
+#
+#-------------------------------------------------------------------------
+
+.PHONY: $(OUT_DIR)\pkgIndex.tcl
+
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+       @nmakehlp -s << $** > $@
+lib@PACKAGE_NAME@@PACKAGE_VERSION@  $(PRJNAME)$(VERSION)$(SUFX)
+@PACKAGE_VERSION@                   $(DOTVERSION)
+<<
+
+#---------------------------------------------------------------------
+# Installation. (EDIT)
+#
+# You may need to modify this section to reflect the final distribution
+# of your files and possibly to generate documentation.
+#
+#---------------------------------------------------------------------
+
+install-binaries:
+       @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+       @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+       @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+install-libraries:
+       @echo Installing library files to '$(SCRIPT_INSTALL_DIR)'
+       @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+       @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)"
+
+install-docs:
+       @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+       @if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"
+
+#---------------------------------------------------------------------
+# Clean up
+#---------------------------------------------------------------------
+
+clean:
+       @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+       @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+       @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+       @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+       @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+
+realclean: clean
+       @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+distclean: realclean
+       @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+       @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
diff --git a/8.x/vqtcl/win/nmakehlp.c b/8.x/vqtcl/win/nmakehlp.c
new file mode 100644 (file)
index 0000000..d33966c
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ * ----------------------------------------------------------------------------
+ * nmakehlp.c --
+ *
+ *     This is used to fix limitations within nmake and the environment.
+ *
+ * Copyright (c) 2002 by David Gravereaux.
+ * Copyright (c) 2006 by Pat Thoyts
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * ----------------------------------------------------------------------------
+ * RCS: @(#) $Id: nmakehlp.c 7 2009-02-20 14:00:31Z patthoyts $
+ * ----------------------------------------------------------------------------
+ */
+
+#define _CRT_SECURE_NO_DEPRECATE
+#include <windows.h>
+#define NO_SHLWAPI_GDI
+#define NO_SHLWAPI_STREAM
+#define NO_SHLWAPI_REG
+#include <shlwapi.h>
+#pragma comment (lib, "user32.lib")
+#pragma comment (lib, "kernel32.lib")
+#pragma comment (lib, "shlwapi.lib")
+#include <stdio.h>
+#include <math.h>
+
+/*
+ * This library is required for x64 builds with _some_ versions of MSVC
+ */
+#if defined(_M_IA64) || defined(_M_AMD64)
+#if _MSC_VER >= 1400 && _MSC_VER < 1500
+#pragma comment(lib, "bufferoverflowU")
+#endif
+#endif
+
+/* ISO hack for dumb VC++ */
+#ifdef _MSC_VER
+#define   snprintf     _snprintf
+#endif
+
+
+
+/* protos */
+
+int            CheckForCompilerFeature(const char *option);
+int            CheckForLinkerFeature(const char *option);
+int            IsIn(const char *string, const char *substring);
+int            GrepForDefine(const char *file, const char *string);
+int            SubstituteFile(const char *substs, const char *filename);
+int            QualifyPath(const char *path);
+const char *    GetVersionFromFile(const char *filename, const char *match);
+DWORD WINAPI   ReadFromPipe(LPVOID args);
+
+/* globals */
+
+#define CHUNK  25
+#define STATICBUFFERSIZE    1000
+typedef struct {
+    HANDLE pipe;
+    char buffer[STATICBUFFERSIZE];
+} pipeinfo;
+
+pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
+pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
+\f
+/*
+ * exitcodes: 0 == no, 1 == yes, 2 == error
+ */
+
+int
+main(
+    int argc,
+    char *argv[])
+{
+    char msg[300];
+    DWORD dwWritten;
+    int chars;
+
+    /*
+     * Make sure children (cl.exe and link.exe) are kept quiet.
+     */
+
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+
+    /*
+     * Make sure the compiler and linker aren't effected by the outside world.
+     */
+
+    SetEnvironmentVariable("CL", "");
+    SetEnvironmentVariable("LINK", "");
+
+    if (argc > 1 && *argv[1] == '-') {
+       switch (*(argv[1]+1)) {
+       case 'c':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -c <compiler option>\n"
+                       "Tests for whether cl.exe supports an option\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return CheckForCompilerFeature(argv[2]);
+       case 'l':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -l <linker option>\n"
+                       "Tests for whether link.exe supports an option\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return CheckForLinkerFeature(argv[2]);
+       case 'f':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -f <string> <substring>\n"
+                       "Find a substring within another\n"
+                       "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           } else if (argc == 3) {
+               /*
+                * If the string is blank, there is no match.
+                */
+
+               return 0;
+           } else {
+               return IsIn(argv[2], argv[3]);
+           }
+       case 'g':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -g <file> <string>\n"
+                       "grep for a #define\n"
+                       "exitcodes: integer of the found string (no decimals)\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return GrepForDefine(argv[2], argv[3]);
+       case 's':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -s <substitutions file> <file>\n"
+                       "Perform a set of string map type substutitions on a file\n"
+                       "exitcodes: 0\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return SubstituteFile(argv[2], argv[3]);
+       case 'V':
+           if (argc != 4) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                   "usage: %s -V filename matchstring\n"
+                   "Extract a version from a file:\n"
+                   "eg: pkgIndex.tcl \"package ifneeded http\"",
+                   argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                   &dwWritten, NULL);
+               return 0;
+           }
+           printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
+           return 0;
+       case 'Q':
+           if (argc != 3) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                   "usage: %s -q path\n"
+                   "Emit the fully qualified path\n"
+                   "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                   &dwWritten, NULL);
+               return 2;
+           }
+           return QualifyPath(argv[2]);
+       }
+    }
+    chars = snprintf(msg, sizeof(msg) - 1,
+           "usage: %s -c|-l|-f|-g|-V|-s|-Q ...\n"
+           "This is a little helper app to equalize shell differences between WinNT and\n"
+           "Win9x and get nmake.exe to accomplish its job.\n",
+           argv[0]);
+    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
+    return 2;
+}
+\f
+int
+CheckForCompilerFeature(
+    const char *option)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    SECURITY_ATTRIBUTES sa;
+    DWORD threadID;
+    char msg[300];
+    BOOL ok;
+    HANDLE hProcess, h, pipeThreads[2];
+    char cmdline[100];
+
+    hProcess = GetCurrentProcess();
+
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO);
+    si.dwFlags   = STARTF_USESTDHANDLES;
+    si.hStdInput = INVALID_HANDLE_VALUE;
+
+    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = FALSE;
+
+    /*
+     * Create a non-inheritible pipe.
+     */
+
+    CreatePipe(&Out.pipe, &h, &sa, 0);
+
+    /*
+     * Dupe the write side, make it inheritible, and close the original.
+     */
+
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Same as above, but for the error side.
+     */
+
+    CreatePipe(&Err.pipe, &h, &sa, 0);
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Base command line.
+     */
+
+    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
+
+    /*
+     * Append our option for testing
+     */
+
+    lstrcat(cmdline, option);
+
+    /*
+     * Filename to compile, which exists, but is nothing and empty.
+     */
+
+    lstrcat(cmdline, " .\\nul");
+
+    ok = CreateProcess(
+           NULL,           /* Module name. */
+           cmdline,        /* Command line. */
+           NULL,           /* Process handle not inheritable. */
+           NULL,           /* Thread handle not inheritable. */
+           TRUE,           /* yes, inherit handles. */
+           DETACHED_PROCESS, /* No console for you. */
+           NULL,           /* Use parent's environment block. */
+           NULL,           /* Use parent's starting directory. */
+           &si,            /* Pointer to STARTUPINFO structure. */
+           &pi);           /* Pointer to PROCESS_INFORMATION structure. */
+
+    if (!ok) {
+       DWORD err = GetLastError();
+       int chars = snprintf(msg, sizeof(msg) - 1,
+               "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
+               FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
+               (300-chars), 0);
+       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+       return 2;
+    }
+
+    /*
+     * Close our references to the write handles that have now been inherited.
+     */
+
+    CloseHandle(si.hStdOutput);
+    CloseHandle(si.hStdError);
+
+    WaitForInputIdle(pi.hProcess, 5000);
+    CloseHandle(pi.hThread);
+
+    /*
+     * Start the pipe reader threads.
+     */
+
+    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
+    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
+
+    /*
+     * Block waiting for the process to end.
+     */
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    CloseHandle(pi.hProcess);
+
+    /*
+     * Wait for our pipe to get done reading, should it be a little slow.
+     */
+
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
+    CloseHandle(pipeThreads[0]);
+    CloseHandle(pipeThreads[1]);
+
+    /*
+     * Look for the commandline warning code in both streams.
+     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
+     */
+
+    return !(strstr(Out.buffer, "D4002") != NULL
+             || strstr(Err.buffer, "D4002") != NULL
+             || strstr(Out.buffer, "D9002") != NULL
+             || strstr(Err.buffer, "D9002") != NULL
+             || strstr(Out.buffer, "D2021") != NULL
+             || strstr(Err.buffer, "D2021") != NULL);
+}
+\f
+int
+CheckForLinkerFeature(
+    const char *option)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    SECURITY_ATTRIBUTES sa;
+    DWORD threadID;
+    char msg[300];
+    BOOL ok;
+    HANDLE hProcess, h, pipeThreads[2];
+    char cmdline[100];
+
+    hProcess = GetCurrentProcess();
+
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO);
+    si.dwFlags   = STARTF_USESTDHANDLES;
+    si.hStdInput = INVALID_HANDLE_VALUE;
+
+    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = TRUE;
+
+    /*
+     * Create a non-inheritible pipe.
+     */
+
+    CreatePipe(&Out.pipe, &h, &sa, 0);
+
+    /*
+     * Dupe the write side, make it inheritible, and close the original.
+     */
+
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Same as above, but for the error side.
+     */
+
+    CreatePipe(&Err.pipe, &h, &sa, 0);
+    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
+           DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+
+    /*
+     * Base command line.
+     */
+
+    lstrcpy(cmdline, "link.exe -nologo ");
+
+    /*
+     * Append our option for testing.
+     */
+
+    lstrcat(cmdline, option);
+
+    ok = CreateProcess(
+           NULL,           /* Module name. */
+           cmdline,        /* Command line. */
+           NULL,           /* Process handle not inheritable. */
+           NULL,           /* Thread handle not inheritable. */
+           TRUE,           /* yes, inherit handles. */
+           DETACHED_PROCESS, /* No console for you. */
+           NULL,           /* Use parent's environment block. */
+           NULL,           /* Use parent's starting directory. */
+           &si,            /* Pointer to STARTUPINFO structure. */
+           &pi);           /* Pointer to PROCESS_INFORMATION structure. */
+
+    if (!ok) {
+       DWORD err = GetLastError();
+       int chars = snprintf(msg, sizeof(msg) - 1,
+               "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
+
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
+               FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
+               (300-chars), 0);
+       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+       return 2;
+    }
+
+    /*
+     * Close our references to the write handles that have now been inherited.
+     */
+
+    CloseHandle(si.hStdOutput);
+    CloseHandle(si.hStdError);
+
+    WaitForInputIdle(pi.hProcess, 5000);
+    CloseHandle(pi.hThread);
+
+    /*
+     * Start the pipe reader threads.
+     */
+
+    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
+    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
+
+    /*
+     * Block waiting for the process to end.
+     */
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    CloseHandle(pi.hProcess);
+
+    /*
+     * Wait for our pipe to get done reading, should it be a little slow.
+     */
+
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
+    CloseHandle(pipeThreads[0]);
+    CloseHandle(pipeThreads[1]);
+
+    /*
+     * Look for the commandline warning code in the stderr stream.
+     */
+
+    return !(strstr(Out.buffer, "LNK1117") != NULL ||
+           strstr(Err.buffer, "LNK1117") != NULL ||
+           strstr(Out.buffer, "LNK4044") != NULL ||
+           strstr(Err.buffer, "LNK4044") != NULL);
+}
+\f
+DWORD WINAPI
+ReadFromPipe(
+    LPVOID args)
+{
+    pipeinfo *pi = (pipeinfo *) args;
+    char *lastBuf = pi->buffer;
+    DWORD dwRead;
+    BOOL ok;
+
+  again:
+    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
+       CloseHandle(pi->pipe);
+       return (DWORD)-1;
+    }
+    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
+    if (!ok || dwRead == 0) {
+       CloseHandle(pi->pipe);
+       return 0;
+    }
+    lastBuf += dwRead;
+    goto again;
+
+    return 0;  /* makes the compiler happy */
+}
+\f
+int
+IsIn(
+    const char *string,
+    const char *substring)
+{
+    return (strstr(string, substring) != NULL);
+}
+\f
+/*
+ * Find a specified #define by name.
+ *
+ * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
+ */
+
+int
+GrepForDefine(
+    const char *file,
+    const char *string)
+{
+    char s1[51], s2[51], s3[51];
+    FILE *f = fopen(file, "rt");
+
+    if (f == NULL) {
+       return 0;
+    }
+
+    do {
+       int r = fscanf(f, "%50s", s1);
+
+       if (r == 1 && !strcmp(s1, "#define")) {
+           /*
+            * Get next two words.
+            */
+
+           r = fscanf(f, "%50s %50s", s2, s3);
+           if (r != 2) {
+               continue;
+           }
+
+           /*
+            * Is the first word what we're looking for?
+            */
+
+           if (!strcmp(s2, string)) {
+               double d1;
+
+               fclose(f);
+
+               /*
+                * Add 1 past first double quote char. "8.5"
+                */
+
+               d1 = atof(s3 + 1);                /*    8.5  */
+               while (floor(d1) != d1) {
+                   d1 *= 10.0;
+               }
+               return ((int) d1);                /*    85   */
+           }
+       }
+    } while (!feof(f));
+
+    fclose(f);
+    return 0;
+}
+\f
+/*
+ * GetVersionFromFile --
+ *     Looks for a match string in a file and then returns the version
+ *     following the match where a version is anything acceptable to
+ *     package provide or package ifneeded.
+ */
+
+const char *
+GetVersionFromFile(
+    const char *filename,
+    const char *match)
+{
+    size_t cbBuffer = 100;
+    static char szBuffer[100];
+    char *szResult = NULL;
+    FILE *fp = fopen(filename, "rt");
+
+    if (fp != NULL) {
+       /*
+        * Read data until we see our match string.
+        */
+
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           LPSTR p, q;
+
+           p = strstr(szBuffer, match);
+           if (p != NULL) {
+               /*
+                * Skip to first digit.
+                */
+
+               while (*p && !isdigit(*p)) {
+                   ++p;
+               }
+
+               /*
+                * Find ending whitespace.
+                */
+
+               q = p;
+               while (*q && (isalnum(*q) || *q == '.')) {
+                   ++q;
+               }
+
+               memcpy(szBuffer, p, q - p);
+               szBuffer[q-p] = 0;
+               szResult = szBuffer;
+               break;
+           }
+       }
+       fclose(fp);
+    }
+    return szResult;
+}
+\f
+/*
+ * List helpers for the SubstituteFile function
+ */
+
+typedef struct list_item_t {
+    struct list_item_t *nextPtr;
+    char * key;
+    char * value;
+} list_item_t;
+
+/* insert a list item into the list (list may be null) */
+static list_item_t *
+list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
+{
+    list_item_t *itemPtr = malloc(sizeof(list_item_t));
+    if (itemPtr) {
+       itemPtr->key = strdup(key);
+       itemPtr->value = strdup(value);
+       itemPtr->nextPtr = NULL;
+
+       while(*listPtrPtr) {
+           listPtrPtr = &(*listPtrPtr)->nextPtr;
+       }
+       *listPtrPtr = itemPtr;
+    }
+    return itemPtr;
+}
+
+static void
+list_free(list_item_t **listPtrPtr)
+{
+    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
+    while (listPtr) {
+       tmpPtr = listPtr;
+       listPtr = listPtr->nextPtr;
+       free(tmpPtr->key);
+       free(tmpPtr->value);
+       free(tmpPtr);
+    }
+}
+\f
+/*
+ * SubstituteFile --
+ *     As windows doesn't provide anything useful like sed and it's unreliable
+ *     to use the tclsh you are building against (consider x-platform builds -
+ *     eg compiling AMD64 target from IX86) we provide a simple substitution
+ *     option here to handle autoconf style substitutions.
+ *     The substitution file is whitespace and line delimited. The file should
+ *     consist of lines matching the regular expression:
+ *       \s*\S+\s+\S*$
+ *
+ *     Usage is something like:
+ *       nmakehlp -S << $** > $@
+ *        @PACKAGE_NAME@ $(PACKAGE_NAME)
+ *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
+ *        <<
+ */
+
+int
+SubstituteFile(
+    const char *substitutions,
+    const char *filename)
+{
+    size_t cbBuffer = 1024;
+    static char szBuffer[1024], szCopy[1024];
+    char *szResult = NULL;
+    list_item_t *substPtr = NULL;
+    FILE *fp, *sp;
+
+    fp = fopen(filename, "rt");
+    if (fp != NULL) {
+
+       /*
+        * Build a list of substutitions from the first filename
+        */
+
+       sp = fopen(substitutions, "rt");
+       if (sp != NULL) {
+           while (fgets(szBuffer, cbBuffer, sp) != NULL) {
+               char *ks, *ke, *vs, *ve;
+               ks = szBuffer;
+               while (ks && *ks && isspace(*ks)) ++ks;
+               ke = ks;
+               while (ke && *ke && !isspace(*ke)) ++ke;
+               vs = ke;
+               while (vs && *vs && isspace(*vs)) ++vs;
+               ve = vs;
+               while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
+               *ke = 0, *ve = 0;
+               list_insert(&substPtr, ks, vs);
+           }
+           fclose(sp);
+       }
+
+       /* debug: dump the list */
+#ifdef _DEBUG
+       {
+           int n = 0;
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
+               fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
+           }
+       }
+#endif
+       
+       /*
+        * Run the substitutions over each line of the input
+        */
+       
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr) {
+               char *m = strstr(szBuffer, p->key);
+               if (m) {
+                   char *cp, *op, *sp;
+                   cp = szCopy;
+                   op = szBuffer;
+                   while (op != m) *cp++ = *op++;
+                   sp = p->value;
+                   while (sp && *sp) *cp++ = *sp++;
+                   op += strlen(p->key);
+                   while (*op) *cp++ = *op++;
+                   *cp = 0;
+                   memcpy(szBuffer, szCopy, sizeof(szCopy));
+               }
+           }
+           printf(szBuffer);
+       }
+       
+       list_free(&substPtr);
+    }
+    fclose(fp);
+    return 0;
+}
+\f
+/*
+ * QualifyPath --
+ *
+ *     This composes the current working directory with a provided path
+ *     and returns the fully qualified and normalized path.
+ *     Mostly needed to setup paths for testing.
+ */
+
+int
+QualifyPath(
+    const char *szPath)
+{
+    char szCwd[MAX_PATH + 1];
+    char szTmp[MAX_PATH + 1];
+    char *p;
+    GetCurrentDirectory(MAX_PATH, szCwd);
+    while ((p = strchr(szPath, '/')) && *p)
+       *p = '\\';
+    PathCombine(szTmp, szCwd, szPath);
+    PathCanonicalize(szCwd, szTmp);
+    printf("%s\n", szCwd);
+    return 0;
+}
+
+/*
+ * Local variables:
+ *   mode: c
+ *   c-basic-offset: 4
+ *   fill-column: 78
+ *   indent-tabs-mode: t
+ *   tab-width: 8
+ * End:
+ */
diff --git a/8.x/vqtcl/win/rules.vc b/8.x/vqtcl/win/rules.vc
new file mode 100644 (file)
index 0000000..0b78bc8
--- /dev/null
@@ -0,0 +1,622 @@
+#------------------------------------------------------------------------------
+# rules.vc --
+#
+#      Microsoft Visual C++ makefile include for decoding the commandline
+#      macros.  This file does not need editing to build Tcl.
+#
+#      This version is modified from the Tcl source version to support
+#      building extensions using nmake.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# Copyright (c) 2001-2002 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+#
+#------------------------------------------------------------------------------
+# RCS: @(#) $Id: rules.vc 7 2009-02-20 14:00:31Z patthoyts $
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+cc32           = $(CC)   # built-in default.
+link32         = link
+lib32          = lib
+rc32           = $(RC)   # built-in default.
+
+!ifndef INSTALLDIR
+### Assume the normal default.
+_INSTALLDIR    = C:\Program Files\Tcl
+!else
+### Fix the path separators.
+_INSTALLDIR    = $(INSTALLDIR:/=\)
+!endif
+
+!ifndef MACHINE
+!if "$(CPU)" == "" || "$(CPU)" == "i386"
+MACHINE         = IX86
+!else
+MACHINE         = $(CPU)
+!endif
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING   = \"cp1252\"
+!endif
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+!if "$(OS)" == "Windows_NT"
+RMDIR  = rmdir /S /Q
+ERRNULL  = 2>NUL
+!if ![ver | find "4.0" > nul]
+CPY    = echo y | xcopy /i >NUL
+COPY   = copy >NUL
+!else
+CPY    = xcopy /i /y >NUL
+COPY   = copy /y >NUL
+!endif
+!else # "$(OS)" != "Windows_NT"
+CPY    = xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
+COPY   = copy >_JUNK.OUT # On Win98 NUL does not work here.
+RMDIR  = deltree /Y
+NULL    = \NUL # Used in testing directory existence
+ERRNULL = >NUL # Win9x shell cannot redirect stderr
+!endif
+MKDIR   = mkdir
+
+!message ===============================================================================
+
+#----------------------------------------------------------
+# build the helper app we need to overcome nmake's limiting
+# environment.
+#----------------------------------------------------------
+
+!if !exist(nmakehlp.exe)
+!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
+!endif
+!endif
+
+#----------------------------------------------------------
+# Test for compiler features
+#----------------------------------------------------------
+
+### test for optimizations
+!if [nmakehlp -c -Ot]
+!message *** Compiler has 'Optimizations'
+OPTIMIZING     = 1
+!else
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING     = 0
+!endif
+
+OPTIMIZATIONS  =
+
+!if [nmakehlp -c -Ot]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
+!endif
+
+!if [nmakehlp -c -Oi]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
+!endif
+
+!if [nmakehlp -c -Op]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
+!endif
+
+!if [nmakehlp -c -fp:strict]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
+!endif
+
+!if [nmakehlp -c -Gs]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
+!endif
+
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
+!endif
+
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
+!endif
+
+DEBUGFLAGS     =
+
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
+!endif
+
+COMPILERFLAGS  =-W3
+
+# In v13 -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+!if ![nmakehlp -c -GL]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
+!endif
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+COMPILERFLAGS  = $(COMPILERFLAGSS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+!if "$(MACHINE)" == "IA64"
+### test for Itanium errata
+!if [nmakehlp -c -QIA64_Bx]
+!message *** Compiler has 'B-stepping errata workarounds'
+COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
+!else
+!message *** Compiler does not have 'B-stepping errata workarounds'
+!endif
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for -align:4096, when align:512 will do.
+!if [nmakehlp -l -opt:nowin98]
+!message *** Linker has 'Win98 alignment problem'
+ALIGN98_HACK   = 1
+!else
+!message *** Linker does not have 'Win98 alignment problem'
+ALIGN98_HACK   = 0
+!endif
+!else
+ALIGN98_HACK   = 0
+!endif
+
+LINKERFLAGS     =
+
+!if [nmakehlp -l -ltcg]
+LINKERFLAGS     =-ltcg
+!endif
+
+#----------------------------------------------------------
+# MSVC8 (ships with Visual Studio 2005) generates a manifest
+# file that we should link into the binaries. This is how.
+#----------------------------------------------------------
+
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
+!include vercl.i
+!if $(VCVERSION) >= 1500
+VCVER=9
+!elseif $(VCVERSION) >= 1400
+VCVER=8
+!elseif $(VCVERSION) >= 1300
+VCVER=7
+!elseif $(VCVERSION) >= 1200
+VCVER=6
+!endif
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+#----------------------------------------------------------
+# Decode the options requested.
+#----------------------------------------------------------
+
+!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
+STATIC_BUILD   = 0
+TCL_THREADS    = 1
+DEBUG          = 0
+PROFILE                = 0
+MSVCRT         = 0
+LOIMPACT       = 0
+TCL_USE_STATIC_PACKAGES        = 0
+USE_THREAD_ALLOC = 1
+USE_THREAD_STORAGE = 1
+UNCHECKED       = 0
+!else
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD   = 1
+!else
+STATIC_BUILD   = 0
+!endif
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT         = 1
+!else
+MSVCRT         = 0
+!endif
+!if [nmakehlp -f $(OPTS) "staticpkg"]
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES        = 1
+!else
+TCL_USE_STATIC_PACKAGES        = 0
+!endif
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS    = 0
+!else
+TCL_THREADS     = 1
+!endif
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG          = 1
+!else
+DEBUG          = 0
+!endif
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE                = 1
+!else
+PROFILE                = 0
+!endif
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Doing loimpact
+LOIMPACT       = 1
+!else
+LOIMPACT       = 0
+!endif
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!else
+USE_THREAD_ALLOC = 0
+!endif
+!if [nmakehlp -f $(OPTS) "thrdstorage"]
+!message *** Doing thrdstorage
+USE_THREAD_STORAGE = 1
+!else
+USE_THREAD_STORAGE = 0
+!endif
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+!endif
+
+
+!if !$(STATIC_BUILD)
+# Make sure we don't build overly fat DLLs.
+MSVCRT         = 1
+# We shouldn't statically put the extensions inside the shell when dynamic.
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+
+#----------------------------------------------------------
+# Figure-out how to name our intermediate and output directories.
+# We wouldn't want different builds to use the same .obj files
+# by accident.
+#----------------------------------------------------------
+
+#----------------------------------------
+# Naming convention:
+#   t = full thread support.
+#   s = static library (as opposed to an
+#      import library)
+#   g = linked to the debug enabled C
+#      run-time.
+#   x = special static build when it
+#      links to the dynamic C run-time.
+#----------------------------------------
+SUFX       = sgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX       = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX       = $(SUFX:s=)
+EXT        = dll
+!if $(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX       = $(SUFX:x=)
+!endif
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT        = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX       = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX       = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR            = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR            = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR            = $(TMP_DIR)
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Decode the statistics requested.
+#----------------------------------------------------------
+
+!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
+TCL_MEM_DEBUG      = 0
+TCL_COMPILE_DEBUG   = 0
+!else
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG      = 1
+!else
+TCL_MEM_DEBUG      = 0
+!endif
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG   = 1
+!else
+TCL_COMPILE_DEBUG   = 0
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Decode the checks requested.
+#----------------------------------------------------------
+
+!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
+TCL_NO_DEPRECATED          = 0
+WARNINGS                   = -W3
+!else
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED          = 1
+!else
+TCL_NO_DEPRECATED          = 0
+!endif
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS                   = -W4
+!if [nmakehlp -l -warn:3]
+LINKERFLAGS                = $(LINKERFLAGS) -warn:3
+!endif
+!else
+WARNINGS                   = -W3
+!endif
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS                   = $(WARNINGS) -Wp64
+!endif
+!endif
+
+#----------------------------------------------------------
+# Set our defines now armed with our options.
+#----------------------------------------------------------
+
+OPTDEFINES     = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES     = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!if $(USE_THREAD_STORAGE)
+OPTDEFINES     = $(OPTDEFINES) -DUSE_THREAD_STORAGE=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES     = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(DEBUG)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_DEBUG
+!elseif $(OPTIMIZING)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!if $(PROFILE)
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
+OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+
+
+#----------------------------------------------------------
+# Get common info used when building extensions.
+#----------------------------------------------------------
+
+!if "$(PROJECT)" != "tcl"
+
+# If INSTALLDIR set to tcl root dir then reset to the lib dir.
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+!if !defined(TCLDIR)
+!if exist("$(_INSTALLDIR)\..\include\tcl.h")
+TCLINSTALL     = 1
+_TCLDIR                = $(_INSTALLDIR)\..
+_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h
+TCLDIR          = $(_INSTALLDIR)\..
+!else
+MSG=^
+Failed to find tcl.h.  Set the TCLDIR macro.
+!error $(MSG)
+!endif
+!else
+_TCLDIR        = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h")
+TCLINSTALL     = 1
+_TCL_H          = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h")
+TCLINSTALL     = 0
+_TCL_H          = $(_TCLDIR)\generic\tcl.h
+!else
+MSG =^
+Failed to find tcl.h.  The TCLDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+
+!if [echo REM = This file is generated from rules.vc > version.vc]
+!endif
+!if exist("$(_TCL_H)")
+!if [echo TCL_DOTVERSION = \>> version.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_VERSION >> version.vc]
+!endif
+!endif
+!include version.vc
+TCL_VERSION    = $(TCL_DOTVERSION:.=)
+
+!if $(TCLINSTALL)
+TCLSH          = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TCLSTUBLIB     = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB      = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
+TCL_LIBRARY    = $(_TCLDIR)\lib
+TCL_INCLUDES    = -I"$(_TCLDIR)\include"
+!else
+TCLSH          = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH          = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TCLSTUBLIB     = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
+TCL_LIBRARY    = $(_TCLDIR)\library
+TCL_INCLUDES   = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+!endif
+
+!endif
+
+#----------------------------------------------------------
+# Optionally check for Tk info for building extensions.
+#----------------------------------------------------------
+
+!ifdef PROJECT_REQUIRES_TK
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+
+!if !defined(TKDIR)
+!if exist("$(_INSTALLDIR)\..\include\tk.h")
+TKINSTALL      = 1
+_TKDIR         = $(_INSTALLDIR)\..
+_TK_H          = $(_TKDIR)\include\tk.h
+TKDIR          = $(_TKDIR)
+!elseif exist("$(_TCLDIR)\include\tk.h")
+TKINSTALL      = 1
+_TKDIR         = $(_TCLDIR)
+_TK_H          = $(_TKDIR)\include\tk.h
+TKDIR          = $(_TKDIR)
+!endif
+!else
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL      = 1
+_TK_H          = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL      = 0
+_TK_H          = $(_TKDIR)\generic\tk.h
+!else
+MSG =^
+Failed to find tk.h. The TKDIR macro does not appear correct.
+!error $(MSG)
+!endif
+!endif
+
+!if defined(TKDIR)
+TK_DOTVERSION = 8.4
+!if exist("$(_TK_H)")
+!if [echo TK_DOTVERSION = \>> version.vc] \
+   && [nmakehlp -V "$(_TK_H)" TK_VERSION >> version.vc]
+!endif
+!endif
+!include version.vc
+TK_VERSION = $(TK_DOTVERSION:.=)
+
+!if $(TKINSTALL)
+WISH           = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
+!if !exist($(WISH)) && $(TCL_THREADS)
+WISH           = "$(_TKDIR)\bin\wish$(TK_VERSION)t$(SUFX).exe"
+!endif
+TKSTUBLIB      = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
+TKIMPLIB       = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
+TK_INCLUDES     = -I"$(_TKDIR)\include"
+TK_LIBRARY     = $(_TKDIR)\lib
+!else
+WISH           = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(WISH)) && $(TCL_THREADS)
+WISH           = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)t$(SUFX).exe"
+!endif
+TKSTUBLIB      = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
+TKIMPLIB       = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
+TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+TK_LIBRARY     = $(_TKDIR)\library
+!endif
+
+!endif
+!endif
+!endif
+
+
+#----------------------------------------------------------
+# Setup the fully qualified OUT_DIR path as OUT_DIR_PATH
+#----------------------------------------------------------
+!if [echo OUT_DIR_PATH = \>> version.vc] \
+    && [nmakehlp -Q "$(OUT_DIR)" >> version.vc]
+!endif
+!include version.vc
+
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Optional defines are '$(OPTDEFINES)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
+!message *** Link options '$(LINKERFLAGS)'
+
+!endif
diff --git a/8.x/vqtcl/win/unistd.h b/8.x/vqtcl/win/unistd.h
new file mode 100644 (file)
index 0000000..bb6da74
--- /dev/null
@@ -0,0 +1,17 @@
+/* unistd.h - this file is for MSVC only, it containd only what Vlerq needs! */
+
+#if defined(_WIN32) && !defined(WIN32)
+#define WIN32 1
+#endif
+
+#ifdef _MSC_VER
+typedef unsigned __int64 uint64_t;
+typedef          __int64 int64_t;
+typedef unsigned __int32 uint32_t;
+typedef          __int32 int32_t;
+typedef unsigned __int16 uint16_t;
+typedef          __int16 int16_t;
+/*typedef unsigned __int8  uint8_t;*/
+typedef          __int8  int8_t;
+#define strcasecmp _stricmp
+#endif
diff --git a/8.x/zlib/CMakeLists.txt b/8.x/zlib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a64fe0b
--- /dev/null
@@ -0,0 +1,190 @@
+cmake_minimum_required(VERSION 2.4.4)
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
+
+project(zlib C)
+
+if(NOT DEFINED BUILD_SHARED_LIBS)
+    option(BUILD_SHARED_LIBS "Build a shared library form of zlib" ON)
+endif()
+
+include(CheckTypeSize)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckCSourceCompiles)
+enable_testing()
+
+check_include_file(sys/types.h HAVE_SYS_TYPES_H)
+check_include_file(stdint.h    HAVE_STDINT_H)
+check_include_file(stddef.h    HAVE_STDDEF_H)
+
+#
+# Check to see if we have large file support
+#
+set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
+# We add these other definitions here because CheckTypeSize.cmake
+# in CMake 2.4.x does not automatically do so and we want
+# compatibility with CMake 2.4.x.
+if(HAVE_SYS_TYPES_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)
+endif()
+if(HAVE_STDINT_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)
+endif()
+if(HAVE_STDDEF_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
+endif()
+check_type_size(off64_t OFF64_T)
+if(HAVE_OFF64_T)
+   add_definitions(-D_LARGEFILE64_SOURCE=1)
+endif()
+set(CMAKE_REQUIRED_DEFINITIONS) # clear variable
+
+#
+# Check for fseeko
+#
+check_function_exists(fseeko HAVE_FSEEKO)
+if(NOT HAVE_FSEEKO)
+    add_definitions(-DNO_FSEEKO)
+endif()
+
+#
+# Check for unistd.h
+#
+check_include_file(unistd.h Z_HAVE_UNISTD_H)
+
+if(MSVC)
+    set(CMAKE_DEBUG_POSTFIX "d")
+    add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
+    add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
+endif()
+
+if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
+    # If we're doing an out of source build and the user has a zconf.h
+    # in their source tree...
+    if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
+        message(FATAL_ERROR
+            "You must remove ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h "
+            "from the source tree.  This file is included with zlib "
+            "but CMake generates this file for you automatically "
+            "in the build directory.")
+  endif()
+endif()
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
+               ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+
+#============================================================================
+# zlib
+#============================================================================
+
+set(ZLIB_PUBLIC_HDRS
+    ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
+    zlib.h
+)
+set(ZLIB_PRIVATE_HDRS
+    crc32.h
+    deflate.h
+    gzguts.h
+    inffast.h
+    inffixed.h
+    inflate.h
+    inftrees.h
+    trees.h
+    zutil.h
+)
+set(ZLIB_SRCS
+    adler32.c
+    compress.c
+    crc32.c
+    deflate.c
+    gzclose.c
+    gzlib.c
+    gzread.c
+    gzwrite.c
+    inflate.c
+    infback.c
+    inftrees.c
+    inffast.c
+    trees.c
+    uncompr.c
+    zutil.c
+    win32/zlib1.rc
+)
+
+# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
+string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9A-Za-z.]+)\".*"
+    "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
+
+if(MINGW)
+    # This gets us DLL resource information when compiling on MinGW.
+    add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+                       COMMAND windres.exe
+                            -D GCC_WINDRES
+                            -I ${CMAKE_CURRENT_SOURCE_DIR}
+                            -I ${CMAKE_CURRENT_BINARY_DIR}
+                            -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+                            -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc)
+    set(ZLIB_SRCS ${ZLIB_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
+endif(MINGW)
+
+add_library(zlib ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
+
+set_target_properties(zlib PROPERTIES SOVERSION 1)
+
+if(NOT CYGWIN)
+    # This property causes shared libraries on Linux to have the full version
+    # encoded into their final filename.  We disable this on Cygwin because
+    # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
+    # seems to be the default.
+    #
+    # This has no effect with MSVC, on that platform the version info for
+    # the DLL comes from the resource file win32/zlib1.rc
+    set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
+endif()
+
+if(UNIX)
+    # On unix-like platforms the library is almost always called libz
+   set_target_properties(zlib PROPERTIES OUTPUT_NAME z)
+elseif(BUILD_SHARED_LIBS AND WIN32)
+    # Creates zlib1.dll when building shared library version
+    set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
+endif()
+
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+    install(TARGETS zlib
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib
+        LIBRARY DESTINATION lib )
+endif()
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
+    install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION include)
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+    install(FILES zlib.3 DESTINATION share/man/man3)
+endif()
+
+#============================================================================
+# Example binaries
+#============================================================================
+
+add_executable(example example.c)
+target_link_libraries(example zlib)
+add_test(example example)
+
+add_executable(minigzip minigzip.c)
+target_link_libraries(minigzip zlib)
+
+if(HAVE_OFF64_T)
+    add_executable(example64 example.c)
+    target_link_libraries(example64 zlib)
+    set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+    add_test(example64 example64)
+
+    add_executable(minigzip64 minigzip.c)
+    target_link_libraries(minigzip64 zlib)
+    set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+endif()
diff --git a/8.x/zlib/ChangeLog b/8.x/zlib/ChangeLog
new file mode 100644 (file)
index 0000000..f310bb0
--- /dev/null
@@ -0,0 +1,1208 @@
+
+                ChangeLog file for zlib
+
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+
+Changes in 1.2.4.3 (10 Apr 2010)
+- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
+- Use CROSS_PREFIX for nm [Bar-Lev]
+- Assume _LARGEFILE64_SOURCE defined is equivalent to true
+- Avoid use of undefined symbols in #if with && and ||
+- Make *64 prototypes in gzguts.h consistent with functions
+- Add -shared load option for MinGW in configure [Bowler]
+- Move z_off64_t to public interface, use instead of off64_t
+- Remove ! from shell test in configure (not portable to Solaris)
+- Change +0 macro tests to -0 for possibly increased portability
+
+Changes in 1.2.4.2 (9 Apr 2010)
+- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
+- Really provide prototypes for *64 functions when building without LFS
+- Only define unlink() in minigzip.c if unistd.h not included
+- Update README to point to contrib/vstudio project files
+- Move projects/vc6 to old/ and remove projects/
+- Include stdlib.h in minigzip.c for setmode() definition under WinCE
+- Clean up assembler builds in win32/Makefile.msc [Rowe]
+- Include sys/types.h for Microsoft for off_t definition
+- Fix memory leak on error in gz_open()
+- Symbolize nm as $NM in configure [Weigelt]
+- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
+- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
+- Fix bug in gzeof() to take into account unused input data
+- Avoid initialization of structures with variables in puff.c
+- Updated win32/README-WIN32.txt [Rowe]
+
+Changes in 1.2.4.1 (28 Mar 2010)
+- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
+- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
+- Restore "for debugging" comment on sprintf() in gzlib.c
+- Remove fdopen for MVS from gzguts.h
+- Put new README-WIN32.txt in win32 [Rowe]
+- Add check for shell to configure and invoke another shell if needed
+- Fix big fat stinking bug in gzseek() on uncompressed files
+- Remove vestigial F_OPEN64 define in zutil.h
+- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
+- Avoid errors on non-LFS systems when applications define LFS macros
+- Set EXE to ".exe" in configure for MINGW [Kahle]
+- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
+- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
+- Add DLL install in win32/makefile.gcc [Bar-Lev]
+- Allow Linux* or linux* from uname in configure [Bar-Lev]
+- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
+- Add cross-compilation prefixes to configure [Bar-Lev]
+- Match type exactly in gz_load() invocation in gzread.c
+- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
+- Provide prototypes for *64 functions when building zlib without LFS
+- Don't use -lc when linking shared library on MinGW
+- Remove errno.h check in configure and vestigial errno code in zutil.h
+
+Changes in 1.2.4 (14 Mar 2010)
+- Fix VER3 extraction in configure for no fourth subversion
+- Update zlib.3, add docs to Makefile.in to make .pdf out of it
+- Add zlib.3.pdf to distribution
+- Don't set error code in gzerror() if passed pointer is NULL
+- Apply destination directory fixes to CMakeLists.txt [Lowman]
+- Move #cmakedefine's to a new zconf.in.cmakein
+- Restore zconf.h for builds that don't use configure or cmake
+- Add distclean to dummy Makefile for convenience
+- Update and improve INDEX, README, and FAQ
+- Update CMakeLists.txt for the return of zconf.h [Lowman]
+- Update contrib/vstudio/vc9 and vc10 [Vollant]
+- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
+- Apply license and readme changes to contrib/asm686 [Raiter]
+- Check file name lengths and add -c option in minigzip.c [Li]
+- Update contrib/amd64 and contrib/masmx86/ [Vollant]
+- Avoid use of "eof" parameter in trees.c to not shadow library variable
+- Update make_vms.com for removal of zlibdefs.h [Zinser]
+- Update assembler code and vstudio projects in contrib [Vollant]
+- Remove outdated assembler code contrib/masm686 and contrib/asm586
+- Remove old vc7 and vc8 from contrib/vstudio
+- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
+- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
+- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
+- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
+- Fix bug in void-returning vsprintf() case in gzwrite.c
+- Fix name change from inflate.h in contrib/inflate86/inffas86.c
+- Check if temporary file exists before removing in make_vms.com [Zinser]
+- Fix make install and uninstall for --static option
+- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
+- Update readme.txt in contrib/masmx64 and masmx86 to assemble
+
+Changes in 1.2.3.9 (21 Feb 2010)
+- Expunge gzio.c
+- Move as400 build information to old
+- Fix updates in contrib/minizip and contrib/vstudio
+- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
+- Delete zconf.h (made by configure) [Weigelt]
+- Change zconf.in.h to zconf.h.in per convention [Weigelt]
+- Check for NULL buf in gzgets()
+- Return empty string for gzgets() with len == 1 (like fgets())
+- Fix description of gzgets() in zlib.h for end-of-file, NULL return
+- Update minizip to 1.1 [Vollant]
+- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
+- Note in zlib.h that gzerror() should be used to distinguish from EOF
+- Remove use of snprintf() from gzlib.c
+- Fix bug in gzseek()
+- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
+- Fix zconf.h generation in CMakeLists.txt [Lowman]
+- Improve comments in zconf.h where modified by configure
+
+Changes in 1.2.3.8 (13 Feb 2010)
+- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
+- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
+- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
+- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
+- Fix missing error return in gzflush(), add zlib.h note
+- Add *64 functions to zlib.map [Levin]
+- Fix signed/unsigned comparison in gz_comp()
+- Use SFLAGS when testing shared linking in configure
+- Add --64 option to ./configure to use -m64 with gcc
+- Fix ./configure --help to correctly name options
+- Have make fail if a test fails [Levin]
+- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
+- Remove assembler object files from contrib
+
+Changes in 1.2.3.7 (24 Jan 2010)
+- Always gzopen() with O_LARGEFILE if available
+- Fix gzdirect() to work immediately after gzopen() or gzdopen()
+- Make gzdirect() more precise when the state changes while reading
+- Improve zlib.h documentation in many places
+- Catch memory allocation failure in gz_open()
+- Complete close operation if seek forward in gzclose_w() fails
+- Return Z_ERRNO from gzclose_r() if close() fails
+- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
+- Return zero for gzwrite() errors to match zlib.h description
+- Return -1 on gzputs() error to match zlib.h description
+- Add zconf.in.h to allow recovery from configure modification [Weigelt]
+- Fix static library permissions in Makefile.in [Weigelt]
+- Avoid warnings in configure tests that hide functionality [Weigelt]
+- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
+- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
+- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
+- Keep object files in subdirectories to reduce the clutter somewhat
+- Remove default Makefile and zlibdefs.h, add dummy Makefile
+- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
+- Remove zlibdefs.h completely -- modify zconf.h instead
+
+Changes in 1.2.3.6 (17 Jan 2010)
+- Avoid void * arithmetic in gzread.c and gzwrite.c
+- Make compilers happier with const char * for gz_error message
+- Avoid unused parameter warning in inflate.c
+- Avoid signed-unsigned comparison warning in inflate.c
+- Indent #pragma's for traditional C
+- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
+- Correct email address in configure for system options
+- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
+- Update zlib.map [Brown]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
+- Apply various fixes to CMakeLists.txt [Lowman]
+- Add checks on len in gzread() and gzwrite()
+- Add error message for no more room for gzungetc()
+- Remove zlib version check in gzwrite()
+- Defer compression of gzprintf() result until need to
+- Use snprintf() in gzdopen() if available
+- Remove USE_MMAP configuration determination (only used by minigzip)
+- Remove examples/pigz.c (available separately)
+- Update examples/gun.c to 1.6
+
+Changes in 1.2.3.5 (8 Jan 2010)
+- Add space after #if in zutil.h for some compilers
+- Fix relatively harmless bug in deflate_fast() [Exarevsky]
+- Fix same problem in deflate_slow()
+- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
+- Add deflate_rle() for faster Z_RLE strategy run-length encoding
+- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
+- Change name of "write" variable in inffast.c to avoid library collisions
+- Fix premature EOF from gzread() in gzio.c [Brown]
+- Use zlib header window size if windowBits is 0 in inflateInit2()
+- Remove compressBound() call in deflate.c to avoid linking compress.o
+- Replace use of errno in gz* with functions, support WinCE [Alves]
+- Provide alternative to perror() in minigzip.c for WinCE [Alves]
+- Don't use _vsnprintf on later versions of MSVC [Lowman]
+- Add CMake build script and input file [Lowman]
+- Update contrib/minizip to 1.1 [Svensson, Vollant]
+- Moved nintendods directory from contrib to .
+- Replace gzio.c with a new set of routines with the same functionality
+- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
+- Update contrib/minizip to 1.1b
+- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
+
+Changes in 1.2.3.4 (21 Dec 2009)
+- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
+- Update comments in configure and Makefile.in for default --shared
+- Fix test -z's in configure [Marquess]
+- Build examplesh and minigzipsh when not testing
+- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
+- Import LDFLAGS from the environment in configure
+- Fix configure to populate SFLAGS with discovered CFLAGS options
+- Adapt make_vms.com to the new Makefile.in [Zinser]
+- Add zlib2ansi script for C++ compilation [Marquess]
+- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
+- Add AMD64 assembler code for longest match to contrib [Teterin]
+- Include options from $SFLAGS when doing $LDSHARED
+- Simplify 64-bit file support by introducing z_off64_t type
+- Make shared object files in objs directory to work around old Sun cc
+- Use only three-part version number for Darwin shared compiles
+- Add rc option to ar in Makefile.in for when ./configure not run
+- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
+- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
+- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
+- Rename Makefile.in targets allstatic to static and allshared to shared
+- Fix static and shared Makefile.in targets to be independent
+- Correct error return bug in gz_open() by setting state [Brown]
+- Put spaces before ;;'s in configure for better sh compatibility
+- Add pigz.c (parallel implementation of gzip) to examples/
+- Correct constant in crc32.c to UL [Leventhal]
+- Reject negative lengths in crc32_combine()
+- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
+- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
+- Correct typo in doc/algorithm.txt [Janik]
+- Fix bug in adler32_combine() [Zhu]
+- Catch missing-end-of-block-code error in all inflates and in puff
+    Assures that random input to inflate eventually results in an error
+- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
+- Update ENOUGH and its usage to reflect discovered bounds
+- Fix gzerror() error report on empty input file [Brown]
+- Add ush casts in trees.c to avoid pedantic runtime errors
+- Fix typo in zlib.h uncompress() description [Reiss]
+- Correct inflate() comments with regard to automatic header detection
+- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
+- Put new version of gzlog (2.0) in examples with interruption recovery
+- Add puff compile option to permit invalid distance-too-far streams
+- Add puff TEST command options, ability to read piped input
+- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
+  _LARGEFILE64_SOURCE not defined
+- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
+- Fix deflateSetDictionary() to use all 32K for output consistency
+- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
+- Clear bytes after deflate lookahead to avoid use of uninitialized data
+- Change a limit in inftrees.c to be more transparent to Coverity Prevent
+- Update win32/zlib.def with exported symbols from zlib.h
+- Correct spelling error in zlib.h [Willem]
+- Allow Z_BLOCK for deflate() to force a new block
+- Allow negative bits in inflatePrime() to delete existing bit buffer
+- Add Z_TREES flush option to inflate() to return at end of trees
+- Add inflateMark() to return current state information for random access
+- Add Makefile for NintendoDS to contrib [Costa]
+- Add -w in configure compile tests to avoid spurious warnings [Beucler]
+- Fix typos in zlib.h comments for deflateSetDictionary()
+- Fix EOF detection in transparent gzread() [Maier]
+
+Changes in 1.2.3.3 (2 October 2006)
+- Make --shared the default for configure, add a --static option
+- Add compile option to permit invalid distance-too-far streams
+- Add inflateUndermine() function which is required to enable above
+- Remove use of "this" variable name for C++ compatibility [Marquess]
+- Add testing of shared library in make test, if shared library built
+- Use ftello() and fseeko() if available instead of ftell() and fseek()
+- Provide two versions of all functions that use the z_off_t type for
+  binary compatibility -- a normal version and a 64-bit offset version,
+  per the Large File Support Extension when _LARGEFILE64_SOURCE is
+  defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
+  is defined to be 64
+- Add a --uname= option to configure to perhaps help with cross-compiling
+
+Changes in 1.2.3.2 (3 September 2006)
+- Turn off silly Borland warnings [Hay]
+- Use off64_t and define _LARGEFILE64_SOURCE when present
+- Fix missing dependency on inffixed.h in Makefile.in
+- Rig configure --shared to build both shared and static [Teredesai, Truta]
+- Remove zconf.in.h and instead create a new zlibdefs.h file
+- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
+- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
+
+Changes in 1.2.3.1 (16 August 2006)
+- Add watcom directory with OpenWatcom make files [Daniel]
+- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
+- Update make_vms.com [Zinser]
+- Use -fPIC for shared build in configure [Teredesai, Nicholson]
+- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
+- Use fdopen() (not _fdopen()) for Interix in zutil.h [B\8ack]
+- Add some FAQ entries about the contrib directory
+- Update the MVS question in the FAQ
+- Avoid extraneous reads after EOF in gzio.c [Brown]
+- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
+- Add comments to zlib.h about gzerror() usage [Brown]
+- Set extra flags in gzip header in gzopen() like deflate() does
+- Make configure options more compatible with double-dash conventions
+  [Weigelt]
+- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
+- Fix uninstall target in Makefile.in [Truta]
+- Add pkgconfig support [Weigelt]
+- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
+- Replace set_data_type() with a more accurate detect_data_type() in
+  trees.c, according to the txtvsbin.txt document [Truta]
+- Swap the order of #include <stdio.h> and #include "zlib.h" in
+  gzio.c, example.c and minigzip.c [Truta]
+- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
+  Truta] (where?)
+- Fix target "clean" from win32/Makefile.bor [Truta]
+- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
+- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
+- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
+- Enable browse info in the "Debug" and "ASM Debug" configurations in
+  the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
+- Add pkgconfig support [Weigelt]
+- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
+  for use in win32/zlib1.rc [Polushin, Rowe, Truta]
+- Add a document that explains the new text detection scheme to
+  doc/txtvsbin.txt [Truta]
+- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
+- Move algorithm.txt into doc/ [Truta]
+- Synchronize FAQ with website
+- Fix compressBound(), was low for some pathological cases [Fearnley]
+- Take into account wrapper variations in deflateBound()
+- Set examples/zpipe.c input and output to binary mode for Windows
+- Update examples/zlib_how.html with new zpipe.c (also web site)
+- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
+  that gcc became pickier in 4.0)
+- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
+  un-versioned, the patch adds versioning only for symbols introduced in
+  zlib-1.2.0 or later.  It also declares as local those symbols which are
+  not designed to be exported." [Levin]
+- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
+- Do not initialize global static by default in trees.c, add a response
+  NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
+- Don't use strerror() in gzio.c under WinCE [Yakimov]
+- Don't use errno.h in zutil.h under WinCE [Yakimov]
+- Move arguments for AR to its usage to allow replacing ar [Marot]
+- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
+- Improve inflateInit() and inflateInit2() documentation
+- Fix structure size comment in inflate.h
+- Change configure help option from --h* to --help [Santos]
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+  compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Add zran.c example of compressed data random access to examples
+  directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+  ENOUGH and MAXD -- this repairs a possible security vulnerability for
+  invalid inflate input.  Thanks to Tavis Ormandy and Markus Oberhumer for
+  discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+  avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+  and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+  contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+  dynamic blocks with only literals and no distance codes --
+  Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+    - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+    - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+  the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+  [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+  and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+  [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+  [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+  INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+  [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+  of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+  parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+  to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+  16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+  Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+  zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+  library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+  special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+    - Report 0 for huffman and rle strategies and for level == 0 or 1
+    - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+    - When Z_RLE requested, restrict matches to distance one
+    - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+    - Refine detection of Turbo C need for dummy returns
+    - Refine ZLIB_DLL compilation
+    - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+  write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+    - About 20% faster
+    - Does not allocate 32K window unless and until needed
+    - Automatically detects and decompresses gzip streams
+    - Raw inflate no longer needs an extra dummy byte at end
+    - Added inflateBack functions using a callback interface--even faster
+      than inflate, useful for file utilities (gzip, zip)
+    - Added inflateCopy() function to record state for random access on
+      externally generated deflate streams (e.g. in gzip files)
+    - More readable code (I hope)
+- New and improved crc32()
+    - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+  and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+  return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+  is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+    - Document raw deflate and inflate
+    - Update RFCs URL
+    - Point out that zlib and gzip formats are different
+    - Note that Z_BUF_ERROR is not fatal
+    - Document string limit for gzprintf() and possible buffer overflow
+    - Note requirement on avail_out when flushing
+    - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+  This creates a security problem described in
+  http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+  less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+  of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+  occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+  (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+  See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean"  (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+  . zutil.c, zutil.h: added "const" for zmem*
+  . Make_vms.com: fixed some typos
+  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+  . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+  . msdos/Makefile.*: use model-dependent name for the built zlib library
+  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+  See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+  completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+  compression ratio on some files. This also allows inlining _tr_tally for
+  matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+  on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+  the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+  them at run time (thanks to Ken Raeburn for this suggestion). To create
+  trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+  Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+  (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+  inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+   contrib/asm386/ by Gilles Vollant <info@winimage.com>
+        386 asm code replacing longest_match().
+   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+   contrib/iostream2/  by Tyge Løvset <Tyge.Lovset@cmr.no>
+        Another C++ I/O streams interface
+   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+        A very simple tar.gz file extractor using zlib
+   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+        How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+  level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+  (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+  bit, so the decompressor could decompress all the correct data but went
+  on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+  small and medium models; this makes the library incompatible with previous
+  versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+  avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+  and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
+     (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+  not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+  (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+  typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+  was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+  pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+  is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+  (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+  TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+  (one's complement) is now done inside crc32(). WARNING: this is
+  incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+  not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+  if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+  user-provided history buffer. This is supported only in deflateInit2
+  and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/8.x/zlib/FAQ b/8.x/zlib/FAQ
new file mode 100644 (file)
index 0000000..1a22750
--- /dev/null
@@ -0,0 +1,366 @@
+
+                Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+    Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+    The zlib sources can be compiled without change to produce a DLL.  See the
+    file win32/DLL_FAQ.txt in the zlib distribution.  Pointers to the
+    precompiled DLL are found in the zlib web site at http://zlib.net/ .
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+    See
+        * http://marknelson.us/1997/01/01/zlib-engine/
+        * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+    Make sure that before the call of compress(), the length of the compressed
+    buffer is equal to the available size of the compressed buffer and not
+    zero.  For Visual Basic, check that this parameter is passed by reference
+    ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+    Before making the call, make sure that avail_in and avail_out are not zero.
+    When setting the parameter flush equal to Z_FINISH, also make sure that
+    avail_out is big enough to allow processing all pending input.  Note that a
+    Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+    made with more input or output space.  A Z_BUF_ERROR may in fact be
+    unavoidable depending on how the functions are used, since it is not
+    possible to tell whether or not there is more output pending when
+    strm.avail_out returns with zero.  See http://zlib.net/zlib_how.html for a
+    heavily annotated example.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+    It's in zlib.h .  Examples of zlib usage are in the files example.c and
+    minigzip.c, with more in examples/ .
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+    Because we would like to keep zlib as a very small and simple package.
+    zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+    Most of the time, such problems are due to an incorrect usage of zlib.
+    Please try to reproduce the problem with a small program and send the
+    corresponding source to us at zlib@gzip.org .  Do not send multi-megabyte
+    data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+    If "make test" produces something like
+
+       example.o(.text+0x154): undefined reference to `gzputc'
+
+    check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+    /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+    See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+    Not by itself, no.  See the directory contrib/minizip in the zlib
+    distribution.
+
+12. Can zlib handle .Z files?
+
+    No, sorry.  You have to spawn an uncompress or gunzip subprocess, or adapt
+    the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+    make clean
+    ./configure -s
+    make
+
+14. How do I install a shared zlib library on Unix?
+
+    After the above, then:
+
+    make install
+
+    However, many flavors of Unix come with a shared zlib already installed.
+    Before going to the trouble of compiling a shared version of zlib and
+    trying to install it, you may want to check if it's already there!  If you
+    can #include <zlib.h>, it's there.  The -lz option will probably link to
+    it.  You can check the version at the top of zlib.h or with the
+    ZLIB_VERSION symbol defined in zlib.h .
+
+15. I have a question about OttoPDF.
+
+    We are not the authors of OttoPDF. The real author is on the OttoPDF web
+    site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+    Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+    http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+    After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+    generates an error such as:
+
+        ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+        symbol __register_frame_info: referenced symbol not found
+
+    The symbol __register_frame_info is not part of zlib, it is generated by
+    the C compiler (cc or gcc).  You must recompile applications using zlib
+    which have this problem.  This problem is specific to Solaris.  See
+    http://www.sunfreeware.com for Solaris versions of zlib and applications
+    using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+    The compress and deflate functions produce data in the zlib format, which
+    is different and incompatible with the gzip format.  The gz* functions in
+    zlib on the other hand use the gzip format.  Both the zlib and gzip formats
+    use the same compressed data format internally, but have different headers
+    and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+    The gzip format was designed to retain the directory information about a
+    single file, such as the name and last modification date.  The zlib format
+    on the other hand was designed for in-memory and communication channel
+    applications, and has a much more compact header and trailer and uses a
+    faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+    You can request that deflate write the gzip format instead of the zlib
+    format using deflateInit2().  You can also request that inflate decode the
+    gzip format using inflateInit2().  Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+    Yes.  However any library routines that zlib uses and any application-
+    provided memory allocation routines must also be thread-safe.  zlib's gz*
+    functions use stdio library routines, and most of zlib's functions use the
+    library memory allocation routines by default.  zlib's *Init* functions
+    allow for the application to provide custom memory allocation routines.
+
+    Of course, you should only operate on any given zlib or gzip stream from a
+    single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+    Yes.  Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+    No.  Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+    what exactly do I need to do to meet that requirement?
+
+    You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h.  In
+    particular, the final version number needs to be changed to "f", and an
+    identification string should be appended to ZLIB_VERSION.  Version numbers
+    x.x.x.f are reserved for modifications to zlib by others than the zlib
+    maintainers.  For example, if the version of the base zlib you are altering
+    is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+    ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3".  You can also
+    update the version strings in deflate.c and inftrees.c.
+
+    For altered source distributions, you should also note the origin and
+    nature of the changes in zlib.h, as well as in ChangeLog and README, along
+    with the dates of the alterations.  The origin should include at least your
+    name (or your company's name), and an email address to contact for help or
+    issues with the library.
+
+    Note that distributing a compiled zlib library along with zlib.h and
+    zconf.h is also a source distribution, and so you should change
+    ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+    in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+    exchange compressed data between them?
+
+    Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+    Yes.  It has been tested on 64-bit machines, and has no dependence on any
+    data types being limited to 32-bits in length.  If you have any
+    difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+    No.  The PKWare DCL uses a completely different compressed data format than
+    does PKZIP and zlib.  However, you can look in zlib's contrib/blast
+    directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+    No, not without some preparation.  If when compressing you periodically use
+    Z_FULL_FLUSH, carefully write all the pending data at those points, and
+    keep an index of those locations, then you can start decompression at those
+    points.  You have to be careful to not use Z_FULL_FLUSH too often, since it
+    can significantly degrade compression.  Alternatively, you can scan a
+    deflate stream once to generate an index, and then use that index for
+    random access.  See examples/zran.c .
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+    It has in the past, but we have not heard of any recent evidence.  There
+    were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+    If you know of recent, successful applications of zlib on these operating
+    systems, please let us know.  Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at to
+    understand the deflate format?
+
+    First off, you should read RFC 1951.  Second, yes.  Look in zlib's
+    contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+    As far as we know, no.  In fact, that was originally the whole point behind
+    zlib.  Look here for some more information:
+
+    http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+    Yes.  inflate() and deflate() will process any amount of data correctly.
+    Each call of inflate() or deflate() is limited to input and output chunks
+    of the maximum value that can be stored in the compiler's "unsigned int"
+    type, but there is no limit to the number of chunks.  Note however that the
+    strm.total_in and strm_total_out counters may be limited to 4 GB.  These
+    counters are provided as a convenience and are not used internally by
+    inflate() or deflate().  The application can easily set up its own counters
+    updated after each call of inflate() or deflate() to count beyond 4 GB.
+    compress() and uncompress() may be limited to 4 GB, since they operate in a
+    single call.  gzseek() and gztell() may be limited to 4 GB depending on how
+    zlib is compiled.  See the zlibCompileFlags() function in zlib.h.
+
+    The word "may" appears several times above since there is a 4 GB limit only
+    if the compiler's "long" type is 32 bits.  If the compiler's "long" type is
+    64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+    The only one that we are aware of is potentially in gzprintf().  If zlib is
+    compiled to use sprintf() or vsprintf(), then there is no protection
+    against a buffer overflow of an 8K string space (or other value as set by
+    gzbuffer()), other than the caller of gzprintf() assuring that the output
+    will not exceed 8K.  On the other hand, if zlib is compiled to use
+    snprintf() or vsnprintf(), which should normally be the case, then there is
+    no vulnerability.  The ./configure script will display warnings if an
+    insecure variation of sprintf() will be used by gzprintf().  Also the
+    zlibCompileFlags() function will return information on what variant of
+    sprintf() is used by gzprintf().
+
+    If you don't have snprintf() or vsnprintf() and would like one, you can
+    find a portable implementation here:
+
+        http://www.ijs.si/software/snprintf/
+
+    Note that you should be using the most recent version of zlib.  Versions
+    1.1.3 and before were subject to a double-free vulnerability, and versions
+    1.2.1 and 1.2.2 were subject to an access exception when decompressing
+    invalid compressed data.
+
+34. Is there a Java version of zlib?
+
+    Probably what you want is to use zlib in Java. zlib is already included
+    as part of the Java SDK in the java.util.zip package. If you really want
+    a version of zlib written in the Java language, look on the zlib home
+    page for links: http://zlib.net/ .
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+    up to maximally-pedantic. Can't you guys write proper code?
+
+    Many years ago, we gave up attempting to avoid warnings on every compiler
+    in the universe.  It just got to be a waste of time, and some compilers
+    were downright silly as well as contradicted each other.  So now, we simply
+    make sure that the code always works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+    performing a conditional jump that depends on an uninitialized value.
+    Isn't that a bug?
+
+    No.  That is intentional for performance reasons, and the output of deflate
+    is not affected.  This only started showing up recently since zlib 1.2.x
+    uses malloc() by default for allocations, whereas earlier versions used
+    calloc(), which zeros out the allocated memory.  Even though the code was
+    correct, versions 1.2.4 and later was changed to not stimulate these
+    checkers.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+    data format?
+
+    Probably not. Look in the comp.compression FAQ for pointers to various
+    formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+    zlib doesn't support encryption.  The original PKZIP encryption is very
+    weak and can be broken with freely available programs.  To get strong
+    encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+    compression.  For PKZIP compatible "encryption", look at
+    http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+    "gzip" is the gzip format, and "deflate" is the zlib format.  They should
+    probably have called the second one "zlib" instead to avoid confusion with
+    the raw deflate compressed data format.  While the HTTP 1.1 RFC 2616
+    correctly points to the zlib specification in RFC 1950 for the "deflate"
+    transfer encoding, there have been reports of servers and browsers that
+    incorrectly produce or expect raw deflate data per the deflate
+    specficiation in RFC 1951, most notably Microsoft.  So even though the
+    "deflate" transfer encoding using the zlib format would be the more
+    efficient approach (and in fact exactly what the zlib format was designed
+    for), using the "gzip" transfer encoding is probably more reliable due to
+    an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+    Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+    No.  PKWare has apparently decided to keep that format proprietary, since
+    they have not documented it as they have previous compression formats.  In
+    any case, the compression improvements are so modest compared to other more
+    modern approaches, that it's not worth the effort to implement.
+
+41. I'm having a problem with the zip functions in zlib, can you help?
+
+    There are no zip functions in zlib.  You are probably using minizip by
+    Giles Vollant, which is found in the contrib directory of zlib.  It is not
+    part of zlib.  In fact none of the stuff in contrib is part of zlib.  The
+    files in there are not supported by the zlib authors.  You need to contact
+    the authors of the respective contribution for help.
+
+42. The match.asm code in contrib is under the GNU General Public License.
+    Since it's part of zlib, doesn't that mean that all of zlib falls under the
+    GNU GPL?
+
+    No.  The files in contrib are not part of zlib.  They were contributed by
+    other authors and are provided as a convenience to the user within the zlib
+    distribution.  Each item in contrib has its own license.
+
+43. Is zlib subject to export controls?  What is its ECCN?
+
+    zlib is not subject to export controls, and so is classified as EAR99.
+
+44. Can you please sign these lengthy legal documents and fax them back to us
+    so that we can use your software in our product?
+
+    No. Go away. Shoo.
diff --git a/8.x/zlib/INDEX b/8.x/zlib/INDEX
new file mode 100644 (file)
index 0000000..f6c51ca
--- /dev/null
@@ -0,0 +1,65 @@
+CMakeLists.txt  cmake build file
+ChangeLog       history of changes
+FAQ             Frequently Asked Questions about zlib
+INDEX           this file
+Makefile        dummy Makefile that tells you to ./configure
+Makefile.in     template for Unix Makefile
+README          guess what
+configure       configure script for Unix
+make_vms.com    makefile for VMS
+treebuild.xml   XML description of source file dependencies
+zconf.h.cmakein zconf.h template for cmake
+zconf.h.in      zconf.h template for configure
+zlib.3          Man page for zlib
+zlib.3.pdf      Man page in PDF format
+zlib.map        Linux symbol information
+zlib.pc.in      Template for pkg-config descriptor
+zlib2ansi       perl script to convert source files for C++ compilation
+
+amiga/          makefiles for Amiga SAS C
+doc/            documentation for formats and algorithms
+msdos/          makefiles for MSDOS
+nintendods/     makefile for Nintendo DS
+old/            makefiles for various architectures and zlib documentation
+                files that have not yet been updated for zlib 1.2.x
+qnx/            makefiles for QNX
+watcom/         makefiles for OpenWatcom
+win32/          makefiles for Windows
+
+                zlib public header files (required for library use):
+zconf.h
+zlib.h
+
+                private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzclose.c
+gzguts.h
+gzlib.c
+gzread.c
+gzwrite.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+                source files for sample programs:
+example.c
+minigzip.c
+See examples/README.examples for more
+
+                unsupported contribution by third parties
+See contrib/README.contrib
diff --git a/8.x/zlib/Makefile b/8.x/zlib/Makefile
new file mode 100644 (file)
index 0000000..6bba86c
--- /dev/null
@@ -0,0 +1,5 @@
+all:
+       -@echo "Please use ./configure first.  Thank you."
+
+distclean:
+       make -f Makefile.in distclean
diff --git a/8.x/zlib/Makefile.in b/8.x/zlib/Makefile.in
new file mode 100644 (file)
index 0000000..5b15bd0
--- /dev/null
@@ -0,0 +1,257 @@
+# Makefile for zlib
+# Copyright (C) 1995-2010 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+#    ./configure; make test
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+
+# To use the asm code, type:
+#    cp contrib/asm?86/match.S ./match.S
+#    make LOC=-DASMV OBJA=match.o
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+#    make install
+# To install in $HOME instead of /usr/local, use:
+#    make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+SFLAGS=-O
+LDFLAGS=
+TEST_LDFLAGS=-L. libz.a
+LDSHARED=$(CC)
+CPP=$(CC) -E
+
+STATICLIB=libz.a
+SHAREDLIB=libz.so
+SHAREDLIBV=libz.so.1.2.5
+SHAREDLIBM=libz.so.1
+LIBS=$(STATICLIB) $(SHAREDLIBV)
+
+AR=ar rc
+RANLIB=ranlib
+LDCONFIG=ldconfig
+LDSHAREDLIBC=-lc
+TAR=tar
+SHELL=/bin/sh
+EXE=
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+sharedlibdir = ${libdir}
+includedir = ${prefix}/include
+mandir = ${prefix}/share/man
+man3dir = ${mandir}/man3
+pkgconfigdir = ${libdir}/pkgconfig
+
+OBJC = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+       gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+
+PIC_OBJC = adler32.lo compress.lo crc32.lo deflate.lo gzclose.lo gzlib.lo gzread.lo \
+       gzwrite.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo uncompr.lo zutil.lo
+
+# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
+OBJA =
+PIC_OBJA =
+
+OBJS = $(OBJC) $(OBJA)
+
+PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
+
+all: static shared
+
+static: example$(EXE) minigzip$(EXE)
+
+shared: examplesh$(EXE) minigzipsh$(EXE)
+
+all64: example64$(EXE) minigzip64$(EXE)
+
+check: test
+
+test: all teststatic testshared
+
+teststatic: static
+       @if echo hello world | ./minigzip | ./minigzip -d && ./example; then \
+         echo '                *** zlib test OK ***'; \
+       else \
+         echo '                *** zlib test FAILED ***'; false; \
+       fi
+       -@rm -f foo.gz
+
+testshared: shared
+       @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+       LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
+       DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
+       SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
+       if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh; then \
+         echo '                *** zlib shared test OK ***'; \
+       else \
+         echo '                *** zlib shared test FAILED ***'; false; \
+       fi
+       -@rm -f foo.gz
+
+test64: all64
+       @if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64; then \
+         echo '                *** zlib 64-bit test OK ***'; \
+       else \
+         echo '                *** zlib 64-bit test FAILED ***'; false; \
+       fi
+       -@rm -f foo.gz
+
+libz.a: $(OBJS)
+       $(AR) $@ $(OBJS)
+       -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+match.o: match.S
+       $(CPP) match.S > _match.s
+       $(CC) -c _match.s
+       mv _match.o match.o
+       rm -f _match.s
+
+match.lo: match.S
+       $(CPP) match.S > _match.s
+       $(CC) -c -fPIC _match.s
+       mv _match.o match.lo
+       rm -f _match.s
+
+example64.o: example.c zlib.h zconf.h
+       $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ example.c
+
+minigzip64.o: minigzip.c zlib.h zconf.h
+       $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ minigzip.c
+
+.SUFFIXES: .lo
+
+.c.lo:
+       -@mkdir objs 2>/dev/null || test -d objs
+       $(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $<
+       -@mv objs/$*.o $@
+
+$(SHAREDLIBV): $(PIC_OBJS)
+       $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)
+       rm -f $(SHAREDLIB) $(SHAREDLIBM)
+       ln -s $@ $(SHAREDLIB)
+       ln -s $@ $(SHAREDLIBM)
+       -@rmdir objs
+
+example$(EXE): example.o $(STATICLIB)
+       $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS)
+
+minigzip$(EXE): minigzip.o $(STATICLIB)
+       $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)
+
+examplesh$(EXE): example.o $(SHAREDLIBV)
+       $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
+
+minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
+       $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
+
+example64$(EXE): example64.o $(STATICLIB)
+       $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)
+
+minigzip64$(EXE): minigzip64.o $(STATICLIB)
+       $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS)
+
+install-libs: $(LIBS)
+       -@if [ ! -d $(DESTDIR)$(exec_prefix)  ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
+       -@if [ ! -d $(DESTDIR)$(libdir)       ]; then mkdir -p $(DESTDIR)$(libdir); fi
+       -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi
+       -@if [ ! -d $(DESTDIR)$(man3dir)      ]; then mkdir -p $(DESTDIR)$(man3dir); fi
+       -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi
+       cp $(STATICLIB) $(DESTDIR)$(libdir)
+       cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)
+       cd $(DESTDIR)$(libdir); chmod u=rw,go=r $(STATICLIB)
+       -@(cd $(DESTDIR)$(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
+       -@cd $(DESTDIR)$(sharedlibdir); if test "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
+         chmod 755 $(SHAREDLIBV); \
+         rm -f $(SHAREDLIB) $(SHAREDLIBM); \
+         ln -s $(SHAREDLIBV) $(SHAREDLIB); \
+         ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
+         ($(LDCONFIG) || true)  >/dev/null 2>&1; \
+       fi
+       cp zlib.3 $(DESTDIR)$(man3dir)
+       chmod 644 $(DESTDIR)$(man3dir)/zlib.3
+       cp zlib.pc $(DESTDIR)$(pkgconfigdir)
+       chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+install: install-libs
+       -@if [ ! -d $(DESTDIR)$(includedir)   ]; then mkdir -p $(DESTDIR)$(includedir); fi
+       cp zlib.h zconf.h $(DESTDIR)$(includedir)
+       chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+
+uninstall:
+       cd $(DESTDIR)$(includedir); rm -f zlib.h zconf.h
+       cd $(DESTDIR)$(libdir); rm -f libz.a; \
+       if test "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
+         rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+       fi
+       cd $(DESTDIR)$(man3dir); rm -f zlib.3
+       cd $(DESTDIR)$(pkgconfigdir); rm -f zlib.pc
+
+docs: zlib.3.pdf
+
+zlib.3.pdf: zlib.3
+       groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf
+
+zconf.h.in: zconf.h.cmakein
+       sed "/^#cmakedefine/D" < zconf.h.cmakein > zconf.h.in
+       touch -r zconf.h.cmakein zconf.h.in
+
+zconf: zconf.h.in
+       cp -p zconf.h.in zconf.h
+
+mostlyclean: clean
+clean:
+       rm -f *.o *.lo *~ \
+          example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
+          example64$(EXE) minigzip64$(EXE) \
+          libz.* foo.gz so_locations \
+          _match.s maketree contrib/infback9/*.o
+       rm -rf objs
+
+maintainer-clean: distclean
+distclean: clean zconf docs
+       rm -f Makefile zlib.pc
+       -@rm -f .DS_Store
+       -@printf 'all:\n\t-@echo "Please use ./configure first.  Thank you."\n' > Makefile
+       -@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile
+       -@touch -r Makefile.in Makefile
+
+tags:
+       etags *.[ch]
+
+depend:
+       makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o zutil.o: zutil.h zlib.h zconf.h
+gzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h
+compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h
+crc32.o: zutil.h zlib.h zconf.h crc32.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+infback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+
+adler32.lo zutil.lo: zutil.h zlib.h zconf.h
+gzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h
+compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h
+crc32.lo: zutil.h zlib.h zconf.h crc32.h
+deflate.lo: deflate.h zutil.h zlib.h zconf.h
+infback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h
+inffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.lo: zutil.h zlib.h zconf.h inftrees.h
+trees.lo: deflate.h zutil.h zlib.h zconf.h trees.h
diff --git a/8.x/zlib/README b/8.x/zlib/README
new file mode 100644 (file)
index 0000000..d4219bf
--- /dev/null
@@ -0,0 +1,115 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.5 is a general purpose data compression library.  All the code is
+thread safe.  The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org).  A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly.  Another example is given in the file minigzip.c.  The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile.in.  In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix.  For Windows, use one
+of the special makefiles in win32/ or contrib/vstudio/ .  For VMS, use
+make_vms.com.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version.  The zlib home page is
+http://zlib.net/ .  Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan.  1997
+issue of Dr.  Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
+
+The changes made in version 1.2.5 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory contrib/ .
+
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html .
+
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+  -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+  compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+  when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+  necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+  other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS or BEOS.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz.  The deflate and
+  zlib specifications were written by L.  Peter Deutsch.  Thanks to all the
+  people who reported problems and suggested various improvements in zlib; they
+  are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign.  The sources are provided for free but without
+warranty of any kind.  The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes.  Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/8.x/zlib/adler32.c b/8.x/zlib/adler32.c
new file mode 100644 (file)
index 0000000..65ad6a5
--- /dev/null
@@ -0,0 +1,169 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2007 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#define local static
+
+local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
+
+#define BASE 65521UL    /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware */
+#ifdef NO_DIVIDE
+#  define MOD(a) \
+    do { \
+        if (a >= (BASE << 16)) a -= (BASE << 16); \
+        if (a >= (BASE << 15)) a -= (BASE << 15); \
+        if (a >= (BASE << 14)) a -= (BASE << 14); \
+        if (a >= (BASE << 13)) a -= (BASE << 13); \
+        if (a >= (BASE << 12)) a -= (BASE << 12); \
+        if (a >= (BASE << 11)) a -= (BASE << 11); \
+        if (a >= (BASE << 10)) a -= (BASE << 10); \
+        if (a >= (BASE << 9)) a -= (BASE << 9); \
+        if (a >= (BASE << 8)) a -= (BASE << 8); \
+        if (a >= (BASE << 7)) a -= (BASE << 7); \
+        if (a >= (BASE << 6)) a -= (BASE << 6); \
+        if (a >= (BASE << 5)) a -= (BASE << 5); \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD4(a) \
+    do { \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD4(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD4(sum2);             /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
+            DO16(buf);
+            buf += 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    rem = (unsigned)(len2 % BASE);
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+    if (sum2 >= BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/8.x/zlib/amiga/Makefile.pup b/8.x/zlib/amiga/Makefile.pup
new file mode 100644 (file)
index 0000000..8940c12
--- /dev/null
@@ -0,0 +1,69 @@
+# Amiga powerUP (TM) Makefile
+# makefile for libpng and SAS C V6.58/7.00 PPC compiler
+# Copyright (C) 1998 by Andreas R. Kleinert
+
+LIBNAME        = libzip.a
+
+CC     = scppc
+CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
+         OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER
+AR     = ppc-amigaos-ar cr
+RANLIB = ppc-amigaos-ranlib
+LD     = ppc-amigaos-ld -r
+LDFLAGS        = -o
+LDLIBS = LIB:scppc.a LIB:end.o
+RM     = delete quiet
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example minigzip
+
+check: test
+test: all
+       example
+       echo hello world | minigzip | minigzip -d
+
+$(LIBNAME): $(OBJS)
+       $(AR) $@ $(OBJS)
+       -$(RANLIB) $@
+
+example: example.o $(LIBNAME)
+       $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
+
+minigzip: minigzip.o $(LIBNAME)
+       $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
+
+mostlyclean: clean
+clean:
+       $(RM) *.o example minigzip $(LIBNAME) foo.gz
+
+zip:
+       zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
+         descrip.mms *.[ch]
+
+tgz:
+       cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
+         zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/8.x/zlib/amiga/Makefile.sas b/8.x/zlib/amiga/Makefile.sas
new file mode 100644 (file)
index 0000000..749e291
--- /dev/null
@@ -0,0 +1,68 @@
+# SMakefile for zlib
+# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
+# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
+# Amiga, SAS/C 6.56 & Smake
+
+CC=sc
+CFLAGS=OPT
+#CFLAGS=OPT CPU=68030
+#CFLAGS=DEBUG=LINE
+LDFLAGS=LIB z.lib
+
+SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
+       NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \
+       DEF=POSTINC
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: SCOPTIONS example minigzip
+
+check: test
+test: all
+       example
+       echo hello world | minigzip | minigzip -d
+
+install: z.lib
+       copy clone zlib.h zconf.h INCLUDE:
+       copy clone z.lib LIB:
+
+z.lib: $(OBJS)
+       oml z.lib r $(OBJS)
+
+example: example.o z.lib
+       $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
+
+minigzip: minigzip.o z.lib
+       $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
+
+mostlyclean: clean
+clean:
+       -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS
+
+SCOPTIONS: Makefile.sas
+       copy to $@ <from <
+$(SCOPTIONS)
+<
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/8.x/zlib/compress.c b/8.x/zlib/compress.c
new file mode 100644 (file)
index 0000000..ea4dfbe
--- /dev/null
@@ -0,0 +1,80 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+     If the default memLevel or windowBits for deflateInit() is changed, then
+   this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+    uLong sourceLen;
+{
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13;
+}
diff --git a/8.x/zlib/configure b/8.x/zlib/configure
new file mode 100755 (executable)
index 0000000..bd9edd2
--- /dev/null
@@ -0,0 +1,596 @@
+#!/bin/sh
+# configure script for zlib.
+#
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+#
+# To impose specific compiler or flags or install directory, use for example:
+#    prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+#    (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+
+# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
+# If you have problems, try without defining CC and CFLAGS before reporting
+# an error.
+
+if [ -n "${CHOST}" ]; then
+    uname="$(echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/')"
+    CROSS_PREFIX="${CHOST}-"
+fi
+
+STATICLIB=libz.a
+LDFLAGS="${LDFLAGS} -L. ${STATICLIB}"
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
+VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h`
+VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
+VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
+if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    AR=${AR-"${CROSS_PREFIX}ar"}
+    test -n "${CROSS_PREFIX}" && echo Using ${AR}
+else
+    AR=${AR-"ar"}
+    test -n "${CROSS_PREFIX}" && echo Using ${AR}
+fi
+AR_RC="${AR} rc"
+if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"}
+    test -n "${CROSS_PREFIX}" && echo Using ${RANLIB}
+else
+    RANLIB=${RANLIB-"ranlib"}
+fi
+if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    NM=${NM-"${CROSS_PREFIX}nm"}
+    test -n "${CROSS_PREFIX}" && echo Using ${NM}
+else
+    NM=${NM-"nm"}
+fi
+LDCONFIG=${LDCONFIG-"ldconfig"}
+LDSHAREDLIBC="${LDSHAREDLIBC--lc}"
+prefix=${prefix-/usr/local}
+exec_prefix=${exec_prefix-'${prefix}'}
+libdir=${libdir-'${exec_prefix}/lib'}
+sharedlibdir=${sharedlibdir-'${libdir}'}
+includedir=${includedir-'${prefix}/include'}
+mandir=${mandir-'${prefix}/share/man'}
+shared_ext='.so'
+shared=1
+zprefix=0
+build64=0
+gcc=0
+old_cc="$CC"
+old_cflags="$CFLAGS"
+
+while test $# -ge 1
+do
+case "$1" in
+    -h* | --help)
+      echo 'usage:'
+      echo '  configure [--zprefix] [--prefix=PREFIX]  [--eprefix=EXPREFIX]'
+      echo '    [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]'
+      echo '    [--includedir=INCLUDEDIR]'
+        exit 0 ;;
+    -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+    -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+    -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;;
+    --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;;
+    -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;;
+    -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;;
+    -p* | --prefix) prefix="$2"; shift; shift ;;
+    -e* | --eprefix) exec_prefix="$2"; shift; shift ;;
+    -l* | --libdir) libdir="$2"; shift; shift ;;
+    -i* | --includedir) includedir="$2"; shift; shift ;;
+    -s* | --shared | --enable-shared) shared=1; shift ;;
+    -t | --static) shared=0; shift ;;
+    -z* | --zprefix) zprefix=1; shift ;;
+    -6* | --64) build64=1; shift ;;
+    --sysconfdir=*) echo "ignored option: --sysconfdir"; shift ;;
+    --localstatedir=*) echo "ignored option: --localstatedir"; shift ;;
+    *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1 ;;
+    esac
+done
+
+test=ztest$$
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+
+test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc...
+cc=${CC-${CROSS_PREFIX}gcc}
+cflags=${CFLAGS-"-O3"}
+# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
+case "$cc" in
+  *gcc*) gcc=1 ;;
+esac
+
+if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
+  CC="$cc"
+  SFLAGS="${CFLAGS--O3} -fPIC"
+  CFLAGS="${CFLAGS--O3}"
+  if test $build64 -eq 1; then
+    CFLAGS="${CFLAGS} -m64"
+    SFLAGS="${SFLAGS} -m64"
+  fi
+  if test "${ZLIBGCCWARN}" = "YES"; then
+    CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
+  fi
+  if test -z "$uname"; then
+    uname=`(uname -s || echo unknown) 2>/dev/null`
+  fi
+  case "$uname" in
+  Linux* | linux* | GNU | GNU/* | *BSD | DragonFly) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;;
+  CYGWIN* | Cygwin* | cygwin* | OS/2*)
+        EXE='.exe' ;;
+  MINGW*|mingw*)
+# temporary bypass
+        rm -f $test.[co] $test $test$shared_ext
+        echo "Please use win32/Makefile.gcc instead."
+        exit 1
+        LDSHARED=${LDSHARED-"$cc -shared"}
+        LDSHAREDLIBC=""
+        EXE='.exe' ;;
+  QNX*)  # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
+         # (alain.bonnefoy@icbt.com)
+                 LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;;
+  HP-UX*)
+         LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
+         case `(uname -m || echo unknown) 2>/dev/null` in
+         ia64)
+                 shared_ext='.so'
+                 SHAREDLIB='libz.so' ;;
+         *)
+                 shared_ext='.sl'
+                 SHAREDLIB='libz.sl' ;;
+         esac ;;
+  Darwin*)   shared_ext='.dylib'
+             SHAREDLIB=libz$shared_ext
+             SHAREDLIBV=libz.$VER$shared_ext
+             SHAREDLIBM=libz.$VER1$shared_ext
+             LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} ;;
+  *)             LDSHARED=${LDSHARED-"$cc -shared"} ;;
+  esac
+else
+  # find system name and corresponding cc options
+  CC=${CC-cc}
+  gcc=0
+  if test -z "$uname"; then
+    uname=`(uname -sr || echo unknown) 2>/dev/null`
+  fi
+  case "$uname" in
+  HP-UX*)    SFLAGS=${CFLAGS-"-O +z"}
+             CFLAGS=${CFLAGS-"-O"}
+#            LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
+             LDSHARED=${LDSHARED-"ld -b"}
+         case `(uname -m || echo unknown) 2>/dev/null` in
+         ia64)
+             shared_ext='.so'
+             SHAREDLIB='libz.so' ;;
+         *)
+             shared_ext='.sl'
+             SHAREDLIB='libz.sl' ;;
+         esac ;;
+  IRIX*)     SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+             CFLAGS=${CFLAGS-"-ansi -O2"}
+             LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+  OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
+             CFLAGS=${CFLAGS-"-O -std1"}
+             LDFLAGS="${LDFLAGS} -Wl,-rpath,."
+             LDSHARED=${LDSHARED-"cc -shared  -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;;
+  OSF1*)     SFLAGS=${CFLAGS-"-O -std1"}
+             CFLAGS=${CFLAGS-"-O -std1"}
+             LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+  QNX*)      SFLAGS=${CFLAGS-"-4 -O"}
+             CFLAGS=${CFLAGS-"-4 -O"}
+             LDSHARED=${LDSHARED-"cc"}
+             RANLIB=${RANLIB-"true"}
+             AR_RC="cc -A" ;;
+  SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+             CFLAGS=${CFLAGS-"-O3"}
+             LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;;
+  SunOS\ 5*) LDSHARED=${LDSHARED-"cc -G"}
+         case `(uname -m || echo unknown) 2>/dev/null` in
+         i86*)
+             SFLAGS=${CFLAGS-"-xpentium -fast -KPIC -R."}
+             CFLAGS=${CFLAGS-"-xpentium -fast"} ;;
+         *)
+             SFLAGS=${CFLAGS-"-fast -xcg92 -KPIC -R."}
+             CFLAGS=${CFLAGS-"-fast -xcg92"} ;;
+         esac ;;
+  SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+             CFLAGS=${CFLAGS-"-O2"}
+             LDSHARED=${LDSHARED-"ld"} ;;
+  SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
+             CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"}
+             LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;;
+  UNIX_System_V\ 4.2.0)
+             SFLAGS=${CFLAGS-"-KPIC -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  UNIX_SV\ 4.2MP)
+             SFLAGS=${CFLAGS-"-Kconform_pic -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  OpenUNIX\ 5)
+             SFLAGS=${CFLAGS-"-KPIC -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  AIX*)  # Courtesy of dbakker@arrayasolutions.com
+             SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+             CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+             LDSHARED=${LDSHARED-"xlc -G"} ;;
+  # send working options for other systems to zlib@gzip.org
+  *)         SFLAGS=${CFLAGS-"-O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -shared"} ;;
+  esac
+fi
+
+SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
+SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
+SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
+
+if test $shared -eq 1; then
+  echo Checking for shared library support...
+  # we must test in two steps (cc then ld), required at least on SunOS 4.x
+  if test "`($CC -w -c $SFLAGS $test.c) 2>&1`" = "" &&
+     test "`($LDSHARED $SFLAGS -o $test$shared_ext $test.o) 2>&1`" = ""; then
+    echo Building shared library $SHAREDLIBV with $CC.
+  elif test -z "$old_cc" -a -z "$old_cflags"; then
+    echo No shared library support.
+    shared=0;
+  else
+    echo Tested $CC -w -c $SFLAGS $test.c
+    $CC -w -c $SFLAGS $test.c
+    echo Tested $LDSHARED $SFLAGS -o $test$shared_ext $test.o
+    $LDSHARED $SFLAGS -o $test$shared_ext $test.o
+    echo 'No shared library support; try without defining CC and CFLAGS'
+    shared=0;
+  fi
+fi
+if test $shared -eq 0; then
+  LDSHARED="$CC"
+  ALL="static"
+  TEST="all teststatic"
+  SHAREDLIB=""
+  SHAREDLIBV=""
+  SHAREDLIBM=""
+  echo Building static library $STATICLIB version $VER with $CC.
+else
+  ALL="static shared"
+  TEST="all teststatic testshared"
+fi
+
+cat > $test.c <<EOF
+#include <sys/types.h>
+off64_t dummy = 0;
+EOF
+if test "`($CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c) 2>&1`" = ""; then
+  CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1"
+  SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1"
+  ALL="${ALL} all64"
+  TEST="${TEST} test64"
+  echo "Checking for off64_t... Yes."
+  echo "Checking for fseeko... Yes."
+else
+  echo "Checking for off64_t... No."
+  cat > $test.c <<EOF
+#include <stdio.h>
+int main(void) {
+  fseeko(NULL, 0, 0);
+  return 0;
+}
+EOF
+  if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
+    echo "Checking for fseeko... Yes."
+  else
+    CFLAGS="${CFLAGS} -DNO_FSEEKO"
+    SFLAGS="${SFLAGS} -DNO_FSEEKO"
+    echo "Checking for fseeko... No."
+  fi
+fi
+
+cp -p zconf.h.in zconf.h
+
+cat > $test.c <<EOF
+#include <unistd.h>
+int main() { return 0; }
+EOF
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+  sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+  mv zconf.temp.h zconf.h
+  echo "Checking for unistd.h... Yes."
+else
+  echo "Checking for unistd.h... No."
+fi
+
+if test $zprefix -eq 1; then
+  sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h
+  mv zconf.temp.h zconf.h
+  echo "Using z_ prefix on all symbols."
+fi
+
+cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+#include "zconf.h"
+
+int main()
+{
+#ifndef STDC
+  choke me
+#endif
+
+  return 0;
+}
+EOF
+
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+  echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()."
+
+  cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(const char *fmt, ...)
+{
+  char buf[20];
+  va_list ap;
+
+  va_start(ap, fmt);
+  vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+  return 0;
+}
+
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+
+  if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
+    echo "Checking for vsnprintf() in stdio.h... Yes."
+
+    cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(const char *fmt, ...)
+{
+  int n;
+  char buf[20];
+  va_list ap;
+
+  va_start(ap, fmt);
+  n = vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+  return n;
+}
+
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+
+    if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+      echo "Checking for return value of vsnprintf()... Yes."
+    else
+      CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
+      SFLAGS="$SFLAGS -DHAS_vsnprintf_void"
+      echo "Checking for return value of vsnprintf()... No."
+      echo "  WARNING: apparently vsnprintf() does not return a value. zlib"
+      echo "  can build but will be open to possible string-format security"
+      echo "  vulnerabilities."
+    fi
+  else
+    CFLAGS="$CFLAGS -DNO_vsnprintf"
+    SFLAGS="$SFLAGS -DNO_vsnprintf"
+    echo "Checking for vsnprintf() in stdio.h... No."
+    echo "  WARNING: vsnprintf() not found, falling back to vsprintf(). zlib"
+    echo "  can build but will be open to possible buffer-overflow security"
+    echo "  vulnerabilities."
+
+    cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(const char *fmt, ...)
+{
+  int n;
+  char buf[20];
+  va_list ap;
+
+  va_start(ap, fmt);
+  n = vsprintf(buf, fmt, ap);
+  va_end(ap);
+  return n;
+}
+
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+
+    if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+      echo "Checking for return value of vsprintf()... Yes."
+    else
+      CFLAGS="$CFLAGS -DHAS_vsprintf_void"
+      SFLAGS="$SFLAGS -DHAS_vsprintf_void"
+      echo "Checking for return value of vsprintf()... No."
+      echo "  WARNING: apparently vsprintf() does not return a value. zlib"
+      echo "  can build but will be open to possible string-format security"
+      echo "  vulnerabilities."
+    fi
+  fi
+else
+  echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()."
+
+  cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+  char buf[20];
+
+  snprintf(buf, sizeof(buf), "%s", "foo");
+  return 0;
+}
+
+int main()
+{
+  return (mytest());
+}
+EOF
+
+  if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
+    echo "Checking for snprintf() in stdio.h... Yes."
+
+    cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+  char buf[20];
+
+  return snprintf(buf, sizeof(buf), "%s", "foo");
+}
+
+int main()
+{
+  return (mytest());
+}
+EOF
+
+    if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+      echo "Checking for return value of snprintf()... Yes."
+    else
+      CFLAGS="$CFLAGS -DHAS_snprintf_void"
+      SFLAGS="$SFLAGS -DHAS_snprintf_void"
+      echo "Checking for return value of snprintf()... No."
+      echo "  WARNING: apparently snprintf() does not return a value. zlib"
+      echo "  can build but will be open to possible string-format security"
+      echo "  vulnerabilities."
+    fi
+  else
+    CFLAGS="$CFLAGS -DNO_snprintf"
+    SFLAGS="$SFLAGS -DNO_snprintf"
+    echo "Checking for snprintf() in stdio.h... No."
+    echo "  WARNING: snprintf() not found, falling back to sprintf(). zlib"
+    echo "  can build but will be open to possible buffer-overflow security"
+    echo "  vulnerabilities."
+
+    cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+  char buf[20];
+
+  return sprintf(buf, "%s", "foo");
+}
+
+int main()
+{
+  return (mytest());
+}
+EOF
+
+    if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+      echo "Checking for return value of sprintf()... Yes."
+    else
+      CFLAGS="$CFLAGS -DHAS_sprintf_void"
+      SFLAGS="$SFLAGS -DHAS_sprintf_void"
+      echo "Checking for return value of sprintf()... No."
+      echo "  WARNING: apparently sprintf() does not return a value. zlib"
+      echo "  can build but will be open to possible string-format security"
+      echo "  vulnerabilities."
+    fi
+  fi
+fi
+
+if test "$gcc" -eq 1; then
+  cat > $test.c <<EOF
+#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33)
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+int ZLIB_INTERNAL foo;
+int main()
+{
+  return 0;
+}
+EOF
+  if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+    echo "Checking for attribute(visibility) support... Yes."
+  else
+    CFLAGS="$CFLAGS -DNO_VIZ"
+    SFLAGS="$SFLAGS -DNO_VIZ"
+    echo "Checking for attribute(visibility) support... No."
+  fi
+fi
+
+CPP=${CPP-"$CC -E"}
+case $CFLAGS in
+  *ASMV*)
+    if test "`$NM $test.o | grep _hello`" = ""; then
+      CPP="$CPP -DNO_UNDERLINE"
+      echo Checking for underline in external names... No.
+    else
+      echo Checking for underline in external names... Yes.
+    fi ;;
+esac
+
+rm -f $test.[co] $test $test$shared_ext
+
+# udpate Makefile
+sed < Makefile.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^SFLAGS *=/s#=.*#=$SFLAGS#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^CPP *=/s#=.*#=$CPP#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR_RC#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^LDCONFIG *=/s#=.*#=$LDCONFIG#
+/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC#
+/^EXE *=/s#=.*#=$EXE#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^all: */s#:.*#: $ALL#
+/^test: */s#:.*#: $TEST#
+" > Makefile
+
+sed < zlib.pc.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^CPP *=/s#=.*#=$CPP#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR_RC#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^EXE *=/s#=.*#=$EXE#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+" | sed -e "
+s/\@VERSION\@/$VER/g;
+" > zlib.pc
diff --git a/8.x/zlib/contrib/README.contrib b/8.x/zlib/contrib/README.contrib
new file mode 100644 (file)
index 0000000..dd2285d
--- /dev/null
@@ -0,0 +1,77 @@
+All files under this contrib directory are UNSUPPORTED. There were
+provided by users of zlib and were not tested by the authors of zlib.
+Use at your own risk. Please contact the authors of the contributions
+for help about these, not the zlib authors. Thanks.
+
+
+ada/        by Dmitriy Anisimkov <anisimkov@yahoo.com>
+        Support for Ada
+        See http://zlib-ada.sourceforge.net/
+
+amd64/      by Mikhail Teterin <mi@ALDAN.algebra.com>
+        asm code for AMD64
+        See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
+
+asm686/     by Brian Raiter <breadbox@muppetlabs.com>
+        asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
+        See http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+blast/      by Mark Adler <madler@alumni.caltech.edu>
+        Decompressor for output of PKWare Data Compression Library (DCL)
+
+delphi/     by Cosmin Truta <cosmint@cs.ubbcluj.ro>
+        Support for Delphi and C++ Builder
+
+dotzlib/    by Henrik Ravn <henrik@ravn.com>
+        Support for Microsoft .Net and Visual C++ .Net
+
+gcc_gvmat64/by Gilles Vollant <info@winimage.com>
+        GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64
+        assembler to replace longest_match() and inflate_fast()
+
+infback9/   by Mark Adler <madler@alumni.caltech.edu>
+        Unsupported diffs to infback to decode the deflate64 format
+
+inflate86/  by Chris Anderson <christop@charm.net>
+        Tuned x86 gcc asm code to replace inflate_fast()
+
+iostream/   by Kevin Ruland <kevin@rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+
+iostream2/  by Tyge Løvset <Tyge.Lovset@cmr.no>
+        Another C++ I/O streams interface
+
+iostream3/  by Ludwig Schwardt <schwardt@sun.ac.za>
+            and Kevin Ruland <kevin@rodin.wustl.edu>
+        Yet another C++ I/O streams interface
+
+masmx64/    by Gilles Vollant <info@winimage.com>
+        x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
+        replace longest_match() and inflate_fast(),  also masm x86
+        64-bits translation of Chris Anderson inflate_fast()
+
+masmx86/    by Gilles Vollant <info@winimage.com>
+        x86 asm code to replace longest_match() and inflate_fast(),
+        for Visual C++ and MASM (32 bits).
+        Based on Brian Raiter (asm686) and Chris Anderson (inflate86)
+
+minizip/    by Gilles Vollant <info@winimage.com>
+        Mini zip and unzip based on zlib
+        Includes Zip64 support by Mathias Svensson <mathias@result42.com>
+        See http://www.winimage.com/zLibDll/unzip.html
+
+pascal/     by Bob Dellaca <bobdl@xtra.co.nz> et al.
+        Support for Pascal
+
+puff/       by Mark Adler <madler@alumni.caltech.edu>
+        Small, low memory usage inflate.  Also serves to provide an
+        unambiguous description of the deflate format.
+
+testzlib/   by Gilles Vollant <info@winimage.com>
+        Example of the use of zlib
+
+untgz/      by Pedro A. Aranda Gutierrez <paag@tid.es>
+        A very simple tar.gz file extractor using zlib
+
+vstudio/    by Gilles Vollant <info@winimage.com>
+        Building a minizip-enhanced zlib with Microsoft Visual Studio
diff --git a/8.x/zlib/contrib/ada/buffer_demo.adb b/8.x/zlib/contrib/ada/buffer_demo.adb
new file mode 100644 (file)
index 0000000..46b8638
--- /dev/null
@@ -0,0 +1,106 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2004 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+--
+--  $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $
+
+--  This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>
+--
+--  Demonstration of a problem with Zlib-Ada (already fixed) when a buffer
+--  of exactly the correct size is used for decompressed data, and the last
+--  few bytes passed in to Zlib are checksum bytes.
+
+--  This program compresses a string of text, and then decompresses the
+--  compressed text into a buffer of the same size as the original text.
+
+with Ada.Streams; use Ada.Streams;
+with Ada.Text_IO;
+
+with ZLib; use ZLib;
+
+procedure Buffer_Demo is
+   EOL  : Character renames ASCII.LF;
+   Text : constant String
+     := "Four score and seven years ago our fathers brought forth," & EOL &
+        "upon this continent, a new nation, conceived in liberty," & EOL &
+        "and dedicated to the proposition that `all men are created equal'.";
+
+   Source : Stream_Element_Array (1 .. Text'Length);
+   for Source'Address use Text'Address;
+
+begin
+   Ada.Text_IO.Put (Text);
+   Ada.Text_IO.New_Line;
+   Ada.Text_IO.Put_Line
+     ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes");
+
+   declare
+      Compressed_Data : Stream_Element_Array (1 .. Text'Length);
+      L               : Stream_Element_Offset;
+   begin
+      Compress : declare
+         Compressor : Filter_Type;
+         I : Stream_Element_Offset;
+      begin
+         Deflate_Init (Compressor);
+
+         --  Compress the whole of T at once.
+
+         Translate (Compressor, Source, I, Compressed_Data, L, Finish);
+         pragma Assert (I = Source'Last);
+
+         Close (Compressor);
+
+         Ada.Text_IO.Put_Line
+           ("Compressed size :   "
+            & Stream_Element_Offset'Image (L) & " bytes");
+      end Compress;
+
+      --  Now we decompress the data, passing short blocks of data to Zlib
+      --  (because this demonstrates the problem - the last block passed will
+      --  contain checksum information and there will be no output, only a
+      --  check inside Zlib that the checksum is correct).
+
+      Decompress : declare
+         Decompressor : Filter_Type;
+
+         Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);
+
+         Block_Size : constant := 4;
+         --  This makes sure that the last block contains
+         --  only Adler checksum data.
+
+         P : Stream_Element_Offset := Compressed_Data'First - 1;
+         O : Stream_Element_Offset;
+      begin
+         Inflate_Init (Decompressor);
+
+         loop
+            Translate
+              (Decompressor,
+               Compressed_Data
+                 (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),
+               P,
+               Uncompressed_Data
+                 (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),
+               O,
+               No_Flush);
+
+               Ada.Text_IO.Put_Line
+                 ("Total in : " & Count'Image (Total_In (Decompressor)) &
+                  ", out : " & Count'Image (Total_Out (Decompressor)));
+
+               exit when P = L;
+         end loop;
+
+         Ada.Text_IO.New_Line;
+         Ada.Text_IO.Put_Line
+           ("Decompressed text matches original text : "
+             & Boolean'Image (Uncompressed_Data = Source));
+      end Decompress;
+   end;
+end Buffer_Demo;
diff --git a/8.x/zlib/contrib/ada/mtest.adb b/8.x/zlib/contrib/ada/mtest.adb
new file mode 100644 (file)
index 0000000..c4dfd08
--- /dev/null
@@ -0,0 +1,156 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+--  Continuous test for ZLib multithreading. If the test would fail
+--  we should provide thread safe allocation routines for the Z_Stream.
+--
+--  $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $
+
+with ZLib;
+with Ada.Streams;
+with Ada.Numerics.Discrete_Random;
+with Ada.Text_IO;
+with Ada.Exceptions;
+with Ada.Task_Identification;
+
+procedure MTest is
+   use Ada.Streams;
+   use ZLib;
+
+   Stop : Boolean := False;
+
+   pragma Atomic (Stop);
+
+   subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
+
+   package Random_Elements is
+      new Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+   task type Test_Task;
+
+   task body Test_Task is
+      Buffer : Stream_Element_Array (1 .. 100_000);
+      Gen : Random_Elements.Generator;
+
+      Buffer_First  : Stream_Element_Offset;
+      Compare_First : Stream_Element_Offset;
+
+      Deflate : Filter_Type;
+      Inflate : Filter_Type;
+
+      procedure Further (Item : in Stream_Element_Array);
+
+      procedure Read_Buffer
+        (Item : out Ada.Streams.Stream_Element_Array;
+         Last : out Ada.Streams.Stream_Element_Offset);
+
+      -------------
+      -- Further --
+      -------------
+
+      procedure Further (Item : in Stream_Element_Array) is
+
+         procedure Compare (Item : in Stream_Element_Array);
+
+         -------------
+         -- Compare --
+         -------------
+
+         procedure Compare (Item : in Stream_Element_Array) is
+            Next_First : Stream_Element_Offset := Compare_First + Item'Length;
+         begin
+            if Buffer (Compare_First .. Next_First - 1) /= Item then
+               raise Program_Error;
+            end if;
+
+            Compare_First := Next_First;
+         end Compare;
+
+         procedure Compare_Write is new ZLib.Write (Write => Compare);
+      begin
+         Compare_Write (Inflate, Item, No_Flush);
+      end Further;
+
+      -----------------
+      -- Read_Buffer --
+      -----------------
+
+      procedure Read_Buffer
+        (Item : out Ada.Streams.Stream_Element_Array;
+         Last : out Ada.Streams.Stream_Element_Offset)
+      is
+         Buff_Diff   : Stream_Element_Offset := Buffer'Last - Buffer_First;
+         Next_First : Stream_Element_Offset;
+      begin
+         if Item'Length <= Buff_Diff then
+            Last := Item'Last;
+
+            Next_First := Buffer_First + Item'Length;
+
+            Item := Buffer (Buffer_First .. Next_First - 1);
+
+            Buffer_First := Next_First;
+         else
+            Last := Item'First + Buff_Diff;
+            Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last);
+            Buffer_First := Buffer'Last + 1;
+         end if;
+      end Read_Buffer;
+
+      procedure Translate is new Generic_Translate
+                                   (Data_In  => Read_Buffer,
+                                    Data_Out => Further);
+
+   begin
+      Random_Elements.Reset (Gen);
+
+      Buffer := (others => 20);
+
+      Main : loop
+         for J in Buffer'Range loop
+            Buffer (J) := Random_Elements.Random (Gen);
+
+            Deflate_Init (Deflate);
+            Inflate_Init (Inflate);
+
+            Buffer_First  := Buffer'First;
+            Compare_First := Buffer'First;
+
+            Translate (Deflate);
+
+            if Compare_First /= Buffer'Last + 1 then
+               raise Program_Error;
+            end if;
+
+            Ada.Text_IO.Put_Line
+              (Ada.Task_Identification.Image
+                 (Ada.Task_Identification.Current_Task)
+               & Stream_Element_Offset'Image (J)
+               & ZLib.Count'Image (Total_Out (Deflate)));
+
+            Close (Deflate);
+            Close (Inflate);
+
+            exit Main when Stop;
+         end loop;
+      end loop Main;
+   exception
+      when E : others =>
+         Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));
+         Stop := True;
+   end Test_Task;
+
+   Test : array (1 .. 4) of Test_Task;
+
+   pragma Unreferenced (Test);
+
+   Dummy : Character;
+
+begin
+   Ada.Text_IO.Get_Immediate (Dummy);
+   Stop := True;
+end MTest;
diff --git a/8.x/zlib/contrib/ada/read.adb b/8.x/zlib/contrib/ada/read.adb
new file mode 100644 (file)
index 0000000..1f2efbf
--- /dev/null
@@ -0,0 +1,156 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $
+
+--  Test/demo program for the generic read interface.
+
+with Ada.Numerics.Discrete_Random;
+with Ada.Streams;
+with Ada.Text_IO;
+
+with ZLib;
+
+procedure Read is
+
+   use Ada.Streams;
+
+   ------------------------------------
+   --  Test configuration parameters --
+   ------------------------------------
+
+   File_Size   : Stream_Element_Offset := 100_000;
+
+   Continuous  : constant Boolean          := False;
+   --  If this constant is True, the test would be repeated again and again,
+   --  with increment File_Size for every iteration.
+
+   Header      : constant ZLib.Header_Type := ZLib.Default;
+   --  Do not use Header other than Default in ZLib versions 1.1.4 and older.
+
+   Init_Random : constant := 8;
+   --  We are using the same random sequence, in case of we catch bug,
+   --  so we would be able to reproduce it.
+
+   -- End --
+
+   Pack_Size : Stream_Element_Offset;
+   Offset    : Stream_Element_Offset;
+
+   Filter     : ZLib.Filter_Type;
+
+   subtype Visible_Symbols
+      is Stream_Element range 16#20# .. 16#7E#;
+
+   package Random_Elements is new
+      Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+   Gen : Random_Elements.Generator;
+   Period  : constant Stream_Element_Offset := 200;
+   --  Period constant variable for random generator not to be very random.
+   --  Bigger period, harder random.
+
+   Read_Buffer : Stream_Element_Array (1 .. 2048);
+   Read_First  : Stream_Element_Offset;
+   Read_Last   : Stream_Element_Offset;
+
+   procedure Reset;
+
+   procedure Read
+     (Item : out Stream_Element_Array;
+      Last : out Stream_Element_Offset);
+   --  this procedure is for generic instantiation of
+   --  ZLib.Read
+   --  reading data from the File_In.
+
+   procedure Read is new ZLib.Read
+                           (Read,
+                            Read_Buffer,
+                            Rest_First => Read_First,
+                            Rest_Last  => Read_Last);
+
+   ----------
+   -- Read --
+   ----------
+
+   procedure Read
+     (Item : out Stream_Element_Array;
+      Last : out Stream_Element_Offset) is
+   begin
+      Last := Stream_Element_Offset'Min
+               (Item'Last,
+                Item'First + File_Size - Offset);
+
+      for J in Item'First .. Last loop
+         if J < Item'First + Period then
+            Item (J) := Random_Elements.Random (Gen);
+         else
+            Item (J) := Item (J - Period);
+         end if;
+
+         Offset   := Offset + 1;
+      end loop;
+   end Read;
+
+   -----------
+   -- Reset --
+   -----------
+
+   procedure Reset is
+   begin
+      Random_Elements.Reset (Gen, Init_Random);
+      Pack_Size := 0;
+      Offset := 1;
+      Read_First := Read_Buffer'Last + 1;
+      Read_Last  := Read_Buffer'Last;
+   end Reset;
+
+begin
+   Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
+
+   loop
+      for Level in ZLib.Compression_Level'Range loop
+
+         Ada.Text_IO.Put ("Level ="
+            & ZLib.Compression_Level'Image (Level));
+
+         --  Deflate using generic instantiation.
+
+         ZLib.Deflate_Init
+               (Filter,
+                Level,
+                Header => Header);
+
+         Reset;
+
+         Ada.Text_IO.Put
+           (Stream_Element_Offset'Image (File_Size) & " ->");
+
+         loop
+            declare
+               Buffer : Stream_Element_Array (1 .. 1024);
+               Last   : Stream_Element_Offset;
+            begin
+               Read (Filter, Buffer, Last);
+
+               Pack_Size := Pack_Size + Last - Buffer'First + 1;
+
+               exit when Last < Buffer'Last;
+            end;
+         end loop;
+
+         Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size));
+
+         ZLib.Close (Filter);
+      end loop;
+
+      exit when not Continuous;
+
+      File_Size := File_Size + 1;
+   end loop;
+end Read;
diff --git a/8.x/zlib/contrib/ada/readme.txt b/8.x/zlib/contrib/ada/readme.txt
new file mode 100644 (file)
index 0000000..ce4d2ca
--- /dev/null
@@ -0,0 +1,65 @@
+                        ZLib for Ada thick binding (ZLib.Ada)
+                        Release 1.3
+
+ZLib.Ada is a thick binding interface to the popular ZLib data
+compression library, available at http://www.gzip.org/zlib/.
+It provides Ada-style access to the ZLib C library.
+
+
+        Here are the main changes since ZLib.Ada 1.2:
+
+- Attension: ZLib.Read generic routine have a initialization requirement
+  for Read_Last parameter now. It is a bit incompartible with previous version,
+  but extends functionality, we could use new parameters Allow_Read_Some and
+  Flush now.
+
+- Added Is_Open routines to ZLib and ZLib.Streams packages.
+
+- Add pragma Assert to check Stream_Element is 8 bit.
+
+- Fix extraction to buffer with exact known decompressed size. Error reported by
+  Steve Sangwine.
+
+- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits
+  computers. Patch provided by Pascal Obry.
+
+- Add Status_Error exception definition.
+
+- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.
+
+
+        How to build ZLib.Ada under GNAT
+
+You should have the ZLib library already build on your computer, before
+building ZLib.Ada. Make the directory of ZLib.Ada sources current and
+issue the command:
+
+  gnatmake test -largs -L<directory where libz.a is> -lz
+
+Or use the GNAT project file build for GNAT 3.15 or later:
+
+  gnatmake -Pzlib.gpr -L<directory where libz.a is>
+
+
+        How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2
+
+1. Make a project with all *.ads and *.adb files from the distribution.
+2. Build the libz.a library from the ZLib C sources.
+3. Rename libz.a to z.lib.
+4. Add the library z.lib to the project.
+5. Add the libc.lib library from the ObjectAda distribution to the project.
+6. Build the executable using test.adb as a main procedure.
+
+
+        How to use ZLib.Ada
+
+The source files test.adb and read.adb are small demo programs that show
+the main functionality of ZLib.Ada.
+
+The routines from the package specifications are commented.
+
+
+Homepage: http://zlib-ada.sourceforge.net/
+Author: Dmitriy Anisimkov <anisimkov@yahoo.com>
+
+Contributors: Pascal Obry <pascal@obry.org>, Steve Sangwine <sjs@essex.ac.uk>
diff --git a/8.x/zlib/contrib/ada/test.adb b/8.x/zlib/contrib/ada/test.adb
new file mode 100644 (file)
index 0000000..90773ac
--- /dev/null
@@ -0,0 +1,463 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $
+
+--  The program has a few aims.
+--  1. Test ZLib.Ada95 thick binding functionality.
+--  2. Show the example of use main functionality of the ZLib.Ada95 binding.
+--  3. Build this program automatically compile all ZLib.Ada95 packages under
+--     GNAT Ada95 compiler.
+
+with ZLib.Streams;
+with Ada.Streams.Stream_IO;
+with Ada.Numerics.Discrete_Random;
+
+with Ada.Text_IO;
+
+with Ada.Calendar;
+
+procedure Test is
+
+   use Ada.Streams;
+   use Stream_IO;
+
+   ------------------------------------
+   --  Test configuration parameters --
+   ------------------------------------
+
+   File_Size   : Count   := 100_000;
+   Continuous  : constant Boolean := False;
+
+   Header      : constant ZLib.Header_Type := ZLib.Default;
+                                              --  ZLib.None;
+                                              --  ZLib.Auto;
+                                              --  ZLib.GZip;
+   --  Do not use Header other then Default in ZLib versions 1.1.4
+   --  and older.
+
+   Strategy    : constant ZLib.Strategy_Type := ZLib.Default_Strategy;
+   Init_Random : constant := 10;
+
+   -- End --
+
+   In_File_Name  : constant String := "testzlib.in";
+   --  Name of the input file
+
+   Z_File_Name   : constant String := "testzlib.zlb";
+   --  Name of the compressed file.
+
+   Out_File_Name : constant String := "testzlib.out";
+   --  Name of the decompressed file.
+
+   File_In   : File_Type;
+   File_Out  : File_Type;
+   File_Back : File_Type;
+   File_Z    : ZLib.Streams.Stream_Type;
+
+   Filter : ZLib.Filter_Type;
+
+   Time_Stamp : Ada.Calendar.Time;
+
+   procedure Generate_File;
+   --  Generate file of spetsified size with some random data.
+   --  The random data is repeatable, for the good compression.
+
+   procedure Compare_Streams
+     (Left, Right : in out Root_Stream_Type'Class);
+   --  The procedure compearing data in 2 streams.
+   --  It is for compare data before and after compression/decompression.
+
+   procedure Compare_Files (Left, Right : String);
+   --  Compare files. Based on the Compare_Streams.
+
+   procedure Copy_Streams
+     (Source, Target : in out Root_Stream_Type'Class;
+      Buffer_Size    : in     Stream_Element_Offset := 1024);
+   --  Copying data from one stream to another. It is for test stream
+   --  interface of the library.
+
+   procedure Data_In
+     (Item : out Stream_Element_Array;
+      Last : out Stream_Element_Offset);
+   --  this procedure is for generic instantiation of
+   --  ZLib.Generic_Translate.
+   --  reading data from the File_In.
+
+   procedure Data_Out (Item : in Stream_Element_Array);
+   --  this procedure is for generic instantiation of
+   --  ZLib.Generic_Translate.
+   --  writing data to the File_Out.
+
+   procedure Stamp;
+   --  Store the timestamp to the local variable.
+
+   procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count);
+   --  Print the time statistic with the message.
+
+   procedure Translate is new ZLib.Generic_Translate
+                                (Data_In  => Data_In,
+                                 Data_Out => Data_Out);
+   --  This procedure is moving data from File_In to File_Out
+   --  with compression or decompression, depend on initialization of
+   --  Filter parameter.
+
+   -------------------
+   -- Compare_Files --
+   -------------------
+
+   procedure Compare_Files (Left, Right : String) is
+      Left_File, Right_File : File_Type;
+   begin
+      Open (Left_File, In_File, Left);
+      Open (Right_File, In_File, Right);
+      Compare_Streams (Stream (Left_File).all, Stream (Right_File).all);
+      Close (Left_File);
+      Close (Right_File);
+   end Compare_Files;
+
+   ---------------------
+   -- Compare_Streams --
+   ---------------------
+
+   procedure Compare_Streams
+     (Left, Right : in out Ada.Streams.Root_Stream_Type'Class)
+   is
+      Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#);
+      Left_Last, Right_Last : Stream_Element_Offset;
+   begin
+      loop
+         Read (Left, Left_Buffer, Left_Last);
+         Read (Right, Right_Buffer, Right_Last);
+
+         if Left_Last /= Right_Last then
+            Ada.Text_IO.Put_Line ("Compare error :"
+              & Stream_Element_Offset'Image (Left_Last)
+              & " /= "
+              & Stream_Element_Offset'Image (Right_Last));
+
+            raise Constraint_Error;
+
+         elsif Left_Buffer (0 .. Left_Last)
+               /= Right_Buffer (0 .. Right_Last)
+         then
+            Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal.");
+            raise Constraint_Error;
+
+         end if;
+
+         exit when Left_Last < Left_Buffer'Last;
+      end loop;
+   end Compare_Streams;
+
+   ------------------
+   -- Copy_Streams --
+   ------------------
+
+   procedure Copy_Streams
+     (Source, Target : in out Ada.Streams.Root_Stream_Type'Class;
+      Buffer_Size    : in     Stream_Element_Offset := 1024)
+   is
+      Buffer : Stream_Element_Array (1 .. Buffer_Size);
+      Last   : Stream_Element_Offset;
+   begin
+      loop
+         Read  (Source, Buffer, Last);
+         Write (Target, Buffer (1 .. Last));
+
+         exit when Last < Buffer'Last;
+      end loop;
+   end Copy_Streams;
+
+   -------------
+   -- Data_In --
+   -------------
+
+   procedure Data_In
+     (Item : out Stream_Element_Array;
+      Last : out Stream_Element_Offset) is
+   begin
+      Read (File_In, Item, Last);
+   end Data_In;
+
+   --------------
+   -- Data_Out --
+   --------------
+
+   procedure Data_Out (Item : in Stream_Element_Array) is
+   begin
+      Write (File_Out, Item);
+   end Data_Out;
+
+   -------------------
+   -- Generate_File --
+   -------------------
+
+   procedure Generate_File is
+      subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
+
+      package Random_Elements is
+         new Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+      Gen    : Random_Elements.Generator;
+      Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;
+
+      Buffer_Count : constant Count := File_Size / Buffer'Length;
+      --  Number of same buffers in the packet.
+
+      Density : constant Count := 30; --  from 0 to Buffer'Length - 2;
+
+      procedure Fill_Buffer (J, D : in Count);
+      --  Change the part of the buffer.
+
+      -----------------
+      -- Fill_Buffer --
+      -----------------
+
+      procedure Fill_Buffer (J, D : in Count) is
+      begin
+         for K in 0 .. D loop
+            Buffer
+              (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1))
+             := Random_Elements.Random (Gen);
+
+         end loop;
+      end Fill_Buffer;
+
+   begin
+      Random_Elements.Reset (Gen, Init_Random);
+
+      Create (File_In, Out_File, In_File_Name);
+
+      Fill_Buffer (1, Buffer'Length - 2);
+
+      for J in 1 .. Buffer_Count loop
+         Write (File_In, Buffer);
+
+         Fill_Buffer (J, Density);
+      end loop;
+
+      --  fill remain size.
+
+      Write
+        (File_In,
+         Buffer
+           (1 .. Stream_Element_Offset
+                   (File_Size - Buffer'Length * Buffer_Count)));
+
+      Flush (File_In);
+      Close (File_In);
+   end Generate_File;
+
+   ---------------------
+   -- Print_Statistic --
+   ---------------------
+
+   procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is
+      use Ada.Calendar;
+      use Ada.Text_IO;
+
+      package Count_IO is new Integer_IO (ZLib.Count);
+
+      Curr_Dur : Duration := Clock - Time_Stamp;
+   begin
+      Put (Msg);
+
+      Set_Col (20);
+      Ada.Text_IO.Put ("size =");
+
+      Count_IO.Put
+        (Data_Size,
+         Width => Stream_IO.Count'Image (File_Size)'Length);
+
+      Put_Line (" duration =" & Duration'Image (Curr_Dur));
+   end Print_Statistic;
+
+   -----------
+   -- Stamp --
+   -----------
+
+   procedure Stamp is
+   begin
+      Time_Stamp := Ada.Calendar.Clock;
+   end Stamp;
+
+begin
+   Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
+
+   loop
+      Generate_File;
+
+      for Level in ZLib.Compression_Level'Range loop
+
+         Ada.Text_IO.Put_Line ("Level ="
+            & ZLib.Compression_Level'Image (Level));
+
+         --  Test generic interface.
+         Open   (File_In, In_File, In_File_Name);
+         Create (File_Out, Out_File, Z_File_Name);
+
+         Stamp;
+
+         --  Deflate using generic instantiation.
+
+         ZLib.Deflate_Init
+               (Filter   => Filter,
+                Level    => Level,
+                Strategy => Strategy,
+                Header   => Header);
+
+         Translate (Filter);
+         Print_Statistic ("Generic compress", ZLib.Total_Out (Filter));
+         ZLib.Close (Filter);
+
+         Close (File_In);
+         Close (File_Out);
+
+         Open   (File_In, In_File, Z_File_Name);
+         Create (File_Out, Out_File, Out_File_Name);
+
+         Stamp;
+
+         --  Inflate using generic instantiation.
+
+         ZLib.Inflate_Init (Filter, Header => Header);
+
+         Translate (Filter);
+         Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter));
+
+         ZLib.Close (Filter);
+
+         Close (File_In);
+         Close (File_Out);
+
+         Compare_Files (In_File_Name, Out_File_Name);
+
+         --  Test stream interface.
+
+         --  Compress to the back stream.
+
+         Open   (File_In, In_File, In_File_Name);
+         Create (File_Back, Out_File, Z_File_Name);
+
+         Stamp;
+
+         ZLib.Streams.Create
+           (Stream          => File_Z,
+            Mode            => ZLib.Streams.Out_Stream,
+            Back            => ZLib.Streams.Stream_Access
+                                 (Stream (File_Back)),
+            Back_Compressed => True,
+            Level           => Level,
+            Strategy        => Strategy,
+            Header          => Header);
+
+         Copy_Streams
+           (Source => Stream (File_In).all,
+            Target => File_Z);
+
+         --  Flushing internal buffers to the back stream.
+
+         ZLib.Streams.Flush (File_Z, ZLib.Finish);
+
+         Print_Statistic ("Write compress",
+                          ZLib.Streams.Write_Total_Out (File_Z));
+
+         ZLib.Streams.Close (File_Z);
+
+         Close (File_In);
+         Close (File_Back);
+
+         --  Compare reading from original file and from
+         --  decompression stream.
+
+         Open (File_In,   In_File, In_File_Name);
+         Open (File_Back, In_File, Z_File_Name);
+
+         ZLib.Streams.Create
+           (Stream          => File_Z,
+            Mode            => ZLib.Streams.In_Stream,
+            Back            => ZLib.Streams.Stream_Access
+                                 (Stream (File_Back)),
+            Back_Compressed => True,
+            Header          => Header);
+
+         Stamp;
+         Compare_Streams (Stream (File_In).all, File_Z);
+
+         Print_Statistic ("Read decompress",
+                          ZLib.Streams.Read_Total_Out (File_Z));
+
+         ZLib.Streams.Close (File_Z);
+         Close (File_In);
+         Close (File_Back);
+
+         --  Compress by reading from compression stream.
+
+         Open (File_Back, In_File, In_File_Name);
+         Create (File_Out, Out_File, Z_File_Name);
+
+         ZLib.Streams.Create
+           (Stream          => File_Z,
+            Mode            => ZLib.Streams.In_Stream,
+            Back            => ZLib.Streams.Stream_Access
+                                 (Stream (File_Back)),
+            Back_Compressed => False,
+            Level           => Level,
+            Strategy        => Strategy,
+            Header          => Header);
+
+         Stamp;
+         Copy_Streams
+           (Source => File_Z,
+            Target => Stream (File_Out).all);
+
+         Print_Statistic ("Read compress",
+                          ZLib.Streams.Read_Total_Out (File_Z));
+
+         ZLib.Streams.Close (File_Z);
+
+         Close (File_Out);
+         Close (File_Back);
+
+         --  Decompress to decompression stream.
+
+         Open   (File_In,   In_File, Z_File_Name);
+         Create (File_Back, Out_File, Out_File_Name);
+
+         ZLib.Streams.Create
+           (Stream          => File_Z,
+            Mode            => ZLib.Streams.Out_Stream,
+            Back            => ZLib.Streams.Stream_Access
+                                 (Stream (File_Back)),
+            Back_Compressed => False,
+            Header          => Header);
+
+         Stamp;
+
+         Copy_Streams
+           (Source => Stream (File_In).all,
+            Target => File_Z);
+
+         Print_Statistic ("Write decompress",
+                          ZLib.Streams.Write_Total_Out (File_Z));
+
+         ZLib.Streams.Close (File_Z);
+         Close (File_In);
+         Close (File_Back);
+
+         Compare_Files (In_File_Name, Out_File_Name);
+      end loop;
+
+      Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok.");
+
+      exit when not Continuous;
+
+      File_Size := File_Size + 1;
+   end loop;
+end Test;
diff --git a/8.x/zlib/contrib/ada/zlib-streams.adb b/8.x/zlib/contrib/ada/zlib-streams.adb
new file mode 100644 (file)
index 0000000..b6497ba
--- /dev/null
@@ -0,0 +1,225 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $
+
+with Ada.Unchecked_Deallocation;
+
+package body ZLib.Streams is
+
+   -----------
+   -- Close --
+   -----------
+
+   procedure Close (Stream : in out Stream_Type) is
+      procedure Free is new Ada.Unchecked_Deallocation
+         (Stream_Element_Array, Buffer_Access);
+   begin
+      if Stream.Mode = Out_Stream or Stream.Mode = Duplex then
+         --  We should flush the data written by the writer.
+
+         Flush (Stream, Finish);
+
+         Close (Stream.Writer);
+      end if;
+
+      if Stream.Mode = In_Stream or Stream.Mode = Duplex then
+         Close (Stream.Reader);
+         Free (Stream.Buffer);
+      end if;
+   end Close;
+
+   ------------
+   -- Create --
+   ------------
+
+   procedure Create
+     (Stream            :    out Stream_Type;
+      Mode              : in     Stream_Mode;
+      Back              : in     Stream_Access;
+      Back_Compressed   : in     Boolean;
+      Level             : in     Compression_Level := Default_Compression;
+      Strategy          : in     Strategy_Type     := Default_Strategy;
+      Header            : in     Header_Type       := Default;
+      Read_Buffer_Size  : in     Ada.Streams.Stream_Element_Offset
+                                    := Default_Buffer_Size;
+      Write_Buffer_Size : in     Ada.Streams.Stream_Element_Offset
+                                    := Default_Buffer_Size)
+   is
+
+      subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size);
+
+      procedure Init_Filter
+         (Filter   : in out Filter_Type;
+          Compress : in     Boolean);
+
+      -----------------
+      -- Init_Filter --
+      -----------------
+
+      procedure Init_Filter
+         (Filter   : in out Filter_Type;
+          Compress : in     Boolean) is
+      begin
+         if Compress then
+            Deflate_Init
+              (Filter, Level, Strategy, Header => Header);
+         else
+            Inflate_Init (Filter, Header => Header);
+         end if;
+      end Init_Filter;
+
+   begin
+      Stream.Back := Back;
+      Stream.Mode := Mode;
+
+      if Mode = Out_Stream or Mode = Duplex then
+         Init_Filter (Stream.Writer, Back_Compressed);
+         Stream.Buffer_Size := Write_Buffer_Size;
+      else
+         Stream.Buffer_Size := 0;
+      end if;
+
+      if Mode = In_Stream or Mode = Duplex then
+         Init_Filter (Stream.Reader, not Back_Compressed);
+
+         Stream.Buffer     := new Buffer_Subtype;
+         Stream.Rest_First := Stream.Buffer'Last + 1;
+         Stream.Rest_Last  := Stream.Buffer'Last;
+      end if;
+   end Create;
+
+   -----------
+   -- Flush --
+   -----------
+
+   procedure Flush
+     (Stream : in out Stream_Type;
+      Mode   : in     Flush_Mode := Sync_Flush)
+   is
+      Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size);
+      Last   : Stream_Element_Offset;
+   begin
+      loop
+         Flush (Stream.Writer, Buffer, Last, Mode);
+
+         Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));
+
+         exit when Last < Buffer'Last;
+      end loop;
+   end Flush;
+
+   -------------
+   -- Is_Open --
+   -------------
+
+   function Is_Open (Stream : Stream_Type) return Boolean is
+   begin
+      return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);
+   end Is_Open;
+
+   ----------
+   -- Read --
+   ----------
+
+   procedure Read
+     (Stream : in out Stream_Type;
+      Item   :    out Stream_Element_Array;
+      Last   :    out Stream_Element_Offset)
+   is
+
+      procedure Read
+        (Item : out Stream_Element_Array;
+         Last : out Stream_Element_Offset);
+
+      ----------
+      -- Read --
+      ----------
+
+      procedure Read
+        (Item : out Stream_Element_Array;
+         Last : out Stream_Element_Offset) is
+      begin
+         Ada.Streams.Read (Stream.Back.all, Item, Last);
+      end Read;
+
+      procedure Read is new ZLib.Read
+         (Read       => Read,
+          Buffer     => Stream.Buffer.all,
+          Rest_First => Stream.Rest_First,
+          Rest_Last  => Stream.Rest_Last);
+
+   begin
+      Read (Stream.Reader, Item, Last);
+   end Read;
+
+   -------------------
+   -- Read_Total_In --
+   -------------------
+
+   function Read_Total_In (Stream : in Stream_Type) return Count is
+   begin
+      return Total_In (Stream.Reader);
+   end Read_Total_In;
+
+   --------------------
+   -- Read_Total_Out --
+   --------------------
+
+   function Read_Total_Out (Stream : in Stream_Type) return Count is
+   begin
+      return Total_Out (Stream.Reader);
+   end Read_Total_Out;
+
+   -----------
+   -- Write --
+   -----------
+
+   procedure Write
+     (Stream : in out Stream_Type;
+      Item   : in     Stream_Element_Array)
+   is
+
+      procedure Write (Item : in Stream_Element_Array);
+
+      -----------
+      -- Write --
+      -----------
+
+      procedure Write (Item : in Stream_Element_Array) is
+      begin
+         Ada.Streams.Write (Stream.Back.all, Item);
+      end Write;
+
+      procedure Write is new ZLib.Write
+         (Write       => Write,
+          Buffer_Size => Stream.Buffer_Size);
+
+   begin
+      Write (Stream.Writer, Item, No_Flush);
+   end Write;
+
+   --------------------
+   -- Write_Total_In --
+   --------------------
+
+   function Write_Total_In (Stream : in Stream_Type) return Count is
+   begin
+      return Total_In (Stream.Writer);
+   end Write_Total_In;
+
+   ---------------------
+   -- Write_Total_Out --
+   ---------------------
+
+   function Write_Total_Out (Stream : in Stream_Type) return Count is
+   begin
+      return Total_Out (Stream.Writer);
+   end Write_Total_Out;
+
+end ZLib.Streams;
diff --git a/8.x/zlib/contrib/ada/zlib-streams.ads b/8.x/zlib/contrib/ada/zlib-streams.ads
new file mode 100644 (file)
index 0000000..f0193c6
--- /dev/null
@@ -0,0 +1,114 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $
+
+package ZLib.Streams is
+
+   type Stream_Mode is (In_Stream, Out_Stream, Duplex);
+
+   type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
+
+   type Stream_Type is
+      new Ada.Streams.Root_Stream_Type with private;
+
+   procedure Read
+     (Stream : in out Stream_Type;
+      Item   :    out Ada.Streams.Stream_Element_Array;
+      Last   :    out Ada.Streams.Stream_Element_Offset);
+
+   procedure Write
+     (Stream : in out Stream_Type;
+      Item   : in     Ada.Streams.Stream_Element_Array);
+
+   procedure Flush
+     (Stream : in out Stream_Type;
+      Mode   : in     Flush_Mode := Sync_Flush);
+   --  Flush the written data to the back stream,
+   --  all data placed to the compressor is flushing to the Back stream.
+   --  Should not be used untill necessary, becouse it is decreasing
+   --  compression.
+
+   function Read_Total_In (Stream : in Stream_Type) return Count;
+   pragma Inline (Read_Total_In);
+   --  Return total number of bytes read from back stream so far.
+
+   function Read_Total_Out (Stream : in Stream_Type) return Count;
+   pragma Inline (Read_Total_Out);
+   --  Return total number of bytes read so far.
+
+   function Write_Total_In (Stream : in Stream_Type) return Count;
+   pragma Inline (Write_Total_In);
+   --  Return total number of bytes written so far.
+
+   function Write_Total_Out (Stream : in Stream_Type) return Count;
+   pragma Inline (Write_Total_Out);
+   --  Return total number of bytes written to the back stream.
+
+   procedure Create
+     (Stream            :    out Stream_Type;
+      Mode              : in     Stream_Mode;
+      Back              : in     Stream_Access;
+      Back_Compressed   : in     Boolean;
+      Level             : in     Compression_Level := Default_Compression;
+      Strategy          : in     Strategy_Type     := Default_Strategy;
+      Header            : in     Header_Type       := Default;
+      Read_Buffer_Size  : in     Ada.Streams.Stream_Element_Offset
+                                    := Default_Buffer_Size;
+      Write_Buffer_Size : in     Ada.Streams.Stream_Element_Offset
+                                    := Default_Buffer_Size);
+   --  Create the Comression/Decompression stream.
+   --  If mode is In_Stream then Write operation is disabled.
+   --  If mode is Out_Stream then Read operation is disabled.
+
+   --  If Back_Compressed is true then
+   --  Data written to the Stream is compressing to the Back stream
+   --  and data read from the Stream is decompressed data from the Back stream.
+
+   --  If Back_Compressed is false then
+   --  Data written to the Stream is decompressing to the Back stream
+   --  and data read from the Stream is compressed data from the Back stream.
+
+   --  !!! When the Need_Header is False ZLib-Ada is using undocumented
+   --  ZLib 1.1.4 functionality to do not create/wait for ZLib headers.
+
+   function Is_Open (Stream : Stream_Type) return Boolean;
+
+   procedure Close (Stream : in out Stream_Type);
+
+private
+
+   use Ada.Streams;
+
+   type Buffer_Access is access all Stream_Element_Array;
+
+   type Stream_Type
+     is new Root_Stream_Type with
+   record
+      Mode       : Stream_Mode;
+
+      Buffer     : Buffer_Access;
+      Rest_First : Stream_Element_Offset;
+      Rest_Last  : Stream_Element_Offset;
+      --  Buffer for Read operation.
+      --  We need to have this buffer in the record
+      --  becouse not all read data from back stream
+      --  could be processed during the read operation.
+
+      Buffer_Size : Stream_Element_Offset;
+      --  Buffer size for write operation.
+      --  We do not need to have this buffer
+      --  in the record becouse all data could be
+      --  processed in the write operation.
+
+      Back       : Stream_Access;
+      Reader     : Filter_Type;
+      Writer     : Filter_Type;
+   end record;
+
+end ZLib.Streams;
diff --git a/8.x/zlib/contrib/ada/zlib-thin.adb b/8.x/zlib/contrib/ada/zlib-thin.adb
new file mode 100644 (file)
index 0000000..0ca4a71
--- /dev/null
@@ -0,0 +1,141 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $
+
+package body ZLib.Thin is
+
+   ZLIB_VERSION  : constant Chars_Ptr := zlibVersion;
+
+   Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;
+
+   --------------
+   -- Avail_In --
+   --------------
+
+   function Avail_In (Strm : in Z_Stream) return UInt is
+   begin
+      return Strm.Avail_In;
+   end Avail_In;
+
+   ---------------
+   -- Avail_Out --
+   ---------------
+
+   function Avail_Out (Strm : in Z_Stream) return UInt is
+   begin
+      return Strm.Avail_Out;
+   end Avail_Out;
+
+   ------------------
+   -- Deflate_Init --
+   ------------------
+
+   function Deflate_Init
+     (strm       : Z_Streamp;
+      level      : Int;
+      method     : Int;
+      windowBits : Int;
+      memLevel   : Int;
+      strategy   : Int)
+      return       Int is
+   begin
+      return deflateInit2
+               (strm,
+                level,
+                method,
+                windowBits,
+                memLevel,
+                strategy,
+                ZLIB_VERSION,
+                Z_Stream_Size);
+   end Deflate_Init;
+
+   ------------------
+   -- Inflate_Init --
+   ------------------
+
+   function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is
+   begin
+      return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);
+   end Inflate_Init;
+
+   ------------------------
+   -- Last_Error_Message --
+   ------------------------
+
+   function Last_Error_Message (Strm : in Z_Stream) return String is
+      use Interfaces.C.Strings;
+   begin
+      if Strm.msg = Null_Ptr then
+         return "";
+      else
+         return Value (Strm.msg);
+      end if;
+   end Last_Error_Message;
+
+   ------------
+   -- Set_In --
+   ------------
+
+   procedure Set_In
+     (Strm   : in out Z_Stream;
+      Buffer : in     Voidp;
+      Size   : in     UInt) is
+   begin
+      Strm.Next_In  := Buffer;
+      Strm.Avail_In := Size;
+   end Set_In;
+
+   ------------------
+   -- Set_Mem_Func --
+   ------------------
+
+   procedure Set_Mem_Func
+     (Strm   : in out Z_Stream;
+      Opaque : in     Voidp;
+      Alloc  : in     alloc_func;
+      Free   : in     free_func) is
+   begin
+      Strm.opaque := Opaque;
+      Strm.zalloc := Alloc;
+      Strm.zfree  := Free;
+   end Set_Mem_Func;
+
+   -------------
+   -- Set_Out --
+   -------------
+
+   procedure Set_Out
+     (Strm   : in out Z_Stream;
+      Buffer : in     Voidp;
+      Size   : in     UInt) is
+   begin
+      Strm.Next_Out  := Buffer;
+      Strm.Avail_Out := Size;
+   end Set_Out;
+
+   --------------
+   -- Total_In --
+   --------------
+
+   function Total_In (Strm : in Z_Stream) return ULong is
+   begin
+      return Strm.Total_In;
+   end Total_In;
+
+   ---------------
+   -- Total_Out --
+   ---------------
+
+   function Total_Out (Strm : in Z_Stream) return ULong is
+   begin
+      return Strm.Total_Out;
+   end Total_Out;
+
+end ZLib.Thin;
diff --git a/8.x/zlib/contrib/ada/zlib-thin.ads b/8.x/zlib/contrib/ada/zlib-thin.ads
new file mode 100644 (file)
index 0000000..d4407eb
--- /dev/null
@@ -0,0 +1,450 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $
+
+with Interfaces.C.Strings;
+
+with System;
+
+private package ZLib.Thin is
+
+   --  From zconf.h
+
+   MAX_MEM_LEVEL : constant := 9;         --  zconf.h:105
+                                          --  zconf.h:105
+   MAX_WBITS : constant := 15;      --  zconf.h:115
+                                    --  32K LZ77 window
+                                    --  zconf.h:115
+   SEEK_SET : constant := 8#0000#;  --  zconf.h:244
+                                    --  Seek from beginning of file.
+                                    --  zconf.h:244
+   SEEK_CUR : constant := 1;        --  zconf.h:245
+                                    --  Seek from current position.
+                                    --  zconf.h:245
+   SEEK_END : constant := 2;        --  zconf.h:246
+                                    --  Set file pointer to EOF plus "offset"
+                                    --  zconf.h:246
+
+   type Byte is new Interfaces.C.unsigned_char; --  8 bits
+                                                --  zconf.h:214
+   type UInt is new Interfaces.C.unsigned;      --  16 bits or more
+                                                --  zconf.h:216
+   type Int is new Interfaces.C.int;
+
+   type ULong is new Interfaces.C.unsigned_long;     --  32 bits or more
+                                                     --  zconf.h:217
+   subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;
+
+   type ULong_Access is access ULong;
+   type Int_Access is access Int;
+
+   subtype Voidp is System.Address;            --  zconf.h:232
+
+   subtype Byte_Access is Voidp;
+
+   Nul : constant Voidp := System.Null_Address;
+   --  end from zconf
+
+   Z_NO_FLUSH : constant := 8#0000#;   --  zlib.h:125
+                                       --  zlib.h:125
+   Z_PARTIAL_FLUSH : constant := 1;       --  zlib.h:126
+                                          --  will be removed, use
+                                          --  Z_SYNC_FLUSH instead
+                                          --  zlib.h:126
+   Z_SYNC_FLUSH : constant := 2;       --  zlib.h:127
+                                       --  zlib.h:127
+   Z_FULL_FLUSH : constant := 3;       --  zlib.h:128
+                                       --  zlib.h:128
+   Z_FINISH : constant := 4;        --  zlib.h:129
+                                    --  zlib.h:129
+   Z_OK : constant := 8#0000#;   --  zlib.h:132
+                                 --  zlib.h:132
+   Z_STREAM_END : constant := 1;       --  zlib.h:133
+                                       --  zlib.h:133
+   Z_NEED_DICT : constant := 2;        --  zlib.h:134
+                                       --  zlib.h:134
+   Z_ERRNO : constant := -1;        --  zlib.h:135
+                                    --  zlib.h:135
+   Z_STREAM_ERROR : constant := -2;       --  zlib.h:136
+                                          --  zlib.h:136
+   Z_DATA_ERROR : constant := -3;      --  zlib.h:137
+                                       --  zlib.h:137
+   Z_MEM_ERROR : constant := -4;       --  zlib.h:138
+                                       --  zlib.h:138
+   Z_BUF_ERROR : constant := -5;       --  zlib.h:139
+                                       --  zlib.h:139
+   Z_VERSION_ERROR : constant := -6;      --  zlib.h:140
+                                          --  zlib.h:140
+   Z_NO_COMPRESSION : constant := 8#0000#;   --  zlib.h:145
+                                             --  zlib.h:145
+   Z_BEST_SPEED : constant := 1;       --  zlib.h:146
+                                       --  zlib.h:146
+   Z_BEST_COMPRESSION : constant := 9;       --  zlib.h:147
+                                             --  zlib.h:147
+   Z_DEFAULT_COMPRESSION : constant := -1;      --  zlib.h:148
+                                                --  zlib.h:148
+   Z_FILTERED : constant := 1;      --  zlib.h:151
+                                    --  zlib.h:151
+   Z_HUFFMAN_ONLY : constant := 2;        --  zlib.h:152
+                                          --  zlib.h:152
+   Z_DEFAULT_STRATEGY : constant := 8#0000#; --  zlib.h:153
+                                             --  zlib.h:153
+   Z_BINARY : constant := 8#0000#;  --  zlib.h:156
+                                    --  zlib.h:156
+   Z_ASCII : constant := 1;      --  zlib.h:157
+                                 --  zlib.h:157
+   Z_UNKNOWN : constant := 2;       --  zlib.h:158
+                                    --  zlib.h:158
+   Z_DEFLATED : constant := 8;      --  zlib.h:161
+                                    --  zlib.h:161
+   Z_NULL : constant := 8#0000#; --  zlib.h:164
+                                 --  for initializing zalloc, zfree, opaque
+                                 --  zlib.h:164
+   type gzFile is new Voidp;                  --  zlib.h:646
+
+   type Z_Stream is private;
+
+   type Z_Streamp is access all Z_Stream;     --  zlib.h:89
+
+   type alloc_func is access function
+     (Opaque : Voidp;
+      Items  : UInt;
+      Size   : UInt)
+      return Voidp; --  zlib.h:63
+
+   type free_func is access procedure (opaque : Voidp; address : Voidp);
+
+   function zlibVersion return Chars_Ptr;
+
+   function Deflate (strm : Z_Streamp; flush : Int) return Int;
+
+   function DeflateEnd (strm : Z_Streamp) return Int;
+
+   function Inflate (strm : Z_Streamp; flush : Int) return Int;
+
+   function InflateEnd (strm : Z_Streamp) return Int;
+
+   function deflateSetDictionary
+     (strm       : Z_Streamp;
+      dictionary : Byte_Access;
+      dictLength : UInt)
+      return       Int;
+
+   function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int;
+   --  zlib.h:478
+
+   function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495
+
+   function deflateParams
+     (strm     : Z_Streamp;
+      level    : Int;
+      strategy : Int)
+      return     Int;       -- zlib.h:506
+
+   function inflateSetDictionary
+     (strm       : Z_Streamp;
+      dictionary : Byte_Access;
+      dictLength : UInt)
+      return       Int; --  zlib.h:548
+
+   function inflateSync (strm : Z_Streamp) return Int;  --  zlib.h:565
+
+   function inflateReset (strm : Z_Streamp) return Int; --  zlib.h:580
+
+   function compress
+     (dest      : Byte_Access;
+      destLen   : ULong_Access;
+      source    : Byte_Access;
+      sourceLen : ULong)
+      return      Int;           -- zlib.h:601
+
+   function compress2
+     (dest      : Byte_Access;
+      destLen   : ULong_Access;
+      source    : Byte_Access;
+      sourceLen : ULong;
+      level     : Int)
+      return      Int;          -- zlib.h:615
+
+   function uncompress
+     (dest      : Byte_Access;
+      destLen   : ULong_Access;
+      source    : Byte_Access;
+      sourceLen : ULong)
+      return      Int;
+
+   function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile;
+
+   function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile;
+
+   function gzsetparams
+     (file     : gzFile;
+      level    : Int;
+      strategy : Int)
+      return     Int;
+
+   function gzread
+     (file : gzFile;
+      buf  : Voidp;
+      len  : UInt)
+      return Int;
+
+   function gzwrite
+     (file : in gzFile;
+      buf  : in Voidp;
+      len  : in UInt)
+      return Int;
+
+   function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int;
+
+   function gzputs (file : in gzFile; s : in Chars_Ptr) return Int;
+
+   function gzgets
+     (file : gzFile;
+      buf  : Chars_Ptr;
+      len  : Int)
+      return Chars_Ptr;
+
+   function gzputc (file : gzFile; char : Int) return Int;
+
+   function gzgetc (file : gzFile) return Int;
+
+   function gzflush (file : gzFile; flush : Int) return Int;
+
+   function gzseek
+     (file   : gzFile;
+      offset : Int;
+      whence : Int)
+      return   Int;
+
+   function gzrewind (file : gzFile) return Int;
+
+   function gztell (file : gzFile) return Int;
+
+   function gzeof (file : gzFile) return Int;
+
+   function gzclose (file : gzFile) return Int;
+
+   function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr;
+
+   function adler32
+     (adler : ULong;
+      buf   : Byte_Access;
+      len   : UInt)
+      return  ULong;
+
+   function crc32
+     (crc  : ULong;
+      buf  : Byte_Access;
+      len  : UInt)
+      return ULong;
+
+   function deflateInit
+     (strm        : Z_Streamp;
+      level       : Int;
+      version     : Chars_Ptr;
+      stream_size : Int)
+      return        Int;
+
+   function deflateInit2
+     (strm        : Z_Streamp;
+      level       : Int;
+      method      : Int;
+      windowBits  : Int;
+      memLevel    : Int;
+      strategy    : Int;
+      version     : Chars_Ptr;
+      stream_size : Int)
+      return        Int;
+
+   function Deflate_Init
+     (strm       : Z_Streamp;
+      level      : Int;
+      method     : Int;
+      windowBits : Int;
+      memLevel   : Int;
+      strategy   : Int)
+      return       Int;
+   pragma Inline (Deflate_Init);
+
+   function inflateInit
+     (strm        : Z_Streamp;
+      version     : Chars_Ptr;
+      stream_size : Int)
+      return        Int;
+
+   function inflateInit2
+     (strm        : in Z_Streamp;
+      windowBits  : in Int;
+      version     : in Chars_Ptr;
+      stream_size : in Int)
+      return      Int;
+
+   function inflateBackInit
+     (strm        : in Z_Streamp;
+      windowBits  : in Int;
+      window      : in Byte_Access;
+      version     : in Chars_Ptr;
+      stream_size : in Int)
+      return      Int;
+   --  Size of window have to be 2**windowBits.
+
+   function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int;
+   pragma Inline (Inflate_Init);
+
+   function zError (err : Int) return Chars_Ptr;
+
+   function inflateSyncPoint (z : Z_Streamp) return Int;
+
+   function get_crc_table return ULong_Access;
+
+   --  Interface to the available fields of the z_stream structure.
+   --  The application must update next_in and avail_in when avail_in has
+   --  dropped to zero. It must update next_out and avail_out when avail_out
+   --  has dropped to zero. The application must initialize zalloc, zfree and
+   --  opaque before calling the init function.
+
+   procedure Set_In
+     (Strm   : in out Z_Stream;
+      Buffer : in Voidp;
+      Size   : in UInt);
+   pragma Inline (Set_In);
+
+   procedure Set_Out
+     (Strm   : in out Z_Stream;
+      Buffer : in Voidp;
+      Size   : in UInt);
+   pragma Inline (Set_Out);
+
+   procedure Set_Mem_Func
+     (Strm   : in out Z_Stream;
+      Opaque : in Voidp;
+      Alloc  : in alloc_func;
+      Free   : in free_func);
+   pragma Inline (Set_Mem_Func);
+
+   function Last_Error_Message (Strm : in Z_Stream) return String;
+   pragma Inline (Last_Error_Message);
+
+   function Avail_Out (Strm : in Z_Stream) return UInt;
+   pragma Inline (Avail_Out);
+
+   function Avail_In (Strm : in Z_Stream) return UInt;
+   pragma Inline (Avail_In);
+
+   function Total_In (Strm : in Z_Stream) return ULong;
+   pragma Inline (Total_In);
+
+   function Total_Out (Strm : in Z_Stream) return ULong;
+   pragma Inline (Total_Out);
+
+   function inflateCopy
+     (dest   : in Z_Streamp;
+      Source : in Z_Streamp)
+      return Int;
+
+   function compressBound (Source_Len : in ULong) return ULong;
+
+   function deflateBound
+     (Strm       : in Z_Streamp;
+      Source_Len : in ULong)
+      return     ULong;
+
+   function gzungetc (C : in Int; File : in  gzFile) return Int;
+
+   function zlibCompileFlags return ULong;
+
+private
+
+   type Z_Stream is record            -- zlib.h:68
+      Next_In   : Voidp      := Nul;  -- next input byte
+      Avail_In  : UInt       := 0;    -- number of bytes available at next_in
+      Total_In  : ULong      := 0;    -- total nb of input bytes read so far
+      Next_Out  : Voidp      := Nul;  -- next output byte should be put there
+      Avail_Out : UInt       := 0;    -- remaining free space at next_out
+      Total_Out : ULong      := 0;    -- total nb of bytes output so far
+      msg       : Chars_Ptr;          -- last error message, NULL if no error
+      state     : Voidp;              -- not visible by applications
+      zalloc    : alloc_func := null; -- used to allocate the internal state
+      zfree     : free_func  := null; -- used to free the internal state
+      opaque    : Voidp;              -- private data object passed to
+                                      --  zalloc and zfree
+      data_type : Int;                -- best guess about the data type:
+                                      --  ascii or binary
+      adler     : ULong;              -- adler32 value of the uncompressed
+                                      --  data
+      reserved  : ULong;              -- reserved for future use
+   end record;
+
+   pragma Convention (C, Z_Stream);
+
+   pragma Import (C, zlibVersion, "zlibVersion");
+   pragma Import (C, Deflate, "deflate");
+   pragma Import (C, DeflateEnd, "deflateEnd");
+   pragma Import (C, Inflate, "inflate");
+   pragma Import (C, InflateEnd, "inflateEnd");
+   pragma Import (C, deflateSetDictionary, "deflateSetDictionary");
+   pragma Import (C, deflateCopy, "deflateCopy");
+   pragma Import (C, deflateReset, "deflateReset");
+   pragma Import (C, deflateParams, "deflateParams");
+   pragma Import (C, inflateSetDictionary, "inflateSetDictionary");
+   pragma Import (C, inflateSync, "inflateSync");
+   pragma Import (C, inflateReset, "inflateReset");
+   pragma Import (C, compress, "compress");
+   pragma Import (C, compress2, "compress2");
+   pragma Import (C, uncompress, "uncompress");
+   pragma Import (C, gzopen, "gzopen");
+   pragma Import (C, gzdopen, "gzdopen");
+   pragma Import (C, gzsetparams, "gzsetparams");
+   pragma Import (C, gzread, "gzread");
+   pragma Import (C, gzwrite, "gzwrite");
+   pragma Import (C, gzprintf, "gzprintf");
+   pragma Import (C, gzputs, "gzputs");
+   pragma Import (C, gzgets, "gzgets");
+   pragma Import (C, gzputc, "gzputc");
+   pragma Import (C, gzgetc, "gzgetc");
+   pragma Import (C, gzflush, "gzflush");
+   pragma Import (C, gzseek, "gzseek");
+   pragma Import (C, gzrewind, "gzrewind");
+   pragma Import (C, gztell, "gztell");
+   pragma Import (C, gzeof, "gzeof");
+   pragma Import (C, gzclose, "gzclose");
+   pragma Import (C, gzerror, "gzerror");
+   pragma Import (C, adler32, "adler32");
+   pragma Import (C, crc32, "crc32");
+   pragma Import (C, deflateInit, "deflateInit_");
+   pragma Import (C, inflateInit, "inflateInit_");
+   pragma Import (C, deflateInit2, "deflateInit2_");
+   pragma Import (C, inflateInit2, "inflateInit2_");
+   pragma Import (C, zError, "zError");
+   pragma Import (C, inflateSyncPoint, "inflateSyncPoint");
+   pragma Import (C, get_crc_table, "get_crc_table");
+
+   --  since zlib 1.2.0:
+
+   pragma Import (C, inflateCopy, "inflateCopy");
+   pragma Import (C, compressBound, "compressBound");
+   pragma Import (C, deflateBound, "deflateBound");
+   pragma Import (C, gzungetc, "gzungetc");
+   pragma Import (C, zlibCompileFlags, "zlibCompileFlags");
+
+   pragma Import (C, inflateBackInit, "inflateBackInit_");
+
+   --  I stopped binding the inflateBack routines, becouse realize that
+   --  it does not support zlib and gzip headers for now, and have no
+   --  symmetric deflateBack routines.
+   --  ZLib-Ada is symmetric regarding deflate/inflate data transformation
+   --  and has a similar generic callback interface for the
+   --  deflate/inflate transformation based on the regular Deflate/Inflate
+   --  routines.
+
+   --  pragma Import (C, inflateBack, "inflateBack");
+   --  pragma Import (C, inflateBackEnd, "inflateBackEnd");
+
+end ZLib.Thin;
diff --git a/8.x/zlib/contrib/ada/zlib.adb b/8.x/zlib/contrib/ada/zlib.adb
new file mode 100644 (file)
index 0000000..8b6fd68
--- /dev/null
@@ -0,0 +1,701 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2004 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
+
+with Ada.Exceptions;
+with Ada.Unchecked_Conversion;
+with Ada.Unchecked_Deallocation;
+
+with Interfaces.C.Strings;
+
+with ZLib.Thin;
+
+package body ZLib is
+
+   use type Thin.Int;
+
+   type Z_Stream is new Thin.Z_Stream;
+
+   type Return_Code_Enum is
+      (OK,
+       STREAM_END,
+       NEED_DICT,
+       ERRNO,
+       STREAM_ERROR,
+       DATA_ERROR,
+       MEM_ERROR,
+       BUF_ERROR,
+       VERSION_ERROR);
+
+   type Flate_Step_Function is access
+     function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
+   pragma Convention (C, Flate_Step_Function);
+
+   type Flate_End_Function is access
+      function (Ctrm : in Thin.Z_Streamp) return Thin.Int;
+   pragma Convention (C, Flate_End_Function);
+
+   type Flate_Type is record
+      Step : Flate_Step_Function;
+      Done : Flate_End_Function;
+   end record;
+
+   subtype Footer_Array is Stream_Element_Array (1 .. 8);
+
+   Simple_GZip_Header : constant Stream_Element_Array (1 .. 10)
+     := (16#1f#, 16#8b#,                 --  Magic header
+         16#08#,                         --  Z_DEFLATED
+         16#00#,                         --  Flags
+         16#00#, 16#00#, 16#00#, 16#00#, --  Time
+         16#00#,                         --  XFlags
+         16#03#                          --  OS code
+        );
+   --  The simplest gzip header is not for informational, but just for
+   --  gzip format compatibility.
+   --  Note that some code below is using assumption
+   --  Simple_GZip_Header'Last > Footer_Array'Last, so do not make
+   --  Simple_GZip_Header'Last <= Footer_Array'Last.
+
+   Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum
+     := (0 => OK,
+         1 => STREAM_END,
+         2 => NEED_DICT,
+        -1 => ERRNO,
+        -2 => STREAM_ERROR,
+        -3 => DATA_ERROR,
+        -4 => MEM_ERROR,
+        -5 => BUF_ERROR,
+        -6 => VERSION_ERROR);
+
+   Flate : constant array (Boolean) of Flate_Type
+     := (True  => (Step => Thin.Deflate'Access,
+                   Done => Thin.DeflateEnd'Access),
+         False => (Step => Thin.Inflate'Access,
+                   Done => Thin.InflateEnd'Access));
+
+   Flush_Finish : constant array (Boolean) of Flush_Mode
+     := (True => Finish, False => No_Flush);
+
+   procedure Raise_Error (Stream : in Z_Stream);
+   pragma Inline (Raise_Error);
+
+   procedure Raise_Error (Message : in String);
+   pragma Inline (Raise_Error);
+
+   procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
+
+   procedure Free is new Ada.Unchecked_Deallocation
+      (Z_Stream, Z_Stream_Access);
+
+   function To_Thin_Access is new Ada.Unchecked_Conversion
+     (Z_Stream_Access, Thin.Z_Streamp);
+
+   procedure Translate_GZip
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode);
+   --  Separate translate routine for make gzip header.
+
+   procedure Translate_Auto
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode);
+   --  translate routine without additional headers.
+
+   -----------------
+   -- Check_Error --
+   -----------------
+
+   procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
+      use type Thin.Int;
+   begin
+      if Code /= Thin.Z_OK then
+         Raise_Error
+            (Return_Code_Enum'Image (Return_Code (Code))
+              & ": " & Last_Error_Message (Stream));
+      end if;
+   end Check_Error;
+
+   -----------
+   -- Close --
+   -----------
+
+   procedure Close
+     (Filter       : in out Filter_Type;
+      Ignore_Error : in     Boolean := False)
+   is
+      Code : Thin.Int;
+   begin
+      if not Ignore_Error and then not Is_Open (Filter) then
+         raise Status_Error;
+      end if;
+
+      Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
+
+      if Ignore_Error or else Code = Thin.Z_OK then
+         Free (Filter.Strm);
+      else
+         declare
+            Error_Message : constant String
+              := Last_Error_Message (Filter.Strm.all);
+         begin
+            Free (Filter.Strm);
+            Ada.Exceptions.Raise_Exception
+               (ZLib_Error'Identity,
+                Return_Code_Enum'Image (Return_Code (Code))
+                  & ": " & Error_Message);
+         end;
+      end if;
+   end Close;
+
+   -----------
+   -- CRC32 --
+   -----------
+
+   function CRC32
+     (CRC  : in Unsigned_32;
+      Data : in Ada.Streams.Stream_Element_Array)
+      return Unsigned_32
+   is
+      use Thin;
+   begin
+      return Unsigned_32 (crc32 (ULong (CRC),
+                                 Data'Address,
+                                 Data'Length));
+   end CRC32;
+
+   procedure CRC32
+     (CRC  : in out Unsigned_32;
+      Data : in     Ada.Streams.Stream_Element_Array) is
+   begin
+      CRC := CRC32 (CRC, Data);
+   end CRC32;
+
+   ------------------
+   -- Deflate_Init --
+   ------------------
+
+   procedure Deflate_Init
+     (Filter       : in out Filter_Type;
+      Level        : in     Compression_Level  := Default_Compression;
+      Strategy     : in     Strategy_Type      := Default_Strategy;
+      Method       : in     Compression_Method := Deflated;
+      Window_Bits  : in     Window_Bits_Type   := Default_Window_Bits;
+      Memory_Level : in     Memory_Level_Type  := Default_Memory_Level;
+      Header       : in     Header_Type        := Default)
+   is
+      use type Thin.Int;
+      Win_Bits : Thin.Int := Thin.Int (Window_Bits);
+   begin
+      if Is_Open (Filter) then
+         raise Status_Error;
+      end if;
+
+      --  We allow ZLib to make header only in case of default header type.
+      --  Otherwise we would either do header by ourselfs, or do not do
+      --  header at all.
+
+      if Header = None or else Header = GZip then
+         Win_Bits := -Win_Bits;
+      end if;
+
+      --  For the GZip CRC calculation and make headers.
+
+      if Header = GZip then
+         Filter.CRC    := 0;
+         Filter.Offset := Simple_GZip_Header'First;
+      else
+         Filter.Offset := Simple_GZip_Header'Last + 1;
+      end if;
+
+      Filter.Strm        := new Z_Stream;
+      Filter.Compression := True;
+      Filter.Stream_End  := False;
+      Filter.Header      := Header;
+
+      if Thin.Deflate_Init
+           (To_Thin_Access (Filter.Strm),
+            Level      => Thin.Int (Level),
+            method     => Thin.Int (Method),
+            windowBits => Win_Bits,
+            memLevel   => Thin.Int (Memory_Level),
+            strategy   => Thin.Int (Strategy)) /= Thin.Z_OK
+      then
+         Raise_Error (Filter.Strm.all);
+      end if;
+   end Deflate_Init;
+
+   -----------
+   -- Flush --
+   -----------
+
+   procedure Flush
+     (Filter    : in out Filter_Type;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode)
+   is
+      No_Data : Stream_Element_Array := (1 .. 0 => 0);
+      Last    : Stream_Element_Offset;
+   begin
+      Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush);
+   end Flush;
+
+   -----------------------
+   -- Generic_Translate --
+   -----------------------
+
+   procedure Generic_Translate
+     (Filter          : in out ZLib.Filter_Type;
+      In_Buffer_Size  : in     Integer := Default_Buffer_Size;
+      Out_Buffer_Size : in     Integer := Default_Buffer_Size)
+   is
+      In_Buffer  : Stream_Element_Array
+                     (1 .. Stream_Element_Offset (In_Buffer_Size));
+      Out_Buffer : Stream_Element_Array
+                     (1 .. Stream_Element_Offset (Out_Buffer_Size));
+      Last       : Stream_Element_Offset;
+      In_Last    : Stream_Element_Offset;
+      In_First   : Stream_Element_Offset;
+      Out_Last   : Stream_Element_Offset;
+   begin
+      Main : loop
+         Data_In (In_Buffer, Last);
+
+         In_First := In_Buffer'First;
+
+         loop
+            Translate
+              (Filter   => Filter,
+               In_Data  => In_Buffer (In_First .. Last),
+               In_Last  => In_Last,
+               Out_Data => Out_Buffer,
+               Out_Last => Out_Last,
+               Flush    => Flush_Finish (Last < In_Buffer'First));
+
+            if Out_Buffer'First <= Out_Last then
+               Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
+            end if;
+
+            exit Main when Stream_End (Filter);
+
+            --  The end of in buffer.
+
+            exit when In_Last = Last;
+
+            In_First := In_Last + 1;
+         end loop;
+      end loop Main;
+
+   end Generic_Translate;
+
+   ------------------
+   -- Inflate_Init --
+   ------------------
+
+   procedure Inflate_Init
+     (Filter      : in out Filter_Type;
+      Window_Bits : in     Window_Bits_Type := Default_Window_Bits;
+      Header      : in     Header_Type      := Default)
+   is
+      use type Thin.Int;
+      Win_Bits : Thin.Int := Thin.Int (Window_Bits);
+
+      procedure Check_Version;
+      --  Check the latest header types compatibility.
+
+      procedure Check_Version is
+      begin
+         if Version <= "1.1.4" then
+            Raise_Error
+              ("Inflate header type " & Header_Type'Image (Header)
+               & " incompatible with ZLib version " & Version);
+         end if;
+      end Check_Version;
+
+   begin
+      if Is_Open (Filter) then
+         raise Status_Error;
+      end if;
+
+      case Header is
+         when None =>
+            Check_Version;
+
+            --  Inflate data without headers determined
+            --  by negative Win_Bits.
+
+            Win_Bits := -Win_Bits;
+         when GZip =>
+            Check_Version;
+
+            --  Inflate gzip data defined by flag 16.
+
+            Win_Bits := Win_Bits + 16;
+         when Auto =>
+            Check_Version;
+
+            --  Inflate with automatic detection
+            --  of gzip or native header defined by flag 32.
+
+            Win_Bits := Win_Bits + 32;
+         when Default => null;
+      end case;
+
+      Filter.Strm        := new Z_Stream;
+      Filter.Compression := False;
+      Filter.Stream_End  := False;
+      Filter.Header      := Header;
+
+      if Thin.Inflate_Init
+         (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK
+      then
+         Raise_Error (Filter.Strm.all);
+      end if;
+   end Inflate_Init;
+
+   -------------
+   -- Is_Open --
+   -------------
+
+   function Is_Open (Filter : in Filter_Type) return Boolean is
+   begin
+      return Filter.Strm /= null;
+   end Is_Open;
+
+   -----------------
+   -- Raise_Error --
+   -----------------
+
+   procedure Raise_Error (Message : in String) is
+   begin
+      Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
+   end Raise_Error;
+
+   procedure Raise_Error (Stream : in Z_Stream) is
+   begin
+      Raise_Error (Last_Error_Message (Stream));
+   end Raise_Error;
+
+   ----------
+   -- Read --
+   ----------
+
+   procedure Read
+     (Filter : in out Filter_Type;
+      Item   :    out Ada.Streams.Stream_Element_Array;
+      Last   :    out Ada.Streams.Stream_Element_Offset;
+      Flush  : in     Flush_Mode := No_Flush)
+   is
+      In_Last    : Stream_Element_Offset;
+      Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
+      V_Flush    : Flush_Mode := Flush;
+
+   begin
+      pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
+      pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
+
+      loop
+         if Rest_Last = Buffer'First - 1 then
+            V_Flush := Finish;
+
+         elsif Rest_First > Rest_Last then
+            Read (Buffer, Rest_Last);
+            Rest_First := Buffer'First;
+
+            if Rest_Last < Buffer'First then
+               V_Flush := Finish;
+            end if;
+         end if;
+
+         Translate
+           (Filter   => Filter,
+            In_Data  => Buffer (Rest_First .. Rest_Last),
+            In_Last  => In_Last,
+            Out_Data => Item (Item_First .. Item'Last),
+            Out_Last => Last,
+            Flush    => V_Flush);
+
+         Rest_First := In_Last + 1;
+
+         exit when Stream_End (Filter)
+           or else Last = Item'Last
+           or else (Last >= Item'First and then Allow_Read_Some);
+
+         Item_First := Last + 1;
+      end loop;
+   end Read;
+
+   ----------------
+   -- Stream_End --
+   ----------------
+
+   function Stream_End (Filter : in Filter_Type) return Boolean is
+   begin
+      if Filter.Header = GZip and Filter.Compression then
+         return Filter.Stream_End
+            and then Filter.Offset = Footer_Array'Last + 1;
+      else
+         return Filter.Stream_End;
+      end if;
+   end Stream_End;
+
+   --------------
+   -- Total_In --
+   --------------
+
+   function Total_In (Filter : in Filter_Type) return Count is
+   begin
+      return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all));
+   end Total_In;
+
+   ---------------
+   -- Total_Out --
+   ---------------
+
+   function Total_Out (Filter : in Filter_Type) return Count is
+   begin
+      return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all));
+   end Total_Out;
+
+   ---------------
+   -- Translate --
+   ---------------
+
+   procedure Translate
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode) is
+   begin
+      if Filter.Header = GZip and then Filter.Compression then
+         Translate_GZip
+           (Filter   => Filter,
+            In_Data  => In_Data,
+            In_Last  => In_Last,
+            Out_Data => Out_Data,
+            Out_Last => Out_Last,
+            Flush    => Flush);
+      else
+         Translate_Auto
+           (Filter   => Filter,
+            In_Data  => In_Data,
+            In_Last  => In_Last,
+            Out_Data => Out_Data,
+            Out_Last => Out_Last,
+            Flush    => Flush);
+      end if;
+   end Translate;
+
+   --------------------
+   -- Translate_Auto --
+   --------------------
+
+   procedure Translate_Auto
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode)
+   is
+      use type Thin.Int;
+      Code : Thin.Int;
+
+   begin
+      if not Is_Open (Filter) then
+         raise Status_Error;
+      end if;
+
+      if Out_Data'Length = 0 and then In_Data'Length = 0 then
+         raise Constraint_Error;
+      end if;
+
+      Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length);
+      Set_In  (Filter.Strm.all, In_Data'Address, In_Data'Length);
+
+      Code := Flate (Filter.Compression).Step
+        (To_Thin_Access (Filter.Strm),
+         Thin.Int (Flush));
+
+      if Code = Thin.Z_STREAM_END then
+         Filter.Stream_End := True;
+      else
+         Check_Error (Filter.Strm.all, Code);
+      end if;
+
+      In_Last  := In_Data'Last
+         - Stream_Element_Offset (Avail_In (Filter.Strm.all));
+      Out_Last := Out_Data'Last
+         - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
+   end Translate_Auto;
+
+   --------------------
+   -- Translate_GZip --
+   --------------------
+
+   procedure Translate_GZip
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode)
+   is
+      Out_First : Stream_Element_Offset;
+
+      procedure Add_Data (Data : in Stream_Element_Array);
+      --  Add data to stream from the Filter.Offset till necessary,
+      --  used for add gzip headr/footer.
+
+      procedure Put_32
+        (Item : in out Stream_Element_Array;
+         Data : in     Unsigned_32);
+      pragma Inline (Put_32);
+
+      --------------
+      -- Add_Data --
+      --------------
+
+      procedure Add_Data (Data : in Stream_Element_Array) is
+         Data_First : Stream_Element_Offset renames Filter.Offset;
+         Data_Last  : Stream_Element_Offset;
+         Data_Len   : Stream_Element_Offset; --  -1
+         Out_Len    : Stream_Element_Offset; --  -1
+      begin
+         Out_First := Out_Last + 1;
+
+         if Data_First > Data'Last then
+            return;
+         end if;
+
+         Data_Len  := Data'Last     - Data_First;
+         Out_Len   := Out_Data'Last - Out_First;
+
+         if Data_Len <= Out_Len then
+            Out_Last  := Out_First  + Data_Len;
+            Data_Last := Data'Last;
+         else
+            Out_Last  := Out_Data'Last;
+            Data_Last := Data_First + Out_Len;
+         end if;
+
+         Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last);
+
+         Data_First := Data_Last + 1;
+         Out_First  := Out_Last + 1;
+      end Add_Data;
+
+      ------------
+      -- Put_32 --
+      ------------
+
+      procedure Put_32
+        (Item : in out Stream_Element_Array;
+         Data : in     Unsigned_32)
+      is
+         D : Unsigned_32 := Data;
+      begin
+         for J in Item'First .. Item'First + 3 loop
+            Item (J) := Stream_Element (D and 16#FF#);
+            D := Shift_Right (D, 8);
+         end loop;
+      end Put_32;
+
+   begin
+      Out_Last := Out_Data'First - 1;
+
+      if not Filter.Stream_End then
+         Add_Data (Simple_GZip_Header);
+
+         Translate_Auto
+           (Filter   => Filter,
+            In_Data  => In_Data,
+            In_Last  => In_Last,
+            Out_Data => Out_Data (Out_First .. Out_Data'Last),
+            Out_Last => Out_Last,
+            Flush    => Flush);
+
+         CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
+      end if;
+
+      if Filter.Stream_End and then Out_Last <= Out_Data'Last then
+         --  This detection method would work only when
+         --  Simple_GZip_Header'Last > Footer_Array'Last
+
+         if Filter.Offset = Simple_GZip_Header'Last + 1 then
+            Filter.Offset := Footer_Array'First;
+         end if;
+
+         declare
+            Footer : Footer_Array;
+         begin
+            Put_32 (Footer, Filter.CRC);
+            Put_32 (Footer (Footer'First + 4 .. Footer'Last),
+                    Unsigned_32 (Total_In (Filter)));
+            Add_Data (Footer);
+         end;
+      end if;
+   end Translate_GZip;
+
+   -------------
+   -- Version --
+   -------------
+
+   function Version return String is
+   begin
+      return Interfaces.C.Strings.Value (Thin.zlibVersion);
+   end Version;
+
+   -----------
+   -- Write --
+   -----------
+
+   procedure Write
+     (Filter : in out Filter_Type;
+      Item   : in     Ada.Streams.Stream_Element_Array;
+      Flush  : in     Flush_Mode := No_Flush)
+   is
+      Buffer   : Stream_Element_Array (1 .. Buffer_Size);
+      In_Last  : Stream_Element_Offset;
+      Out_Last : Stream_Element_Offset;
+      In_First : Stream_Element_Offset := Item'First;
+   begin
+      if Item'Length = 0 and Flush = No_Flush then
+         return;
+      end if;
+
+      loop
+         Translate
+           (Filter   => Filter,
+            In_Data  => Item (In_First .. Item'Last),
+            In_Last  => In_Last,
+            Out_Data => Buffer,
+            Out_Last => Out_Last,
+            Flush    => Flush);
+
+         if Out_Last >= Buffer'First then
+            Write (Buffer (1 .. Out_Last));
+         end if;
+
+         exit when In_Last = Item'Last or Stream_End (Filter);
+
+         In_First := In_Last + 1;
+      end loop;
+   end Write;
+
+end ZLib;
diff --git a/8.x/zlib/contrib/ada/zlib.ads b/8.x/zlib/contrib/ada/zlib.ads
new file mode 100644 (file)
index 0000000..79ffc40
--- /dev/null
@@ -0,0 +1,328 @@
+------------------------------------------------------------------------------
+--                      ZLib for Ada thick binding.                         --
+--                                                                          --
+--              Copyright (C) 2002-2004 Dmitriy Anisimkov                   --
+--                                                                          --
+--  This library 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 library 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 library; if not, write to the Free Software Foundation, --
+--  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.          --
+--                                                                          --
+--  As a special exception, if other files instantiate generics from this   --
+--  unit, or you link this unit with other files to produce an executable,  --
+--  this  unit  does not  by itself cause  the resulting executable to be   --
+--  covered by the GNU General Public License. This exception does not      --
+--  however invalidate any other reasons why the executable file  might be  --
+--  covered by the  GNU Public License.                                     --
+------------------------------------------------------------------------------
+
+--  $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $
+
+with Ada.Streams;
+
+with Interfaces;
+
+package ZLib is
+
+   ZLib_Error   : exception;
+   Status_Error : exception;
+
+   type Compression_Level is new Integer range -1 .. 9;
+
+   type Flush_Mode is private;
+
+   type Compression_Method is private;
+
+   type Window_Bits_Type is new Integer range 8 .. 15;
+
+   type Memory_Level_Type is new Integer range 1 .. 9;
+
+   type Unsigned_32 is new Interfaces.Unsigned_32;
+
+   type Strategy_Type is private;
+
+   type Header_Type is (None, Auto, Default, GZip);
+   --  Header type usage have a some limitation for inflate.
+   --  See comment for Inflate_Init.
+
+   subtype Count is Ada.Streams.Stream_Element_Count;
+
+   Default_Memory_Level : constant Memory_Level_Type := 8;
+   Default_Window_Bits  : constant Window_Bits_Type  := 15;
+
+   ----------------------------------
+   -- Compression method constants --
+   ----------------------------------
+
+   Deflated : constant Compression_Method;
+   --  Only one method allowed in this ZLib version
+
+   ---------------------------------
+   -- Compression level constants --
+   ---------------------------------
+
+   No_Compression      : constant Compression_Level := 0;
+   Best_Speed          : constant Compression_Level := 1;
+   Best_Compression    : constant Compression_Level := 9;
+   Default_Compression : constant Compression_Level := -1;
+
+   --------------------------
+   -- Flush mode constants --
+   --------------------------
+
+   No_Flush      : constant Flush_Mode;
+   --  Regular way for compression, no flush
+
+   Partial_Flush : constant Flush_Mode;
+   --  Will be removed, use Z_SYNC_FLUSH instead
+
+   Sync_Flush    : constant Flush_Mode;
+   --  All pending output is flushed to the output buffer and the output
+   --  is aligned on a byte boundary, so that the decompressor can get all
+   --  input data available so far. (In particular avail_in is zero after the
+   --  call if enough output space has been provided  before the call.)
+   --  Flushing may degrade compression for some compression algorithms and so
+   --  it should be used only when necessary.
+
+   Block_Flush   : constant Flush_Mode;
+   --  Z_BLOCK requests that inflate() stop
+   --  if and when it get to the next deflate block boundary. When decoding the
+   --  zlib or gzip format, this will cause inflate() to return immediately
+   --  after the header and before the first block. When doing a raw inflate,
+   --  inflate() will go ahead and process the first block, and will return
+   --  when it gets to the end of that block, or when it runs out of data.
+
+   Full_Flush    : constant Flush_Mode;
+   --  All output is flushed as with SYNC_FLUSH, and the compression state
+   --  is reset so that decompression can restart from this point if previous
+   --  compressed data has been damaged or if random access is desired. Using
+   --  Full_Flush too often can seriously degrade the compression.
+
+   Finish        : constant Flush_Mode;
+   --  Just for tell the compressor that input data is complete.
+
+   ------------------------------------
+   -- Compression strategy constants --
+   ------------------------------------
+
+   --  RLE stategy could be used only in version 1.2.0 and later.
+
+   Filtered         : constant Strategy_Type;
+   Huffman_Only     : constant Strategy_Type;
+   RLE              : constant Strategy_Type;
+   Default_Strategy : constant Strategy_Type;
+
+   Default_Buffer_Size : constant := 4096;
+
+   type Filter_Type is tagged limited private;
+   --  The filter is for compression and for decompression.
+   --  The usage of the type is depend of its initialization.
+
+   function Version return String;
+   pragma Inline (Version);
+   --  Return string representation of the ZLib version.
+
+   procedure Deflate_Init
+     (Filter       : in out Filter_Type;
+      Level        : in     Compression_Level  := Default_Compression;
+      Strategy     : in     Strategy_Type      := Default_Strategy;
+      Method       : in     Compression_Method := Deflated;
+      Window_Bits  : in     Window_Bits_Type   := Default_Window_Bits;
+      Memory_Level : in     Memory_Level_Type  := Default_Memory_Level;
+      Header       : in     Header_Type        := Default);
+   --  Compressor initialization.
+   --  When Header parameter is Auto or Default, then default zlib header
+   --  would be provided for compressed data.
+   --  When Header is GZip, then gzip header would be set instead of
+   --  default header.
+   --  When Header is None, no header would be set for compressed data.
+
+   procedure Inflate_Init
+     (Filter      : in out Filter_Type;
+      Window_Bits : in     Window_Bits_Type := Default_Window_Bits;
+      Header      : in     Header_Type      := Default);
+   --  Decompressor initialization.
+   --  Default header type mean that ZLib default header is expecting in the
+   --  input compressed stream.
+   --  Header type None mean that no header is expecting in the input stream.
+   --  GZip header type mean that GZip header is expecting in the
+   --  input compressed stream.
+   --  Auto header type mean that header type (GZip or Native) would be
+   --  detected automatically in the input stream.
+   --  Note that header types parameter values None, GZip and Auto are
+   --  supported for inflate routine only in ZLib versions 1.2.0.2 and later.
+   --  Deflate_Init is supporting all header types.
+
+   function Is_Open (Filter : in Filter_Type) return Boolean;
+   pragma Inline (Is_Open);
+   --  Is the filter opened for compression or decompression.
+
+   procedure Close
+     (Filter       : in out Filter_Type;
+      Ignore_Error : in     Boolean := False);
+   --  Closing the compression or decompressor.
+   --  If stream is closing before the complete and Ignore_Error is False,
+   --  The exception would be raised.
+
+   generic
+      with procedure Data_In
+        (Item : out Ada.Streams.Stream_Element_Array;
+         Last : out Ada.Streams.Stream_Element_Offset);
+      with procedure Data_Out
+        (Item : in Ada.Streams.Stream_Element_Array);
+   procedure Generic_Translate
+     (Filter          : in out Filter_Type;
+      In_Buffer_Size  : in     Integer := Default_Buffer_Size;
+      Out_Buffer_Size : in     Integer := Default_Buffer_Size);
+   --  Compress/decompress data fetch from Data_In routine and pass the result
+   --  to the Data_Out routine. User should provide Data_In and Data_Out
+   --  for compression/decompression data flow.
+   --  Compression or decompression depend on Filter initialization.
+
+   function Total_In (Filter : in Filter_Type) return Count;
+   pragma Inline (Total_In);
+   --  Returns total number of input bytes read so far
+
+   function Total_Out (Filter : in Filter_Type) return Count;
+   pragma Inline (Total_Out);
+   --  Returns total number of bytes output so far
+
+   function CRC32
+     (CRC    : in Unsigned_32;
+      Data   : in Ada.Streams.Stream_Element_Array)
+      return Unsigned_32;
+   pragma Inline (CRC32);
+   --  Compute CRC32, it could be necessary for make gzip format
+
+   procedure CRC32
+     (CRC  : in out Unsigned_32;
+      Data : in     Ada.Streams.Stream_Element_Array);
+   pragma Inline (CRC32);
+   --  Compute CRC32, it could be necessary for make gzip format
+
+   -------------------------------------------------
+   --  Below is more complex low level routines.  --
+   -------------------------------------------------
+
+   procedure Translate
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode);
+   --  Compress/decompress the In_Data buffer and place the result into
+   --  Out_Data. In_Last is the index of last element from In_Data accepted by
+   --  the Filter. Out_Last is the last element of the received data from
+   --  Filter. To tell the filter that incoming data are complete put the
+   --  Flush parameter to Finish.
+
+   function Stream_End (Filter : in Filter_Type) return Boolean;
+   pragma Inline (Stream_End);
+   --  Return the true when the stream is complete.
+
+   procedure Flush
+     (Filter    : in out Filter_Type;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode);
+   pragma Inline (Flush);
+   --  Flushing the data from the compressor.
+
+   generic
+      with procedure Write
+        (Item : in Ada.Streams.Stream_Element_Array);
+      --  User should provide this routine for accept
+      --  compressed/decompressed data.
+
+      Buffer_Size : in Ada.Streams.Stream_Element_Offset
+         := Default_Buffer_Size;
+      --  Buffer size for Write user routine.
+
+   procedure Write
+     (Filter  : in out Filter_Type;
+      Item    : in     Ada.Streams.Stream_Element_Array;
+      Flush   : in     Flush_Mode := No_Flush);
+   --  Compress/Decompress data from Item to the generic parameter procedure
+   --  Write. Output buffer size could be set in Buffer_Size generic parameter.
+
+   generic
+      with procedure Read
+        (Item : out Ada.Streams.Stream_Element_Array;
+         Last : out Ada.Streams.Stream_Element_Offset);
+      --  User should provide data for compression/decompression
+      --  thru this routine.
+
+      Buffer : in out Ada.Streams.Stream_Element_Array;
+      --  Buffer for keep remaining data from the previous
+      --  back read.
+
+      Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;
+      --  Rest_First have to be initialized to Buffer'Last + 1
+      --  Rest_Last have to be initialized to Buffer'Last
+      --  before usage.
+
+      Allow_Read_Some : in Boolean := False;
+      --  Is it allowed to return Last < Item'Last before end of data.
+
+   procedure Read
+     (Filter : in out Filter_Type;
+      Item   :    out Ada.Streams.Stream_Element_Array;
+      Last   :    out Ada.Streams.Stream_Element_Offset;
+      Flush  : in     Flush_Mode := No_Flush);
+   --  Compress/Decompress data from generic parameter procedure Read to the
+   --  Item. User should provide Buffer and initialized Rest_First, Rest_Last
+   --  indicators. If Allow_Read_Some is True, Read routines could return
+   --  Last < Item'Last only at end of stream.
+
+private
+
+   use Ada.Streams;
+
+   pragma Assert (Ada.Streams.Stream_Element'Size    =    8);
+   pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);
+
+   type Flush_Mode is new Integer range 0 .. 5;
+
+   type Compression_Method is new Integer range 8 .. 8;
+
+   type Strategy_Type is new Integer range 0 .. 3;
+
+   No_Flush      : constant Flush_Mode := 0;
+   Partial_Flush : constant Flush_Mode := 1;
+   Sync_Flush    : constant Flush_Mode := 2;
+   Full_Flush    : constant Flush_Mode := 3;
+   Finish        : constant Flush_Mode := 4;
+   Block_Flush   : constant Flush_Mode := 5;
+
+   Filtered         : constant Strategy_Type := 1;
+   Huffman_Only     : constant Strategy_Type := 2;
+   RLE              : constant Strategy_Type := 3;
+   Default_Strategy : constant Strategy_Type := 0;
+
+   Deflated : constant Compression_Method := 8;
+
+   type Z_Stream;
+
+   type Z_Stream_Access is access all Z_Stream;
+
+   type Filter_Type is tagged limited record
+      Strm        : Z_Stream_Access;
+      Compression : Boolean;
+      Stream_End  : Boolean;
+      Header      : Header_Type;
+      CRC         : Unsigned_32;
+      Offset      : Stream_Element_Offset;
+      --  Offset for gzip header/footer output.
+   end record;
+
+end ZLib;
diff --git a/8.x/zlib/contrib/ada/zlib.gpr b/8.x/zlib/contrib/ada/zlib.gpr
new file mode 100644 (file)
index 0000000..296b22a
--- /dev/null
@@ -0,0 +1,20 @@
+project Zlib is
+
+   for Languages use ("Ada");
+   for Source_Dirs use (".");
+   for Object_Dir use ".";
+   for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo");
+
+   package Compiler is
+      for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst");
+   end Compiler;
+
+   package Linker is
+      for Default_Switches ("ada") use ("-lz");
+   end Linker;
+
+   package Builder is
+      for Default_Switches ("ada") use ("-s", "-gnatQ");
+   end Builder;
+
+end Zlib;
diff --git a/8.x/zlib/contrib/amd64/amd64-match.S b/8.x/zlib/contrib/amd64/amd64-match.S
new file mode 100644 (file)
index 0000000..81d4a1c
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * match.S -- optimized version of longest_match()
+ * based on the similar work by Gilles Vollant, and Brian Raiter, written 1998
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the BSD License. Use by owners of Che Guevarra
+ * parafernalia is prohibited, where possible, and highly discouraged
+ * elsewhere.
+ */
+
+#ifndef NO_UNDERLINE
+#      define  match_init      _match_init
+#      define  longest_match   _longest_match
+#endif
+
+#define        scanend         ebx
+#define        scanendw        bx
+#define        chainlenwmask   edx /* high word: current chain len low word: s->wmask */
+#define        curmatch        rsi
+#define        curmatchd       esi
+#define        windowbestlen   r8
+#define        scanalign       r9
+#define        scanalignd      r9d
+#define        window          r10
+#define        bestlen         r11
+#define        bestlend        r11d
+#define        scanstart       r12d
+#define        scanstartw      r12w
+#define scan           r13
+#define nicematch      r14d
+#define        limit           r15
+#define        limitd          r15d
+#define prev           rcx
+
+/*
+ * The 258 is a "magic number, not a parameter -- changing it
+ * breaks the hell loose
+ */
+#define        MAX_MATCH       (258)
+#define        MIN_MATCH       (3)
+#define        MIN_LOOKAHEAD   (MAX_MATCH + MIN_MATCH + 1)
+#define        MAX_MATCH_8     ((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+#define        LocalVarsSize   (112)
+#define _chainlenwmask ( 8-LocalVarsSize)(%rsp)
+#define _windowbestlen (16-LocalVarsSize)(%rsp)
+#define save_r14        (24-LocalVarsSize)(%rsp)
+#define save_rsi        (32-LocalVarsSize)(%rsp)
+#define save_rbx        (40-LocalVarsSize)(%rsp)
+#define save_r12        (56-LocalVarsSize)(%rsp)
+#define save_r13        (64-LocalVarsSize)(%rsp)
+#define save_r15        (80-LocalVarsSize)(%rsp)
+
+
+.globl match_init, longest_match
+
+/*
+ * On AMD64 the first argument of a function (in our case -- the pointer to
+ * deflate_state structure) is passed in %rdi, hence our offsets below are
+ * all off of that.
+ */
+
+/* you can check the structure offset by running
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "deflate.h"
+
+void print_depl()
+{
+deflate_state ds;
+deflate_state *s=&ds;
+printf("size pointer=%u\n",(int)sizeof(void*));
+
+printf("#define dsWSize         (%3u)(%%rdi)\n",(int)(((char*)&(s->w_size))-((char*)s)));
+printf("#define dsWMask         (%3u)(%%rdi)\n",(int)(((char*)&(s->w_mask))-((char*)s)));
+printf("#define dsWindow        (%3u)(%%rdi)\n",(int)(((char*)&(s->window))-((char*)s)));
+printf("#define dsPrev          (%3u)(%%rdi)\n",(int)(((char*)&(s->prev))-((char*)s)));
+printf("#define dsMatchLen      (%3u)(%%rdi)\n",(int)(((char*)&(s->match_length))-((char*)s)));
+printf("#define dsPrevMatch     (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_match))-((char*)s)));
+printf("#define dsStrStart      (%3u)(%%rdi)\n",(int)(((char*)&(s->strstart))-((char*)s)));
+printf("#define dsMatchStart    (%3u)(%%rdi)\n",(int)(((char*)&(s->match_start))-((char*)s)));
+printf("#define dsLookahead     (%3u)(%%rdi)\n",(int)(((char*)&(s->lookahead))-((char*)s)));
+printf("#define dsPrevLen       (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_length))-((char*)s)));
+printf("#define dsMaxChainLen   (%3u)(%%rdi)\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
+printf("#define dsGoodMatch     (%3u)(%%rdi)\n",(int)(((char*)&(s->good_match))-((char*)s)));
+printf("#define dsNiceMatch     (%3u)(%%rdi)\n",(int)(((char*)&(s->nice_match))-((char*)s)));
+}
+
+*/
+
+
+/*
+  to compile for XCode 3.2 on MacOSX x86_64
+  - run "gcc -g -c -DXCODE_MAC_X64_STRUCTURE amd64-match.S"
+ */
+
+
+#ifndef CURRENT_LINX_XCODE_MAC_X64_STRUCTURE
+#define dsWSize                ( 68)(%rdi)
+#define dsWMask                ( 76)(%rdi)
+#define dsWindow       ( 80)(%rdi)
+#define dsPrev         ( 96)(%rdi)
+#define dsMatchLen     (144)(%rdi)
+#define dsPrevMatch    (148)(%rdi)
+#define dsStrStart     (156)(%rdi)
+#define dsMatchStart   (160)(%rdi)
+#define dsLookahead    (164)(%rdi)
+#define dsPrevLen      (168)(%rdi)
+#define dsMaxChainLen  (172)(%rdi)
+#define dsGoodMatch    (188)(%rdi)
+#define dsNiceMatch    (192)(%rdi)
+
+#else 
+
+#ifndef STRUCT_OFFSET
+#      define STRUCT_OFFSET    (0)
+#endif
+
+
+#define dsWSize                ( 56 + STRUCT_OFFSET)(%rdi)
+#define dsWMask                ( 64 + STRUCT_OFFSET)(%rdi)
+#define dsWindow       ( 72 + STRUCT_OFFSET)(%rdi)
+#define dsPrev         ( 88 + STRUCT_OFFSET)(%rdi)
+#define dsMatchLen     (136 + STRUCT_OFFSET)(%rdi)
+#define dsPrevMatch    (140 + STRUCT_OFFSET)(%rdi)
+#define dsStrStart     (148 + STRUCT_OFFSET)(%rdi)
+#define dsMatchStart   (152 + STRUCT_OFFSET)(%rdi)
+#define dsLookahead    (156 + STRUCT_OFFSET)(%rdi)
+#define dsPrevLen      (160 + STRUCT_OFFSET)(%rdi)
+#define dsMaxChainLen  (164 + STRUCT_OFFSET)(%rdi)
+#define dsGoodMatch    (180 + STRUCT_OFFSET)(%rdi)
+#define dsNiceMatch    (184 + STRUCT_OFFSET)(%rdi)
+
+#endif
+
+
+
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+
+longest_match:
+/*
+ * Retrieve the function arguments. %curmatch will hold cur_match
+ * throughout the entire function (passed via rsi on amd64).
+ * rdi will hold the pointer to the deflate_state (first arg on amd64)
+ */
+               mov     %rsi, save_rsi
+               mov     %rbx, save_rbx
+               mov     %r12, save_r12
+               mov     %r13, save_r13
+               mov     %r14, save_r14
+               mov     %r15, save_r15
+
+/* uInt wmask = s->w_mask;                                             */
+/* unsigned chain_length = s->max_chain_length;                                */
+/* if (s->prev_length >= s->good_match) {                              */
+/*     chain_length >>= 2;                                             */
+/* }                                                                   */
+
+               movl    dsPrevLen, %eax
+               movl    dsGoodMatch, %ebx
+               cmpl    %ebx, %eax
+               movl    dsWMask, %eax
+               movl    dsMaxChainLen, %chainlenwmask
+               jl      LastMatchGood
+               shrl    $2, %chainlenwmask
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can    */
+/* use the sign flag instead of the zero flag for the exit test.       */
+/* It is then shifted into the high word, to make room for the wmask   */
+/* value, which it will always accompany.                              */
+
+               decl    %chainlenwmask
+               shll    $16, %chainlenwmask
+               orl     %eax, %chainlenwmask
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;     */
+
+               movl    dsNiceMatch, %eax
+               movl    dsLookahead, %ebx
+               cmpl    %eax, %ebx
+               jl      LookaheadLess
+               movl    %eax, %ebx
+LookaheadLess: movl    %ebx, %nicematch
+
+/* register Bytef *scan = s->window + s->strstart;                     */
+
+               mov     dsWindow, %window
+               movl    dsStrStart, %limitd
+               lea     (%limit, %window), %scan
+
+/* Determine how many bytes the scan ptr is off from being             */
+/* dword-aligned.                                                      */
+
+               mov     %scan, %scanalign
+               negl    %scanalignd
+               andl    $3, %scanalignd
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?                      */
+/*     s->strstart - (IPos)MAX_DIST(s) : NIL;                          */
+
+               movl    dsWSize, %eax
+               subl    $MIN_LOOKAHEAD, %eax
+               xorl    %ecx, %ecx
+               subl    %eax, %limitd
+               cmovng  %ecx, %limitd
+
+/* int best_len = s->prev_length;                                      */
+
+               movl    dsPrevLen, %bestlend
+
+/* Store the sum of s->window + best_len in %windowbestlen locally, and in memory.     */
+
+               lea     (%window, %bestlen), %windowbestlen
+               mov     %windowbestlen, _windowbestlen
+
+/* register ush scan_start = *(ushf*)scan;                             */
+/* register ush scan_end   = *(ushf*)(scan+best_len-1);                        */
+/* Posf *prev = s->prev;                                               */
+
+               movzwl  (%scan), %scanstart
+               movzwl  -1(%scan, %bestlen), %scanend
+               mov     dsPrev, %prev
+
+/* Jump into the main loop.                                            */
+
+               movl    %chainlenwmask, _chainlenwmask
+               jmp     LoopEntry
+
+.balign 16
+
+/* do {
+ *     match = s->window + cur_match;
+ *     if (*(ushf*)(match+best_len-1) != scan_end ||
+ *         *(ushf*)match != scan_start) continue;
+ *     [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ *          && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ */
+LookupLoop:
+               andl    %chainlenwmask, %curmatchd
+               movzwl  (%prev, %curmatch, 2), %curmatchd
+               cmpl    %limitd, %curmatchd
+               jbe     LeaveNow
+               subl    $0x00010000, %chainlenwmask
+               js      LeaveNow
+LoopEntry:     cmpw    -1(%windowbestlen, %curmatch), %scanendw
+               jne     LookupLoop
+               cmpw    %scanstartw, (%window, %curmatch)
+               jne     LookupLoop
+
+/* Store the current value of chainlen.                                        */
+               movl    %chainlenwmask, _chainlenwmask
+
+/* %scan is the string under scrutiny, and %prev to the string we      */
+/* are hoping to match it up with. In actuality, %esi and %edi are     */
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is     */
+/* initialized to -(MAX_MATCH_8 - scanalign).                          */
+
+               mov     $(-MAX_MATCH_8), %rdx
+               lea     (%curmatch, %window), %windowbestlen
+               lea     MAX_MATCH_8(%windowbestlen, %scanalign), %windowbestlen
+               lea     MAX_MATCH_8(%scan, %scanalign), %prev
+
+/* the prefetching below makes very little difference... */
+               prefetcht1      (%windowbestlen, %rdx)
+               prefetcht1      (%prev, %rdx)
+
+/*
+ * Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %rdx so that it is offset to the exact byte that mismatched.
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance -- unrolling it, for example, makes no difference.
+ */
+
+#undef USE_SSE /* works, but is 6-7% slower, than non-SSE... */
+
+LoopCmps:
+#ifdef USE_SSE
+               /* Preload the SSE registers */
+               movdqu    (%windowbestlen, %rdx), %xmm1
+               movdqu    (%prev, %rdx), %xmm2
+               pcmpeqb %xmm2, %xmm1
+               movdqu  16(%windowbestlen, %rdx), %xmm3
+               movdqu  16(%prev, %rdx), %xmm4
+               pcmpeqb %xmm4, %xmm3
+               movdqu  32(%windowbestlen, %rdx), %xmm5
+               movdqu  32(%prev, %rdx), %xmm6
+               pcmpeqb %xmm6, %xmm5
+               movdqu  48(%windowbestlen, %rdx), %xmm7
+               movdqu  48(%prev, %rdx), %xmm8
+               pcmpeqb %xmm8, %xmm7
+
+               /* Check the comparisions' results */
+               pmovmskb %xmm1, %rax
+               notw    %ax
+               bsfw    %ax, %ax
+               jnz     LeaveLoopCmps
+               
+               /* this is the only iteration of the loop with a possibility of having
+                  incremented rdx by 0x108 (each loop iteration add 16*4 = 0x40 
+                  and (0x40*4)+8=0x108 */
+               add     $8, %rdx
+               jz LenMaximum
+               add     $8, %rdx
+
+               
+               pmovmskb %xmm3, %rax
+               notw    %ax
+               bsfw    %ax, %ax
+               jnz     LeaveLoopCmps
+               
+               
+               add     $16, %rdx
+
+
+               pmovmskb %xmm5, %rax
+               notw    %ax
+               bsfw    %ax, %ax
+               jnz     LeaveLoopCmps
+               
+               add     $16, %rdx
+
+
+               pmovmskb %xmm7, %rax
+               notw    %ax
+               bsfw    %ax, %ax
+               jnz     LeaveLoopCmps
+               
+               add     $16, %rdx
+               
+               jmp     LoopCmps
+LeaveLoopCmps: add     %rax, %rdx
+#else
+               mov     (%windowbestlen, %rdx), %rax
+               xor     (%prev, %rdx), %rax
+               jnz     LeaveLoopCmps
+               
+               mov     8(%windowbestlen, %rdx), %rax
+               xor     8(%prev, %rdx), %rax
+               jnz     LeaveLoopCmps8
+
+               mov     16(%windowbestlen, %rdx), %rax
+               xor     16(%prev, %rdx), %rax
+               jnz     LeaveLoopCmps16
+                               
+               add     $24, %rdx
+               jnz     LoopCmps
+               jmp     LenMaximum
+#      if 0
+/*
+ * This three-liner is tantalizingly simple, but bsf is a slow instruction,
+ * and the complicated alternative down below is quite a bit faster. Sad...
+ */
+
+LeaveLoopCmps: bsf     %rax, %rax /* find the first non-zero bit */
+               shrl    $3, %eax /* divide by 8 to get the byte */
+               add     %rax, %rdx
+#      else
+LeaveLoopCmps16:
+               add     $8, %rdx
+LeaveLoopCmps8:
+               add     $8, %rdx
+LeaveLoopCmps: testl   $0xFFFFFFFF, %eax /* Check the first 4 bytes */
+               jnz     Check16
+               add     $4, %rdx
+               shr     $32, %rax
+Check16:        testw   $0xFFFF, %ax
+               jnz     LenLower
+               add     $2, %rdx
+               shrl    $16, %eax
+LenLower:      subb    $1, %al
+               adc     $0, %rdx
+#      endif
+#endif
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH,  */
+/* then automatically accept it as the best possible match and leave.  */
+
+               lea     (%prev, %rdx), %rax
+               sub     %scan, %rax
+               cmpl    $MAX_MATCH, %eax
+               jge     LenMaximum
+
+/* If the length of the match is not longer than the best match we     */
+/* have so far, then forget it and return to the lookup loop.          */
+
+               cmpl    %bestlend, %eax
+               jg      LongerMatch
+               mov     _windowbestlen, %windowbestlen
+               mov     dsPrev, %prev
+               movl    _chainlenwmask, %edx
+               jmp     LookupLoop
+
+/*         s->match_start = cur_match;                                 */
+/*         best_len = len;                                             */
+/*         if (len >= nice_match) break;                               */
+/*         scan_end = *(ushf*)(scan+best_len-1);                       */
+
+LongerMatch:
+               movl    %eax, %bestlend
+               movl    %curmatchd, dsMatchStart
+               cmpl    %nicematch, %eax
+               jge     LeaveNow
+
+               lea     (%window, %bestlen), %windowbestlen
+               mov     %windowbestlen, _windowbestlen
+
+               movzwl  -1(%scan, %rax), %scanend
+               mov     dsPrev, %prev
+               movl    _chainlenwmask, %chainlenwmask
+               jmp     LookupLoop
+
+/* Accept the current string, with the maximum possible length.                */
+
+LenMaximum:
+               movl    $MAX_MATCH, %bestlend
+               movl    %curmatchd, dsMatchStart
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;          */
+/* return s->lookahead;                                                        */
+
+LeaveNow:
+               movl    dsLookahead, %eax
+               cmpl    %eax, %bestlend
+               cmovngl %bestlend, %eax
+LookaheadRet:
+
+/* Restore the registers and return from whence we came.                       */
+
+       mov     save_rsi, %rsi
+       mov     save_rbx, %rbx
+       mov     save_r12, %r12
+       mov     save_r13, %r13
+       mov     save_r14, %r14
+       mov     save_r15, %r15
+
+       ret
+
+match_init:    ret
diff --git a/8.x/zlib/contrib/asm686/README.686 b/8.x/zlib/contrib/asm686/README.686
new file mode 100644 (file)
index 0000000..a0bf3be
--- /dev/null
@@ -0,0 +1,51 @@
+This is a patched version of zlib, modified to use
+Pentium-Pro-optimized assembly code in the deflation algorithm. The
+files changed/added by this patch are:
+
+README.686
+match.S
+
+The speedup that this patch provides varies, depending on whether the
+compiler used to build the original version of zlib falls afoul of the
+PPro's speed traps. My own tests show a speedup of around 10-20% at
+the default compression level, and 20-30% using -9, against a version
+compiled using gcc 2.7.2.3. Your mileage may vary.
+
+Note that this code has been tailored for the PPro/PII in particular,
+and will not perform particuarly well on a Pentium.
+
+If you are using an assembler other than GNU as, you will have to
+translate match.S to use your assembler's syntax. (Have fun.)
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 1998
+
+
+Added for zlib 1.1.3:
+
+The patches come from
+http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+To compile zlib with this asm file, copy match.S to the zlib directory
+then do:
+
+CFLAGS="-O3 -DASMV" ./configure
+make OBJA=match.o
+
+
+Update:
+
+I've been ignoring these assembly routines for years, believing that
+gcc's generated code had caught up with it sometime around gcc 2.95
+and the major rearchitecting of the Pentium 4. However, I recently
+learned that, despite what I believed, this code still has some life
+in it. On the Pentium 4 and AMD64 chips, it continues to run about 8%
+faster than the code produced by gcc 4.1.
+
+In acknowledgement of its continuing usefulness, I've altered the
+license to match that of the rest of zlib. Share and Enjoy!
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 2007
diff --git a/8.x/zlib/contrib/asm686/match.S b/8.x/zlib/contrib/asm686/match.S
new file mode 100644 (file)
index 0000000..06817e1
--- /dev/null
@@ -0,0 +1,343 @@
+/* match.S -- x86 assembly version of the zlib longest_match() function.
+ * Optimized for the Intel 686 chips (PPro and later).
+ *
+ * Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef NO_UNDERLINE
+#define        match_init      _match_init
+#define        longest_match   _longest_match
+#endif
+
+#define        MAX_MATCH       (258)
+#define        MIN_MATCH       (3)
+#define        MIN_LOOKAHEAD   (MAX_MATCH + MIN_MATCH + 1)
+#define        MAX_MATCH_8     ((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+
+#define        chainlenwmask           0       /* high word: current chain len */
+                                       /* low word: s->wmask           */
+#define        window                  4       /* local copy of s->window      */
+#define        windowbestlen           8       /* s->window + bestlen          */
+#define        scanstart               16      /* first two bytes of string    */
+#define        scanend                 12      /* last two bytes of string     */
+#define        scanalign               20      /* dword-misalignment of string */
+#define        nicematch               24      /* a good enough match size     */
+#define        bestlen                 28      /* size of best match so far    */
+#define        scan                    32      /* ptr to string wanting match  */
+
+#define        LocalVarsSize           (36)
+/*     saved ebx               36 */
+/*     saved edi               40 */
+/*     saved esi               44 */
+/*     saved ebp               48 */
+/*     return address          52 */
+#define        deflatestate            56      /* the function arguments       */
+#define        curmatch                60
+
+/* All the +zlib1222add offsets are due to the addition of fields
+ *  in zlib in the deflate_state structure since the asm code was first written
+ * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+ * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+ * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+ */
+
+#define zlib1222add            (8)
+
+#define        dsWSize                 (36+zlib1222add)
+#define        dsWMask                 (44+zlib1222add)
+#define        dsWindow                (48+zlib1222add)
+#define        dsPrev                  (56+zlib1222add)
+#define        dsMatchLen              (88+zlib1222add)
+#define        dsPrevMatch             (92+zlib1222add)
+#define        dsStrStart              (100+zlib1222add)
+#define        dsMatchStart            (104+zlib1222add)
+#define        dsLookahead             (108+zlib1222add)
+#define        dsPrevLen               (112+zlib1222add)
+#define        dsMaxChainLen           (116+zlib1222add)
+#define        dsGoodMatch             (132+zlib1222add)
+#define        dsNiceMatch             (136+zlib1222add)
+
+
+.file "match.S"
+
+.globl match_init, longest_match
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+
+longest_match:
+
+/* Save registers that the compiler may be using, and adjust %esp to   */
+/* make room for our stack frame.                                      */
+
+               pushl   %ebp
+               pushl   %edi
+               pushl   %esi
+               pushl   %ebx
+               subl    $LocalVarsSize, %esp
+
+/* Retrieve the function arguments. %ecx will hold cur_match           */
+/* throughout the entire function. %edx will hold the pointer to the   */
+/* deflate_state structure during the function's setup (before         */
+/* entering the main loop).                                            */
+
+               movl    deflatestate(%esp), %edx
+               movl    curmatch(%esp), %ecx
+
+/* uInt wmask = s->w_mask;                                             */
+/* unsigned chain_length = s->max_chain_length;                                */
+/* if (s->prev_length >= s->good_match) {                              */
+/*     chain_length >>= 2;                                             */
+/* }                                                                   */
+
+               movl    dsPrevLen(%edx), %eax
+               movl    dsGoodMatch(%edx), %ebx
+               cmpl    %ebx, %eax
+               movl    dsWMask(%edx), %eax
+               movl    dsMaxChainLen(%edx), %ebx
+               jl      LastMatchGood
+               shrl    $2, %ebx
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can    */
+/* use the sign flag instead of the zero flag for the exit test.       */
+/* It is then shifted into the high word, to make room for the wmask   */
+/* value, which it will always accompany.                              */
+
+               decl    %ebx
+               shll    $16, %ebx
+               orl     %eax, %ebx
+               movl    %ebx, chainlenwmask(%esp)
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;     */
+
+               movl    dsNiceMatch(%edx), %eax
+               movl    dsLookahead(%edx), %ebx
+               cmpl    %eax, %ebx
+               jl      LookaheadLess
+               movl    %eax, %ebx
+LookaheadLess: movl    %ebx, nicematch(%esp)
+
+/* register Bytef *scan = s->window + s->strstart;                     */
+
+               movl    dsWindow(%edx), %esi
+               movl    %esi, window(%esp)
+               movl    dsStrStart(%edx), %ebp
+               lea     (%esi,%ebp), %edi
+               movl    %edi, scan(%esp)
+
+/* Determine how many bytes the scan ptr is off from being             */
+/* dword-aligned.                                                      */
+
+               movl    %edi, %eax
+               negl    %eax
+               andl    $3, %eax
+               movl    %eax, scanalign(%esp)
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?                      */
+/*     s->strstart - (IPos)MAX_DIST(s) : NIL;                          */
+
+               movl    dsWSize(%edx), %eax
+               subl    $MIN_LOOKAHEAD, %eax
+               subl    %eax, %ebp
+               jg      LimitPositive
+               xorl    %ebp, %ebp
+LimitPositive:
+
+/* int best_len = s->prev_length;                                      */
+
+               movl    dsPrevLen(%edx), %eax
+               movl    %eax, bestlen(%esp)
+
+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
+
+               addl    %eax, %esi
+               movl    %esi, windowbestlen(%esp)
+
+/* register ush scan_start = *(ushf*)scan;                             */
+/* register ush scan_end   = *(ushf*)(scan+best_len-1);                        */
+/* Posf *prev = s->prev;                                               */
+
+               movzwl  (%edi), %ebx
+               movl    %ebx, scanstart(%esp)
+               movzwl  -1(%edi,%eax), %ebx
+               movl    %ebx, scanend(%esp)
+               movl    dsPrev(%edx), %edi
+
+/* Jump into the main loop.                                            */
+
+               movl    chainlenwmask(%esp), %edx
+               jmp     LoopEntry
+
+.balign 16
+
+/* do {
+ *     match = s->window + cur_match;
+ *     if (*(ushf*)(match+best_len-1) != scan_end ||
+ *         *(ushf*)match != scan_start) continue;
+ *     [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ *          && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ *
+ * Within this loop:
+ * %ebx = scanend
+ * %ecx = curmatch
+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+ * %esi = windowbestlen - i.e., (window + bestlen)
+ * %edi = prev
+ * %ebp = limit
+ */
+LookupLoop:
+               andl    %edx, %ecx
+               movzwl  (%edi,%ecx,2), %ecx
+               cmpl    %ebp, %ecx
+               jbe     LeaveNow
+               subl    $0x00010000, %edx
+               js      LeaveNow
+LoopEntry:     movzwl  -1(%esi,%ecx), %eax
+               cmpl    %ebx, %eax
+               jnz     LookupLoop
+               movl    window(%esp), %eax
+               movzwl  (%eax,%ecx), %eax
+               cmpl    scanstart(%esp), %eax
+               jnz     LookupLoop
+
+/* Store the current value of chainlen.                                        */
+
+               movl    %edx, chainlenwmask(%esp)
+
+/* Point %edi to the string under scrutiny, and %esi to the string we  */
+/* are hoping to match it up with. In actuality, %esi and %edi are     */
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is     */
+/* initialized to -(MAX_MATCH_8 - scanalign).                          */
+
+               movl    window(%esp), %esi
+               movl    scan(%esp), %edi
+               addl    %ecx, %esi
+               movl    scanalign(%esp), %eax
+               movl    $(-MAX_MATCH_8), %edx
+               lea     MAX_MATCH_8(%edi,%eax), %edi
+               lea     MAX_MATCH_8(%esi,%eax), %esi
+
+/* Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %edx so that it is offset to the exact byte that mismatched.
+ *
+ * We already know at this point that the first three bytes of the
+ * strings match each other, and they can be safely passed over before
+ * starting the compare loop. So what this code does is skip over 0-3
+ * bytes, as much as necessary in order to dword-align the %edi
+ * pointer. (%esi will still be misaligned three times out of four.)
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance.
+ */
+LoopCmps:
+               movl    (%esi,%edx), %eax
+               xorl    (%edi,%edx), %eax
+               jnz     LeaveLoopCmps
+               movl    4(%esi,%edx), %eax
+               xorl    4(%edi,%edx), %eax
+               jnz     LeaveLoopCmps4
+               addl    $8, %edx
+               jnz     LoopCmps
+               jmp     LenMaximum
+LeaveLoopCmps4:        addl    $4, %edx
+LeaveLoopCmps: testl   $0x0000FFFF, %eax
+               jnz     LenLower
+               addl    $2, %edx
+               shrl    $16, %eax
+LenLower:      subb    $1, %al
+               adcl    $0, %edx
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH,  */
+/* then automatically accept it as the best possible match and leave.  */
+
+               lea     (%edi,%edx), %eax
+               movl    scan(%esp), %edi
+               subl    %edi, %eax
+               cmpl    $MAX_MATCH, %eax
+               jge     LenMaximum
+
+/* If the length of the match is not longer than the best match we     */
+/* have so far, then forget it and return to the lookup loop.          */
+
+               movl    deflatestate(%esp), %edx
+               movl    bestlen(%esp), %ebx
+               cmpl    %ebx, %eax
+               jg      LongerMatch
+               movl    windowbestlen(%esp), %esi
+               movl    dsPrev(%edx), %edi
+               movl    scanend(%esp), %ebx
+               movl    chainlenwmask(%esp), %edx
+               jmp     LookupLoop
+
+/*         s->match_start = cur_match;                                 */
+/*         best_len = len;                                             */
+/*         if (len >= nice_match) break;                               */
+/*         scan_end = *(ushf*)(scan+best_len-1);                       */
+
+LongerMatch:   movl    nicematch(%esp), %ebx
+               movl    %eax, bestlen(%esp)
+               movl    %ecx, dsMatchStart(%edx)
+               cmpl    %ebx, %eax
+               jge     LeaveNow
+               movl    window(%esp), %esi
+               addl    %eax, %esi
+               movl    %esi, windowbestlen(%esp)
+               movzwl  -1(%edi,%eax), %ebx
+               movl    dsPrev(%edx), %edi
+               movl    %ebx, scanend(%esp)
+               movl    chainlenwmask(%esp), %edx
+               jmp     LookupLoop
+
+/* Accept the current string, with the maximum possible length.                */
+
+LenMaximum:    movl    deflatestate(%esp), %edx
+               movl    $MAX_MATCH, bestlen(%esp)
+               movl    %ecx, dsMatchStart(%edx)
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;          */
+/* return s->lookahead;                                                        */
+
+LeaveNow:
+               movl    deflatestate(%esp), %edx
+               movl    bestlen(%esp), %ebx
+               movl    dsLookahead(%edx), %eax
+               cmpl    %eax, %ebx
+               jg      LookaheadRet
+               movl    %ebx, %eax
+LookaheadRet:
+
+/* Restore the stack and return from whence we came.                   */
+
+               addl    $LocalVarsSize, %esp
+               popl    %ebx
+               popl    %esi
+               popl    %edi
+               popl    %ebp
+match_init:    ret
diff --git a/8.x/zlib/contrib/blast/Makefile b/8.x/zlib/contrib/blast/Makefile
new file mode 100644 (file)
index 0000000..9be80ba
--- /dev/null
@@ -0,0 +1,8 @@
+blast: blast.c blast.h
+       cc -DTEST -o blast blast.c
+
+test: blast
+       blast < test.pk | cmp - test.txt
+
+clean:
+       rm -f blast blast.o
diff --git a/8.x/zlib/contrib/blast/README b/8.x/zlib/contrib/blast/README
new file mode 100644 (file)
index 0000000..e3a60b3
--- /dev/null
@@ -0,0 +1,4 @@
+Read blast.h for purpose and usage.
+
+Mark Adler
+madler@alumni.caltech.edu
diff --git a/8.x/zlib/contrib/blast/blast.c b/8.x/zlib/contrib/blast/blast.c
new file mode 100644 (file)
index 0000000..4ce697a
--- /dev/null
@@ -0,0 +1,444 @@
+/* blast.c
+ * Copyright (C) 2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in blast.h
+ * version 1.1, 16 Feb 2003
+ *
+ * blast.c decompresses data compressed by the PKWare Compression Library.
+ * This function provides functionality similar to the explode() function of
+ * the PKWare library, hence the name "blast".
+ *
+ * This decompressor is based on the excellent format description provided by
+ * Ben Rudiak-Gould in comp.compression on August 13, 2001.  Interestingly, the
+ * example Ben provided in the post is incorrect.  The distance 110001 should
+ * instead be 111000.  When corrected, the example byte stream becomes:
+ *
+ *    00 04 82 24 25 8f 80 7f
+ *
+ * which decompresses to "AIAIAIAIAIAIA" (without the quotes).
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0  12 Feb 2003     - First version
+ * 1.1  16 Feb 2003     - Fixed distance check for > 4 GB uncompressed data
+ */
+
+#include <setjmp.h>             /* for setjmp(), longjmp(), and jmp_buf */
+#include "blast.h"              /* prototype for blast() */
+
+#define local static            /* for local function definitions */
+#define MAXBITS 13              /* maximum code length */
+#define MAXWIN 4096             /* maximum window size */
+
+/* input and output state */
+struct state {
+    /* input state */
+    blast_in infun;             /* input function provided by user */
+    void *inhow;                /* opaque information passed to infun() */
+    unsigned char *in;          /* next input location */
+    unsigned left;              /* available input at in */
+    int bitbuf;                 /* bit buffer */
+    int bitcnt;                 /* number of bits in bit buffer */
+
+    /* input limit error return state for bits() and decode() */
+    jmp_buf env;
+
+    /* output state */
+    blast_out outfun;           /* output function provided by user */
+    void *outhow;               /* opaque information passed to outfun() */
+    unsigned next;              /* index of next write location in out[] */
+    int first;                  /* true to check distances (for first 4K) */
+    unsigned char out[MAXWIN];  /* output buffer and sliding window */
+};
+
+/*
+ * Return need bits from the input stream.  This always leaves less than
+ * eight bits in the buffer.  bits() works properly for need == 0.
+ *
+ * Format notes:
+ *
+ * - Bits are stored in bytes from the least significant bit to the most
+ *   significant bit.  Therefore bits are dropped from the bottom of the bit
+ *   buffer, using shift right, and new bytes are appended to the top of the
+ *   bit buffer, using shift left.
+ */
+local int bits(struct state *s, int need)
+{
+    int val;            /* bit accumulator */
+
+    /* load at least need bits into val */
+    val = s->bitbuf;
+    while (s->bitcnt < need) {
+        if (s->left == 0) {
+            s->left = s->infun(s->inhow, &(s->in));
+            if (s->left == 0) longjmp(s->env, 1);       /* out of input */
+        }
+        val |= (int)(*(s->in)++) << s->bitcnt;          /* load eight bits */
+        s->left--;
+        s->bitcnt += 8;
+    }
+
+    /* drop need bits and update buffer, always zero to seven bits left */
+    s->bitbuf = val >> need;
+    s->bitcnt -= need;
+
+    /* return need bits, zeroing the bits above that */
+    return val & ((1 << need) - 1);
+}
+
+/*
+ * Huffman code decoding tables.  count[1..MAXBITS] is the number of symbols of
+ * each length, which for a canonical code are stepped through in order.
+ * symbol[] are the symbol values in canonical order, where the number of
+ * entries is the sum of the counts in count[].  The decoding process can be
+ * seen in the function decode() below.
+ */
+struct huffman {
+    short *count;       /* number of symbols of each length */
+    short *symbol;      /* canonically ordered symbols */
+};
+
+/*
+ * Decode a code from the stream s using huffman table h.  Return the symbol or
+ * a negative value if there is an error.  If all of the lengths are zero, i.e.
+ * an empty code, or if the code is incomplete and an invalid code is received,
+ * then -9 is returned after reading MAXBITS bits.
+ *
+ * Format notes:
+ *
+ * - The codes as stored in the compressed data are bit-reversed relative to
+ *   a simple integer ordering of codes of the same lengths.  Hence below the
+ *   bits are pulled from the compressed data one at a time and used to
+ *   build the code value reversed from what is in the stream in order to
+ *   permit simple integer comparisons for decoding.
+ *
+ * - The first code for the shortest length is all ones.  Subsequent codes of
+ *   the same length are simply integer decrements of the previous code.  When
+ *   moving up a length, a one bit is appended to the code.  For a complete
+ *   code, the last code of the longest length will be all zeros.  To support
+ *   this ordering, the bits pulled during decoding are inverted to apply the
+ *   more "natural" ordering starting with all zeros and incrementing.
+ */
+local int decode(struct state *s, struct huffman *h)
+{
+    int len;            /* current number of bits in code */
+    int code;           /* len bits being decoded */
+    int first;          /* first code of length len */
+    int count;          /* number of codes of length len */
+    int index;          /* index of first code of length len in symbol table */
+    int bitbuf;         /* bits from stream */
+    int left;           /* bits left in next or left to process */
+    short *next;        /* next number of codes */
+
+    bitbuf = s->bitbuf;
+    left = s->bitcnt;
+    code = first = index = 0;
+    len = 1;
+    next = h->count + 1;
+    while (1) {
+        while (left--) {
+            code |= (bitbuf & 1) ^ 1;   /* invert code */
+            bitbuf >>= 1;
+            count = *next++;
+            if (code < first + count) { /* if length len, return symbol */
+                s->bitbuf = bitbuf;
+                s->bitcnt = (s->bitcnt - len) & 7;
+                return h->symbol[index + (code - first)];
+            }
+            index += count;             /* else update for next length */
+            first += count;
+            first <<= 1;
+            code <<= 1;
+            len++;
+        }
+        left = (MAXBITS+1) - len;
+        if (left == 0) break;
+        if (s->left == 0) {
+            s->left = s->infun(s->inhow, &(s->in));
+            if (s->left == 0) longjmp(s->env, 1);       /* out of input */
+        }
+        bitbuf = *(s->in)++;
+        s->left--;
+        if (left > 8) left = 8;
+    }
+    return -9;                          /* ran out of codes */
+}
+
+/*
+ * Given a list of repeated code lengths rep[0..n-1], where each byte is a
+ * count (high four bits + 1) and a code length (low four bits), generate the
+ * list of code lengths.  This compaction reduces the size of the object code.
+ * Then given the list of code lengths length[0..n-1] representing a canonical
+ * Huffman code for n symbols, construct the tables required to decode those
+ * codes.  Those tables are the number of codes of each length, and the symbols
+ * sorted by length, retaining their original order within each length.  The
+ * return value is zero for a complete code set, negative for an over-
+ * subscribed code set, and positive for an incomplete code set.  The tables
+ * can be used if the return value is zero or positive, but they cannot be used
+ * if the return value is negative.  If the return value is zero, it is not
+ * possible for decode() using that table to return an error--any stream of
+ * enough bits will resolve to a symbol.  If the return value is positive, then
+ * it is possible for decode() using that table to return an error for received
+ * codes past the end of the incomplete lengths.
+ */
+local int construct(struct huffman *h, const unsigned char *rep, int n)
+{
+    int symbol;         /* current symbol when stepping through length[] */
+    int len;            /* current length when stepping through h->count[] */
+    int left;           /* number of possible codes left of current length */
+    short offs[MAXBITS+1];      /* offsets in symbol table for each length */
+    short length[256];  /* code lengths */
+
+    /* convert compact repeat counts into symbol bit length list */
+    symbol = 0;
+    do {
+        len = *rep++;
+        left = (len >> 4) + 1;
+        len &= 15;
+        do {
+            length[symbol++] = len;
+        } while (--left);
+    } while (--n);
+    n = symbol;
+
+    /* count number of codes of each length */
+    for (len = 0; len <= MAXBITS; len++)
+        h->count[len] = 0;
+    for (symbol = 0; symbol < n; symbol++)
+        (h->count[length[symbol]])++;   /* assumes lengths are within bounds */
+    if (h->count[0] == n)               /* no codes! */
+        return 0;                       /* complete, but decode() will fail */
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;                           /* one possible code of zero length */
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;                     /* one more bit, double codes left */
+        left -= h->count[len];          /* deduct count from possible codes */
+        if (left < 0) return left;      /* over-subscribed--return negative */
+    }                                   /* left > 0 means incomplete */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + h->count[len];
+
+    /*
+     * put symbols in table sorted by length, by symbol order within each
+     * length
+     */
+    for (symbol = 0; symbol < n; symbol++)
+        if (length[symbol] != 0)
+            h->symbol[offs[length[symbol]]++] = symbol;
+
+    /* return zero for complete set, positive for incomplete set */
+    return left;
+}
+
+/*
+ * Decode PKWare Compression Library stream.
+ *
+ * Format notes:
+ *
+ * - First byte is 0 if literals are uncoded or 1 if they are coded.  Second
+ *   byte is 4, 5, or 6 for the number of extra bits in the distance code.
+ *   This is the base-2 logarithm of the dictionary size minus six.
+ *
+ * - Compressed data is a combination of literals and length/distance pairs
+ *   terminated by an end code.  Literals are either Huffman coded or
+ *   uncoded bytes.  A length/distance pair is a coded length followed by a
+ *   coded distance to represent a string that occurs earlier in the
+ *   uncompressed data that occurs again at the current location.
+ *
+ * - A bit preceding a literal or length/distance pair indicates which comes
+ *   next, 0 for literals, 1 for length/distance.
+ *
+ * - If literals are uncoded, then the next eight bits are the literal, in the
+ *   normal bit order in th stream, i.e. no bit-reversal is needed. Similarly,
+ *   no bit reversal is needed for either the length extra bits or the distance
+ *   extra bits.
+ *
+ * - Literal bytes are simply written to the output.  A length/distance pair is
+ *   an instruction to copy previously uncompressed bytes to the output.  The
+ *   copy is from distance bytes back in the output stream, copying for length
+ *   bytes.
+ *
+ * - Distances pointing before the beginning of the output data are not
+ *   permitted.
+ *
+ * - Overlapped copies, where the length is greater than the distance, are
+ *   allowed and common.  For example, a distance of one and a length of 518
+ *   simply copies the last byte 518 times.  A distance of four and a length of
+ *   twelve copies the last four bytes three times.  A simple forward copy
+ *   ignoring whether the length is greater than the distance or not implements
+ *   this correctly.
+ */
+local int decomp(struct state *s)
+{
+    int lit;            /* true if literals are coded */
+    int dict;           /* log2(dictionary size) - 6 */
+    int symbol;         /* decoded symbol, extra bits for distance */
+    int len;            /* length for copy */
+    int dist;           /* distance for copy */
+    int copy;           /* copy counter */
+    unsigned char *from, *to;   /* copy pointers */
+    static int virgin = 1;                              /* build tables once */
+    static short litcnt[MAXBITS+1], litsym[256];        /* litcode memory */
+    static short lencnt[MAXBITS+1], lensym[16];         /* lencode memory */
+    static short distcnt[MAXBITS+1], distsym[64];       /* distcode memory */
+    static struct huffman litcode = {litcnt, litsym};   /* length code */
+    static struct huffman lencode = {lencnt, lensym};   /* length code */
+    static struct huffman distcode = {distcnt, distsym};/* distance code */
+        /* bit lengths of literal codes */
+    static const unsigned char litlen[] = {
+        11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,
+        9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,
+        7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,
+        8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,
+        44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,
+        44, 173};
+        /* bit lengths of length codes 0..15 */
+    static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};
+        /* bit lengths of distance codes 0..63 */
+    static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};
+    static const short base[16] = {     /* base for length codes */
+        3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};
+    static const char extra[16] = {     /* extra bits for length codes */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
+
+    /* set up decoding tables (once--might not be thread-safe) */
+    if (virgin) {
+        construct(&litcode, litlen, sizeof(litlen));
+        construct(&lencode, lenlen, sizeof(lenlen));
+        construct(&distcode, distlen, sizeof(distlen));
+        virgin = 0;
+    }
+
+    /* read header */
+    lit = bits(s, 8);
+    if (lit > 1) return -1;
+    dict = bits(s, 8);
+    if (dict < 4 || dict > 6) return -2;
+
+    /* decode literals and length/distance pairs */
+    do {
+        if (bits(s, 1)) {
+            /* get length */
+            symbol = decode(s, &lencode);
+            len = base[symbol] + bits(s, extra[symbol]);
+            if (len == 519) break;              /* end code */
+
+            /* get distance */
+            symbol = len == 2 ? 2 : dict;
+            dist = decode(s, &distcode) << symbol;
+            dist += bits(s, symbol);
+            dist++;
+            if (s->first && dist > s->next)
+                return -3;              /* distance too far back */
+
+            /* copy length bytes from distance bytes back */
+            do {
+                to = s->out + s->next;
+                from = to - dist;
+                copy = MAXWIN;
+                if (s->next < dist) {
+                    from += copy;
+                    copy = dist;
+                }
+                copy -= s->next;
+                if (copy > len) copy = len;
+                len -= copy;
+                s->next += copy;
+                do {
+                    *to++ = *from++;
+                } while (--copy);
+                if (s->next == MAXWIN) {
+                    if (s->outfun(s->outhow, s->out, s->next)) return 1;
+                    s->next = 0;
+                    s->first = 0;
+                }
+            } while (len != 0);
+        }
+        else {
+            /* get literal and write it */
+            symbol = lit ? decode(s, &litcode) : bits(s, 8);
+            s->out[s->next++] = symbol;
+            if (s->next == MAXWIN) {
+                if (s->outfun(s->outhow, s->out, s->next)) return 1;
+                s->next = 0;
+                s->first = 0;
+            }
+        }
+    } while (1);
+    return 0;
+}
+
+/* See comments in blast.h */
+int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow)
+{
+    struct state s;             /* input/output state */
+    int err;                    /* return value */
+
+    /* initialize input state */
+    s.infun = infun;
+    s.inhow = inhow;
+    s.left = 0;
+    s.bitbuf = 0;
+    s.bitcnt = 0;
+
+    /* initialize output state */
+    s.outfun = outfun;
+    s.outhow = outhow;
+    s.next = 0;
+    s.first = 1;
+
+    /* return if bits() or decode() tries to read past available input */
+    if (setjmp(s.env) != 0)             /* if came back here via longjmp(), */
+        err = 2;                        /*  then skip decomp(), return error */
+    else
+        err = decomp(&s);               /* decompress */
+
+    /* write any leftover output and update the error code if needed */
+    if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)
+        err = 1;
+    return err;
+}
+
+#ifdef TEST
+/* Example of how to use blast() */
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CHUNK 16384
+
+local unsigned inf(void *how, unsigned char **buf)
+{
+    static unsigned char hold[CHUNK];
+
+    *buf = hold;
+    return fread(hold, 1, CHUNK, (FILE *)how);
+}
+
+local int outf(void *how, unsigned char *buf, unsigned len)
+{
+    return fwrite(buf, 1, len, (FILE *)how) != len;
+}
+
+/* Decompress a PKWare Compression Library stream from stdin to stdout */
+int main(void)
+{
+    int ret, n;
+
+    /* decompress to stdout */
+    ret = blast(inf, stdin, outf, stdout);
+    if (ret != 0) fprintf(stderr, "blast error: %d\n", ret);
+
+    /* see if there are any leftover bytes */
+    n = 0;
+    while (getchar() != EOF) n++;
+    if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n);
+
+    /* return blast() error code */
+    return ret;
+}
+#endif
diff --git a/8.x/zlib/contrib/blast/blast.h b/8.x/zlib/contrib/blast/blast.h
new file mode 100644 (file)
index 0000000..ce9e541
--- /dev/null
@@ -0,0 +1,71 @@
+/* blast.h -- interface for blast.c
+  Copyright (C) 2003 Mark Adler
+  version 1.1, 16 Feb 2003
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+
+/*
+ * blast() decompresses the PKWare Data Compression Library (DCL) compressed
+ * format.  It provides the same functionality as the explode() function in
+ * that library.  (Note: PKWare overused the "implode" verb, and the format
+ * used by their library implode() function is completely different and
+ * incompatible with the implode compression method supported by PKZIP.)
+ */
+
+
+typedef unsigned (*blast_in)(void *how, unsigned char **buf);
+typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len);
+/* Definitions for input/output functions passed to blast().  See below for
+ * what the provided functions need to do.
+ */
+
+
+int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow);
+/* Decompress input to output using the provided infun() and outfun() calls.
+ * On success, the return value of blast() is zero.  If there is an error in
+ * the source data, i.e. it is not in the proper format, then a negative value
+ * is returned.  If there is not enough input available or there is not enough
+ * output space, then a positive error is returned.
+ *
+ * The input function is invoked: len = infun(how, &buf), where buf is set by
+ * infun() to point to the input buffer, and infun() returns the number of
+ * available bytes there.  If infun() returns zero, then blast() returns with
+ * an input error.  (blast() only asks for input if it needs it.)  inhow is for
+ * use by the application to pass an input descriptor to infun(), if desired.
+ *
+ * The output function is invoked: err = outfun(how, buf, len), where the bytes
+ * to be written are buf[0..len-1].  If err is not zero, then blast() returns
+ * with an output error.  outfun() is always called with len <= 4096.  outhow
+ * is for use by the application to pass an output descriptor to outfun(), if
+ * desired.
+ *
+ * The return codes are:
+ *
+ *   2:  ran out of input before completing decompression
+ *   1:  output error before completing decompression
+ *   0:  successful decompression
+ *  -1:  literal flag not zero or one
+ *  -2:  dictionary size not in 4..6
+ *  -3:  distance is too far back
+ *
+ * At the bottom of blast.c is an example program that uses blast() that can be
+ * compiled to produce a command-line decompression filter by defining TEST.
+ */
diff --git a/8.x/zlib/contrib/blast/test.pk b/8.x/zlib/contrib/blast/test.pk
new file mode 100644 (file)
index 0000000..be10b2b
Binary files /dev/null and b/8.x/zlib/contrib/blast/test.pk differ
diff --git a/8.x/zlib/contrib/blast/test.txt b/8.x/zlib/contrib/blast/test.txt
new file mode 100644 (file)
index 0000000..bfdf1c5
--- /dev/null
@@ -0,0 +1 @@
+AIAIAIAIAIAIA
\ No newline at end of file
diff --git a/8.x/zlib/contrib/delphi/ZLib.pas b/8.x/zlib/contrib/delphi/ZLib.pas
new file mode 100644 (file)
index 0000000..0d86fb5
--- /dev/null
@@ -0,0 +1,557 @@
+{*******************************************************}
+{                                                       }
+{       Borland Delphi Supplemental Components          }
+{       ZLIB Data Compression Interface Unit            }
+{                                                       }
+{       Copyright (c) 1997,99 Borland Corporation       }
+{                                                       }
+{*******************************************************}
+
+{ Updated for zlib 1.2.x by Cosmin Truta <cosmint@cs.ubbcluj.ro> }
+
+unit ZLib;
+
+interface
+
+uses SysUtils, Classes;
+
+type
+  TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+  TFree = procedure (AppData, Block: Pointer); cdecl;
+
+  // Internal structure.  Ignore.
+  TZStreamRec = packed record
+    next_in: PChar;       // next input byte
+    avail_in: Integer;    // number of bytes available at next_in
+    total_in: Longint;    // total nb of input bytes read so far
+
+    next_out: PChar;      // next output byte should be put here
+    avail_out: Integer;   // remaining free space at next_out
+    total_out: Longint;   // total nb of bytes output so far
+
+    msg: PChar;           // last error message, NULL if no error
+    internal: Pointer;    // not visible by applications
+
+    zalloc: TAlloc;       // used to allocate the internal state
+    zfree: TFree;         // used to free the internal state
+    AppData: Pointer;     // private data object passed to zalloc and zfree
+
+    data_type: Integer;   // best guess about the data type: ascii or binary
+    adler: Longint;       // adler32 value of the uncompressed data
+    reserved: Longint;    // reserved for future use
+  end;
+
+  // Abstract ancestor class
+  TCustomZlibStream = class(TStream)
+  private
+    FStrm: TStream;
+    FStrmPos: Integer;
+    FOnProgress: TNotifyEvent;
+    FZRec: TZStreamRec;
+    FBuffer: array [Word] of Char;
+  protected
+    procedure Progress(Sender: TObject); dynamic;
+    property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
+    constructor Create(Strm: TStream);
+  end;
+
+{ TCompressionStream compresses data on the fly as data is written to it, and
+  stores the compressed data to another stream.
+
+  TCompressionStream is write-only and strictly sequential. Reading from the
+  stream will raise an exception. Using Seek to move the stream pointer
+  will raise an exception.
+
+  Output data is cached internally, written to the output stream only when
+  the internal output buffer is full.  All pending output data is flushed
+  when the stream is destroyed.
+
+  The Position property returns the number of uncompressed bytes of
+  data that have been written to the stream so far.
+
+  CompressionRate returns the on-the-fly percentage by which the original
+  data has been compressed:  (1 - (CompressedBytes / UncompressedBytes)) * 100
+  If raw data size = 100 and compressed data size = 25, the CompressionRate
+  is 75%
+
+  The OnProgress event is called each time the output buffer is filled and
+  written to the output stream.  This is useful for updating a progress
+  indicator when you are writing a large chunk of data to the compression
+  stream in a single call.}
+
+
+  TCompressionLevel = (clNone, clFastest, clDefault, clMax);
+
+  TCompressionStream = class(TCustomZlibStream)
+  private
+    function GetCompressionRate: Single;
+  public
+    constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);
+    destructor Destroy; override;
+    function Read(var Buffer; Count: Longint): Longint; override;
+    function Write(const Buffer; Count: Longint): Longint; override;
+    function Seek(Offset: Longint; Origin: Word): Longint; override;
+    property CompressionRate: Single read GetCompressionRate;
+    property OnProgress;
+  end;
+
+{ TDecompressionStream decompresses data on the fly as data is read from it.
+
+  Compressed data comes from a separate source stream.  TDecompressionStream
+  is read-only and unidirectional; you can seek forward in the stream, but not
+  backwards.  The special case of setting the stream position to zero is
+  allowed.  Seeking forward decompresses data until the requested position in
+  the uncompressed data has been reached.  Seeking backwards, seeking relative
+  to the end of the stream, requesting the size of the stream, and writing to
+  the stream will raise an exception.
+
+  The Position property returns the number of bytes of uncompressed data that
+  have been read from the stream so far.
+
+  The OnProgress event is called each time the internal input buffer of
+  compressed data is exhausted and the next block is read from the input stream.
+  This is useful for updating a progress indicator when you are reading a
+  large chunk of data from the decompression stream in a single call.}
+
+  TDecompressionStream = class(TCustomZlibStream)
+  public
+    constructor Create(Source: TStream);
+    destructor Destroy; override;
+    function Read(var Buffer; Count: Longint): Longint; override;
+    function Write(const Buffer; Count: Longint): Longint; override;
+    function Seek(Offset: Longint; Origin: Word): Longint; override;
+    property OnProgress;
+  end;
+
+
+
+{ CompressBuf compresses data, buffer to buffer, in one call.
+   In: InBuf = ptr to compressed data
+       InBytes = number of bytes in InBuf
+  Out: OutBuf = ptr to newly allocated buffer containing decompressed data
+       OutBytes = number of bytes in OutBuf   }
+procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
+                      out OutBuf: Pointer; out OutBytes: Integer);
+
+
+{ DecompressBuf decompresses data, buffer to buffer, in one call.
+   In: InBuf = ptr to compressed data
+       InBytes = number of bytes in InBuf
+       OutEstimate = zero, or est. size of the decompressed data
+  Out: OutBuf = ptr to newly allocated buffer containing decompressed data
+       OutBytes = number of bytes in OutBuf   }
+procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+ OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
+
+{ DecompressToUserBuf decompresses data, buffer to buffer, in one call.
+   In: InBuf = ptr to compressed data
+       InBytes = number of bytes in InBuf
+  Out: OutBuf = ptr to user-allocated buffer to contain decompressed data
+       BufSize = number of bytes in OutBuf   }
+procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
+  const OutBuf: Pointer; BufSize: Integer);
+
+const
+  zlib_version = '1.2.5';
+
+type
+  EZlibError = class(Exception);
+  ECompressionError = class(EZlibError);
+  EDecompressionError = class(EZlibError);
+
+implementation
+
+uses ZLibConst;
+
+const
+  Z_NO_FLUSH      = 0;
+  Z_PARTIAL_FLUSH = 1;
+  Z_SYNC_FLUSH    = 2;
+  Z_FULL_FLUSH    = 3;
+  Z_FINISH        = 4;
+
+  Z_OK            = 0;
+  Z_STREAM_END    = 1;
+  Z_NEED_DICT     = 2;
+  Z_ERRNO         = (-1);
+  Z_STREAM_ERROR  = (-2);
+  Z_DATA_ERROR    = (-3);
+  Z_MEM_ERROR     = (-4);
+  Z_BUF_ERROR     = (-5);
+  Z_VERSION_ERROR = (-6);
+
+  Z_NO_COMPRESSION       =   0;
+  Z_BEST_SPEED           =   1;
+  Z_BEST_COMPRESSION     =   9;
+  Z_DEFAULT_COMPRESSION  = (-1);
+
+  Z_FILTERED            = 1;
+  Z_HUFFMAN_ONLY        = 2;
+  Z_RLE                 = 3;
+  Z_DEFAULT_STRATEGY    = 0;
+
+  Z_BINARY   = 0;
+  Z_ASCII    = 1;
+  Z_UNKNOWN  = 2;
+
+  Z_DEFLATED = 8;
+
+
+{$L adler32.obj}
+{$L compress.obj}
+{$L crc32.obj}
+{$L deflate.obj}
+{$L infback.obj}
+{$L inffast.obj}
+{$L inflate.obj}
+{$L inftrees.obj}
+{$L trees.obj}
+{$L uncompr.obj}
+{$L zutil.obj}
+
+procedure adler32; external;
+procedure compressBound; external;
+procedure crc32; external;
+procedure deflateInit2_; external;
+procedure deflateParams; external;
+
+function _malloc(Size: Integer): Pointer; cdecl;
+begin
+  Result := AllocMem(Size);
+end;
+
+procedure _free(Block: Pointer); cdecl;
+begin
+  FreeMem(Block);
+end;
+
+procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
+begin
+  FillChar(P^, count, B);
+end;
+
+procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
+begin
+  Move(source^, dest^, count);
+end;
+
+
+
+// deflate compresses data
+function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
+  recsize: Integer): Integer; external;
+function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
+function deflateEnd(var strm: TZStreamRec): Integer; external;
+
+// inflate decompresses data
+function inflateInit_(var strm: TZStreamRec; version: PChar;
+  recsize: Integer): Integer; external;
+function inflate(var strm: TZStreamRec; flush: Integer): Integer; external;
+function inflateEnd(var strm: TZStreamRec): Integer; external;
+function inflateReset(var strm: TZStreamRec): Integer; external;
+
+
+function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+begin
+//  GetMem(Result, Items*Size);
+  Result := AllocMem(Items * Size);
+end;
+
+procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
+begin
+  FreeMem(Block);
+end;
+
+{function zlibCheck(code: Integer): Integer;
+begin
+  Result := code;
+  if code < 0 then
+    raise EZlibError.Create('error');    //!!
+end;}
+
+function CCheck(code: Integer): Integer;
+begin
+  Result := code;
+  if code < 0 then
+    raise ECompressionError.Create('error'); //!!
+end;
+
+function DCheck(code: Integer): Integer;
+begin
+  Result := code;
+  if code < 0 then
+    raise EDecompressionError.Create('error');  //!!
+end;
+
+procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
+                      out OutBuf: Pointer; out OutBytes: Integer);
+var
+  strm: TZStreamRec;
+  P: Pointer;
+begin
+  FillChar(strm, sizeof(strm), 0);
+  strm.zalloc := zlibAllocMem;
+  strm.zfree := zlibFreeMem;
+  OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
+  GetMem(OutBuf, OutBytes);
+  try
+    strm.next_in := InBuf;
+    strm.avail_in := InBytes;
+    strm.next_out := OutBuf;
+    strm.avail_out := OutBytes;
+    CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)));
+    try
+      while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
+      begin
+        P := OutBuf;
+        Inc(OutBytes, 256);
+        ReallocMem(OutBuf, OutBytes);
+        strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+        strm.avail_out := 256;
+      end;
+    finally
+      CCheck(deflateEnd(strm));
+    end;
+    ReallocMem(OutBuf, strm.total_out);
+    OutBytes := strm.total_out;
+  except
+    FreeMem(OutBuf);
+    raise
+  end;
+end;
+
+
+procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+  OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
+var
+  strm: TZStreamRec;
+  P: Pointer;
+  BufInc: Integer;
+begin
+  FillChar(strm, sizeof(strm), 0);
+  strm.zalloc := zlibAllocMem;
+  strm.zfree := zlibFreeMem;
+  BufInc := (InBytes + 255) and not 255;
+  if OutEstimate = 0 then
+    OutBytes := BufInc
+  else
+    OutBytes := OutEstimate;
+  GetMem(OutBuf, OutBytes);
+  try
+    strm.next_in := InBuf;
+    strm.avail_in := InBytes;
+    strm.next_out := OutBuf;
+    strm.avail_out := OutBytes;
+    DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
+    try
+      while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
+      begin
+        P := OutBuf;
+        Inc(OutBytes, BufInc);
+        ReallocMem(OutBuf, OutBytes);
+        strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+        strm.avail_out := BufInc;
+      end;
+    finally
+      DCheck(inflateEnd(strm));
+    end;
+    ReallocMem(OutBuf, strm.total_out);
+    OutBytes := strm.total_out;
+  except
+    FreeMem(OutBuf);
+    raise
+  end;
+end;
+
+procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
+  const OutBuf: Pointer; BufSize: Integer);
+var
+  strm: TZStreamRec;
+begin
+  FillChar(strm, sizeof(strm), 0);
+  strm.zalloc := zlibAllocMem;
+  strm.zfree := zlibFreeMem;
+  strm.next_in := InBuf;
+  strm.avail_in := InBytes;
+  strm.next_out := OutBuf;
+  strm.avail_out := BufSize;
+  DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
+  try
+    if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then
+      raise EZlibError.CreateRes(@sTargetBufferTooSmall);
+  finally
+    DCheck(inflateEnd(strm));
+  end;
+end;
+
+// TCustomZlibStream
+
+constructor TCustomZLibStream.Create(Strm: TStream);
+begin
+  inherited Create;
+  FStrm := Strm;
+  FStrmPos := Strm.Position;
+  FZRec.zalloc := zlibAllocMem;
+  FZRec.zfree := zlibFreeMem;
+end;
+
+procedure TCustomZLibStream.Progress(Sender: TObject);
+begin
+  if Assigned(FOnProgress) then FOnProgress(Sender);
+end;
+
+
+// TCompressionStream
+
+constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
+  Dest: TStream);
+const
+  Levels: array [TCompressionLevel] of ShortInt =
+    (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
+begin
+  inherited Create(Dest);
+  FZRec.next_out := FBuffer;
+  FZRec.avail_out := sizeof(FBuffer);
+  CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));
+end;
+
+destructor TCompressionStream.Destroy;
+begin
+  FZRec.next_in := nil;
+  FZRec.avail_in := 0;
+  try
+    if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+    while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
+      and (FZRec.avail_out = 0) do
+    begin
+      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
+      FZRec.next_out := FBuffer;
+      FZRec.avail_out := sizeof(FBuffer);
+    end;
+    if FZRec.avail_out < sizeof(FBuffer) then
+      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
+  finally
+    deflateEnd(FZRec);
+  end;
+  inherited Destroy;
+end;
+
+function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
+begin
+  raise ECompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
+begin
+  FZRec.next_in := @Buffer;
+  FZRec.avail_in := Count;
+  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+  while (FZRec.avail_in > 0) do
+  begin
+    CCheck(deflate(FZRec, 0));
+    if FZRec.avail_out = 0 then
+    begin
+      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
+      FZRec.next_out := FBuffer;
+      FZRec.avail_out := sizeof(FBuffer);
+      FStrmPos := FStrm.Position;
+      Progress(Self);
+    end;
+  end;
+  Result := Count;
+end;
+
+function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+begin
+  if (Offset = 0) and (Origin = soFromCurrent) then
+    Result := FZRec.total_in
+  else
+    raise ECompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TCompressionStream.GetCompressionRate: Single;
+begin
+  if FZRec.total_in = 0 then
+    Result := 0
+  else
+    Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;
+end;
+
+
+// TDecompressionStream
+
+constructor TDecompressionStream.Create(Source: TStream);
+begin
+  inherited Create(Source);
+  FZRec.next_in := FBuffer;
+  FZRec.avail_in := 0;
+  DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));
+end;
+
+destructor TDecompressionStream.Destroy;
+begin
+  FStrm.Seek(-FZRec.avail_in, 1);
+  inflateEnd(FZRec);
+  inherited Destroy;
+end;
+
+function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
+begin
+  FZRec.next_out := @Buffer;
+  FZRec.avail_out := Count;
+  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+  while (FZRec.avail_out > 0) do
+  begin
+    if FZRec.avail_in = 0 then
+    begin
+      FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
+      if FZRec.avail_in = 0 then
+      begin
+        Result := Count - FZRec.avail_out;
+        Exit;
+      end;
+      FZRec.next_in := FBuffer;
+      FStrmPos := FStrm.Position;
+      Progress(Self);
+    end;
+    CCheck(inflate(FZRec, 0));
+  end;
+  Result := Count;
+end;
+
+function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
+begin
+  raise EDecompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+var
+  I: Integer;
+  Buf: array [0..4095] of Char;
+begin
+  if (Offset = 0) and (Origin = soFromBeginning) then
+  begin
+    DCheck(inflateReset(FZRec));
+    FZRec.next_in := FBuffer;
+    FZRec.avail_in := 0;
+    FStrm.Position := 0;
+    FStrmPos := 0;
+  end
+  else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
+          ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
+  begin
+    if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
+    if Offset > 0 then
+    begin
+      for I := 1 to Offset div sizeof(Buf) do
+        ReadBuffer(Buf, sizeof(Buf));
+      ReadBuffer(Buf, Offset mod sizeof(Buf));
+    end;
+  end
+  else
+    raise EDecompressionError.CreateRes(@sInvalidStreamOp);
+  Result := FZRec.total_out;
+end;
+
+
+end.
diff --git a/8.x/zlib/contrib/delphi/ZLibConst.pas b/8.x/zlib/contrib/delphi/ZLibConst.pas
new file mode 100644 (file)
index 0000000..cdfe136
--- /dev/null
@@ -0,0 +1,11 @@
+unit ZLibConst;
+
+interface
+
+resourcestring
+  sTargetBufferTooSmall = 'ZLib error: target buffer may be too small';
+  sInvalidStreamOp = 'Invalid stream operation';
+
+implementation
+
+end.
diff --git a/8.x/zlib/contrib/delphi/readme.txt b/8.x/zlib/contrib/delphi/readme.txt
new file mode 100644 (file)
index 0000000..2dc9a8b
--- /dev/null
@@ -0,0 +1,76 @@
+
+Overview
+========
+
+This directory contains an update to the ZLib interface unit,
+distributed by Borland as a Delphi supplemental component.
+
+The original ZLib unit is Copyright (c) 1997,99 Borland Corp.,
+and is based on zlib version 1.0.4.  There are a series of bugs
+and security problems associated with that old zlib version, and
+we recommend the users to update their ZLib unit.
+
+
+Summary of modifications
+========================
+
+- Improved makefile, adapted to zlib version 1.2.1.
+
+- Some field types from TZStreamRec are changed from Integer to
+  Longint, for consistency with the zlib.h header, and for 64-bit
+  readiness.
+
+- The zlib_version constant is updated.
+
+- The new Z_RLE strategy has its corresponding symbolic constant.
+
+- The allocation and deallocation functions and function types
+  (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl,
+  and _malloc and _free are added as C RTL stubs.  As a result,
+  the original C sources of zlib can be compiled out of the box,
+  and linked to the ZLib unit.
+
+
+Suggestions for improvements
+============================
+
+Currently, the ZLib unit provides only a limited wrapper around
+the zlib library, and much of the original zlib functionality is
+missing.  Handling compressed file formats like ZIP/GZIP or PNG
+cannot be implemented without having this functionality.
+Applications that handle these formats are either using their own,
+duplicated code, or not using the ZLib unit at all.
+
+Here are a few suggestions:
+
+- Checksum class wrappers around adler32() and crc32(), similar
+  to the Java classes that implement the java.util.zip.Checksum
+  interface.
+
+- The ability to read and write raw deflate streams, without the
+  zlib stream header and trailer.  Raw deflate streams are used
+  in the ZIP file format.
+
+- The ability to read and write gzip streams, used in the GZIP
+  file format, and normally produced by the gzip program.
+
+- The ability to select a different compression strategy, useful
+  to PNG and MNG image compression, and to multimedia compression
+  in general.  Besides the compression level
+
+    TCompressionLevel = (clNone, clFastest, clDefault, clMax);
+
+  which, in fact, could have used the 'z' prefix and avoided
+  TColor-like symbols
+
+    TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);
+
+  there could be a compression strategy
+
+    TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle);
+
+- ZIP and GZIP stream handling via TStreams.
+
+
+--
+Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/8.x/zlib/contrib/delphi/zlibd32.mak b/8.x/zlib/contrib/delphi/zlibd32.mak
new file mode 100644 (file)
index 0000000..0d0699a
--- /dev/null
@@ -0,0 +1,99 @@
+# Makefile for zlib
+# For use with Delphi and C++ Builder under Win32
+# Updated for zlib 1.2.x by Cosmin Truta
+
+# ------------ Borland C++ ------------
+
+# This project uses the Delphi (fastcall/register) calling convention:
+LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
+
+CC = bcc32
+LD = bcc32
+AR = tlib
+# do not use "-pr" in CFLAGS
+CFLAGS = -a -d -k- -O2 $(LOC)
+LDFLAGS =
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+       $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: example.c zlib.h zconf.h
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+       -del $(ZLIB_LIB)
+       $(AR) $(ZLIB_LIB) $(OBJP1)
+       $(AR) $(ZLIB_LIB) $(OBJP2)
+
+
+# testing
+test: example.exe minigzip.exe
+       example
+       echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+       -del *.obj
+       -del *.exe
+       -del *.lib
+       -del *.tds
+       -del zlib.bak
+       -del foo.gz
+
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib.build b/8.x/zlib/contrib/dotzlib/DotZLib.build
new file mode 100644 (file)
index 0000000..7f90d6b
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>\r
+<project name="DotZLib" default="build" basedir="./DotZLib">\r
+       <description>A .Net wrapper library around ZLib1.dll</description>\r
+\r
+       <property name="nunit.location" value="c:/program files/NUnit V2.1/bin" />\r
+       <property name="build.root" value="bin" />\r
+\r
+       <property name="debug" value="true" />\r
+       <property name="nunit" value="true" />\r
+\r
+       <property name="build.folder" value="${build.root}/debug/" if="${debug}" />\r
+       <property name="build.folder" value="${build.root}/release/" unless="${debug}" />\r
+\r
+       <target name="clean" description="Remove all generated files">\r
+               <delete dir="${build.root}" failonerror="false" />\r
+       </target>\r
+\r
+       <target name="build" description="compiles the source code">\r
+\r
+               <mkdir dir="${build.folder}" />\r
+               <csc target="library" output="${build.folder}DotZLib.dll" debug="${debug}">\r
+                       <references basedir="${nunit.location}">\r
+                               <includes if="${nunit}" name="nunit.framework.dll" />\r
+                       </references>\r
+                       <sources>\r
+                               <includes name="*.cs" />\r
+                               <excludes name="UnitTests.cs" unless="${nunit}" />\r
+                       </sources>\r
+                       <arg value="/d:nunit" if="${nunit}" />\r
+               </csc>\r
+       </target>\r
+\r
+</project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib.chm b/8.x/zlib/contrib/dotzlib/DotZLib.chm
new file mode 100644 (file)
index 0000000..f214a44
Binary files /dev/null and b/8.x/zlib/contrib/dotzlib/DotZLib.chm differ
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib.sln b/8.x/zlib/contrib/dotzlib/DotZLib.sln
new file mode 100644 (file)
index 0000000..ac45ca0
--- /dev/null
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+       EndProjectSection\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfiguration) = preSolution\r
+               Debug = Debug\r
+               Release = Release\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfiguration) = postSolution\r
+               {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET\r
+               {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET\r
+               {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET\r
+               {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityGlobals) = postSolution\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityAddIns) = postSolution\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/8.x/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..0491bfc
--- /dev/null
@@ -0,0 +1,58 @@
+using System.Reflection;\r
+using System.Runtime.CompilerServices;\r
+\r
+//\r
+// General Information about an assembly is controlled through the following\r
+// set of attributes. Change these attribute values to modify the information\r
+// associated with an assembly.\r
+//\r
+[assembly: AssemblyTitle("DotZLib")]\r
+[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")]\r
+[assembly: AssemblyConfiguration("")]\r
+[assembly: AssemblyCompany("Henrik Ravn")]\r
+[assembly: AssemblyProduct("")]\r
+[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")]\r
+[assembly: AssemblyTrademark("")]\r
+[assembly: AssemblyCulture("")]\r
+\r
+//\r
+// Version information for an assembly consists of the following four values:\r
+//\r
+//      Major Version\r
+//      Minor Version\r
+//      Build Number\r
+//      Revision\r
+//\r
+// You can specify all the values or you can default the Revision and Build Numbers\r
+// by using the '*' as shown below:\r
+\r
+[assembly: AssemblyVersion("1.0.*")]\r
+\r
+//\r
+// In order to sign your assembly you must specify a key to use. Refer to the\r
+// Microsoft .NET Framework documentation for more information on assembly signing.\r
+//\r
+// Use the attributes below to control which key is used for signing.\r
+//\r
+// Notes:\r
+//   (*) If no key is specified, the assembly is not signed.\r
+//   (*) KeyName refers to a key that has been installed in the Crypto Service\r
+//       Provider (CSP) on your machine. KeyFile refers to a file which contains\r
+//       a key.\r
+//   (*) If the KeyFile and the KeyName values are both specified, the\r
+//       following processing occurs:\r
+//       (1) If the KeyName can be found in the CSP, that key is used.\r
+//       (2) If the KeyName does not exist and the KeyFile does exist, the key\r
+//           in the KeyFile is installed into the CSP and used.\r
+//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.\r
+//       When specifying the KeyFile, the location of the KeyFile should be\r
+//       relative to the project output directory which is\r
+//       %Project Directory%\obj\<configuration>. For example, if your KeyFile is\r
+//       located in the project directory, you would specify the AssemblyKeyFile\r
+//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]\r
+//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework\r
+//       documentation for more information on this.\r
+//\r
+[assembly: AssemblyDelaySign(false)]\r
+[assembly: AssemblyKeyFile("")]\r
+[assembly: AssemblyKeyName("")]\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/8.x/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs
new file mode 100644 (file)
index 0000000..788b2fc
--- /dev/null
@@ -0,0 +1,202 @@
+//\r
+// © Copyright Henrik Ravn 2004\r
+//\r
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+\r
+using System;\r
+using System.Runtime.InteropServices;\r
+using System.Text;\r
+\r
+\r
+namespace DotZLib\r
+{\r
+    #region ChecksumGeneratorBase\r
+    /// <summary>\r
+    /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s\r
+    /// </summary>\r
+    /// <example></example>\r
+    public abstract class ChecksumGeneratorBase : ChecksumGenerator\r
+    {\r
+        /// <summary>\r
+        /// The value of the current checksum\r
+        /// </summary>\r
+        protected uint _current;\r
+\r
+        /// <summary>\r
+        /// Initializes a new instance of the checksum generator base - the current checksum is\r
+        /// set to zero\r
+        /// </summary>\r
+        public ChecksumGeneratorBase()\r
+        {\r
+            _current = 0;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Initializes a new instance of the checksum generator basewith a specified value\r
+        /// </summary>\r
+        /// <param name="initialValue">The value to set the current checksum to</param>\r
+        public ChecksumGeneratorBase(uint initialValue)\r
+        {\r
+            _current = initialValue;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Resets the current checksum to zero\r
+        /// </summary>\r
+        public void Reset() { _current = 0; }\r
+\r
+        /// <summary>\r
+        /// Gets the current checksum value\r
+        /// </summary>\r
+        public uint Value { get { return _current; } }\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with part of an array of bytes\r
+        /// </summary>\r
+        /// <param name="data">The data to update the checksum with</param>\r
+        /// <param name="offset">Where in <c>data</c> to start updating</param>\r
+        /// <param name="count">The number of bytes from <c>data</c> to use</param>\r
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>\r
+        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>\r
+        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>\r
+        /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.\r
+        /// This is therefore the only method a derived class has to implement</remarks>\r
+        public abstract void Update(byte[] data, int offset, int count);\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with an array of bytes.\r
+        /// </summary>\r
+        /// <param name="data">The data to update the checksum with</param>\r
+        public void Update(byte[] data)\r
+        {\r
+            Update(data, 0, data.Length);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with the data from a string\r
+        /// </summary>\r
+        /// <param name="data">The string to update the checksum with</param>\r
+        /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>\r
+        public void Update(string data)\r
+        {\r
+                       Update(Encoding.UTF8.GetBytes(data));\r
+        }\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with the data from a string, using a specific encoding\r
+        /// </summary>\r
+        /// <param name="data">The string to update the checksum with</param>\r
+        /// <param name="encoding">The encoding to use</param>\r
+        public void Update(string data, Encoding encoding)\r
+        {\r
+            Update(encoding.GetBytes(data));\r
+        }\r
+\r
+    }\r
+    #endregion\r
+\r
+    #region CRC32\r
+    /// <summary>\r
+    /// Implements a CRC32 checksum generator\r
+    /// </summary>\r
+    public sealed class CRC32Checksum : ChecksumGeneratorBase\r
+    {\r
+        #region DLL imports\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern uint crc32(uint crc, int data, uint length);\r
+\r
+        #endregion\r
+\r
+        /// <summary>\r
+        /// Initializes a new instance of the CRC32 checksum generator\r
+        /// </summary>\r
+        public CRC32Checksum() : base() {}\r
+\r
+        /// <summary>\r
+        /// Initializes a new instance of the CRC32 checksum generator with a specified value\r
+        /// </summary>\r
+        /// <param name="initialValue">The value to set the current checksum to</param>\r
+        public CRC32Checksum(uint initialValue) : base(initialValue) {}\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with part of an array of bytes\r
+        /// </summary>\r
+        /// <param name="data">The data to update the checksum with</param>\r
+        /// <param name="offset">Where in <c>data</c> to start updating</param>\r
+        /// <param name="count">The number of bytes from <c>data</c> to use</param>\r
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>\r
+        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>\r
+        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>\r
+        public override void Update(byte[] data, int offset, int count)\r
+        {\r
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\r
+            if ((offset+count) > data.Length) throw new ArgumentException();\r
+            GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);\r
+            try\r
+            {\r
+                _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);\r
+            }\r
+            finally\r
+            {\r
+                hData.Free();\r
+            }\r
+        }\r
+\r
+    }\r
+    #endregion\r
+\r
+    #region Adler\r
+    /// <summary>\r
+    /// Implements a checksum generator that computes the Adler checksum on data\r
+    /// </summary>\r
+    public sealed class AdlerChecksum : ChecksumGeneratorBase\r
+    {\r
+        #region DLL imports\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern uint adler32(uint adler, int data, uint length);\r
+\r
+        #endregion\r
+\r
+        /// <summary>\r
+        /// Initializes a new instance of the Adler checksum generator\r
+        /// </summary>\r
+        public AdlerChecksum() : base() {}\r
+\r
+        /// <summary>\r
+        /// Initializes a new instance of the Adler checksum generator with a specified value\r
+        /// </summary>\r
+        /// <param name="initialValue">The value to set the current checksum to</param>\r
+        public AdlerChecksum(uint initialValue) : base(initialValue) {}\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with part of an array of bytes\r
+        /// </summary>\r
+        /// <param name="data">The data to update the checksum with</param>\r
+        /// <param name="offset">Where in <c>data</c> to start updating</param>\r
+        /// <param name="count">The number of bytes from <c>data</c> to use</param>\r
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>\r
+        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>\r
+        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>\r
+        public override void Update(byte[] data, int offset, int count)\r
+        {\r
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\r
+            if ((offset+count) > data.Length) throw new ArgumentException();\r
+            GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);\r
+            try\r
+            {\r
+                _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);\r
+            }\r
+            finally\r
+            {\r
+                hData.Free();\r
+            }\r
+        }\r
+\r
+    }\r
+    #endregion\r
+\r
+}
\ No newline at end of file
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs b/8.x/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs
new file mode 100644 (file)
index 0000000..c1cab3a
--- /dev/null
@@ -0,0 +1,83 @@
+//\r
+// © Copyright Henrik Ravn 2004\r
+//\r
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+\r
+using System;\r
+using System.Diagnostics;\r
+\r
+namespace DotZLib\r
+{\r
+\r
+       /// <summary>\r
+       /// This class implements a circular buffer\r
+       /// </summary>\r
+       internal class CircularBuffer\r
+       {\r
+        #region Private data\r
+        private int _capacity;\r
+        private int _head;\r
+        private int _tail;\r
+        private int _size;\r
+        private byte[] _buffer;\r
+        #endregion\r
+\r
+        public CircularBuffer(int capacity)\r
+        {\r
+            Debug.Assert( capacity > 0 );\r
+            _buffer = new byte[capacity];\r
+            _capacity = capacity;\r
+            _head = 0;\r
+            _tail = 0;\r
+            _size = 0;\r
+        }\r
+\r
+        public int Size { get { return _size; } }\r
+\r
+        public int Put(byte[] source, int offset, int count)\r
+        {\r
+            Debug.Assert( count > 0 );\r
+            int trueCount = Math.Min(count, _capacity - Size);\r
+            for (int i = 0; i < trueCount; ++i)\r
+                _buffer[(_tail+i) % _capacity] = source[offset+i];\r
+            _tail += trueCount;\r
+            _tail %= _capacity;\r
+            _size += trueCount;\r
+            return trueCount;\r
+        }\r
+\r
+        public bool Put(byte b)\r
+        {\r
+            if (Size == _capacity) // no room\r
+                return false;\r
+            _buffer[_tail++] = b;\r
+            _tail %= _capacity;\r
+            ++_size;\r
+            return true;\r
+        }\r
+\r
+        public int Get(byte[] destination, int offset, int count)\r
+        {\r
+            int trueCount = Math.Min(count,Size);\r
+            for (int i = 0; i < trueCount; ++i)\r
+                destination[offset + i] = _buffer[(_head+i) % _capacity];\r
+            _head += trueCount;\r
+            _head %= _capacity;\r
+            _size -= trueCount;\r
+            return trueCount;\r
+        }\r
+\r
+        public int Get()\r
+        {\r
+            if (Size == 0)\r
+                return -1;\r
+\r
+            int result = (int)_buffer[_head++ % _capacity];\r
+            --_size;\r
+            return result;\r
+        }\r
+\r
+    }\r
+}\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/CodecBase.cs b/8.x/zlib/contrib/dotzlib/DotZLib/CodecBase.cs
new file mode 100644 (file)
index 0000000..42e6da3
--- /dev/null
@@ -0,0 +1,198 @@
+//\r
+// © Copyright Henrik Ravn 2004\r
+//\r
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+\r
+using System;\r
+using System.Runtime.InteropServices;\r
+\r
+namespace DotZLib\r
+{\r
+       /// <summary>\r
+       /// Implements the common functionality needed for all <see cref="Codec"/>s\r
+       /// </summary>\r
+       public abstract class CodecBase : Codec, IDisposable\r
+       {\r
+\r
+        #region Data members\r
+\r
+        /// <summary>\r
+        /// Instance of the internal zlib buffer structure that is\r
+        /// passed to all functions in the zlib dll\r
+        /// </summary>\r
+        internal ZStream _ztream = new ZStream();\r
+\r
+        /// <summary>\r
+        /// True if the object instance has been disposed, false otherwise\r
+        /// </summary>\r
+        protected bool _isDisposed = false;\r
+\r
+        /// <summary>\r
+        /// The size of the internal buffers\r
+        /// </summary>\r
+        protected const int kBufferSize = 16384;\r
+\r
+        private byte[] _outBuffer = new byte[kBufferSize];\r
+        private byte[] _inBuffer = new byte[kBufferSize];\r
+\r
+        private GCHandle _hInput;\r
+        private GCHandle _hOutput;\r
+\r
+        private uint _checksum = 0;\r
+\r
+        #endregion\r
+\r
+        /// <summary>\r
+        /// Initializes a new instance of the <c>CodeBase</c> class.\r
+        /// </summary>\r
+               public CodecBase()\r
+               {\r
+            try\r
+            {\r
+                _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);\r
+                _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);\r
+            }\r
+            catch (Exception)\r
+            {\r
+                CleanUp(false);\r
+                throw;\r
+            }\r
+        }\r
+\r
+\r
+        #region Codec Members\r
+\r
+        /// <summary>\r
+        /// Occurs when more processed data are available.\r
+        /// </summary>\r
+        public event DataAvailableHandler DataAvailable;\r
+\r
+        /// <summary>\r
+        /// Fires the <see cref="DataAvailable"/> event\r
+        /// </summary>\r
+        protected void OnDataAvailable()\r
+        {\r
+            if (_ztream.total_out > 0)\r
+            {\r
+                if (DataAvailable != null)\r
+                    DataAvailable( _outBuffer, 0, (int)_ztream.total_out);\r
+                resetOutput();\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Adds more data to the codec to be processed.\r
+        /// </summary>\r
+        /// <param name="data">Byte array containing the data to be added to the codec</param>\r
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\r
+        public void Add(byte[] data)\r
+        {\r
+            Add(data,0,data.Length);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Adds more data to the codec to be processed.\r
+        /// </summary>\r
+        /// <param name="data">Byte array containing the data to be added to the codec</param>\r
+        /// <param name="offset">The index of the first byte to add from <c>data</c></param>\r
+        /// <param name="count">The number of bytes to add</param>\r
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\r
+        /// <remarks>This must be implemented by a derived class</remarks>\r
+        public abstract void Add(byte[] data, int offset, int count);\r
+\r
+        /// <summary>\r
+        /// Finishes up any pending data that needs to be processed and handled.\r
+        /// </summary>\r
+        /// <remarks>This must be implemented by a derived class</remarks>\r
+        public abstract void Finish();\r
+\r
+        /// <summary>\r
+        /// Gets the checksum of the data that has been added so far\r
+        /// </summary>\r
+        public uint Checksum { get { return _checksum; } }\r
+\r
+        #endregion\r
+\r
+        #region Destructor & IDisposable stuff\r
+\r
+        /// <summary>\r
+        /// Destroys this instance\r
+        /// </summary>\r
+        ~CodecBase()\r
+        {\r
+            CleanUp(false);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class\r
+        /// </summary>\r
+        public void Dispose()\r
+        {\r
+            CleanUp(true);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Performs any codec specific cleanup\r
+        /// </summary>\r
+        /// <remarks>This must be implemented by a derived class</remarks>\r
+        protected abstract void CleanUp();\r
+\r
+        // performs the release of the handles and calls the dereived CleanUp()\r
+        private void CleanUp(bool isDisposing)\r
+        {\r
+            if (!_isDisposed)\r
+            {\r
+                CleanUp();\r
+                if (_hInput.IsAllocated)\r
+                    _hInput.Free();\r
+                if (_hOutput.IsAllocated)\r
+                    _hOutput.Free();\r
+\r
+                _isDisposed = true;\r
+            }\r
+        }\r
+\r
+\r
+        #endregion\r
+\r
+        #region Helper methods\r
+\r
+        /// <summary>\r
+        /// Copies a number of bytes to the internal codec buffer - ready for proccesing\r
+        /// </summary>\r
+        /// <param name="data">The byte array that contains the data to copy</param>\r
+        /// <param name="startIndex">The index of the first byte to copy</param>\r
+        /// <param name="count">The number of bytes to copy from <c>data</c></param>\r
+        protected void copyInput(byte[] data, int startIndex, int count)\r
+        {\r
+            Array.Copy(data, startIndex, _inBuffer,0, count);\r
+            _ztream.next_in = _hInput.AddrOfPinnedObject();\r
+            _ztream.total_in = 0;\r
+            _ztream.avail_in = (uint)count;\r
+\r
+        }\r
+\r
+        /// <summary>\r
+        /// Resets the internal output buffers to a known state - ready for processing\r
+        /// </summary>\r
+        protected void resetOutput()\r
+        {\r
+            _ztream.total_out = 0;\r
+            _ztream.avail_out = kBufferSize;\r
+            _ztream.next_out = _hOutput.AddrOfPinnedObject();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Updates the running checksum property\r
+        /// </summary>\r
+        /// <param name="newSum">The new checksum value</param>\r
+        protected void setChecksum(uint newSum)\r
+        {\r
+            _checksum = newSum;\r
+        }\r
+        #endregion\r
+\r
+    }\r
+}\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/Deflater.cs b/8.x/zlib/contrib/dotzlib/DotZLib/Deflater.cs
new file mode 100644 (file)
index 0000000..c247792
--- /dev/null
@@ -0,0 +1,106 @@
+//\r
+// © Copyright Henrik Ravn 2004\r
+//\r
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+\r
+using System;\r
+using System.Diagnostics;\r
+using System.Runtime.InteropServices;\r
+\r
+namespace DotZLib\r
+{\r
+\r
+    /// <summary>\r
+    /// Implements a data compressor, using the deflate algorithm in the ZLib dll\r
+    /// </summary>\r
+       public sealed class Deflater : CodecBase\r
+       {\r
+        #region Dll imports\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]\r
+        private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int deflate(ref ZStream sz, int flush);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int deflateReset(ref ZStream sz);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int deflateEnd(ref ZStream sz);\r
+        #endregion\r
+\r
+        /// <summary>\r
+        /// Constructs an new instance of the <c>Deflater</c>\r
+        /// </summary>\r
+        /// <param name="level">The compression level to use for this <c>Deflater</c></param>\r
+               public Deflater(CompressLevel level) : base()\r
+               {\r
+            int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));\r
+            if (retval != 0)\r
+                throw new ZLibException(retval, "Could not initialize deflater");\r
+\r
+            resetOutput();\r
+               }\r
+\r
+        /// <summary>\r
+        /// Adds more data to the codec to be processed.\r
+        /// </summary>\r
+        /// <param name="data">Byte array containing the data to be added to the codec</param>\r
+        /// <param name="offset">The index of the first byte to add from <c>data</c></param>\r
+        /// <param name="count">The number of bytes to add</param>\r
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\r
+        public override void Add(byte[] data, int offset, int count)\r
+        {\r
+            if (data == null) throw new ArgumentNullException();\r
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\r
+            if ((offset+count) > data.Length) throw new ArgumentException();\r
+\r
+            int total = count;\r
+            int inputIndex = offset;\r
+            int err = 0;\r
+\r
+            while (err >= 0 && inputIndex < total)\r
+            {\r
+                copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));\r
+                while (err >= 0 && _ztream.avail_in > 0)\r
+                {\r
+                    err = deflate(ref _ztream, (int)FlushTypes.None);\r
+                    if (err == 0)\r
+                        while (_ztream.avail_out == 0)\r
+                        {\r
+                            OnDataAvailable();\r
+                            err = deflate(ref _ztream, (int)FlushTypes.None);\r
+                        }\r
+                    inputIndex += (int)_ztream.total_in;\r
+                }\r
+            }\r
+            setChecksum( _ztream.adler );\r
+        }\r
+\r
+\r
+        /// <summary>\r
+        /// Finishes up any pending data that needs to be processed and handled.\r
+        /// </summary>\r
+        public override void Finish()\r
+        {\r
+            int err;\r
+            do\r
+            {\r
+                err = deflate(ref _ztream, (int)FlushTypes.Finish);\r
+                OnDataAvailable();\r
+            }\r
+            while (err == 0);\r
+            setChecksum( _ztream.adler );\r
+            deflateReset(ref _ztream);\r
+            resetOutput();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Closes the internal zlib deflate stream\r
+        /// </summary>\r
+        protected override void CleanUp() { deflateEnd(ref _ztream); }\r
+\r
+    }\r
+}\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/DotZLib.cs b/8.x/zlib/contrib/dotzlib/DotZLib/DotZLib.cs
new file mode 100644 (file)
index 0000000..be184b4
--- /dev/null
@@ -0,0 +1,288 @@
+//\r
+// © Copyright Henrik Ravn 2004\r
+//\r
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+\r
+using System;\r
+using System.IO;\r
+using System.Runtime.InteropServices;\r
+using System.Text;\r
+\r
+\r
+namespace DotZLib\r
+{\r
+\r
+    #region Internal types\r
+\r
+    /// <summary>\r
+    /// Defines constants for the various flush types used with zlib\r
+    /// </summary>\r
+    internal enum FlushTypes\r
+    {\r
+        None,  Partial,  Sync,  Full,  Finish,  Block\r
+    }\r
+\r
+    #region ZStream structure\r
+    // internal mapping of the zlib zstream structure for marshalling\r
+    [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]\r
+    internal struct ZStream\r
+    {\r
+        public IntPtr next_in;\r
+        public uint avail_in;\r
+        public uint total_in;\r
+\r
+        public IntPtr next_out;\r
+        public uint avail_out;\r
+        public uint total_out;\r
+\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        string msg;\r
+        uint state;\r
+\r
+        uint zalloc;\r
+        uint zfree;\r
+        uint opaque;\r
+\r
+        int data_type;\r
+        public uint adler;\r
+        uint reserved;\r
+    }\r
+\r
+    #endregion\r
+\r
+    #endregion\r
+\r
+    #region Public enums\r
+    /// <summary>\r
+    /// Defines constants for the available compression levels in zlib\r
+    /// </summary>\r
+    public enum CompressLevel : int\r
+    {\r
+        /// <summary>\r
+        /// The default compression level with a reasonable compromise between compression and speed\r
+        /// </summary>\r
+        Default = -1,\r
+        /// <summary>\r
+        /// No compression at all. The data are passed straight through.\r
+        /// </summary>\r
+        None = 0,\r
+        /// <summary>\r
+        /// The maximum compression rate available.\r
+        /// </summary>\r
+        Best = 9,\r
+        /// <summary>\r
+        /// The fastest available compression level.\r
+        /// </summary>\r
+        Fastest = 1\r
+    }\r
+    #endregion\r
+\r
+    #region Exception classes\r
+    /// <summary>\r
+    /// The exception that is thrown when an error occurs on the zlib dll\r
+    /// </summary>\r
+    public class ZLibException : ApplicationException\r
+    {\r
+        /// <summary>\r
+        /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified\r
+        /// error message and error code\r
+        /// </summary>\r
+        /// <param name="errorCode">The zlib error code that caused the exception</param>\r
+        /// <param name="msg">A message that (hopefully) describes the error</param>\r
+        public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))\r
+        {\r
+        }\r
+\r
+        /// <summary>\r
+        /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified\r
+        /// error code\r
+        /// </summary>\r
+        /// <param name="errorCode">The zlib error code that caused the exception</param>\r
+        public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))\r
+        {\r
+        }\r
+    }\r
+    #endregion\r
+\r
+    #region Interfaces\r
+\r
+    /// <summary>\r
+    /// Declares methods and properties that enables a running checksum to be calculated\r
+    /// </summary>\r
+    public interface ChecksumGenerator\r
+    {\r
+        /// <summary>\r
+        /// Gets the current value of the checksum\r
+        /// </summary>\r
+        uint Value { get; }\r
+\r
+        /// <summary>\r
+        /// Clears the current checksum to 0\r
+        /// </summary>\r
+        void Reset();\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with an array of bytes\r
+        /// </summary>\r
+        /// <param name="data">The data to update the checksum with</param>\r
+        void Update(byte[] data);\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with part of an array of bytes\r
+        /// </summary>\r
+        /// <param name="data">The data to update the checksum with</param>\r
+        /// <param name="offset">Where in <c>data</c> to start updating</param>\r
+        /// <param name="count">The number of bytes from <c>data</c> to use</param>\r
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>\r
+        /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>\r
+        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>\r
+        void Update(byte[] data, int offset, int count);\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with the data from a string\r
+        /// </summary>\r
+        /// <param name="data">The string to update the checksum with</param>\r
+        /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>\r
+        void Update(string data);\r
+\r
+        /// <summary>\r
+        /// Updates the current checksum with the data from a string, using a specific encoding\r
+        /// </summary>\r
+        /// <param name="data">The string to update the checksum with</param>\r
+        /// <param name="encoding">The encoding to use</param>\r
+        void Update(string data, Encoding encoding);\r
+    }\r
+\r
+\r
+    /// <summary>\r
+    /// Represents the method that will be called from a codec when new data\r
+    /// are available.\r
+    /// </summary>\r
+    /// <paramref name="data">The byte array containing the processed data</paramref>\r
+    /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>\r
+    /// <paramref name="count">The number of processed bytes available</paramref>\r
+    /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.\r
+    /// You cannot assume that startIndex will be zero.\r
+    /// </remarks>\r
+    public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);\r
+\r
+    /// <summary>\r
+    /// Declares methods and events for implementing compressors/decompressors\r
+    /// </summary>\r
+    public interface Codec\r
+    {\r
+        /// <summary>\r
+        /// Occurs when more processed data are available.\r
+        /// </summary>\r
+        event DataAvailableHandler DataAvailable;\r
+\r
+        /// <summary>\r
+        /// Adds more data to the codec to be processed.\r
+        /// </summary>\r
+        /// <param name="data">Byte array containing the data to be added to the codec</param>\r
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\r
+        void Add(byte[] data);\r
+\r
+        /// <summary>\r
+        /// Adds more data to the codec to be processed.\r
+        /// </summary>\r
+        /// <param name="data">Byte array containing the data to be added to the codec</param>\r
+        /// <param name="offset">The index of the first byte to add from <c>data</c></param>\r
+        /// <param name="count">The number of bytes to add</param>\r
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\r
+        void Add(byte[] data, int offset, int count);\r
+\r
+        /// <summary>\r
+        /// Finishes up any pending data that needs to be processed and handled.\r
+        /// </summary>\r
+        void Finish();\r
+\r
+        /// <summary>\r
+        /// Gets the checksum of the data that has been added so far\r
+        /// </summary>\r
+        uint Checksum { get; }\r
+\r
+\r
+    }\r
+\r
+    #endregion\r
+\r
+    #region Classes\r
+    /// <summary>\r
+    /// Encapsulates general information about the ZLib library\r
+    /// </summary>\r
+    public class Info\r
+    {\r
+        #region DLL imports\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern uint zlibCompileFlags();\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern string zlibVersion();\r
+        #endregion\r
+\r
+        #region Private stuff\r
+        private uint _flags;\r
+\r
+        // helper function that unpacks a bitsize mask\r
+        private static int bitSize(uint bits)\r
+        {\r
+            switch (bits)\r
+            {\r
+                case 0: return 16;\r
+                case 1: return 32;\r
+                case 2: return 64;\r
+            }\r
+            return -1;\r
+        }\r
+        #endregion\r
+\r
+        /// <summary>\r
+        /// Constructs an instance of the <c>Info</c> class.\r
+        /// </summary>\r
+        public Info()\r
+        {\r
+            _flags = zlibCompileFlags();\r
+        }\r
+\r
+        /// <summary>\r
+        /// True if the library is compiled with debug info\r
+        /// </summary>\r
+        public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }\r
+\r
+        /// <summary>\r
+        /// True if the library is compiled with assembly optimizations\r
+        /// </summary>\r
+        public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }\r
+\r
+        /// <summary>\r
+        /// Gets the size of the unsigned int that was compiled into Zlib\r
+        /// </summary>\r
+        public int SizeOfUInt { get { return bitSize(_flags & 3); } }\r
+\r
+        /// <summary>\r
+        /// Gets the size of the unsigned long that was compiled into Zlib\r
+        /// </summary>\r
+        public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }\r
+\r
+        /// <summary>\r
+        /// Gets the size of the pointers that were compiled into Zlib\r
+        /// </summary>\r
+        public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }\r
+\r
+        /// <summary>\r
+        /// Gets the size of the z_off_t type that was compiled into Zlib\r
+        /// </summary>\r
+        public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }\r
+\r
+        /// <summary>\r
+        /// Gets the version of ZLib as a string, e.g. "1.2.1"\r
+        /// </summary>\r
+        public static string Version { get { return zlibVersion(); } }\r
+    }\r
+\r
+    #endregion\r
+\r
+}\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj b/8.x/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj
new file mode 100644 (file)
index 0000000..71eeb85
--- /dev/null
@@ -0,0 +1,141 @@
+<VisualStudioProject>\r
+    <CSHARP\r
+        ProjectType = "Local"\r
+        ProductVersion = "7.10.3077"\r
+        SchemaVersion = "2.0"\r
+        ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"\r
+    >\r
+        <Build>\r
+            <Settings\r
+                ApplicationIcon = ""\r
+                AssemblyKeyContainerName = ""\r
+                AssemblyName = "DotZLib"\r
+                AssemblyOriginatorKeyFile = ""\r
+                DefaultClientScript = "JScript"\r
+                DefaultHTMLPageLayout = "Grid"\r
+                DefaultTargetSchema = "IE50"\r
+                DelaySign = "false"\r
+                OutputType = "Library"\r
+                PreBuildEvent = ""\r
+                PostBuildEvent = ""\r
+                RootNamespace = "DotZLib"\r
+                RunPostBuildEvent = "OnBuildSuccess"\r
+                StartupObject = ""\r
+            >\r
+                <Config\r
+                    Name = "Debug"\r
+                    AllowUnsafeBlocks = "false"\r
+                    BaseAddress = "285212672"\r
+                    CheckForOverflowUnderflow = "false"\r
+                    ConfigurationOverrideFile = ""\r
+                    DefineConstants = "DEBUG;TRACE"\r
+                    DocumentationFile = "docs\DotZLib.xml"\r
+                    DebugSymbols = "true"\r
+                    FileAlignment = "4096"\r
+                    IncrementalBuild = "false"\r
+                    NoStdLib = "false"\r
+                    NoWarn = "1591"\r
+                    Optimize = "false"\r
+                    OutputPath = "bin\Debug\"\r
+                    RegisterForComInterop = "false"\r
+                    RemoveIntegerChecks = "false"\r
+                    TreatWarningsAsErrors = "false"\r
+                    WarningLevel = "4"\r
+                />\r
+                <Config\r
+                    Name = "Release"\r
+                    AllowUnsafeBlocks = "false"\r
+                    BaseAddress = "285212672"\r
+                    CheckForOverflowUnderflow = "false"\r
+                    ConfigurationOverrideFile = ""\r
+                    DefineConstants = "TRACE"\r
+                    DocumentationFile = "docs\DotZLib.xml"\r
+                    DebugSymbols = "false"\r
+                    FileAlignment = "4096"\r
+                    IncrementalBuild = "false"\r
+                    NoStdLib = "false"\r
+                    NoWarn = ""\r
+                    Optimize = "true"\r
+                    OutputPath = "bin\Release\"\r
+                    RegisterForComInterop = "false"\r
+                    RemoveIntegerChecks = "false"\r
+                    TreatWarningsAsErrors = "false"\r
+                    WarningLevel = "4"\r
+                />\r
+            </Settings>\r
+            <References>\r
+                <Reference\r
+                    Name = "System"\r
+                    AssemblyName = "System"\r
+                    HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll"\r
+                />\r
+                <Reference\r
+                    Name = "System.Data"\r
+                    AssemblyName = "System.Data"\r
+                    HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"\r
+                />\r
+                <Reference\r
+                    Name = "System.XML"\r
+                    AssemblyName = "System.Xml"\r
+                    HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"\r
+                />\r
+                <Reference\r
+                    Name = "nunit.framework"\r
+                    AssemblyName = "nunit.framework"\r
+                    HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll"\r
+                    AssemblyFolderKey = "hklm\dn\nunit.framework"\r
+                />\r
+            </References>\r
+        </Build>\r
+        <Files>\r
+            <Include>\r
+                <File\r
+                    RelPath = "AssemblyInfo.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "ChecksumImpl.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "CircularBuffer.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "CodecBase.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "Deflater.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "DotZLib.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "GZipStream.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "Inflater.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "UnitTests.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+            </Include>\r
+        </Files>\r
+    </CSHARP>\r
+</VisualStudioProject>\r
+\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/GZipStream.cs b/8.x/zlib/contrib/dotzlib/DotZLib/GZipStream.cs
new file mode 100644 (file)
index 0000000..b161300
--- /dev/null
@@ -0,0 +1,301 @@
+//\r
+// © Copyright Henrik Ravn 2004\r
+//\r
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+\r
+using System;\r
+using System.IO;\r
+using System.Runtime.InteropServices;\r
+\r
+namespace DotZLib\r
+{\r
+       /// <summary>\r
+       /// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.\r
+       /// </summary>\r
+       public class GZipStream : Stream, IDisposable\r
+       {\r
+        #region Dll Imports\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]\r
+        private static extern IntPtr gzopen(string name, string mode);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int gzclose(IntPtr gzFile);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int gzwrite(IntPtr gzFile, int data, int length);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int gzread(IntPtr gzFile, int data, int length);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int gzgetc(IntPtr gzFile);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int gzputc(IntPtr gzFile, int c);\r
+\r
+        #endregion\r
+\r
+        #region Private data\r
+        private IntPtr _gzFile;\r
+        private bool _isDisposed = false;\r
+        private bool _isWriting;\r
+        #endregion\r
+\r
+        #region Constructors\r
+        /// <summary>\r
+        /// Creates a new file as a writeable GZipStream\r
+        /// </summary>\r
+        /// <param name="fileName">The name of the compressed file to create</param>\r
+        /// <param name="level">The compression level to use when adding data</param>\r
+        /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>\r
+               public GZipStream(string fileName, CompressLevel level)\r
+               {\r
+            _isWriting = true;\r
+            _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));\r
+            if (_gzFile == IntPtr.Zero)\r
+                throw new ZLibException(-1, "Could not open " + fileName);\r
+               }\r
+\r
+        /// <summary>\r
+        /// Opens an existing file as a readable GZipStream\r
+        /// </summary>\r
+        /// <param name="fileName">The name of the file to open</param>\r
+        /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>\r
+        public GZipStream(string fileName)\r
+        {\r
+            _isWriting = false;\r
+            _gzFile = gzopen(fileName, "rb");\r
+            if (_gzFile == IntPtr.Zero)\r
+                throw new ZLibException(-1, "Could not open " + fileName);\r
+\r
+        }\r
+        #endregion\r
+\r
+        #region Access properties\r
+        /// <summary>\r
+        /// Returns true of this stream can be read from, false otherwise\r
+        /// </summary>\r
+        public override bool CanRead\r
+        {\r
+            get\r
+            {\r
+                return !_isWriting;\r
+            }\r
+        }\r
+\r
+\r
+        /// <summary>\r
+        /// Returns false.\r
+        /// </summary>\r
+        public override bool CanSeek\r
+        {\r
+            get\r
+            {\r
+                return false;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Returns true if this tsream is writeable, false otherwise\r
+        /// </summary>\r
+        public override bool CanWrite\r
+        {\r
+            get\r
+            {\r
+                return _isWriting;\r
+            }\r
+        }\r
+        #endregion\r
+\r
+        #region Destructor & IDispose stuff\r
+\r
+        /// <summary>\r
+        /// Destroys this instance\r
+        /// </summary>\r
+        ~GZipStream()\r
+        {\r
+            cleanUp(false);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Closes the external file handle\r
+        /// </summary>\r
+        public void Dispose()\r
+        {\r
+            cleanUp(true);\r
+        }\r
+\r
+        // Does the actual closing of the file handle.\r
+        private void cleanUp(bool isDisposing)\r
+        {\r
+            if (!_isDisposed)\r
+            {\r
+                gzclose(_gzFile);\r
+                _isDisposed = true;\r
+            }\r
+        }\r
+        #endregion\r
+\r
+        #region Basic reading and writing\r
+        /// <summary>\r
+        /// Attempts to read a number of bytes from the stream.\r
+        /// </summary>\r
+        /// <param name="buffer">The destination data buffer</param>\r
+        /// <param name="offset">The index of the first destination byte in <c>buffer</c></param>\r
+        /// <param name="count">The number of bytes requested</param>\r
+        /// <returns>The number of bytes read</returns>\r
+        /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>\r
+        /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>\r
+        /// <exception cref="ArgumentException">If <c>offset</c>  + <c>count</c> is &gt; buffer.Length</exception>\r
+        /// <exception cref="NotSupportedException">If this stream is not readable.</exception>\r
+        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>\r
+        public override int Read(byte[] buffer, int offset, int count)\r
+        {\r
+            if (!CanRead) throw new NotSupportedException();\r
+            if (buffer == null) throw new ArgumentNullException();\r
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\r
+            if ((offset+count) > buffer.Length) throw new ArgumentException();\r
+            if (_isDisposed) throw new ObjectDisposedException("GZipStream");\r
+\r
+            GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);\r
+            int result;\r
+            try\r
+            {\r
+                result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);\r
+                if (result < 0)\r
+                    throw new IOException();\r
+            }\r
+            finally\r
+            {\r
+                h.Free();\r
+            }\r
+            return result;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Attempts to read a single byte from the stream.\r
+        /// </summary>\r
+        /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>\r
+        public override int ReadByte()\r
+        {\r
+            if (!CanRead) throw new NotSupportedException();\r
+            if (_isDisposed) throw new ObjectDisposedException("GZipStream");\r
+            return gzgetc(_gzFile);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Writes a number of bytes to the stream\r
+        /// </summary>\r
+        /// <param name="buffer"></param>\r
+        /// <param name="offset"></param>\r
+        /// <param name="count"></param>\r
+        /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>\r
+        /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>\r
+        /// <exception cref="ArgumentException">If <c>offset</c>  + <c>count</c> is &gt; buffer.Length</exception>\r
+        /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>\r
+        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>\r
+        public override void Write(byte[] buffer, int offset, int count)\r
+        {\r
+            if (!CanWrite) throw new NotSupportedException();\r
+            if (buffer == null) throw new ArgumentNullException();\r
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\r
+            if ((offset+count) > buffer.Length) throw new ArgumentException();\r
+            if (_isDisposed) throw new ObjectDisposedException("GZipStream");\r
+\r
+            GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);\r
+            try\r
+            {\r
+                int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);\r
+                if (result < 0)\r
+                    throw new IOException();\r
+            }\r
+            finally\r
+            {\r
+                h.Free();\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Writes a single byte to the stream\r
+        /// </summary>\r
+        /// <param name="value">The byte to add to the stream.</param>\r
+        /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>\r
+        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>\r
+        public override void WriteByte(byte value)\r
+        {\r
+            if (!CanWrite) throw new NotSupportedException();\r
+            if (_isDisposed) throw new ObjectDisposedException("GZipStream");\r
+\r
+            int result = gzputc(_gzFile, (int)value);\r
+            if (result < 0)\r
+                throw new IOException();\r
+        }\r
+        #endregion\r
+\r
+        #region Position & length stuff\r
+        /// <summary>\r
+        /// Not supported.\r
+        /// </summary>\r
+        /// <param name="value"></param>\r
+        /// <exception cref="NotSupportedException">Always thrown</exception>\r
+        public override void SetLength(long value)\r
+        {\r
+            throw new NotSupportedException();\r
+        }\r
+\r
+        /// <summary>\r
+        ///  Not suppported.\r
+        /// </summary>\r
+        /// <param name="offset"></param>\r
+        /// <param name="origin"></param>\r
+        /// <returns></returns>\r
+        /// <exception cref="NotSupportedException">Always thrown</exception>\r
+        public override long Seek(long offset, SeekOrigin origin)\r
+        {\r
+            throw new NotSupportedException();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Flushes the <c>GZipStream</c>.\r
+        /// </summary>\r
+        /// <remarks>In this implementation, this method does nothing. This is because excessive\r
+        /// flushing may degrade the achievable compression rates.</remarks>\r
+        public override void Flush()\r
+        {\r
+            // left empty on purpose\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.\r
+        /// </summary>\r
+        /// <remarks>In this implementation this property is not supported</remarks>\r
+        /// <exception cref="NotSupportedException">Always thrown</exception>\r
+        public override long Position\r
+        {\r
+            get\r
+            {\r
+                throw new NotSupportedException();\r
+            }\r
+            set\r
+            {\r
+                throw new NotSupportedException();\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets the size of the stream. Not suppported.\r
+        /// </summary>\r
+        /// <remarks>In this implementation this property is not supported</remarks>\r
+        /// <exception cref="NotSupportedException">Always thrown</exception>\r
+        public override long Length\r
+        {\r
+            get\r
+            {\r
+                throw new NotSupportedException();\r
+            }\r
+        }\r
+        #endregion\r
+    }\r
+}\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/Inflater.cs b/8.x/zlib/contrib/dotzlib/DotZLib/Inflater.cs
new file mode 100644 (file)
index 0000000..8ed5451
--- /dev/null
@@ -0,0 +1,105 @@
+//\r
+// © Copyright Henrik Ravn 2004\r
+//\r
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+\r
+using System;\r
+using System.Diagnostics;\r
+using System.Runtime.InteropServices;\r
+\r
+namespace DotZLib\r
+{\r
+\r
+    /// <summary>\r
+    /// Implements a data decompressor, using the inflate algorithm in the ZLib dll\r
+    /// </summary>\r
+    public class Inflater : CodecBase\r
+       {\r
+        #region Dll imports\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]\r
+        private static extern int inflateInit_(ref ZStream sz, string vs, int size);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int inflate(ref ZStream sz, int flush);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int inflateReset(ref ZStream sz);\r
+\r
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]\r
+        private static extern int inflateEnd(ref ZStream sz);\r
+        #endregion\r
+\r
+        /// <summary>\r
+        /// Constructs an new instance of the <c>Inflater</c>\r
+        /// </summary>\r
+        public Inflater() : base()\r
+               {\r
+            int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));\r
+            if (retval != 0)\r
+                throw new ZLibException(retval, "Could not initialize inflater");\r
+\r
+            resetOutput();\r
+        }\r
+\r
+\r
+        /// <summary>\r
+        /// Adds more data to the codec to be processed.\r
+        /// </summary>\r
+        /// <param name="data">Byte array containing the data to be added to the codec</param>\r
+        /// <param name="offset">The index of the first byte to add from <c>data</c></param>\r
+        /// <param name="count">The number of bytes to add</param>\r
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\r
+        public override void Add(byte[] data, int offset, int count)\r
+        {\r
+            if (data == null) throw new ArgumentNullException();\r
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();\r
+            if ((offset+count) > data.Length) throw new ArgumentException();\r
+\r
+            int total = count;\r
+            int inputIndex = offset;\r
+            int err = 0;\r
+\r
+            while (err >= 0 && inputIndex < total)\r
+            {\r
+                copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));\r
+                err = inflate(ref _ztream, (int)FlushTypes.None);\r
+                if (err == 0)\r
+                    while (_ztream.avail_out == 0)\r
+                    {\r
+                        OnDataAvailable();\r
+                        err = inflate(ref _ztream, (int)FlushTypes.None);\r
+                    }\r
+\r
+                inputIndex += (int)_ztream.total_in;\r
+            }\r
+            setChecksum( _ztream.adler );\r
+        }\r
+\r
+\r
+        /// <summary>\r
+        /// Finishes up any pending data that needs to be processed and handled.\r
+        /// </summary>\r
+        public override void Finish()\r
+        {\r
+            int err;\r
+            do\r
+            {\r
+                err = inflate(ref _ztream, (int)FlushTypes.Finish);\r
+                OnDataAvailable();\r
+            }\r
+            while (err == 0);\r
+            setChecksum( _ztream.adler );\r
+            inflateReset(ref _ztream);\r
+            resetOutput();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Closes the internal zlib inflate stream\r
+        /// </summary>\r
+        protected override void CleanUp() { inflateEnd(ref _ztream); }\r
+\r
+\r
+       }\r
+}\r
diff --git a/8.x/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/8.x/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
new file mode 100644 (file)
index 0000000..3bbcc8c
--- /dev/null
@@ -0,0 +1,274 @@
+//\r
+// © Copyright Henrik Ravn 2004\r
+//\r
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+\r
+using System;\r
+using System.Collections;\r
+using System.IO;\r
+\r
+// uncomment the define below to include unit tests\r
+//#define nunit\r
+#if nunit\r
+using NUnit.Framework;\r
+\r
+// Unit tests for the DotZLib class library\r
+// ----------------------------------------\r
+//\r
+// Use this with NUnit 2 from http://www.nunit.org\r
+//\r
+\r
+namespace DotZLibTests\r
+{\r
+    using DotZLib;\r
+\r
+    // helper methods\r
+    internal class Utils\r
+    {\r
+        public static bool byteArrEqual( byte[] lhs, byte[] rhs )\r
+        {\r
+            if (lhs.Length != rhs.Length)\r
+                return false;\r
+            for (int i = lhs.Length-1; i >= 0; --i)\r
+                if (lhs[i] != rhs[i])\r
+                    return false;\r
+            return true;\r
+        }\r
+\r
+    }\r
+\r
+\r
+    [TestFixture]\r
+    public class CircBufferTests\r
+    {\r
+        #region Circular buffer tests\r
+        [Test]\r
+        public void SinglePutGet()\r
+        {\r
+            CircularBuffer buf = new CircularBuffer(10);\r
+            Assert.AreEqual( 0, buf.Size );\r
+            Assert.AreEqual( -1, buf.Get() );\r
+\r
+            Assert.IsTrue(buf.Put( 1 ));\r
+            Assert.AreEqual( 1, buf.Size );\r
+            Assert.AreEqual( 1, buf.Get() );\r
+            Assert.AreEqual( 0, buf.Size );\r
+            Assert.AreEqual( -1, buf.Get() );\r
+        }\r
+\r
+        [Test]\r
+        public void BlockPutGet()\r
+        {\r
+            CircularBuffer buf = new CircularBuffer(10);\r
+            byte[] arr = {1,2,3,4,5,6,7,8,9,10};\r
+            Assert.AreEqual( 10, buf.Put(arr,0,10) );\r
+            Assert.AreEqual( 10, buf.Size );\r
+            Assert.IsFalse( buf.Put(11) );\r
+            Assert.AreEqual( 1, buf.Get() );\r
+            Assert.IsTrue( buf.Put(11) );\r
+\r
+            byte[] arr2 = (byte[])arr.Clone();\r
+            Assert.AreEqual( 9, buf.Get(arr2,1,9) );\r
+            Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );\r
+        }\r
+\r
+        #endregion\r
+    }\r
+\r
+    [TestFixture]\r
+    public class ChecksumTests\r
+    {\r
+        #region CRC32 Tests\r
+        [Test]\r
+        public void CRC32_Null()\r
+        {\r
+            CRC32Checksum crc32 = new CRC32Checksum();\r
+            Assert.AreEqual( 0, crc32.Value );\r
+\r
+            crc32 = new CRC32Checksum(1);\r
+            Assert.AreEqual( 1, crc32.Value );\r
+\r
+            crc32 = new CRC32Checksum(556);\r
+            Assert.AreEqual( 556, crc32.Value );\r
+        }\r
+\r
+        [Test]\r
+        public void CRC32_Data()\r
+        {\r
+            CRC32Checksum crc32 = new CRC32Checksum();\r
+            byte[] data = { 1,2,3,4,5,6,7 };\r
+            crc32.Update(data);\r
+            Assert.AreEqual( 0x70e46888, crc32.Value  );\r
+\r
+            crc32 = new CRC32Checksum();\r
+            crc32.Update("penguin");\r
+            Assert.AreEqual( 0x0e5c1a120, crc32.Value );\r
+\r
+            crc32 = new CRC32Checksum(1);\r
+            crc32.Update("penguin");\r
+            Assert.AreEqual(0x43b6aa94, crc32.Value);\r
+\r
+        }\r
+        #endregion\r
+\r
+        #region Adler tests\r
+\r
+        [Test]\r
+        public void Adler_Null()\r
+        {\r
+            AdlerChecksum adler = new AdlerChecksum();\r
+            Assert.AreEqual(0, adler.Value);\r
+\r
+            adler = new AdlerChecksum(1);\r
+            Assert.AreEqual( 1, adler.Value );\r
+\r
+            adler = new AdlerChecksum(556);\r
+            Assert.AreEqual( 556, adler.Value );\r
+        }\r
+\r
+        [Test]\r
+        public void Adler_Data()\r
+        {\r
+            AdlerChecksum adler = new AdlerChecksum(1);\r
+            byte[] data = { 1,2,3,4,5,6,7 };\r
+            adler.Update(data);\r
+            Assert.AreEqual( 0x5b001d, adler.Value  );\r
+\r
+            adler = new AdlerChecksum();\r
+            adler.Update("penguin");\r
+            Assert.AreEqual(0x0bcf02f6, adler.Value );\r
+\r
+            adler = new AdlerChecksum(1);\r
+            adler.Update("penguin");\r
+            Assert.AreEqual(0x0bd602f7, adler.Value);\r
+\r
+        }\r
+        #endregion\r
+    }\r
+\r
+    [TestFixture]\r
+    public class InfoTests\r
+    {\r
+        #region Info tests\r
+        [Test]\r
+        public void Info_Version()\r
+        {\r
+            Info info = new Info();\r
+            Assert.AreEqual("1.2.5", Info.Version);\r
+            Assert.AreEqual(32, info.SizeOfUInt);\r
+            Assert.AreEqual(32, info.SizeOfULong);\r
+            Assert.AreEqual(32, info.SizeOfPointer);\r
+            Assert.AreEqual(32, info.SizeOfOffset);\r
+        }\r
+        #endregion\r
+    }\r
+\r
+    [TestFixture]\r
+    public class DeflateInflateTests\r
+    {\r
+        #region Deflate tests\r
+        [Test]\r
+        public void Deflate_Init()\r
+        {\r
+            using (Deflater def = new Deflater(CompressLevel.Default))\r
+            {\r
+            }\r
+        }\r
+\r
+        private ArrayList compressedData = new ArrayList();\r
+        private uint adler1;\r
+\r
+        private ArrayList uncompressedData = new ArrayList();\r
+        private uint adler2;\r
+\r
+        public void CDataAvail(byte[] data, int startIndex, int count)\r
+        {\r
+            for (int i = 0; i < count; ++i)\r
+                compressedData.Add(data[i+startIndex]);\r
+        }\r
+\r
+        [Test]\r
+        public void Deflate_Compress()\r
+        {\r
+            compressedData.Clear();\r
+\r
+            byte[] testData = new byte[35000];\r
+            for (int i = 0; i < testData.Length; ++i)\r
+                testData[i] = 5;\r
+\r
+            using (Deflater def = new Deflater((CompressLevel)5))\r
+            {\r
+                def.DataAvailable += new DataAvailableHandler(CDataAvail);\r
+                def.Add(testData);\r
+                def.Finish();\r
+                adler1 = def.Checksum;\r
+            }\r
+        }\r
+        #endregion\r
+\r
+        #region Inflate tests\r
+        [Test]\r
+        public void Inflate_Init()\r
+        {\r
+            using (Inflater inf = new Inflater())\r
+            {\r
+            }\r
+        }\r
+\r
+        private void DDataAvail(byte[] data, int startIndex, int count)\r
+        {\r
+            for (int i = 0; i < count; ++i)\r
+                uncompressedData.Add(data[i+startIndex]);\r
+        }\r
+\r
+        [Test]\r
+        public void Inflate_Expand()\r
+        {\r
+            uncompressedData.Clear();\r
+\r
+            using (Inflater inf = new Inflater())\r
+            {\r
+                inf.DataAvailable += new DataAvailableHandler(DDataAvail);\r
+                inf.Add((byte[])compressedData.ToArray(typeof(byte)));\r
+                inf.Finish();\r
+                adler2 = inf.Checksum;\r
+            }\r
+            Assert.AreEqual( adler1, adler2 );\r
+        }\r
+        #endregion\r
+    }\r
+\r
+    [TestFixture]\r
+    public class GZipStreamTests\r
+    {\r
+        #region GZipStream test\r
+        [Test]\r
+        public void GZipStream_WriteRead()\r
+        {\r
+            using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best))\r
+            {\r
+                BinaryWriter writer = new BinaryWriter(gzOut);\r
+                writer.Write("hi there");\r
+                writer.Write(Math.PI);\r
+                writer.Write(42);\r
+            }\r
+\r
+            using (GZipStream gzIn = new GZipStream("gzstream.gz"))\r
+            {\r
+                BinaryReader reader = new BinaryReader(gzIn);\r
+                string s = reader.ReadString();\r
+                Assert.AreEqual("hi there",s);\r
+                double d = reader.ReadDouble();\r
+                Assert.AreEqual(Math.PI, d);\r
+                int i = reader.ReadInt32();\r
+                Assert.AreEqual(42,i);\r
+            }\r
+\r
+        }\r
+        #endregion\r
+       }\r
+}\r
+\r
+#endif\r
diff --git a/8.x/zlib/contrib/dotzlib/LICENSE_1_0.txt b/8.x/zlib/contrib/dotzlib/LICENSE_1_0.txt
new file mode 100644 (file)
index 0000000..30aac2c
--- /dev/null
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003\r
+\r
+Permission is hereby granted, free of charge, to any person or organization\r
+obtaining a copy of the software and accompanying documentation covered by\r
+this license (the "Software") to use, reproduce, display, distribute,\r
+execute, and transmit the Software, and to prepare derivative works of the\r
+Software, and to permit third-parties to whom the Software is furnished to\r
+do so, all subject to the following:\r
+\r
+The copyright notices in the Software and this entire statement, including\r
+the above license grant, this restriction and the following disclaimer,\r
+must be included in all copies of the Software, in whole or in part, and\r
+all derivative works of the Software, unless such copies or derivative\r
+works are solely in the form of machine-executable object code generated by\r
+a source language processor.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\r
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\r
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\r
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/8.x/zlib/contrib/dotzlib/readme.txt b/8.x/zlib/contrib/dotzlib/readme.txt
new file mode 100644 (file)
index 0000000..b239572
--- /dev/null
@@ -0,0 +1,58 @@
+This directory contains a .Net wrapper class library for the ZLib1.dll\r
+\r
+The wrapper includes support for inflating/deflating memory buffers,\r
+.Net streaming wrappers for the gz streams part of zlib, and wrappers\r
+for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples.\r
+\r
+Directory structure:\r
+--------------------\r
+\r
+LICENSE_1_0.txt       - License file.\r
+readme.txt            - This file.\r
+DotZLib.chm           - Class library documentation\r
+DotZLib.build         - NAnt build file\r
+DotZLib.sln           - Microsoft Visual Studio 2003 solution file\r
+\r
+DotZLib\*.cs          - Source files for the class library\r
+\r
+Unit tests:\r
+-----------\r
+The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher.\r
+To include unit tests in the build, define nunit before building.\r
+\r
+\r
+Build instructions:\r
+-------------------\r
+\r
+1. Using Visual Studio.Net 2003:\r
+   Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll)\r
+   will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on\r
+   you are building the release or debug version of the library. Check\r
+   DotZLib/UnitTests.cs for instructions on how to include unit tests in the\r
+   build.\r
+\r
+2. Using NAnt:\r
+   Open a command prompt with access to the build environment and run nant\r
+   in the same directory as the DotZLib.build file.\r
+   You can define 2 properties on the nant command-line to control the build:\r
+   debug={true|false} to toggle between release/debug builds (default=true).\r
+   nunit={true|false} to include or esclude unit tests (default=true).\r
+   Also the target clean will remove binaries.\r
+   Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release\r
+   or ./DotZLib/bin/debug, depending on whether you are building the release\r
+   or debug version of the library.\r
+\r
+   Examples:\r
+     nant -D:debug=false -D:nunit=false\r
+       will build a release mode version of the library without unit tests.\r
+     nant\r
+       will build a debug version of the library with unit tests\r
+     nant clean\r
+       will remove all previously built files.\r
+\r
+\r
+---------------------------------\r
+Copyright (c) Henrik Ravn 2004\r
+\r
+Use, modification and distribution are subject to the Boost Software License, Version 1.0.\r
+(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
diff --git a/8.x/zlib/contrib/gcc_gvmat64/gvmat64.S b/8.x/zlib/contrib/gcc_gvmat64/gvmat64.S
new file mode 100644 (file)
index 0000000..dd858dd
--- /dev/null
@@ -0,0 +1,574 @@
+/*\r
+;uInt longest_match_x64(\r
+;    deflate_state *s,\r
+;    IPos cur_match);                             // current match \r
+\r
+; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64\r
+;  (AMD64 on Athlon 64, Opteron, Phenom\r
+;     and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)\r
+; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode)\r
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.\r
+;\r
+; File written by Gilles Vollant, by converting to assembly the longest_match\r
+;  from Jean-loup Gailly in deflate.c of zLib and infoZip zip.\r
+;  and by taking inspiration on asm686 with masm, optimised assembly code\r
+;        from Brian Raiter, written 1998\r
+;\r
+;  This software is provided 'as-is', without any express or implied\r
+;  warranty.  In no event will the authors be held liable for any damages\r
+;  arising from the use of this software.\r
+;\r
+;  Permission is granted to anyone to use this software for any purpose,\r
+;  including commercial applications, and to alter it and redistribute it\r
+;  freely, subject to the following restrictions:\r
+;\r
+;  1. The origin of this software must not be misrepresented; you must not\r
+;     claim that you wrote the original software. If you use this software\r
+;     in a product, an acknowledgment in the product documentation would be\r
+;     appreciated but is not required.\r
+;  2. Altered source versions must be plainly marked as such, and must not be\r
+;     misrepresented as being the original software\r
+;  3. This notice may not be removed or altered from any source distribution.\r
+;\r
+;         http://www.zlib.net\r
+;         http://www.winimage.com/zLibDll\r
+;         http://www.muppetlabs.com/~breadbox/software/assembly.html\r
+;\r
+; to compile this file for zLib, I use option:\r
+;   gcc -c -arch x86_64 gvmat64.S\r
+\r
+\r
+;uInt longest_match(s, cur_match)\r
+;    deflate_state *s;\r
+;    IPos cur_match;                             // current match /\r
+;\r
+; with XCode for Mac, I had strange error with some jump on intel syntax\r
+; this is why BEFORE_JMP and AFTER_JMP are used\r
+ */\r
+\r
+\r
+#define BEFORE_JMP .att_syntax\r
+#define AFTER_JMP .intel_syntax noprefix\r
+\r
+#ifndef NO_UNDERLINE\r
+#      define  match_init      _match_init\r
+#      define  longest_match   _longest_match\r
+#endif\r
+\r
+.intel_syntax noprefix\r
+\r
+.globl match_init, longest_match\r
+.text\r
+longest_match:\r
+\r
+\r
+\r
+#define LocalVarsSize 96\r
+/*\r
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12\r
+; free register :  r14,r15\r
+; register can be saved : rsp\r
+*/\r
+\r
+#define chainlenwmask     (rsp + 8 - LocalVarsSize)\r
+#define nicematch         (rsp + 16 - LocalVarsSize)\r
+\r
+#define save_rdi        (rsp + 24 - LocalVarsSize)\r
+#define save_rsi        (rsp + 32 - LocalVarsSize)\r
+#define save_rbx        (rsp + 40 - LocalVarsSize)\r
+#define save_rbp        (rsp + 48 - LocalVarsSize)\r
+#define save_r12        (rsp + 56 - LocalVarsSize)\r
+#define save_r13        (rsp + 64 - LocalVarsSize)\r
+#define save_r14        (rsp + 72 - LocalVarsSize)\r
+#define save_r15        (rsp + 80 - LocalVarsSize)\r
+\r
+\r
+/*\r
+;  all the +4 offsets are due to the addition of pending_buf_size (in zlib\r
+;  in the deflate_state structure since the asm code was first written\r
+;  (if you compile with zlib 1.0.4 or older, remove the +4).\r
+;  Note : these value are good with a 8 bytes boundary pack structure\r
+*/\r
+\r
+#define    MAX_MATCH              258\r
+#define    MIN_MATCH              3\r
+#define    MIN_LOOKAHEAD          (MAX_MATCH+MIN_MATCH+1)\r
+\r
+/*\r
+;;; Offsets for fields in the deflate_state structure. These numbers\r
+;;; are calculated from the definition of deflate_state, with the\r
+;;; assumption that the compiler will dword-align the fields. (Thus,\r
+;;; changing the definition of deflate_state could easily cause this\r
+;;; program to crash horribly, without so much as a warning at\r
+;;; compile time. Sigh.)\r
+\r
+;  all the +zlib1222add offsets are due to the addition of fields\r
+;  in zlib in the deflate_state structure since the asm code was first written\r
+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").\r
+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").\r
+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").\r
+*/\r
+\r
+\r
+\r
+/* you can check the structure offset by running\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include "deflate.h"\r
+\r
+void print_depl()\r
+{\r
+deflate_state ds;\r
+deflate_state *s=&ds;\r
+printf("size pointer=%u\n",(int)sizeof(void*));\r
+\r
+printf("#define dsWSize         %u\n",(int)(((char*)&(s->w_size))-((char*)s)));\r
+printf("#define dsWMask         %u\n",(int)(((char*)&(s->w_mask))-((char*)s)));\r
+printf("#define dsWindow        %u\n",(int)(((char*)&(s->window))-((char*)s)));\r
+printf("#define dsPrev          %u\n",(int)(((char*)&(s->prev))-((char*)s)));\r
+printf("#define dsMatchLen      %u\n",(int)(((char*)&(s->match_length))-((char*)s)));\r
+printf("#define dsPrevMatch     %u\n",(int)(((char*)&(s->prev_match))-((char*)s)));\r
+printf("#define dsStrStart      %u\n",(int)(((char*)&(s->strstart))-((char*)s)));\r
+printf("#define dsMatchStart    %u\n",(int)(((char*)&(s->match_start))-((char*)s)));\r
+printf("#define dsLookahead     %u\n",(int)(((char*)&(s->lookahead))-((char*)s)));\r
+printf("#define dsPrevLen       %u\n",(int)(((char*)&(s->prev_length))-((char*)s)));\r
+printf("#define dsMaxChainLen   %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));\r
+printf("#define dsGoodMatch     %u\n",(int)(((char*)&(s->good_match))-((char*)s)));\r
+printf("#define dsNiceMatch     %u\n",(int)(((char*)&(s->nice_match))-((char*)s)));\r
+}\r
+*/\r
+\r
+#define dsWSize          68\r
+#define dsWMask          76\r
+#define dsWindow         80\r
+#define dsPrev           96\r
+#define dsMatchLen       144\r
+#define dsPrevMatch      148\r
+#define dsStrStart       156\r
+#define dsMatchStart     160\r
+#define dsLookahead      164\r
+#define dsPrevLen        168\r
+#define dsMaxChainLen    172\r
+#define dsGoodMatch      188\r
+#define dsNiceMatch      192\r
+\r
+#define window_size      [ rcx + dsWSize]\r
+#define WMask            [ rcx + dsWMask]\r
+#define window_ad        [ rcx + dsWindow]\r
+#define prev_ad          [ rcx + dsPrev]\r
+#define strstart         [ rcx + dsStrStart]\r
+#define match_start      [ rcx + dsMatchStart]\r
+#define Lookahead        [ rcx + dsLookahead] //; 0ffffffffh on infozip\r
+#define prev_length      [ rcx + dsPrevLen]\r
+#define max_chain_length [ rcx + dsMaxChainLen]\r
+#define good_match       [ rcx + dsGoodMatch]\r
+#define nice_match       [ rcx + dsNiceMatch]\r
+\r
+/*\r
+; windows:\r
+; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match)\r
+\r
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and\r
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp\r
+;\r
+; All registers must be preserved across the call, except for\r
+;   rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.\r
+\r
+;\r
+; gcc on macosx-linux:\r
+; see http://www.x86-64.org/documentation/abi-0.99.pdf\r
+; param 1 in rdi, param 2 in rsi\r
+; rbx, rsp, rbp, r12 to r15 must be preserved\r
+\r
+;;; Save registers that the compiler may be using, and adjust esp to\r
+;;; make room for our stack frame.\r
+\r
+\r
+;;; Retrieve the function arguments. r8d will hold cur_match\r
+;;; throughout the entire function. edx will hold the pointer to the\r
+;;; deflate_state structure during the function's setup (before\r
+;;; entering the main loop.\r
+\r
+; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)\r
+; mac: param 1 in rdi, param 2 rsi\r
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx\r
+*/\r
+        mov [save_rbx],rbx\r
+        mov [save_rbp],rbp\r
+\r
+\r
+        mov rcx,rdi\r
+\r
+        mov r8d,esi\r
+\r
+\r
+        mov [save_r12],r12\r
+        mov [save_r13],r13\r
+        mov [save_r14],r14\r
+        mov [save_r15],r15\r
+\r
+\r
+//;;; uInt wmask = s->w_mask;\r
+//;;; unsigned chain_length = s->max_chain_length;\r
+//;;; if (s->prev_length >= s->good_match) {\r
+//;;;     chain_length >>= 2;\r
+//;;; }\r
+\r
+\r
+        mov edi, prev_length\r
+        mov esi, good_match\r
+        mov eax, WMask\r
+        mov ebx, max_chain_length\r
+        cmp edi, esi\r
+        jl  LastMatchGood\r
+        shr ebx, 2\r
+LastMatchGood:\r
+\r
+//;;; chainlen is decremented once beforehand so that the function can\r
+//;;; use the sign flag instead of the zero flag for the exit test.\r
+//;;; It is then shifted into the high word, to make room for the wmask\r
+//;;; value, which it will always accompany.\r
+\r
+        dec ebx\r
+        shl ebx, 16\r
+        or  ebx, eax\r
+\r
+//;;; on zlib only\r
+//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\r
+\r
+\r
+\r
+        mov eax, nice_match\r
+        mov [chainlenwmask], ebx\r
+        mov r10d, Lookahead\r
+        cmp r10d, eax\r
+        cmovnl r10d, eax\r
+        mov [nicematch],r10d\r
+\r
+\r
+\r
+//;;; register Bytef *scan = s->window + s->strstart;\r
+        mov r10, window_ad\r
+        mov ebp, strstart\r
+        lea r13, [r10 + rbp]\r
+\r
+//;;; Determine how many bytes the scan ptr is off from being\r
+//;;; dword-aligned.\r
+\r
+         mov r9,r13\r
+         neg r13\r
+         and r13,3\r
+\r
+//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\r
+//;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;\r
+\r
+\r
+        mov eax, window_size\r
+        sub eax, MIN_LOOKAHEAD\r
+\r
+\r
+        xor edi,edi\r
+        sub ebp, eax\r
+\r
+        mov r11d, prev_length\r
+\r
+        cmovng ebp,edi\r
+\r
+//;;; int best_len = s->prev_length;\r
+\r
+\r
+//;;; Store the sum of s->window + best_len in esi locally, and in esi.\r
+\r
+       lea  rsi,[r10+r11]\r
+\r
+//;;; register ush scan_start = *(ushf*)scan;\r
+//;;; register ush scan_end   = *(ushf*)(scan+best_len-1);\r
+//;;; Posf *prev = s->prev;\r
+\r
+        movzx r12d,word ptr [r9]\r
+        movzx ebx, word ptr [r9 + r11 - 1]\r
+\r
+        mov rdi, prev_ad\r
+\r
+//;;; Jump into the main loop.\r
+\r
+        mov edx, [chainlenwmask]\r
+\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+        jz  LookupLoopIsZero\r
+                               \r
+                                               \r
+                                               \r
+LookupLoop1:\r
+        and r8d, edx\r
+\r
+        movzx   r8d, word ptr [rdi + r8*2]\r
+        cmp r8d, ebp\r
+        jbe LeaveNow\r
+               \r
+               \r
+               \r
+        sub edx, 0x00010000\r
+               BEFORE_JMP\r
+        js  LeaveNow\r
+               AFTER_JMP\r
+\r
+LoopEntry1:\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+               BEFORE_JMP\r
+        jz  LookupLoopIsZero\r
+               AFTER_JMP\r
+\r
+LookupLoop2:\r
+        and r8d, edx\r
+\r
+        movzx   r8d, word ptr [rdi + r8*2]\r
+        cmp r8d, ebp\r
+               BEFORE_JMP\r
+        jbe LeaveNow\r
+               AFTER_JMP\r
+        sub edx, 0x00010000\r
+               BEFORE_JMP\r
+        js  LeaveNow\r
+               AFTER_JMP\r
+\r
+LoopEntry2:\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+               BEFORE_JMP\r
+        jz  LookupLoopIsZero\r
+               AFTER_JMP\r
+\r
+LookupLoop4:\r
+        and r8d, edx\r
+\r
+        movzx   r8d, word ptr [rdi + r8*2]\r
+        cmp r8d, ebp\r
+               BEFORE_JMP\r
+        jbe LeaveNow\r
+               AFTER_JMP\r
+        sub edx, 0x00010000\r
+               BEFORE_JMP\r
+        js  LeaveNow\r
+               AFTER_JMP\r
+\r
+LoopEntry4:\r
+\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+               BEFORE_JMP\r
+        jnz LookupLoop1\r
+        jmp LookupLoopIsZero\r
+               AFTER_JMP\r
+/*\r
+;;; do {\r
+;;;     match = s->window + cur_match;\r
+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||\r
+;;;         *(ushf*)match != scan_start) continue;\r
+;;;     [...]\r
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit\r
+;;;          && --chain_length != 0);\r
+;;;\r
+;;; Here is the inner loop of the function. The function will spend the\r
+;;; majority of its time in this loop, and majority of that time will\r
+;;; be spent in the first ten instructions.\r
+;;;\r
+;;; Within this loop:\r
+;;; ebx = scanend\r
+;;; r8d = curmatch\r
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)\r
+;;; esi = windowbestlen - i.e., (window + bestlen)\r
+;;; edi = prev\r
+;;; ebp = limit\r
+*/\r
+.balign 16\r
+LookupLoop:\r
+        and r8d, edx\r
+\r
+        movzx   r8d, word ptr [rdi + r8*2]\r
+        cmp r8d, ebp\r
+               BEFORE_JMP\r
+        jbe LeaveNow\r
+               AFTER_JMP\r
+        sub edx, 0x00010000\r
+               BEFORE_JMP\r
+        js  LeaveNow\r
+               AFTER_JMP\r
+\r
+LoopEntry:\r
+\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+               BEFORE_JMP\r
+        jnz LookupLoop1\r
+               AFTER_JMP\r
+LookupLoopIsZero:\r
+        cmp     r12w, word ptr [r10 + r8]\r
+               BEFORE_JMP\r
+        jnz LookupLoop1\r
+               AFTER_JMP\r
+\r
+\r
+//;;; Store the current value of chainlen.\r
+        mov [chainlenwmask], edx\r
+/*\r
+;;; Point edi to the string under scrutiny, and esi to the string we\r
+;;; are hoping to match it up with. In actuality, esi and edi are\r
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is\r
+;;; initialized to -(MAX_MATCH_8 - scanalign).\r
+*/\r
+        lea rsi,[r8+r10]\r
+        mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8)\r
+        lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8]\r
+        lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8]\r
+\r
+        prefetcht1 [rsi+rdx]\r
+        prefetcht1 [rdi+rdx]\r
+\r
+/*\r
+;;; Test the strings for equality, 8 bytes at a time. At the end,\r
+;;; adjust rdx so that it is offset to the exact byte that mismatched.\r
+;;;\r
+;;; We already know at this point that the first three bytes of the\r
+;;; strings match each other, and they can be safely passed over before\r
+;;; starting the compare loop. So what this code does is skip over 0-3\r
+;;; bytes, as much as necessary in order to dword-align the edi\r
+;;; pointer. (rsi will still be misaligned three times out of four.)\r
+;;;\r
+;;; It should be confessed that this loop usually does not represent\r
+;;; much of the total running time. Replacing it with a more\r
+;;; straightforward "rep cmpsb" would not drastically degrade\r
+;;; performance.\r
+*/\r
+\r
+LoopCmps:\r
+        mov rax, [rsi + rdx]\r
+        xor rax, [rdi + rdx]\r
+        jnz LeaveLoopCmps\r
+\r
+        mov rax, [rsi + rdx + 8]\r
+        xor rax, [rdi + rdx + 8]\r
+        jnz LeaveLoopCmps8\r
+\r
+\r
+        mov rax, [rsi + rdx + 8+8]\r
+        xor rax, [rdi + rdx + 8+8]\r
+        jnz LeaveLoopCmps16\r
+\r
+        add rdx,8+8+8\r
+\r
+               BEFORE_JMP\r
+        jnz  LoopCmps\r
+        jmp  LenMaximum\r
+               AFTER_JMP\r
+               \r
+LeaveLoopCmps16: add rdx,8\r
+LeaveLoopCmps8: add rdx,8\r
+LeaveLoopCmps:\r
+\r
+        test    eax, 0x0000FFFF\r
+        jnz LenLower\r
+\r
+        test eax,0xffffffff\r
+\r
+        jnz LenLower32\r
+\r
+        add rdx,4\r
+        shr rax,32\r
+        or ax,ax\r
+               BEFORE_JMP\r
+        jnz LenLower\r
+               AFTER_JMP\r
+\r
+LenLower32:\r
+        shr eax,16\r
+        add rdx,2\r
+               \r
+LenLower:              \r
+        sub al, 1\r
+        adc rdx, 0\r
+//;;; Calculate the length of the match. If it is longer than MAX_MATCH,\r
+//;;; then automatically accept it as the best possible match and leave.\r
+\r
+        lea rax, [rdi + rdx]\r
+        sub rax, r9\r
+        cmp eax, MAX_MATCH\r
+               BEFORE_JMP\r
+        jge LenMaximum\r
+               AFTER_JMP\r
+/*\r
+;;; If the length of the match is not longer than the best match we\r
+;;; have so far, then forget it and return to the lookup loop.\r
+;///////////////////////////////////\r
+*/\r
+        cmp eax, r11d\r
+        jg  LongerMatch\r
+\r
+        lea rsi,[r10+r11]\r
+\r
+        mov rdi, prev_ad\r
+        mov edx, [chainlenwmask]\r
+               BEFORE_JMP\r
+        jmp LookupLoop\r
+               AFTER_JMP\r
+/*\r
+;;;         s->match_start = cur_match;\r
+;;;         best_len = len;\r
+;;;         if (len >= nice_match) break;\r
+;;;         scan_end = *(ushf*)(scan+best_len-1);\r
+*/\r
+LongerMatch:\r
+        mov r11d, eax\r
+        mov match_start, r8d\r
+        cmp eax, [nicematch]\r
+               BEFORE_JMP\r
+        jge LeaveNow\r
+               AFTER_JMP\r
+\r
+        lea rsi,[r10+rax]\r
+\r
+        movzx   ebx, word ptr [r9 + rax - 1]\r
+        mov rdi, prev_ad\r
+        mov edx, [chainlenwmask]\r
+               BEFORE_JMP\r
+        jmp LookupLoop\r
+               AFTER_JMP\r
+\r
+//;;; Accept the current string, with the maximum possible length.\r
+\r
+LenMaximum:\r
+        mov r11d,MAX_MATCH\r
+        mov match_start, r8d\r
+\r
+//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\r
+//;;; return s->lookahead;\r
+\r
+LeaveNow:\r
+        mov eax, Lookahead\r
+        cmp r11d, eax\r
+        cmovng eax, r11d\r
+\r
+\r
+\r
+//;;; Restore the stack and return from whence we came.\r
+\r
+\r
+//        mov rsi,[save_rsi]\r
+//        mov rdi,[save_rdi]\r
+        mov rbx,[save_rbx]\r
+        mov rbp,[save_rbp]\r
+        mov r12,[save_r12]\r
+        mov r13,[save_r13]\r
+        mov r14,[save_r14]\r
+        mov r15,[save_r15]\r
+\r
+\r
+        ret 0\r
+//; please don't remove this string !\r
+//; Your can freely use gvmat64 in any free or commercial app\r
+//; but it is far better don't remove the string in the binary!\r
+ //   db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0\r
+\r
+\r
+match_init:\r
+  ret 0\r
+\r
+\r
diff --git a/8.x/zlib/contrib/infback9/README b/8.x/zlib/contrib/infback9/README
new file mode 100644 (file)
index 0000000..e75ed13
--- /dev/null
@@ -0,0 +1 @@
+See infback9.h for what this is and how to use it.
diff --git a/8.x/zlib/contrib/infback9/infback9.c b/8.x/zlib/contrib/infback9/infback9.c
new file mode 100644 (file)
index 0000000..7bbe90c
--- /dev/null
@@ -0,0 +1,617 @@
+/* infback9.c -- inflate deflate64 data using a call-back interface
+ * Copyright (C) 1995-2008 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infback9.h"
+#include "inftree9.h"
+#include "inflate9.h"
+
+#define WSIZE 65536UL
+
+/*
+   strm provides memory allocation functions in zalloc and zfree, or
+   Z_NULL to use the library memory allocation functions.
+
+   window is a user-supplied window and output buffer that is 64K bytes.
+ */
+int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
+z_stream FAR *strm;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL || window == Z_NULL)
+        return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+                                               sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (voidpf)state;
+    state->window = window;
+    return Z_OK;
+}
+
+/*
+   Build and output length and distance decoding tables for fixed code
+   decoding.
+ */
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+void makefixed9(void)
+{
+    unsigned sym, bits, low, size;
+    code *next, *lenfix, *distfix;
+    struct inflate_state state;
+    code fixed[544];
+
+    /* literal/length table */
+    sym = 0;
+    while (sym < 144) state.lens[sym++] = 8;
+    while (sym < 256) state.lens[sym++] = 9;
+    while (sym < 280) state.lens[sym++] = 7;
+    while (sym < 288) state.lens[sym++] = 8;
+    next = fixed;
+    lenfix = next;
+    bits = 9;
+    inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
+
+    /* distance table */
+    sym = 0;
+    while (sym < 32) state.lens[sym++] = 5;
+    distfix = next;
+    bits = 5;
+    inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
+
+    /* write tables */
+    puts("    /* inffix9.h -- table for decoding deflate64 fixed codes");
+    puts("     * Generated automatically by makefixed9().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
+               lenfix[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 5) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
+               distfix[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/* Macros for inflateBack(): */
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Assure that some input is available.  If input is requested, but denied,
+   then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+    do { \
+        if (have == 0) { \
+            have = in(in_desc, &next); \
+            if (have == 0) { \
+                next = Z_NULL; \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+   with an error if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        PULL(); \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflateBack() with
+   an error. */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n <= 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Assure that some output space is available, by writing out the window
+   if it's full.  If the write fails, return from inflateBack() with a
+   Z_BUF_ERROR. */
+#define ROOM() \
+    do { \
+        if (left == 0) { \
+            put = window; \
+            left = WSIZE; \
+            wrap = 1; \
+            if (out(out_desc, put, (unsigned)left)) { \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/*
+   strm provides the memory allocation functions and window buffer on input,
+   and provides information on the unused input on return.  For Z_DATA_ERROR
+   returns, strm will also provide an error message.
+
+   in() and out() are the call-back input and output functions.  When
+   inflateBack() needs more input, it calls in().  When inflateBack() has
+   filled the window with output, or when it completes with data in the
+   window, it calls out() to write out the data.  The application must not
+   change the provided input until in() is called again or inflateBack()
+   returns.  The application must not change the window/output buffer until
+   inflateBack() returns.
+
+   in() and out() are called with a descriptor parameter provided in the
+   inflateBack() call.  This parameter can be a structure that provides the
+   information required to do the read or write, as well as accumulated
+   information on the input and output such as totals and check values.
+
+   in() should return zero on failure.  out() should return non-zero on
+   failure.  If either in() or out() fails, than inflateBack() returns a
+   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
+   was in() or out() that caused in the error.  Otherwise,  inflateBack()
+   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+   error, or Z_MEM_ERROR if it could not allocate memory for the state.
+   inflateBack() can also return Z_STREAM_ERROR if the input parameters
+   are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
+z_stream FAR *strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have;              /* available input */
+    unsigned long left;         /* available output */
+    inflate_mode mode;          /* current inflate mode */
+    int lastblock;              /* true if processing last block */
+    int wrap;                   /* true if the window has wrapped */
+    unsigned long write;        /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned extra;             /* extra bits needed */
+    unsigned long length;       /* literal or length of data to copy */
+    unsigned long offset;       /* distance back to copy string from */
+    unsigned long copy;         /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+#include "inffix9.h"
+
+    /* Check that the strm exists and that the state was initialized */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* Reset the state */
+    strm->msg = Z_NULL;
+    mode = TYPE;
+    lastblock = 0;
+    write = 0;
+    wrap = 0;
+    window = state->window;
+    next = strm->next_in;
+    have = next != Z_NULL ? strm->avail_in : 0;
+    hold = 0;
+    bits = 0;
+    put = window;
+    left = WSIZE;
+    lencode = Z_NULL;
+    distcode = Z_NULL;
+
+    /* Inflate until end of block marked as last */
+    for (;;)
+        switch (mode) {
+        case TYPE:
+            /* determine and dispatch block type */
+            if (lastblock) {
+                BYTEBITS();
+                mode = DONE;
+                break;
+            }
+            NEEDBITS(3);
+            lastblock = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        lastblock ? " (last)" : ""));
+                mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                lencode = lenfix;
+                lenbits = 9;
+                distcode = distfix;
+                distbits = 5;
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        lastblock ? " (last)" : ""));
+                mode = LEN;                     /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        lastblock ? " (last)" : ""));
+                mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+
+        case STORED:
+            /* get and verify stored block length */
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                mode = BAD;
+                break;
+            }
+            length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %lu\n",
+                    length));
+            INITBITS();
+
+            /* copy stored block from input to output */
+            while (length != 0) {
+                copy = length;
+                PULL();
+                ROOM();
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                length -= copy;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            mode = TYPE;
+            break;
+
+        case TABLE:
+            /* get dynamic table entries descriptor */
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+            if (state->nlen > 286) {
+                strm->msg = (char *)"too many length symbols";
+                mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+
+            /* get code length code lengths (not a typo) */
+            state->have = 0;
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            lencode = (code const FAR *)(state->next);
+            lenbits = 7;
+            ret = inflate_table9(CODES, state->lens, 19, &(state->next),
+                                &(lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+
+            /* get length and distance code code lengths */
+            state->have = 0;
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = lencode[BITS(lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    NEEDBITS(here.bits);
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            mode = BAD;
+                            break;
+                        }
+                        len = (unsigned)(state->lens[state->have - 1]);
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftree9.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            lencode = (code const FAR *)(state->next);
+            lenbits = 9;
+            ret = inflate_table9(LENS, state->lens, state->nlen,
+                            &(state->next), &(lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                mode = BAD;
+                break;
+            }
+            distcode = (code const FAR *)(state->next);
+            distbits = 6;
+            ret = inflate_table9(DISTS, state->lens + state->nlen,
+                            state->ndist, &(state->next), &(distbits),
+                            state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            mode = LEN;
+
+        case LEN:
+            /* get a literal, length, or end-of-block code */
+            for (;;) {
+                here = lencode[BITS(lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            length = (unsigned)here.val;
+
+            /* process literal */
+            if (here.op == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                ROOM();
+                *put++ = (unsigned char)(length);
+                left--;
+                mode = LEN;
+                break;
+            }
+
+            /* process end of block */
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                mode = TYPE;
+                break;
+            }
+
+            /* invalid code */
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                mode = BAD;
+                break;
+            }
+
+            /* length code -- get extra bits, if any */
+            extra = (unsigned)(here.op) & 31;
+            if (extra != 0) {
+                NEEDBITS(extra);
+                length += BITS(extra);
+                DROPBITS(extra);
+            }
+            Tracevv((stderr, "inflate:         length %lu\n", length));
+
+            /* get distance code */
+            for (;;) {
+                here = distcode[BITS(distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                mode = BAD;
+                break;
+            }
+            offset = (unsigned)here.val;
+
+            /* get distance extra bits, if any */
+            extra = (unsigned)(here.op) & 15;
+            if (extra != 0) {
+                NEEDBITS(extra);
+                offset += BITS(extra);
+                DROPBITS(extra);
+            }
+            if (offset > WSIZE - (wrap ? 0: left)) {
+                strm->msg = (char *)"invalid distance too far back";
+                mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %lu\n", offset));
+
+            /* copy match from window to output */
+            do {
+                ROOM();
+                copy = WSIZE - offset;
+                if (copy < left) {
+                    from = put + copy;
+                    copy = left - copy;
+                }
+                else {
+                    from = put - offset;
+                    copy = left;
+                }
+                if (copy > length) copy = length;
+                length -= copy;
+                left -= copy;
+                do {
+                    *put++ = *from++;
+                } while (--copy);
+            } while (length != 0);
+            break;
+
+        case DONE:
+            /* inflate stream terminated properly -- write leftover output */
+            ret = Z_STREAM_END;
+            if (left < WSIZE) {
+                if (out(out_desc, window, (unsigned)(WSIZE - left)))
+                    ret = Z_BUF_ERROR;
+            }
+            goto inf_leave;
+
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+
+        default:                /* can't happen, but makes compilers happy */
+            ret = Z_STREAM_ERROR;
+            goto inf_leave;
+        }
+
+    /* Return unused input */
+  inf_leave:
+    strm->next_in = next;
+    strm->avail_in = have;
+    return ret;
+}
+
+int ZEXPORT inflateBack9End(strm)
+z_stream FAR *strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
diff --git a/8.x/zlib/contrib/infback9/infback9.h b/8.x/zlib/contrib/infback9/infback9.h
new file mode 100644 (file)
index 0000000..1073c0a
--- /dev/null
@@ -0,0 +1,37 @@
+/* infback9.h -- header for using inflateBack9 functions
+ * Copyright (C) 2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * This header file and associated patches provide a decoder for PKWare's
+ * undocumented deflate64 compression method (method 9).  Use with infback9.c,
+ * inftree9.h, inftree9.c, and inffix9.h.  These patches are not supported.
+ * This should be compiled with zlib, since it uses zutil.h and zutil.o.
+ * This code has not yet been tested on 16-bit architectures.  See the
+ * comments in zlib.h for inflateBack() usage.  These functions are used
+ * identically, except that there is no windowBits parameter, and a 64K
+ * window must be provided.  Also if int's are 16 bits, then a zero for
+ * the third parameter of the "out" function actually means 65536UL.
+ * zlib.h must be included before this header file.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm));
+ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define inflateBack9Init(strm, window) \
+        inflateBack9Init_((strm), (window), \
+        ZLIB_VERSION, sizeof(z_stream))
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/8.x/zlib/contrib/infback9/inffix9.h b/8.x/zlib/contrib/infback9/inffix9.h
new file mode 100644 (file)
index 0000000..ee5671d
--- /dev/null
@@ -0,0 +1,107 @@
+    /* inffix9.h -- table for decoding deflate64 fixed codes
+     * Generated automatically by makefixed9().
+     */
+
+    /* WARNING: this file should *not* be used by applications.
+       It is part of the implementation of this library and is
+       subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112},
+        {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160},
+        {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88},
+        {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208},
+        {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136},
+        {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227},
+        {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},
+        {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124},
+        {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184},
+        {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82},
+        {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196},
+        {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130},
+        {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106},
+        {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},
+        {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118},
+        {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94},
+        {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220},
+        {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131},
+        {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97},
+        {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226},
+        {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121},
+        {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178},
+        {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85},
+        {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},
+        {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154},
+        {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109},
+        {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250},
+        {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115},
+        {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166},
+        {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214},
+        {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},
+        {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0},
+        {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103},
+        {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238},
+        {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127},
+        {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},
+        {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193},
+        {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145},
+        {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104},
+        {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241},
+        {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169},
+        {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92},
+        {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217},
+        {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140},
+        {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163},
+        {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98},
+        {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122},
+        {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181},
+        {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86},
+        {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205},
+        {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134},
+        {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157},
+        {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},
+        {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113},
+        {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89},
+        {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211},
+        {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137},
+        {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3},
+        {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101},
+        {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},
+        {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125},
+        {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187},
+        {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83},
+        {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199},
+        {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151},
+        {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107},
+        {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247},
+        {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119},
+        {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175},
+        {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95},
+        {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},
+        {0,8,79},{0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5},
+        {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513},
+        {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129},
+        {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145},
+        {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4},
+        {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073},
+        {134,5,193},{142,5,49153}
+    };
diff --git a/8.x/zlib/contrib/infback9/inflate9.h b/8.x/zlib/contrib/infback9/inflate9.h
new file mode 100644 (file)
index 0000000..ee9a793
--- /dev/null
@@ -0,0 +1,47 @@
+/* inflate9.h -- internal inflate state definition
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+            LEN,        /* i: waiting for length/lit code */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD         /* got a data error -- remain here until reset */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to the BAD mode -- not shown for clarity)
+
+    Read deflate blocks:
+            TYPE -> STORED or TABLE or LEN or DONE
+            STORED -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN
+    Read deflate codes:
+                LEN -> LEN or TYPE
+ */
+
+/* state maintained between inflate() calls.  Approximately 7K bytes. */
+struct inflate_state {
+        /* sliding window */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+};
diff --git a/8.x/zlib/contrib/infback9/inftree9.c b/8.x/zlib/contrib/infback9/inftree9.c
new file mode 100644 (file)
index 0000000..306c5f1
--- /dev/null
@@ -0,0 +1,324 @@
+/* inftree9.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftree9.h"
+
+#define MAXBITS 15
+
+const char inflate9_copyright[] =
+   " inflate9 1.2.5 Copyright 1995-2010 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int inflate_table9(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code this;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17,
+        19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115,
+        131, 163, 195, 227, 3, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
+        130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
+        133, 133, 133, 133, 144, 73, 195};
+    static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
+        65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
+        4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153};
+    static const unsigned short dext[32] = { /* Distance codes 0..31 extra */
+        128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132,
+        133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138,
+        139, 139, 140, 140, 141, 141, 142, 142};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) return -1;            /* no codes! */
+    for (min = 1; min <= MAXBITS; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked for LENS and DIST tables against
+       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+       the initial root table size constants.  See the comments in inftree9.h
+       for more information.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if ((type == LENS && used >= ENOUGH_LENS) ||
+        (type == DISTS && used >= ENOUGH_DISTS))
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        this.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            this.op = (unsigned char)0;
+            this.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            this.op = (unsigned char)(extra[work[sym]]);
+            this.val = base[work[sym]];
+        }
+        else {
+            this.op = (unsigned char)(32 + 64);         /* end of block */
+            this.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = this;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += 1U << curr;
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if ((type == LENS && used >= ENOUGH_LENS) ||
+                (type == DISTS && used >= ENOUGH_DISTS))
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /*
+       Fill in rest of table for incomplete codes.  This loop is similar to the
+       loop above in incrementing huff for table indices.  It is assumed that
+       len is equal to curr + drop, so there is no loop needed to increment
+       through high index bits.  When the current sub-table is filled, the loop
+       drops back to the root table to fill in any remaining entries there.
+     */
+    this.op = (unsigned char)64;                /* invalid code marker */
+    this.bits = (unsigned char)(len - drop);
+    this.val = (unsigned short)0;
+    while (huff != 0) {
+        /* when done with sub-table, drop back to root table */
+        if (drop != 0 && (huff & mask) != low) {
+            drop = 0;
+            len = root;
+            next = *table;
+            curr = root;
+            this.bits = (unsigned char)len;
+        }
+
+        /* put invalid code marker in table */
+        next[huff >> drop] = this;
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
diff --git a/8.x/zlib/contrib/infback9/inftree9.h b/8.x/zlib/contrib/infback9/inftree9.h
new file mode 100644 (file)
index 0000000..5ab21f0
--- /dev/null
@@ -0,0 +1,61 @@
+/* inftree9.h -- header to use inftree9.c
+ * Copyright (C) 1995-2008 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    100eeeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table.  The maximum number of code structures is
+   1446, which is the sum of 852 for literal/length codes and 594 for distance
+   codes.  These values were found by exhaustive searches using the program
+   examples/enough.c found in the zlib distribtution.  The arguments to that
+   program are the number of symbols, the initial root table size, and the
+   maximum bit length of a code.  "enough 286 9 15" for literal/length codes
+   returns returns 852, and "enough 32 6 15" for distance codes returns 594.
+   The initial root table size (9 or 6) is found in the fifth argument of the
+   inflate_table() calls in infback9.c.  If the root table size is changed,
+   then these maximum sizes would be need to be recalculated and updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 594
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table9() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+extern int inflate_table9 OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
diff --git a/8.x/zlib/contrib/inflate86/inffas86.c b/8.x/zlib/contrib/inflate86/inffas86.c
new file mode 100644 (file)
index 0000000..7292f67
--- /dev/null
@@ -0,0 +1,1157 @@
+/* inffas86.c is a hand tuned assembler version of
+ *
+ * inffast.c -- fast decoding
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * Dec-29-2003 -- I added AMD64 inflate asm support.  This version is also
+ * slightly quicker on x86 systems because, instead of using rep movsb to copy
+ * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
+ * bytes.  I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
+ * from http://fedora.linux.duke.edu/fc1_x86_64
+ * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
+ * 1GB ram.  The 64-bit version is about 4% faster than the 32-bit version,
+ * when decompressing mozilla-source-1.3.tar.gz.
+ *
+ * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+ * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at
+ * the moment.  I have successfully compiled and tested this code with gcc2.96,
+ * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S
+ * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+ * enabled.  I will attempt to merge the MMX code into this version.  Newer
+ * versions of this and inffast.S can be found at
+ * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* Mark Adler's comments from inffast.c: */
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    struct inffast_ar {
+/* 64   32                               x86  x86_64 */
+/* ar offset                              register */
+/*  0    0 */ void *esp;                /* esp save */
+/*  8    4 */ void *ebp;                /* ebp save */
+/* 16    8 */ unsigned char FAR *in;    /* esi rsi  local strm->next_in */
+/* 24   12 */ unsigned char FAR *last;  /*     r9   while in < last */
+/* 32   16 */ unsigned char FAR *out;   /* edi rdi  local strm->next_out */
+/* 40   20 */ unsigned char FAR *beg;   /*          inflate()'s init next_out */
+/* 48   24 */ unsigned char FAR *end;   /*     r10  while out < end */
+/* 56   28 */ unsigned char FAR *window;/*          size of window, wsize!=0 */
+/* 64   32 */ code const FAR *lcode;    /* ebp rbp  local strm->lencode */
+/* 72   36 */ code const FAR *dcode;    /*     r11  local strm->distcode */
+/* 80   40 */ unsigned long hold;       /* edx rdx  local strm->hold */
+/* 88   44 */ unsigned bits;            /* ebx rbx  local strm->bits */
+/* 92   48 */ unsigned wsize;           /*          window size */
+/* 96   52 */ unsigned write;           /*          window write index */
+/*100   56 */ unsigned lmask;           /*     r12  mask for lcode */
+/*104   60 */ unsigned dmask;           /*     r13  mask for dcode */
+/*108   64 */ unsigned len;             /*     r14  match length */
+/*112   68 */ unsigned dist;            /*     r15  match distance */
+/*116   72 */ unsigned status;          /*          set when state chng*/
+    } ar;
+
+#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
+#define PAD_AVAIL_IN 6
+#define PAD_AVAIL_OUT 258
+#else
+#define PAD_AVAIL_IN 5
+#define PAD_AVAIL_OUT 257
+#endif
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    ar.in = strm->next_in;
+    ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
+    ar.out = strm->next_out;
+    ar.beg = ar.out - (start - strm->avail_out);
+    ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
+    ar.wsize = state->wsize;
+    ar.write = state->wnext;
+    ar.window = state->window;
+    ar.hold = state->hold;
+    ar.bits = state->bits;
+    ar.lcode = state->lencode;
+    ar.dcode = state->distcode;
+    ar.lmask = (1U << state->lenbits) - 1;
+    ar.dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+
+    /* align in on 1/2 hold size boundary */
+    while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
+        ar.hold += (unsigned long)*ar.in++ << ar.bits;
+        ar.bits += 8;
+    }
+
+#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
+    __asm__ __volatile__ (
+"        leaq    %0, %%rax\n"
+"        movq    %%rbp, 8(%%rax)\n"       /* save regs rbp and rsp */
+"        movq    %%rsp, (%%rax)\n"
+"        movq    %%rax, %%rsp\n"          /* make rsp point to &ar */
+"        movq    16(%%rsp), %%rsi\n"      /* rsi  = in */
+"        movq    32(%%rsp), %%rdi\n"      /* rdi  = out */
+"        movq    24(%%rsp), %%r9\n"       /* r9   = last */
+"        movq    48(%%rsp), %%r10\n"      /* r10  = end */
+"        movq    64(%%rsp), %%rbp\n"      /* rbp  = lcode */
+"        movq    72(%%rsp), %%r11\n"      /* r11  = dcode */
+"        movq    80(%%rsp), %%rdx\n"      /* rdx  = hold */
+"        movl    88(%%rsp), %%ebx\n"      /* ebx  = bits */
+"        movl    100(%%rsp), %%r12d\n"    /* r12d = lmask */
+"        movl    104(%%rsp), %%r13d\n"    /* r13d = dmask */
+                                          /* r14d = len */
+                                          /* r15d = dist */
+"        cld\n"
+"        cmpq    %%rdi, %%r10\n"
+"        je      .L_one_time\n"           /* if only one decode left */
+"        cmpq    %%rsi, %%r9\n"
+"        je      .L_one_time\n"
+"        jmp     .L_do_loop\n"
+
+".L_one_time:\n"
+"        movq    %%r12, %%r8\n"           /* r8 = lmask */
+"        cmpb    $32, %%bl\n"
+"        ja      .L_get_length_code_one_time\n"
+
+"        lodsl\n"                         /* eax = *(uint *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $32, %%bl\n"             /* bits += 32 */
+"        shlq    %%cl, %%rax\n"
+"        orq     %%rax, %%rdx\n"          /* hold |= *((uint *)in)++ << bits */
+"        jmp     .L_get_length_code_one_time\n"
+
+".align 32,0x90\n"
+".L_while_test:\n"
+"        cmpq    %%rdi, %%r10\n"
+"        jbe     .L_break_loop\n"
+"        cmpq    %%rsi, %%r9\n"
+"        jbe     .L_break_loop\n"
+
+".L_do_loop:\n"
+"        movq    %%r12, %%r8\n"           /* r8 = lmask */
+"        cmpb    $32, %%bl\n"
+"        ja      .L_get_length_code\n"    /* if (32 < bits) */
+
+"        lodsl\n"                         /* eax = *(uint *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $32, %%bl\n"             /* bits += 32 */
+"        shlq    %%cl, %%rax\n"
+"        orq     %%rax, %%rdx\n"          /* hold |= *((uint *)in)++ << bits */
+
+".L_get_length_code:\n"
+"        andq    %%rdx, %%r8\n"            /* r8 &= hold */
+"        movl    (%%rbp,%%r8,4), %%eax\n"  /* eax = lcode[hold & lmask] */
+
+"        movb    %%ah, %%cl\n"            /* cl = this.bits */
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrq    %%cl, %%rdx\n"           /* hold >>= this.bits */
+
+"        testb   %%al, %%al\n"
+"        jnz     .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+"        movq    %%r12, %%r8\n"            /* r8 = lmask */
+"        shrl    $16, %%eax\n"            /* output this.val char */
+"        stosb\n"
+
+".L_get_length_code_one_time:\n"
+"        andq    %%rdx, %%r8\n"            /* r8 &= hold */
+"        movl    (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
+
+".L_dolen:\n"
+"        movb    %%ah, %%cl\n"            /* cl = this.bits */
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrq    %%cl, %%rdx\n"           /* hold >>= this.bits */
+
+"        testb   %%al, %%al\n"
+"        jnz     .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+"        shrl    $16, %%eax\n"            /* output this.val char */
+"        stosb\n"
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_length_base:\n"
+"        movl    %%eax, %%r14d\n"         /* len = this */
+"        shrl    $16, %%r14d\n"           /* len = this.val */
+"        movb    %%al, %%cl\n"
+
+"        testb   $16, %%al\n"
+"        jz      .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
+"        andb    $15, %%cl\n"             /* op &= 15 */
+"        jz      .L_decode_distance\n"    /* if (!op) */
+
+".L_add_bits_to_len:\n"
+"        subb    %%cl, %%bl\n"
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        shrq    %%cl, %%rdx\n"
+"        addl    %%eax, %%r14d\n"         /* len += hold & mask[op] */
+
+".L_decode_distance:\n"
+"        movq    %%r13, %%r8\n"           /* r8 = dmask */
+"        cmpb    $32, %%bl\n"
+"        ja      .L_get_distance_code\n"  /* if (32 < bits) */
+
+"        lodsl\n"                         /* eax = *(uint *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $32, %%bl\n"             /* bits += 32 */
+"        shlq    %%cl, %%rax\n"
+"        orq     %%rax, %%rdx\n"          /* hold |= *((uint *)in)++ << bits */
+
+".L_get_distance_code:\n"
+"        andq    %%rdx, %%r8\n"           /* r8 &= hold */
+"        movl    (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */
+
+".L_dodist:\n"
+"        movl    %%eax, %%r15d\n"         /* dist = this */
+"        shrl    $16, %%r15d\n"           /* dist = this.val */
+"        movb    %%ah, %%cl\n"
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrq    %%cl, %%rdx\n"           /* hold >>= this.bits */
+"        movb    %%al, %%cl\n"            /* cl = this.op */
+
+"        testb   $16, %%al\n"             /* if ((op & 16) == 0) */
+"        jz      .L_test_for_second_level_dist\n"
+"        andb    $15, %%cl\n"             /* op &= 15 */
+"        jz      .L_check_dist_one\n"
+
+".L_add_bits_to_dist:\n"
+"        subb    %%cl, %%bl\n"
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"                 /* (1 << op) - 1 */
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        shrq    %%cl, %%rdx\n"
+"        addl    %%eax, %%r15d\n"         /* dist += hold & ((1 << op) - 1) */
+
+".L_check_window:\n"
+"        movq    %%rsi, %%r8\n"           /* save in so from can use it's reg */
+"        movq    %%rdi, %%rax\n"
+"        subq    40(%%rsp), %%rax\n"      /* nbytes = out - beg */
+
+"        cmpl    %%r15d, %%eax\n"
+"        jb      .L_clip_window\n"        /* if (dist > nbytes) 4.2% */
+
+"        movl    %%r14d, %%ecx\n"         /* ecx = len */
+"        movq    %%rdi, %%rsi\n"
+"        subq    %%r15, %%rsi\n"          /* from = out - dist */
+
+"        sarl    %%ecx\n"
+"        jnc     .L_copy_two\n"           /* if len % 2 == 0 */
+
+"        rep     movsw\n"
+"        movb    (%%rsi), %%al\n"
+"        movb    %%al, (%%rdi)\n"
+"        incq    %%rdi\n"
+
+"        movq    %%r8, %%rsi\n"           /* move in back to %rsi, toss from */
+"        jmp     .L_while_test\n"
+
+".L_copy_two:\n"
+"        rep     movsw\n"
+"        movq    %%r8, %%rsi\n"           /* move in back to %rsi, toss from */
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_check_dist_one:\n"
+"        cmpl    $1, %%r15d\n"            /* if dist 1, is a memset */
+"        jne     .L_check_window\n"
+"        cmpq    %%rdi, 40(%%rsp)\n"      /* if out == beg, outside window */
+"        je      .L_check_window\n"
+
+"        movl    %%r14d, %%ecx\n"         /* ecx = len */
+"        movb    -1(%%rdi), %%al\n"
+"        movb    %%al, %%ah\n"
+
+"        sarl    %%ecx\n"
+"        jnc     .L_set_two\n"
+"        movb    %%al, (%%rdi)\n"
+"        incq    %%rdi\n"
+
+".L_set_two:\n"
+"        rep     stosw\n"
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_length:\n"
+"        testb   $64, %%al\n"
+"        jnz     .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
+
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"         /* eax &= hold */
+"        addl    %%r14d, %%eax\n"        /* eax += len */
+"        movl    (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
+"        jmp     .L_dolen\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_dist:\n"
+"        testb   $64, %%al\n"
+"        jnz     .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
+
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"         /* eax &= hold */
+"        addl    %%r15d, %%eax\n"        /* eax += dist */
+"        movl    (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
+"        jmp     .L_dodist\n"
+
+".align 32,0x90\n"
+".L_clip_window:\n"
+"        movl    %%eax, %%ecx\n"         /* ecx = nbytes */
+"        movl    92(%%rsp), %%eax\n"     /* eax = wsize, prepare for dist cmp */
+"        negl    %%ecx\n"                /* nbytes = -nbytes */
+
+"        cmpl    %%r15d, %%eax\n"
+"        jb      .L_invalid_distance_too_far\n" /* if (dist > wsize) */
+
+"        addl    %%r15d, %%ecx\n"         /* nbytes = dist - nbytes */
+"        cmpl    $0, 96(%%rsp)\n"
+"        jne     .L_wrap_around_window\n" /* if (write != 0) */
+
+"        movq    56(%%rsp), %%rsi\n"     /* from  = window */
+"        subl    %%ecx, %%eax\n"         /* eax  -= nbytes */
+"        addq    %%rax, %%rsi\n"         /* from += wsize - nbytes */
+
+"        movl    %%r14d, %%eax\n"        /* eax = len */
+"        cmpl    %%ecx, %%r14d\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* eax -= nbytes */
+"        rep     movsb\n"
+"        movq    %%rdi, %%rsi\n"
+"        subq    %%r15, %%rsi\n"         /* from = &out[ -dist ] */
+"        jmp     .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_wrap_around_window:\n"
+"        movl    96(%%rsp), %%eax\n"     /* eax = write */
+"        cmpl    %%eax, %%ecx\n"
+"        jbe     .L_contiguous_in_window\n" /* if (write >= nbytes) */
+
+"        movl    92(%%rsp), %%esi\n"     /* from  = wsize */
+"        addq    56(%%rsp), %%rsi\n"     /* from += window */
+"        addq    %%rax, %%rsi\n"         /* from += write */
+"        subq    %%rcx, %%rsi\n"         /* from -= nbytes */
+"        subl    %%eax, %%ecx\n"         /* nbytes -= write */
+
+"        movl    %%r14d, %%eax\n"        /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movq    56(%%rsp), %%rsi\n"     /* from = window */
+"        movl    96(%%rsp), %%ecx\n"     /* nbytes = write */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movq    %%rdi, %%rsi\n"
+"        subq    %%r15, %%rsi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_contiguous_in_window:\n"
+"        movq    56(%%rsp), %%rsi\n"     /* rsi = window */
+"        addq    %%rax, %%rsi\n"
+"        subq    %%rcx, %%rsi\n"         /* from += write - nbytes */
+
+"        movl    %%r14d, %%eax\n"        /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movq    %%rdi, %%rsi\n"
+"        subq    %%r15, %%rsi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"           /* if (nbytes >= len) */
+
+".align 32,0x90\n"
+".L_do_copy:\n"
+"        movl    %%eax, %%ecx\n"         /* ecx = len */
+"        rep     movsb\n"
+
+"        movq    %%r8, %%rsi\n"          /* move in back to %esi, toss from */
+"        jmp     .L_while_test\n"
+
+".L_test_for_end_of_block:\n"
+"        testb   $32, %%al\n"
+"        jz      .L_invalid_literal_length_code\n"
+"        movl    $1, 116(%%rsp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_literal_length_code:\n"
+"        movl    $2, 116(%%rsp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_distance_code:\n"
+"        movl    $3, 116(%%rsp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_distance_too_far:\n"
+"        movl    $4, 116(%%rsp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_break_loop:\n"
+"        movl    $0, 116(%%rsp)\n"
+
+".L_break_loop_with_status:\n"
+/* put in, out, bits, and hold back into ar and pop esp */
+"        movq    %%rsi, 16(%%rsp)\n"     /* in */
+"        movq    %%rdi, 32(%%rsp)\n"     /* out */
+"        movl    %%ebx, 88(%%rsp)\n"     /* bits */
+"        movq    %%rdx, 80(%%rsp)\n"     /* hold */
+"        movq    (%%rsp), %%rax\n"       /* restore rbp and rsp */
+"        movq    8(%%rsp), %%rbp\n"
+"        movq    %%rax, %%rsp\n"
+          :
+          : "m" (ar)
+          : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
+            "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+    );
+#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )
+    __asm__ __volatile__ (
+"        leal    %0, %%eax\n"
+"        movl    %%esp, (%%eax)\n"        /* save esp, ebp */
+"        movl    %%ebp, 4(%%eax)\n"
+"        movl    %%eax, %%esp\n"
+"        movl    8(%%esp), %%esi\n"       /* esi = in */
+"        movl    16(%%esp), %%edi\n"      /* edi = out */
+"        movl    40(%%esp), %%edx\n"      /* edx = hold */
+"        movl    44(%%esp), %%ebx\n"      /* ebx = bits */
+"        movl    32(%%esp), %%ebp\n"      /* ebp = lcode */
+
+"        cld\n"
+"        jmp     .L_do_loop\n"
+
+".align 32,0x90\n"
+".L_while_test:\n"
+"        cmpl    %%edi, 24(%%esp)\n"      /* out < end */
+"        jbe     .L_break_loop\n"
+"        cmpl    %%esi, 12(%%esp)\n"      /* in < last */
+"        jbe     .L_break_loop\n"
+
+".L_do_loop:\n"
+"        cmpb    $15, %%bl\n"
+"        ja      .L_get_length_code\n"    /* if (15 < bits) */
+
+"        xorl    %%eax, %%eax\n"
+"        lodsw\n"                         /* al = *(ushort *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $16, %%bl\n"             /* bits += 16 */
+"        shll    %%cl, %%eax\n"
+"        orl     %%eax, %%edx\n"        /* hold |= *((ushort *)in)++ << bits */
+
+".L_get_length_code:\n"
+"        movl    56(%%esp), %%eax\n"      /* eax = lmask */
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        movl    (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */
+
+".L_dolen:\n"
+"        movb    %%ah, %%cl\n"            /* cl = this.bits */
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrl    %%cl, %%edx\n"           /* hold >>= this.bits */
+
+"        testb   %%al, %%al\n"
+"        jnz     .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+"        shrl    $16, %%eax\n"            /* output this.val char */
+"        stosb\n"
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_length_base:\n"
+"        movl    %%eax, %%ecx\n"          /* len = this */
+"        shrl    $16, %%ecx\n"            /* len = this.val */
+"        movl    %%ecx, 64(%%esp)\n"      /* save len */
+"        movb    %%al, %%cl\n"
+
+"        testb   $16, %%al\n"
+"        jz      .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
+"        andb    $15, %%cl\n"             /* op &= 15 */
+"        jz      .L_decode_distance\n"    /* if (!op) */
+"        cmpb    %%cl, %%bl\n"
+"        jae     .L_add_bits_to_len\n"    /* if (op <= bits) */
+
+"        movb    %%cl, %%ch\n"            /* stash op in ch, freeing cl */
+"        xorl    %%eax, %%eax\n"
+"        lodsw\n"                         /* al = *(ushort *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $16, %%bl\n"             /* bits += 16 */
+"        shll    %%cl, %%eax\n"
+"        orl     %%eax, %%edx\n"         /* hold |= *((ushort *)in)++ << bits */
+"        movb    %%ch, %%cl\n"            /* move op back to ecx */
+
+".L_add_bits_to_len:\n"
+"        subb    %%cl, %%bl\n"
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        shrl    %%cl, %%edx\n"
+"        addl    %%eax, 64(%%esp)\n"      /* len += hold & mask[op] */
+
+".L_decode_distance:\n"
+"        cmpb    $15, %%bl\n"
+"        ja      .L_get_distance_code\n"  /* if (15 < bits) */
+
+"        xorl    %%eax, %%eax\n"
+"        lodsw\n"                         /* al = *(ushort *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $16, %%bl\n"             /* bits += 16 */
+"        shll    %%cl, %%eax\n"
+"        orl     %%eax, %%edx\n"         /* hold |= *((ushort *)in)++ << bits */
+
+".L_get_distance_code:\n"
+"        movl    60(%%esp), %%eax\n"      /* eax = dmask */
+"        movl    36(%%esp), %%ecx\n"      /* ecx = dcode */
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        movl    (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */
+
+".L_dodist:\n"
+"        movl    %%eax, %%ebp\n"          /* dist = this */
+"        shrl    $16, %%ebp\n"            /* dist = this.val */
+"        movb    %%ah, %%cl\n"
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrl    %%cl, %%edx\n"           /* hold >>= this.bits */
+"        movb    %%al, %%cl\n"            /* cl = this.op */
+
+"        testb   $16, %%al\n"             /* if ((op & 16) == 0) */
+"        jz      .L_test_for_second_level_dist\n"
+"        andb    $15, %%cl\n"             /* op &= 15 */
+"        jz      .L_check_dist_one\n"
+"        cmpb    %%cl, %%bl\n"
+"        jae     .L_add_bits_to_dist\n"   /* if (op <= bits) 97.6% */
+
+"        movb    %%cl, %%ch\n"            /* stash op in ch, freeing cl */
+"        xorl    %%eax, %%eax\n"
+"        lodsw\n"                         /* al = *(ushort *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $16, %%bl\n"             /* bits += 16 */
+"        shll    %%cl, %%eax\n"
+"        orl     %%eax, %%edx\n"        /* hold |= *((ushort *)in)++ << bits */
+"        movb    %%ch, %%cl\n"            /* move op back to ecx */
+
+".L_add_bits_to_dist:\n"
+"        subb    %%cl, %%bl\n"
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"                 /* (1 << op) - 1 */
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        shrl    %%cl, %%edx\n"
+"        addl    %%eax, %%ebp\n"          /* dist += hold & ((1 << op) - 1) */
+
+".L_check_window:\n"
+"        movl    %%esi, 8(%%esp)\n"       /* save in so from can use it's reg */
+"        movl    %%edi, %%eax\n"
+"        subl    20(%%esp), %%eax\n"      /* nbytes = out - beg */
+
+"        cmpl    %%ebp, %%eax\n"
+"        jb      .L_clip_window\n"        /* if (dist > nbytes) 4.2% */
+
+"        movl    64(%%esp), %%ecx\n"      /* ecx = len */
+"        movl    %%edi, %%esi\n"
+"        subl    %%ebp, %%esi\n"          /* from = out - dist */
+
+"        sarl    %%ecx\n"
+"        jnc     .L_copy_two\n"           /* if len % 2 == 0 */
+
+"        rep     movsw\n"
+"        movb    (%%esi), %%al\n"
+"        movb    %%al, (%%edi)\n"
+"        incl    %%edi\n"
+
+"        movl    8(%%esp), %%esi\n"       /* move in back to %esi, toss from */
+"        movl    32(%%esp), %%ebp\n"      /* ebp = lcode */
+"        jmp     .L_while_test\n"
+
+".L_copy_two:\n"
+"        rep     movsw\n"
+"        movl    8(%%esp), %%esi\n"       /* move in back to %esi, toss from */
+"        movl    32(%%esp), %%ebp\n"      /* ebp = lcode */
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_check_dist_one:\n"
+"        cmpl    $1, %%ebp\n"            /* if dist 1, is a memset */
+"        jne     .L_check_window\n"
+"        cmpl    %%edi, 20(%%esp)\n"
+"        je      .L_check_window\n"      /* out == beg, if outside window */
+
+"        movl    64(%%esp), %%ecx\n"      /* ecx = len */
+"        movb    -1(%%edi), %%al\n"
+"        movb    %%al, %%ah\n"
+
+"        sarl    %%ecx\n"
+"        jnc     .L_set_two\n"
+"        movb    %%al, (%%edi)\n"
+"        incl    %%edi\n"
+
+".L_set_two:\n"
+"        rep     stosw\n"
+"        movl    32(%%esp), %%ebp\n"      /* ebp = lcode */
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_length:\n"
+"        testb   $64, %%al\n"
+"        jnz     .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
+
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"         /* eax &= hold */
+"        addl    64(%%esp), %%eax\n"     /* eax += len */
+"        movl    (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
+"        jmp     .L_dolen\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_dist:\n"
+"        testb   $64, %%al\n"
+"        jnz     .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
+
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"         /* eax &= hold */
+"        addl    %%ebp, %%eax\n"         /* eax += dist */
+"        movl    36(%%esp), %%ecx\n"     /* ecx = dcode */
+"        movl    (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
+"        jmp     .L_dodist\n"
+
+".align 32,0x90\n"
+".L_clip_window:\n"
+"        movl    %%eax, %%ecx\n"
+"        movl    48(%%esp), %%eax\n"     /* eax = wsize */
+"        negl    %%ecx\n"                /* nbytes = -nbytes */
+"        movl    28(%%esp), %%esi\n"     /* from = window */
+
+"        cmpl    %%ebp, %%eax\n"
+"        jb      .L_invalid_distance_too_far\n" /* if (dist > wsize) */
+
+"        addl    %%ebp, %%ecx\n"         /* nbytes = dist - nbytes */
+"        cmpl    $0, 52(%%esp)\n"
+"        jne     .L_wrap_around_window\n" /* if (write != 0) */
+
+"        subl    %%ecx, %%eax\n"
+"        addl    %%eax, %%esi\n"         /* from += wsize - nbytes */
+
+"        movl    64(%%esp), %%eax\n"     /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movl    %%edi, %%esi\n"
+"        subl    %%ebp, %%esi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_wrap_around_window:\n"
+"        movl    52(%%esp), %%eax\n"     /* eax = write */
+"        cmpl    %%eax, %%ecx\n"
+"        jbe     .L_contiguous_in_window\n" /* if (write >= nbytes) */
+
+"        addl    48(%%esp), %%esi\n"     /* from += wsize */
+"        addl    %%eax, %%esi\n"         /* from += write */
+"        subl    %%ecx, %%esi\n"         /* from -= nbytes */
+"        subl    %%eax, %%ecx\n"         /* nbytes -= write */
+
+"        movl    64(%%esp), %%eax\n"     /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movl    28(%%esp), %%esi\n"     /* from = window */
+"        movl    52(%%esp), %%ecx\n"     /* nbytes = write */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movl    %%edi, %%esi\n"
+"        subl    %%ebp, %%esi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_contiguous_in_window:\n"
+"        addl    %%eax, %%esi\n"
+"        subl    %%ecx, %%esi\n"         /* from += write - nbytes */
+
+"        movl    64(%%esp), %%eax\n"     /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movl    %%edi, %%esi\n"
+"        subl    %%ebp, %%esi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"           /* if (nbytes >= len) */
+
+".align 32,0x90\n"
+".L_do_copy:\n"
+"        movl    %%eax, %%ecx\n"
+"        rep     movsb\n"
+
+"        movl    8(%%esp), %%esi\n"      /* move in back to %esi, toss from */
+"        movl    32(%%esp), %%ebp\n"     /* ebp = lcode */
+"        jmp     .L_while_test\n"
+
+".L_test_for_end_of_block:\n"
+"        testb   $32, %%al\n"
+"        jz      .L_invalid_literal_length_code\n"
+"        movl    $1, 72(%%esp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_literal_length_code:\n"
+"        movl    $2, 72(%%esp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_distance_code:\n"
+"        movl    $3, 72(%%esp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_distance_too_far:\n"
+"        movl    8(%%esp), %%esi\n"
+"        movl    $4, 72(%%esp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_break_loop:\n"
+"        movl    $0, 72(%%esp)\n"
+
+".L_break_loop_with_status:\n"
+/* put in, out, bits, and hold back into ar and pop esp */
+"        movl    %%esi, 8(%%esp)\n"      /* save in */
+"        movl    %%edi, 16(%%esp)\n"     /* save out */
+"        movl    %%ebx, 44(%%esp)\n"     /* save bits */
+"        movl    %%edx, 40(%%esp)\n"     /* save hold */
+"        movl    4(%%esp), %%ebp\n"      /* restore esp, ebp */
+"        movl    (%%esp), %%esp\n"
+          :
+          : "m" (ar)
+          : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
+    );
+#elif defined( _MSC_VER ) && ! defined( _M_AMD64 )
+    __asm {
+       lea     eax, ar
+       mov     [eax], esp         /* save esp, ebp */
+       mov     [eax+4], ebp
+       mov     esp, eax
+       mov     esi, [esp+8]       /* esi = in */
+       mov     edi, [esp+16]      /* edi = out */
+       mov     edx, [esp+40]      /* edx = hold */
+       mov     ebx, [esp+44]      /* ebx = bits */
+       mov     ebp, [esp+32]      /* ebp = lcode */
+
+       cld
+       jmp     L_do_loop
+
+ALIGN 4
+L_while_test:
+       cmp     [esp+24], edi
+       jbe     L_break_loop
+       cmp     [esp+12], esi
+       jbe     L_break_loop
+
+L_do_loop:
+       cmp     bl, 15
+       ja      L_get_length_code    /* if (15 < bits) */
+
+       xor     eax, eax
+       lodsw                         /* al = *(ushort *)in++ */
+       mov     cl, bl            /* cl = bits, needs it for shifting */
+       add     bl, 16             /* bits += 16 */
+       shl     eax, cl
+       or      edx, eax        /* hold |= *((ushort *)in)++ << bits */
+
+L_get_length_code:
+       mov     eax, [esp+56]      /* eax = lmask */
+       and     eax, edx          /* eax &= hold */
+       mov     eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */
+
+L_dolen:
+       mov     cl, ah            /* cl = this.bits */
+       sub     bl, ah            /* bits -= this.bits */
+       shr     edx, cl           /* hold >>= this.bits */
+
+       test    al, al
+       jnz     L_test_for_length_base /* if (op != 0) 45.7% */
+
+       shr     eax, 16            /* output this.val char */
+       stosb
+       jmp     L_while_test
+
+ALIGN 4
+L_test_for_length_base:
+       mov     ecx, eax          /* len = this */
+       shr     ecx, 16            /* len = this.val */
+       mov     [esp+64], ecx      /* save len */
+       mov     cl, al
+
+       test    al, 16
+       jz      L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
+       and     cl, 15             /* op &= 15 */
+       jz      L_decode_distance    /* if (!op) */
+       cmp     bl, cl
+       jae     L_add_bits_to_len    /* if (op <= bits) */
+
+       mov     ch, cl            /* stash op in ch, freeing cl */
+       xor     eax, eax
+       lodsw                         /* al = *(ushort *)in++ */
+       mov     cl, bl            /* cl = bits, needs it for shifting */
+       add     bl, 16             /* bits += 16 */
+       shl     eax, cl
+       or      edx, eax         /* hold |= *((ushort *)in)++ << bits */
+       mov     cl, ch            /* move op back to ecx */
+
+L_add_bits_to_len:
+       sub     bl, cl
+       xor     eax, eax
+       inc     eax
+       shl     eax, cl
+       dec     eax
+       and     eax, edx          /* eax &= hold */
+       shr     edx, cl
+       add     [esp+64], eax      /* len += hold & mask[op] */
+
+L_decode_distance:
+       cmp     bl, 15
+       ja      L_get_distance_code  /* if (15 < bits) */
+
+       xor     eax, eax
+       lodsw                         /* al = *(ushort *)in++ */
+       mov     cl, bl            /* cl = bits, needs it for shifting */
+       add     bl, 16             /* bits += 16 */
+       shl     eax, cl
+       or      edx, eax         /* hold |= *((ushort *)in)++ << bits */
+
+L_get_distance_code:
+       mov     eax, [esp+60]      /* eax = dmask */
+       mov     ecx, [esp+36]      /* ecx = dcode */
+       and     eax, edx          /* eax &= hold */
+       mov     eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */
+
+L_dodist:
+       mov     ebp, eax          /* dist = this */
+       shr     ebp, 16            /* dist = this.val */
+       mov     cl, ah
+       sub     bl, ah            /* bits -= this.bits */
+       shr     edx, cl           /* hold >>= this.bits */
+       mov     cl, al            /* cl = this.op */
+
+       test    al, 16             /* if ((op & 16) == 0) */
+       jz      L_test_for_second_level_dist
+       and     cl, 15             /* op &= 15 */
+       jz      L_check_dist_one
+       cmp     bl, cl
+       jae     L_add_bits_to_dist   /* if (op <= bits) 97.6% */
+
+       mov     ch, cl            /* stash op in ch, freeing cl */
+       xor     eax, eax
+       lodsw                         /* al = *(ushort *)in++ */
+       mov     cl, bl            /* cl = bits, needs it for shifting */
+       add     bl, 16             /* bits += 16 */
+       shl     eax, cl
+       or      edx, eax        /* hold |= *((ushort *)in)++ << bits */
+       mov     cl, ch            /* move op back to ecx */
+
+L_add_bits_to_dist:
+       sub     bl, cl
+       xor     eax, eax
+       inc     eax
+       shl     eax, cl
+       dec     eax                 /* (1 << op) - 1 */
+       and     eax, edx          /* eax &= hold */
+       shr     edx, cl
+       add     ebp, eax          /* dist += hold & ((1 << op) - 1) */
+
+L_check_window:
+       mov     [esp+8], esi       /* save in so from can use it's reg */
+       mov     eax, edi
+       sub     eax, [esp+20]      /* nbytes = out - beg */
+
+       cmp     eax, ebp
+       jb      L_clip_window        /* if (dist > nbytes) 4.2% */
+
+       mov     ecx, [esp+64]      /* ecx = len */
+       mov     esi, edi
+       sub     esi, ebp          /* from = out - dist */
+
+       sar     ecx, 1
+       jnc     L_copy_two
+
+       rep     movsw
+       mov     al, [esi]
+       mov     [edi], al
+       inc     edi
+
+       mov     esi, [esp+8]      /* move in back to %esi, toss from */
+       mov     ebp, [esp+32]     /* ebp = lcode */
+       jmp     L_while_test
+
+L_copy_two:
+       rep     movsw
+       mov     esi, [esp+8]      /* move in back to %esi, toss from */
+       mov     ebp, [esp+32]     /* ebp = lcode */
+       jmp     L_while_test
+
+ALIGN 4
+L_check_dist_one:
+       cmp     ebp, 1            /* if dist 1, is a memset */
+       jne     L_check_window
+       cmp     [esp+20], edi
+       je      L_check_window    /* out == beg, if outside window */
+
+       mov     ecx, [esp+64]     /* ecx = len */
+       mov     al, [edi-1]
+       mov     ah, al
+
+       sar     ecx, 1
+       jnc     L_set_two
+       mov     [edi], al         /* memset out with from[-1] */
+       inc     edi
+
+L_set_two:
+       rep     stosw
+       mov     ebp, [esp+32]     /* ebp = lcode */
+       jmp     L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+       test    al, 64
+       jnz     L_test_for_end_of_block /* if ((op & 64) != 0) */
+
+       xor     eax, eax
+       inc     eax
+       shl     eax, cl
+       dec     eax
+       and     eax, edx         /* eax &= hold */
+       add     eax, [esp+64]     /* eax += len */
+       mov     eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/
+       jmp     L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+       test    al, 64
+       jnz     L_invalid_distance_code /* if ((op & 64) != 0) */
+
+       xor     eax, eax
+       inc     eax
+       shl     eax, cl
+       dec     eax
+       and     eax, edx         /* eax &= hold */
+       add     eax, ebp         /* eax += dist */
+       mov     ecx, [esp+36]     /* ecx = dcode */
+       mov     eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/
+       jmp     L_dodist
+
+ALIGN 4
+L_clip_window:
+       mov     ecx, eax
+       mov     eax, [esp+48]     /* eax = wsize */
+       neg     ecx                /* nbytes = -nbytes */
+       mov     esi, [esp+28]     /* from = window */
+
+       cmp     eax, ebp
+       jb      L_invalid_distance_too_far /* if (dist > wsize) */
+
+       add     ecx, ebp         /* nbytes = dist - nbytes */
+       cmp     dword ptr [esp+52], 0
+       jne     L_wrap_around_window /* if (write != 0) */
+
+       sub     eax, ecx
+       add     esi, eax         /* from += wsize - nbytes */
+
+       mov     eax, [esp+64]    /* eax = len */
+       cmp     eax, ecx
+       jbe     L_do_copy          /* if (nbytes >= len) */
+
+       sub     eax, ecx         /* len -= nbytes */
+       rep     movsb
+       mov     esi, edi
+       sub     esi, ebp         /* from = out - dist */
+       jmp     L_do_copy
+
+ALIGN 4
+L_wrap_around_window:
+       mov     eax, [esp+52]    /* eax = write */
+       cmp     ecx, eax
+       jbe     L_contiguous_in_window /* if (write >= nbytes) */
+
+       add     esi, [esp+48]    /* from += wsize */
+       add     esi, eax         /* from += write */
+       sub     esi, ecx         /* from -= nbytes */
+       sub     ecx, eax         /* nbytes -= write */
+
+       mov     eax, [esp+64]    /* eax = len */
+       cmp     eax, ecx
+       jbe     L_do_copy          /* if (nbytes >= len) */
+
+       sub     eax, ecx         /* len -= nbytes */
+       rep     movsb
+       mov     esi, [esp+28]     /* from = window */
+       mov     ecx, [esp+52]     /* nbytes = write */
+       cmp     eax, ecx
+       jbe     L_do_copy          /* if (nbytes >= len) */
+
+       sub     eax, ecx         /* len -= nbytes */
+       rep     movsb
+       mov     esi, edi
+       sub     esi, ebp         /* from = out - dist */
+       jmp     L_do_copy
+
+ALIGN 4
+L_contiguous_in_window:
+       add     esi, eax
+       sub     esi, ecx         /* from += write - nbytes */
+
+       mov     eax, [esp+64]    /* eax = len */
+       cmp     eax, ecx
+       jbe     L_do_copy          /* if (nbytes >= len) */
+
+       sub     eax, ecx         /* len -= nbytes */
+       rep     movsb
+       mov     esi, edi
+       sub     esi, ebp         /* from = out - dist */
+       jmp     L_do_copy
+
+ALIGN 4
+L_do_copy:
+       mov     ecx, eax
+       rep     movsb
+
+       mov     esi, [esp+8]      /* move in back to %esi, toss from */
+       mov     ebp, [esp+32]     /* ebp = lcode */
+       jmp     L_while_test
+
+L_test_for_end_of_block:
+       test    al, 32
+       jz      L_invalid_literal_length_code
+       mov     dword ptr [esp+72], 1
+       jmp     L_break_loop_with_status
+
+L_invalid_literal_length_code:
+       mov     dword ptr [esp+72], 2
+       jmp     L_break_loop_with_status
+
+L_invalid_distance_code:
+       mov     dword ptr [esp+72], 3
+       jmp     L_break_loop_with_status
+
+L_invalid_distance_too_far:
+       mov     esi, [esp+4]
+       mov     dword ptr [esp+72], 4
+       jmp     L_break_loop_with_status
+
+L_break_loop:
+       mov     dword ptr [esp+72], 0
+
+L_break_loop_with_status:
+/* put in, out, bits, and hold back into ar and pop esp */
+       mov     [esp+8], esi     /* save in */
+       mov     [esp+16], edi    /* save out */
+       mov     [esp+44], ebx    /* save bits */
+       mov     [esp+40], edx    /* save hold */
+       mov     ebp, [esp+4]     /* restore esp, ebp */
+       mov     esp, [esp]
+    }
+#else
+#error "x86 architecture not defined"
+#endif
+
+    if (ar.status > 1) {
+        if (ar.status == 2)
+            strm->msg = "invalid literal/length code";
+        else if (ar.status == 3)
+            strm->msg = "invalid distance code";
+        else
+            strm->msg = "invalid distance too far back";
+        state->mode = BAD;
+    }
+    else if ( ar.status == 1 ) {
+        state->mode = TYPE;
+    }
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    ar.len = ar.bits >> 3;
+    ar.in -= ar.len;
+    ar.bits -= ar.len << 3;
+    ar.hold &= (1U << ar.bits) - 1;
+
+    /* update state and return */
+    strm->next_in = ar.in;
+    strm->next_out = ar.out;
+    strm->avail_in = (unsigned)(ar.in < ar.last ?
+                                PAD_AVAIL_IN + (ar.last - ar.in) :
+                                PAD_AVAIL_IN - (ar.in - ar.last));
+    strm->avail_out = (unsigned)(ar.out < ar.end ?
+                                 PAD_AVAIL_OUT + (ar.end - ar.out) :
+                                 PAD_AVAIL_OUT - (ar.out - ar.end));
+    state->hold = ar.hold;
+    state->bits = ar.bits;
+    return;
+}
+
diff --git a/8.x/zlib/contrib/inflate86/inffast.S b/8.x/zlib/contrib/inflate86/inffast.S
new file mode 100644 (file)
index 0000000..2245a29
--- /dev/null
@@ -0,0 +1,1368 @@
+/*
+ * inffast.S is a hand tuned assembler version of:
+ *
+ * inffast.c -- fast decoding
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * This version (Jan-23-2003) of inflate_fast was coded and tested under
+ * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution.  On that
+ * machine, I found that gzip style archives decompressed about 20% faster than
+ * the gcc-3.2 -O3 -fomit-frame-pointer compiled version.  Your results will
+ * depend on how large of a buffer is used for z_stream.next_in & next_out
+ * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in
+ * stream processing I/O and crc32/addler32.  In my case, this routine used
+ * 70% of the cpu time and crc32 used 20%.
+ *
+ * I am confident that this version will work in the general case, but I have
+ * not tested a wide variety of datasets or a wide variety of platforms.
+ *
+ * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating.
+ * It should be a runtime flag instead of compile time flag...
+ *
+ * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction.
+ * With -DUSE_MMX, only MMX code is compiled.  With -DNO_MMX, only non-MMX code
+ * is compiled.  Without either option, runtime detection is enabled.  Runtime
+ * detection should work on all modern cpus and the recomended algorithm (flip
+ * ID bit on eflags and then use the cpuid instruction) is used in many
+ * multimedia applications.  Tested under win2k with gcc-2.95 and gas-2.12
+ * distributed with cygwin3.  Compiling with gcc-2.95 -c inffast.S -o
+ * inffast.obj generates a COFF object which can then be linked with MSVC++
+ * compiled code.  Tested under FreeBSD 4.7 with gcc-2.95.
+ *
+ * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and
+ * slower than compiler generated code).  Adjusted cpuid check to use the MMX
+ * code only for Pentiums < P4 until I have more data on the P4.  Speed
+ * improvment is only about 15% on the Athlon when compared with code generated
+ * with MSVC++.  Not sure yet, but I think the P4 will also be slower using the
+ * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and
+ * have less latency than MMX ops.  Added code to buffer the last 11 bytes of
+ * the input stream since the MMX code grabs bits in chunks of 32, which
+ * differs from the inffast.c algorithm.  I don't think there would have been
+ * read overruns where a page boundary was crossed (a segfault), but there
+ * could have been overruns when next_in ends on unaligned memory (unintialized
+ * memory read).
+ *
+ * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX.  I created a C
+ * version of the non-MMX code so that it doesn't depend on zstrm and zstate
+ * structure offsets which are hard coded in this file.  This was last tested
+ * with zlib-1.2.0 which is currently in beta testing, newer versions of this
+ * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and
+ * http://www.charm.net/~christop/zlib/
+ */
+
+
+/*
+ * if you have underscore linking problems (_inflate_fast undefined), try
+ * using -DGAS_COFF
+ */
+#if ! defined( GAS_COFF ) && ! defined( GAS_ELF )
+
+#if defined( WIN32 ) || defined( __CYGWIN__ )
+#define GAS_COFF /* windows object format */
+#else
+#define GAS_ELF
+#endif
+
+#endif /* ! GAS_COFF && ! GAS_ELF */
+
+
+#if defined( GAS_COFF )
+
+/* coff externals have underscores */
+#define inflate_fast _inflate_fast
+#define inflate_fast_use_mmx _inflate_fast_use_mmx
+
+#endif /* GAS_COFF */
+
+
+.file "inffast.S"
+
+.globl inflate_fast
+
+.text
+.align 4,0
+.L_invalid_literal_length_code_msg:
+.string "invalid literal/length code"
+
+.align 4,0
+.L_invalid_distance_code_msg:
+.string "invalid distance code"
+
+.align 4,0
+.L_invalid_distance_too_far_msg:
+.string "invalid distance too far back"
+
+#if ! defined( NO_MMX )
+.align 4,0
+.L_mask: /* mask[N] = ( 1 << N ) - 1 */
+.long 0
+.long 1
+.long 3
+.long 7
+.long 15
+.long 31
+.long 63
+.long 127
+.long 255
+.long 511
+.long 1023
+.long 2047
+.long 4095
+.long 8191
+.long 16383
+.long 32767
+.long 65535
+.long 131071
+.long 262143
+.long 524287
+.long 1048575
+.long 2097151
+.long 4194303
+.long 8388607
+.long 16777215
+.long 33554431
+.long 67108863
+.long 134217727
+.long 268435455
+.long 536870911
+.long 1073741823
+.long 2147483647
+.long 4294967295
+#endif /* NO_MMX */
+
+.text
+
+/*
+ * struct z_stream offsets, in zlib.h
+ */
+#define next_in_strm   0   /* strm->next_in */
+#define avail_in_strm  4   /* strm->avail_in */
+#define next_out_strm  12  /* strm->next_out */
+#define avail_out_strm 16  /* strm->avail_out */
+#define msg_strm       24  /* strm->msg */
+#define state_strm     28  /* strm->state */
+
+/*
+ * struct inflate_state offsets, in inflate.h
+ */
+#define mode_state     0   /* state->mode */
+#define wsize_state    32  /* state->wsize */
+#define write_state    40  /* state->write */
+#define window_state   44  /* state->window */
+#define hold_state     48  /* state->hold */
+#define bits_state     52  /* state->bits */
+#define lencode_state  68  /* state->lencode */
+#define distcode_state 72  /* state->distcode */
+#define lenbits_state  76  /* state->lenbits */
+#define distbits_state 80  /* state->distbits */
+
+/*
+ * inflate_fast's activation record
+ */
+#define local_var_size 64 /* how much local space for vars */
+#define strm_sp        88 /* first arg: z_stream * (local_var_size + 24) */
+#define start_sp       92 /* second arg: unsigned int (local_var_size + 28) */
+
+/*
+ * offsets for local vars on stack
+ */
+#define out            60  /* unsigned char* */
+#define window         56  /* unsigned char* */
+#define wsize          52  /* unsigned int */
+#define write          48  /* unsigned int */
+#define in             44  /* unsigned char* */
+#define beg            40  /* unsigned char* */
+#define buf            28  /* char[ 12 ] */
+#define len            24  /* unsigned int */
+#define last           20  /* unsigned char* */
+#define end            16  /* unsigned char* */
+#define dcode          12  /* code* */
+#define lcode           8  /* code* */
+#define dmask           4  /* unsigned int */
+#define lmask           0  /* unsigned int */
+
+/*
+ * typedef enum inflate_mode consts, in inflate.h
+ */
+#define INFLATE_MODE_TYPE 11  /* state->mode flags enum-ed in inflate.h */
+#define INFLATE_MODE_BAD  26
+
+
+#if ! defined( USE_MMX ) && ! defined( NO_MMX )
+
+#define RUN_TIME_MMX
+
+#define CHECK_MMX    1
+#define DO_USE_MMX   2
+#define DONT_USE_MMX 3
+
+.globl inflate_fast_use_mmx
+
+.data
+
+.align 4,0
+inflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */
+.long CHECK_MMX
+
+#if defined( GAS_ELF )
+/* elf info */
+.type   inflate_fast_use_mmx,@object
+.size   inflate_fast_use_mmx,4
+#endif
+
+#endif /* RUN_TIME_MMX */
+
+#if defined( GAS_COFF )
+/* coff info: scl 2 = extern, type 32 = function */
+.def inflate_fast; .scl 2; .type 32; .endef
+#endif
+
+.text
+
+.align 32,0x90
+inflate_fast:
+        pushl   %edi
+        pushl   %esi
+        pushl   %ebp
+        pushl   %ebx
+        pushf   /* save eflags (strm_sp, state_sp assumes this is 32 bits) */
+        subl    $local_var_size, %esp
+        cld
+
+#define strm_r  %esi
+#define state_r %edi
+
+        movl    strm_sp(%esp), strm_r
+        movl    state_strm(strm_r), state_r
+
+        /* in = strm->next_in;
+         * out = strm->next_out;
+         * last = in + strm->avail_in - 11;
+         * beg = out - (start - strm->avail_out);
+         * end = out + (strm->avail_out - 257);
+         */
+        movl    avail_in_strm(strm_r), %edx
+        movl    next_in_strm(strm_r), %eax
+
+        addl    %eax, %edx      /* avail_in += next_in */
+        subl    $11, %edx       /* avail_in -= 11 */
+
+        movl    %eax, in(%esp)
+        movl    %edx, last(%esp)
+
+        movl    start_sp(%esp), %ebp
+        movl    avail_out_strm(strm_r), %ecx
+        movl    next_out_strm(strm_r), %ebx
+
+        subl    %ecx, %ebp      /* start -= avail_out */
+        negl    %ebp            /* start = -start */
+        addl    %ebx, %ebp      /* start += next_out */
+
+        subl    $257, %ecx      /* avail_out -= 257 */
+        addl    %ebx, %ecx      /* avail_out += out */
+
+        movl    %ebx, out(%esp)
+        movl    %ebp, beg(%esp)
+        movl    %ecx, end(%esp)
+
+        /* wsize = state->wsize;
+         * write = state->write;
+         * window = state->window;
+         * hold = state->hold;
+         * bits = state->bits;
+         * lcode = state->lencode;
+         * dcode = state->distcode;
+         * lmask = ( 1 << state->lenbits ) - 1;
+         * dmask = ( 1 << state->distbits ) - 1;
+         */
+
+        movl    lencode_state(state_r), %eax
+        movl    distcode_state(state_r), %ecx
+
+        movl    %eax, lcode(%esp)
+        movl    %ecx, dcode(%esp)
+
+        movl    $1, %eax
+        movl    lenbits_state(state_r), %ecx
+        shll    %cl, %eax
+        decl    %eax
+        movl    %eax, lmask(%esp)
+
+        movl    $1, %eax
+        movl    distbits_state(state_r), %ecx
+        shll    %cl, %eax
+        decl    %eax
+        movl    %eax, dmask(%esp)
+
+        movl    wsize_state(state_r), %eax
+        movl    write_state(state_r), %ecx
+        movl    window_state(state_r), %edx
+
+        movl    %eax, wsize(%esp)
+        movl    %ecx, write(%esp)
+        movl    %edx, window(%esp)
+
+        movl    hold_state(state_r), %ebp
+        movl    bits_state(state_r), %ebx
+
+#undef strm_r
+#undef state_r
+
+#define in_r       %esi
+#define from_r     %esi
+#define out_r      %edi
+
+        movl    in(%esp), in_r
+        movl    last(%esp), %ecx
+        cmpl    in_r, %ecx
+        ja      .L_align_long           /* if in < last */
+
+        addl    $11, %ecx               /* ecx = &in[ avail_in ] */
+        subl    in_r, %ecx              /* ecx = avail_in */
+        movl    $12, %eax
+        subl    %ecx, %eax              /* eax = 12 - avail_in */
+        leal    buf(%esp), %edi
+        rep     movsb                   /* memcpy( buf, in, avail_in ) */
+        movl    %eax, %ecx
+        xorl    %eax, %eax
+        rep     stosb         /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */
+        leal    buf(%esp), in_r         /* in = buf */
+        movl    in_r, last(%esp)        /* last = in, do just one iteration */
+        jmp     .L_is_aligned
+
+        /* align in_r on long boundary */
+.L_align_long:
+        testl   $3, in_r
+        jz      .L_is_aligned
+        xorl    %eax, %eax
+        movb    (in_r), %al
+        incl    in_r
+        movl    %ebx, %ecx
+        addl    $8, %ebx
+        shll    %cl, %eax
+        orl     %eax, %ebp
+        jmp     .L_align_long
+
+.L_is_aligned:
+        movl    out(%esp), out_r
+
+#if defined( NO_MMX )
+        jmp     .L_do_loop
+#endif
+
+#if defined( USE_MMX )
+        jmp     .L_init_mmx
+#endif
+
+/*** Runtime MMX check ***/
+
+#if defined( RUN_TIME_MMX )
+.L_check_mmx:
+        cmpl    $DO_USE_MMX, inflate_fast_use_mmx
+        je      .L_init_mmx
+        ja      .L_do_loop /* > 2 */
+
+        pushl   %eax
+        pushl   %ebx
+        pushl   %ecx
+        pushl   %edx
+        pushf
+        movl    (%esp), %eax      /* copy eflags to eax */
+        xorl    $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21)
+                                   * to see if cpu supports cpuid...
+                                   * ID bit method not supported by NexGen but
+                                   * bios may load a cpuid instruction and
+                                   * cpuid may be disabled on Cyrix 5-6x86 */
+        popf
+        pushf
+        popl    %edx              /* copy new eflags to edx */
+        xorl    %eax, %edx        /* test if ID bit is flipped */
+        jz      .L_dont_use_mmx   /* not flipped if zero */
+        xorl    %eax, %eax
+        cpuid
+        cmpl    $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */
+        jne     .L_dont_use_mmx
+        cmpl    $0x6c65746e, %ecx
+        jne     .L_dont_use_mmx
+        cmpl    $0x49656e69, %edx
+        jne     .L_dont_use_mmx
+        movl    $1, %eax
+        cpuid                     /* get cpu features */
+        shrl    $8, %eax
+        andl    $15, %eax
+        cmpl    $6, %eax          /* check for Pentium family, is 0xf for P4 */
+        jne     .L_dont_use_mmx
+        testl   $0x800000, %edx   /* test if MMX feature is set (bit 23) */
+        jnz     .L_use_mmx
+        jmp     .L_dont_use_mmx
+.L_use_mmx:
+        movl    $DO_USE_MMX, inflate_fast_use_mmx
+        jmp     .L_check_mmx_pop
+.L_dont_use_mmx:
+        movl    $DONT_USE_MMX, inflate_fast_use_mmx
+.L_check_mmx_pop:
+        popl    %edx
+        popl    %ecx
+        popl    %ebx
+        popl    %eax
+        jmp     .L_check_mmx
+#endif
+
+
+/*** Non-MMX code ***/
+
+#if defined ( NO_MMX ) || defined( RUN_TIME_MMX )
+
+#define hold_r     %ebp
+#define bits_r     %bl
+#define bitslong_r %ebx
+
+.align 32,0x90
+.L_while_test:
+        /* while (in < last && out < end)
+         */
+        cmpl    out_r, end(%esp)
+        jbe     .L_break_loop           /* if (out >= end) */
+
+        cmpl    in_r, last(%esp)
+        jbe     .L_break_loop
+
+.L_do_loop:
+        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
+         *
+         * do {
+         *   if (bits < 15) {
+         *     hold |= *((unsigned short *)in)++ << bits;
+         *     bits += 16
+         *   }
+         *   this = lcode[hold & lmask]
+         */
+        cmpb    $15, bits_r
+        ja      .L_get_length_code      /* if (15 < bits) */
+
+        xorl    %eax, %eax
+        lodsw                           /* al = *(ushort *)in++ */
+        movb    bits_r, %cl             /* cl = bits, needs it for shifting */
+        addb    $16, bits_r             /* bits += 16 */
+        shll    %cl, %eax
+        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */
+
+.L_get_length_code:
+        movl    lmask(%esp), %edx       /* edx = lmask */
+        movl    lcode(%esp), %ecx       /* ecx = lcode */
+        andl    hold_r, %edx            /* edx &= hold */
+        movl    (%ecx,%edx,4), %eax     /* eax = lcode[hold & lmask] */
+
+.L_dolen:
+        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
+         *
+         * dolen:
+         *    bits -= this.bits;
+         *    hold >>= this.bits
+         */
+        movb    %ah, %cl                /* cl = this.bits */
+        subb    %ah, bits_r             /* bits -= this.bits */
+        shrl    %cl, hold_r             /* hold >>= this.bits */
+
+        /* check if op is a literal
+         * if (op == 0) {
+         *    PUP(out) = this.val;
+         *  }
+         */
+        testb   %al, %al
+        jnz     .L_test_for_length_base /* if (op != 0) 45.7% */
+
+        shrl    $16, %eax               /* output this.val char */
+        stosb
+        jmp     .L_while_test
+
+.L_test_for_length_base:
+        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len
+         *
+         * else if (op & 16) {
+         *   len = this.val
+         *   op &= 15
+         *   if (op) {
+         *     if (op > bits) {
+         *       hold |= *((unsigned short *)in)++ << bits;
+         *       bits += 16
+         *     }
+         *     len += hold & mask[op];
+         *     bits -= op;
+         *     hold >>= op;
+         *   }
+         */
+#define len_r %edx
+        movl    %eax, len_r             /* len = this */
+        shrl    $16, len_r              /* len = this.val */
+        movb    %al, %cl
+
+        testb   $16, %al
+        jz      .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
+        andb    $15, %cl                /* op &= 15 */
+        jz      .L_save_len             /* if (!op) */
+        cmpb    %cl, bits_r
+        jae     .L_add_bits_to_len      /* if (op <= bits) */
+
+        movb    %cl, %ch                /* stash op in ch, freeing cl */
+        xorl    %eax, %eax
+        lodsw                           /* al = *(ushort *)in++ */
+        movb    bits_r, %cl             /* cl = bits, needs it for shifting */
+        addb    $16, bits_r             /* bits += 16 */
+        shll    %cl, %eax
+        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */
+        movb    %ch, %cl                /* move op back to ecx */
+
+.L_add_bits_to_len:
+        movl    $1, %eax
+        shll    %cl, %eax
+        decl    %eax
+        subb    %cl, bits_r
+        andl    hold_r, %eax            /* eax &= hold */
+        shrl    %cl, hold_r
+        addl    %eax, len_r             /* len += hold & mask[op] */
+
+.L_save_len:
+        movl    len_r, len(%esp)        /* save len */
+#undef  len_r
+
+.L_decode_distance:
+        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *
+         *   if (bits < 15) {
+         *     hold |= *((unsigned short *)in)++ << bits;
+         *     bits += 16
+         *   }
+         *   this = dcode[hold & dmask];
+         * dodist:
+         *   bits -= this.bits;
+         *   hold >>= this.bits;
+         *   op = this.op;
+         */
+
+        cmpb    $15, bits_r
+        ja      .L_get_distance_code    /* if (15 < bits) */
+
+        xorl    %eax, %eax
+        lodsw                           /* al = *(ushort *)in++ */
+        movb    bits_r, %cl             /* cl = bits, needs it for shifting */
+        addb    $16, bits_r             /* bits += 16 */
+        shll    %cl, %eax
+        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */
+
+.L_get_distance_code:
+        movl    dmask(%esp), %edx       /* edx = dmask */
+        movl    dcode(%esp), %ecx       /* ecx = dcode */
+        andl    hold_r, %edx            /* edx &= hold */
+        movl    (%ecx,%edx,4), %eax     /* eax = dcode[hold & dmask] */
+
+#define dist_r %edx
+.L_dodist:
+        movl    %eax, dist_r            /* dist = this */
+        shrl    $16, dist_r             /* dist = this.val */
+        movb    %ah, %cl
+        subb    %ah, bits_r             /* bits -= this.bits */
+        shrl    %cl, hold_r             /* hold >>= this.bits */
+
+        /* if (op & 16) {
+         *   dist = this.val
+         *   op &= 15
+         *   if (op > bits) {
+         *     hold |= *((unsigned short *)in)++ << bits;
+         *     bits += 16
+         *   }
+         *   dist += hold & mask[op];
+         *   bits -= op;
+         *   hold >>= op;
+         */
+        movb    %al, %cl                /* cl = this.op */
+
+        testb   $16, %al                /* if ((op & 16) == 0) */
+        jz      .L_test_for_second_level_dist
+        andb    $15, %cl                /* op &= 15 */
+        jz      .L_check_dist_one
+        cmpb    %cl, bits_r
+        jae     .L_add_bits_to_dist     /* if (op <= bits) 97.6% */
+
+        movb    %cl, %ch                /* stash op in ch, freeing cl */
+        xorl    %eax, %eax
+        lodsw                           /* al = *(ushort *)in++ */
+        movb    bits_r, %cl             /* cl = bits, needs it for shifting */
+        addb    $16, bits_r             /* bits += 16 */
+        shll    %cl, %eax
+        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */
+        movb    %ch, %cl                /* move op back to ecx */
+
+.L_add_bits_to_dist:
+        movl    $1, %eax
+        shll    %cl, %eax
+        decl    %eax                    /* (1 << op) - 1 */
+        subb    %cl, bits_r
+        andl    hold_r, %eax            /* eax &= hold */
+        shrl    %cl, hold_r
+        addl    %eax, dist_r            /* dist += hold & ((1 << op) - 1) */
+        jmp     .L_check_window
+
+.L_check_window:
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes
+         *
+         * nbytes = out - beg;
+         * if (dist <= nbytes) {
+         *   from = out - dist;
+         *   do {
+         *     PUP(out) = PUP(from);
+         *   } while (--len > 0) {
+         * }
+         */
+
+        movl    in_r, in(%esp)          /* save in so from can use it's reg */
+        movl    out_r, %eax
+        subl    beg(%esp), %eax         /* nbytes = out - beg */
+
+        cmpl    dist_r, %eax
+        jb      .L_clip_window          /* if (dist > nbytes) 4.2% */
+
+        movl    len(%esp), %ecx
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+
+        subl    $3, %ecx
+        movb    (from_r), %al
+        movb    %al, (out_r)
+        movb    1(from_r), %al
+        movb    2(from_r), %dl
+        addl    $3, from_r
+        movb    %al, 1(out_r)
+        movb    %dl, 2(out_r)
+        addl    $3, out_r
+        rep     movsb
+
+        movl    in(%esp), in_r          /* move in back to %esi, toss from */
+        jmp     .L_while_test
+
+.align 16,0x90
+.L_check_dist_one:
+        cmpl    $1, dist_r
+        jne     .L_check_window
+        cmpl    out_r, beg(%esp)
+        je      .L_check_window
+
+        decl    out_r
+        movl    len(%esp), %ecx
+        movb    (out_r), %al
+        subl    $3, %ecx
+
+        movb    %al, 1(out_r)
+        movb    %al, 2(out_r)
+        movb    %al, 3(out_r)
+        addl    $4, out_r
+        rep     stosb
+
+        jmp     .L_while_test
+
+.align 16,0x90
+.L_test_for_second_level_length:
+        /* else if ((op & 64) == 0) {
+         *   this = lcode[this.val + (hold & mask[op])];
+         * }
+         */
+        testb   $64, %al
+        jnz     .L_test_for_end_of_block  /* if ((op & 64) != 0) */
+
+        movl    $1, %eax
+        shll    %cl, %eax
+        decl    %eax
+        andl    hold_r, %eax            /* eax &= hold */
+        addl    %edx, %eax              /* eax += this.val */
+        movl    lcode(%esp), %edx       /* edx = lcode */
+        movl    (%edx,%eax,4), %eax     /* eax = lcode[val + (hold&mask[op])] */
+        jmp     .L_dolen
+
+.align 16,0x90
+.L_test_for_second_level_dist:
+        /* else if ((op & 64) == 0) {
+         *   this = dcode[this.val + (hold & mask[op])];
+         * }
+         */
+        testb   $64, %al
+        jnz     .L_invalid_distance_code  /* if ((op & 64) != 0) */
+
+        movl    $1, %eax
+        shll    %cl, %eax
+        decl    %eax
+        andl    hold_r, %eax            /* eax &= hold */
+        addl    %edx, %eax              /* eax += this.val */
+        movl    dcode(%esp), %edx       /* edx = dcode */
+        movl    (%edx,%eax,4), %eax     /* eax = dcode[val + (hold&mask[op])] */
+        jmp     .L_dodist
+
+.align 16,0x90
+.L_clip_window:
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes
+         *
+         * else {
+         *   if (dist > wsize) {
+         *     invalid distance
+         *   }
+         *   from = window;
+         *   nbytes = dist - nbytes;
+         *   if (write == 0) {
+         *     from += wsize - nbytes;
+         */
+#define nbytes_r %ecx
+        movl    %eax, nbytes_r
+        movl    wsize(%esp), %eax       /* prepare for dist compare */
+        negl    nbytes_r                /* nbytes = -nbytes */
+        movl    window(%esp), from_r    /* from = window */
+
+        cmpl    dist_r, %eax
+        jb      .L_invalid_distance_too_far /* if (dist > wsize) */
+
+        addl    dist_r, nbytes_r        /* nbytes = dist - nbytes */
+        cmpl    $0, write(%esp)
+        jne     .L_wrap_around_window   /* if (write != 0) */
+
+        subl    nbytes_r, %eax
+        addl    %eax, from_r            /* from += wsize - nbytes */
+
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes, %eax = len
+         *
+         *     if (nbytes < len) {
+         *       len -= nbytes;
+         *       do {
+         *         PUP(out) = PUP(from);
+         *       } while (--nbytes);
+         *       from = out - dist;
+         *     }
+         *   }
+         */
+#define len_r %eax
+        movl    len(%esp), len_r
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1
+
+.L_wrap_around_window:
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes, %eax = write, %eax = len
+         *
+         *   else if (write < nbytes) {
+         *     from += wsize + write - nbytes;
+         *     nbytes -= write;
+         *     if (nbytes < len) {
+         *       len -= nbytes;
+         *       do {
+         *         PUP(out) = PUP(from);
+         *       } while (--nbytes);
+         *       from = window;
+         *       nbytes = write;
+         *       if (nbytes < len) {
+         *         len -= nbytes;
+         *         do {
+         *           PUP(out) = PUP(from);
+         *         } while(--nbytes);
+         *         from = out - dist;
+         *       }
+         *     }
+         *   }
+         */
+#define write_r %eax
+        movl    write(%esp), write_r
+        cmpl    write_r, nbytes_r
+        jbe     .L_contiguous_in_window /* if (write >= nbytes) */
+
+        addl    wsize(%esp), from_r
+        addl    write_r, from_r
+        subl    nbytes_r, from_r        /* from += wsize + write - nbytes */
+        subl    write_r, nbytes_r       /* nbytes -= write */
+#undef write_r
+
+        movl    len(%esp), len_r
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    window(%esp), from_r    /* from = window */
+        movl    write(%esp), nbytes_r   /* nbytes = write */
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1
+
+.L_contiguous_in_window:
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes, %eax = write, %eax = len
+         *
+         *   else {
+         *     from += write - nbytes;
+         *     if (nbytes < len) {
+         *       len -= nbytes;
+         *       do {
+         *         PUP(out) = PUP(from);
+         *       } while (--nbytes);
+         *       from = out - dist;
+         *     }
+         *   }
+         */
+#define write_r %eax
+        addl    write_r, from_r
+        subl    nbytes_r, from_r        /* from += write - nbytes */
+#undef write_r
+
+        movl    len(%esp), len_r
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+
+.L_do_copy1:
+        /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out
+         *       %eax = len
+         *
+         *     while (len > 0) {
+         *       PUP(out) = PUP(from);
+         *       len--;
+         *     }
+         *   }
+         * } while (in < last && out < end);
+         */
+#undef nbytes_r
+#define in_r %esi
+        movl    len_r, %ecx
+        rep     movsb
+
+        movl    in(%esp), in_r          /* move in back to %esi, toss from */
+        jmp     .L_while_test
+
+#undef len_r
+#undef dist_r
+
+#endif /* NO_MMX || RUN_TIME_MMX */
+
+
+/*** MMX code ***/
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+.align 32,0x90
+.L_init_mmx:
+        emms
+
+#undef  bits_r
+#undef  bitslong_r
+#define bitslong_r %ebp
+#define hold_mm    %mm0
+        movd    %ebp, hold_mm
+        movl    %ebx, bitslong_r
+
+#define used_mm   %mm1
+#define dmask2_mm %mm2
+#define lmask2_mm %mm3
+#define lmask_mm  %mm4
+#define dmask_mm  %mm5
+#define tmp_mm    %mm6
+
+        movd    lmask(%esp), lmask_mm
+        movq    lmask_mm, lmask2_mm
+        movd    dmask(%esp), dmask_mm
+        movq    dmask_mm, dmask2_mm
+        pxor    used_mm, used_mm
+        movl    lcode(%esp), %ebx       /* ebx = lcode */
+        jmp     .L_do_loop_mmx
+
+.align 32,0x90
+.L_while_test_mmx:
+        /* while (in < last && out < end)
+         */
+        cmpl    out_r, end(%esp)
+        jbe     .L_break_loop           /* if (out >= end) */
+
+        cmpl    in_r, last(%esp)
+        jbe     .L_break_loop
+
+.L_do_loop_mmx:
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+
+        cmpl    $32, bitslong_r
+        ja      .L_get_length_code_mmx  /* if (32 < bits) */
+
+        movd    bitslong_r, tmp_mm
+        movd    (in_r), %mm7
+        addl    $4, in_r
+        psllq   tmp_mm, %mm7
+        addl    $32, bitslong_r
+        por     %mm7, hold_mm           /* hold_mm |= *((uint *)in)++ << bits */
+
+.L_get_length_code_mmx:
+        pand    hold_mm, lmask_mm
+        movd    lmask_mm, %eax
+        movq    lmask2_mm, lmask_mm
+        movl    (%ebx,%eax,4), %eax     /* eax = lcode[hold & lmask] */
+
+.L_dolen_mmx:
+        movzbl  %ah, %ecx               /* ecx = this.bits */
+        movd    %ecx, used_mm
+        subl    %ecx, bitslong_r        /* bits -= this.bits */
+
+        testb   %al, %al
+        jnz     .L_test_for_length_base_mmx /* if (op != 0) 45.7% */
+
+        shrl    $16, %eax               /* output this.val char */
+        stosb
+        jmp     .L_while_test_mmx
+
+.L_test_for_length_base_mmx:
+#define len_r  %edx
+        movl    %eax, len_r             /* len = this */
+        shrl    $16, len_r              /* len = this.val */
+
+        testb   $16, %al
+        jz      .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */
+        andl    $15, %eax               /* op &= 15 */
+        jz      .L_decode_distance_mmx  /* if (!op) */
+
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    %eax, used_mm
+        movd    hold_mm, %ecx
+        subl    %eax, bitslong_r
+        andl    .L_mask(,%eax,4), %ecx
+        addl    %ecx, len_r             /* len += hold & mask[op] */
+
+.L_decode_distance_mmx:
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+
+        cmpl    $32, bitslong_r
+        ja      .L_get_dist_code_mmx    /* if (32 < bits) */
+
+        movd    bitslong_r, tmp_mm
+        movd    (in_r), %mm7
+        addl    $4, in_r
+        psllq   tmp_mm, %mm7
+        addl    $32, bitslong_r
+        por     %mm7, hold_mm           /* hold_mm |= *((uint *)in)++ << bits */
+
+.L_get_dist_code_mmx:
+        movl    dcode(%esp), %ebx       /* ebx = dcode */
+        pand    hold_mm, dmask_mm
+        movd    dmask_mm, %eax
+        movq    dmask2_mm, dmask_mm
+        movl    (%ebx,%eax,4), %eax     /* eax = dcode[hold & lmask] */
+
+.L_dodist_mmx:
+#define dist_r %ebx
+        movzbl  %ah, %ecx               /* ecx = this.bits */
+        movl    %eax, dist_r
+        shrl    $16, dist_r             /* dist  = this.val */
+        subl    %ecx, bitslong_r        /* bits -= this.bits */
+        movd    %ecx, used_mm
+
+        testb   $16, %al                /* if ((op & 16) == 0) */
+        jz      .L_test_for_second_level_dist_mmx
+        andl    $15, %eax               /* op &= 15 */
+        jz      .L_check_dist_one_mmx
+
+.L_add_bits_to_dist_mmx:
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    %eax, used_mm           /* save bit length of current op */
+        movd    hold_mm, %ecx           /* get the next bits on input stream */
+        subl    %eax, bitslong_r        /* bits -= op bits */
+        andl    .L_mask(,%eax,4), %ecx  /* ecx   = hold & mask[op] */
+        addl    %ecx, dist_r            /* dist += hold & mask[op] */
+
+.L_check_window_mmx:
+        movl    in_r, in(%esp)          /* save in so from can use it's reg */
+        movl    out_r, %eax
+        subl    beg(%esp), %eax         /* nbytes = out - beg */
+
+        cmpl    dist_r, %eax
+        jb      .L_clip_window_mmx      /* if (dist > nbytes) 4.2% */
+
+        movl    len_r, %ecx
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+
+        subl    $3, %ecx
+        movb    (from_r), %al
+        movb    %al, (out_r)
+        movb    1(from_r), %al
+        movb    2(from_r), %dl
+        addl    $3, from_r
+        movb    %al, 1(out_r)
+        movb    %dl, 2(out_r)
+        addl    $3, out_r
+        rep     movsb
+
+        movl    in(%esp), in_r          /* move in back to %esi, toss from */
+        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */
+        jmp     .L_while_test_mmx
+
+.align 16,0x90
+.L_check_dist_one_mmx:
+        cmpl    $1, dist_r
+        jne     .L_check_window_mmx
+        cmpl    out_r, beg(%esp)
+        je      .L_check_window_mmx
+
+        decl    out_r
+        movl    len_r, %ecx
+        movb    (out_r), %al
+        subl    $3, %ecx
+
+        movb    %al, 1(out_r)
+        movb    %al, 2(out_r)
+        movb    %al, 3(out_r)
+        addl    $4, out_r
+        rep     stosb
+
+        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */
+        jmp     .L_while_test_mmx
+
+.align 16,0x90
+.L_test_for_second_level_length_mmx:
+        testb   $64, %al
+        jnz     .L_test_for_end_of_block  /* if ((op & 64) != 0) */
+
+        andl    $15, %eax
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    hold_mm, %ecx
+        andl    .L_mask(,%eax,4), %ecx
+        addl    len_r, %ecx
+        movl    (%ebx,%ecx,4), %eax     /* eax = lcode[hold & lmask] */
+        jmp     .L_dolen_mmx
+
+.align 16,0x90
+.L_test_for_second_level_dist_mmx:
+        testb   $64, %al
+        jnz     .L_invalid_distance_code  /* if ((op & 64) != 0) */
+
+        andl    $15, %eax
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    hold_mm, %ecx
+        andl    .L_mask(,%eax,4), %ecx
+        movl    dcode(%esp), %eax       /* ecx = dcode */
+        addl    dist_r, %ecx
+        movl    (%eax,%ecx,4), %eax     /* eax = lcode[hold & lmask] */
+        jmp     .L_dodist_mmx
+
+.align 16,0x90
+.L_clip_window_mmx:
+#define nbytes_r %ecx
+        movl    %eax, nbytes_r
+        movl    wsize(%esp), %eax       /* prepare for dist compare */
+        negl    nbytes_r                /* nbytes = -nbytes */
+        movl    window(%esp), from_r    /* from = window */
+
+        cmpl    dist_r, %eax
+        jb      .L_invalid_distance_too_far /* if (dist > wsize) */
+
+        addl    dist_r, nbytes_r        /* nbytes = dist - nbytes */
+        cmpl    $0, write(%esp)
+        jne     .L_wrap_around_window_mmx /* if (write != 0) */
+
+        subl    nbytes_r, %eax
+        addl    %eax, from_r            /* from += wsize - nbytes */
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1_mmx
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1_mmx
+
+.L_wrap_around_window_mmx:
+#define write_r %eax
+        movl    write(%esp), write_r
+        cmpl    write_r, nbytes_r
+        jbe     .L_contiguous_in_window_mmx /* if (write >= nbytes) */
+
+        addl    wsize(%esp), from_r
+        addl    write_r, from_r
+        subl    nbytes_r, from_r        /* from += wsize + write - nbytes */
+        subl    write_r, nbytes_r       /* nbytes -= write */
+#undef write_r
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    window(%esp), from_r    /* from = window */
+        movl    write(%esp), nbytes_r   /* nbytes = write */
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1_mmx
+
+.L_contiguous_in_window_mmx:
+#define write_r %eax
+        addl    write_r, from_r
+        subl    nbytes_r, from_r        /* from += write - nbytes */
+#undef write_r
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+
+.L_do_copy1_mmx:
+#undef nbytes_r
+#define in_r %esi
+        movl    len_r, %ecx
+        rep     movsb
+
+        movl    in(%esp), in_r          /* move in back to %esi, toss from */
+        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */
+        jmp     .L_while_test_mmx
+
+#undef hold_r
+#undef bitslong_r
+
+#endif /* USE_MMX || RUN_TIME_MMX */
+
+
+/*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/
+
+.L_invalid_distance_code:
+        /* else {
+         *   strm->msg = "invalid distance code";
+         *   state->mode = BAD;
+         * }
+         */
+        movl    $.L_invalid_distance_code_msg, %ecx
+        movl    $INFLATE_MODE_BAD, %edx
+        jmp     .L_update_stream_state
+
+.L_test_for_end_of_block:
+        /* else if (op & 32) {
+         *   state->mode = TYPE;
+         *   break;
+         * }
+         */
+        testb   $32, %al
+        jz      .L_invalid_literal_length_code  /* if ((op & 32) == 0) */
+
+        movl    $0, %ecx
+        movl    $INFLATE_MODE_TYPE, %edx
+        jmp     .L_update_stream_state
+
+.L_invalid_literal_length_code:
+        /* else {
+         *   strm->msg = "invalid literal/length code";
+         *   state->mode = BAD;
+         * }
+         */
+        movl    $.L_invalid_literal_length_code_msg, %ecx
+        movl    $INFLATE_MODE_BAD, %edx
+        jmp     .L_update_stream_state
+
+.L_invalid_distance_too_far:
+        /* strm->msg = "invalid distance too far back";
+         * state->mode = BAD;
+         */
+        movl    in(%esp), in_r          /* from_r has in's reg, put in back */
+        movl    $.L_invalid_distance_too_far_msg, %ecx
+        movl    $INFLATE_MODE_BAD, %edx
+        jmp     .L_update_stream_state
+
+.L_update_stream_state:
+        /* set strm->msg = %ecx, strm->state->mode = %edx */
+        movl    strm_sp(%esp), %eax
+        testl   %ecx, %ecx              /* if (msg != NULL) */
+        jz      .L_skip_msg
+        movl    %ecx, msg_strm(%eax)    /* strm->msg = msg */
+.L_skip_msg:
+        movl    state_strm(%eax), %eax  /* state = strm->state */
+        movl    %edx, mode_state(%eax)  /* state->mode = edx (BAD | TYPE) */
+        jmp     .L_break_loop
+
+.align 32,0x90
+.L_break_loop:
+
+/*
+ * Regs:
+ *
+ * bits = %ebp when mmx, and in %ebx when non-mmx
+ * hold = %hold_mm when mmx, and in %ebp when non-mmx
+ * in   = %esi
+ * out  = %edi
+ */
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+#if defined( RUN_TIME_MMX )
+
+        cmpl    $DO_USE_MMX, inflate_fast_use_mmx
+        jne     .L_update_next_in
+
+#endif /* RUN_TIME_MMX */
+
+        movl    %ebp, %ebx
+
+.L_update_next_in:
+
+#endif
+
+#define strm_r  %eax
+#define state_r %edx
+
+        /* len = bits >> 3;
+         * in -= len;
+         * bits -= len << 3;
+         * hold &= (1U << bits) - 1;
+         * state->hold = hold;
+         * state->bits = bits;
+         * strm->next_in = in;
+         * strm->next_out = out;
+         */
+        movl    strm_sp(%esp), strm_r
+        movl    %ebx, %ecx
+        movl    state_strm(strm_r), state_r
+        shrl    $3, %ecx
+        subl    %ecx, in_r
+        shll    $3, %ecx
+        subl    %ecx, %ebx
+        movl    out_r, next_out_strm(strm_r)
+        movl    %ebx, bits_state(state_r)
+        movl    %ebx, %ecx
+
+        leal    buf(%esp), %ebx
+        cmpl    %ebx, last(%esp)
+        jne     .L_buf_not_used         /* if buf != last */
+
+        subl    %ebx, in_r              /* in -= buf */
+        movl    next_in_strm(strm_r), %ebx
+        movl    %ebx, last(%esp)        /* last = strm->next_in */
+        addl    %ebx, in_r              /* in += strm->next_in */
+        movl    avail_in_strm(strm_r), %ebx
+        subl    $11, %ebx
+        addl    %ebx, last(%esp)    /* last = &strm->next_in[ avail_in - 11 ] */
+
+.L_buf_not_used:
+        movl    in_r, next_in_strm(strm_r)
+
+        movl    $1, %ebx
+        shll    %cl, %ebx
+        decl    %ebx
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+#if defined( RUN_TIME_MMX )
+
+        cmpl    $DO_USE_MMX, inflate_fast_use_mmx
+        jne     .L_update_hold
+
+#endif /* RUN_TIME_MMX */
+
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    hold_mm, %ebp
+
+        emms
+
+.L_update_hold:
+
+#endif /* USE_MMX || RUN_TIME_MMX */
+
+        andl    %ebx, %ebp
+        movl    %ebp, hold_state(state_r)
+
+#define last_r %ebx
+
+        /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */
+        movl    last(%esp), last_r
+        cmpl    in_r, last_r
+        jbe     .L_last_is_smaller     /* if (in >= last) */
+
+        subl    in_r, last_r           /* last -= in */
+        addl    $11, last_r            /* last += 11 */
+        movl    last_r, avail_in_strm(strm_r)
+        jmp     .L_fixup_out
+.L_last_is_smaller:
+        subl    last_r, in_r           /* in -= last */
+        negl    in_r                   /* in = -in */
+        addl    $11, in_r              /* in += 11 */
+        movl    in_r, avail_in_strm(strm_r)
+
+#undef last_r
+#define end_r %ebx
+
+.L_fixup_out:
+        /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/
+        movl    end(%esp), end_r
+        cmpl    out_r, end_r
+        jbe     .L_end_is_smaller      /* if (out >= end) */
+
+        subl    out_r, end_r           /* end -= out */
+        addl    $257, end_r            /* end += 257 */
+        movl    end_r, avail_out_strm(strm_r)
+        jmp     .L_done
+.L_end_is_smaller:
+        subl    end_r, out_r           /* out -= end */
+        negl    out_r                  /* out = -out */
+        addl    $257, out_r            /* out += 257 */
+        movl    out_r, avail_out_strm(strm_r)
+
+#undef end_r
+#undef strm_r
+#undef state_r
+
+.L_done:
+        addl    $local_var_size, %esp
+        popf
+        popl    %ebx
+        popl    %ebp
+        popl    %esi
+        popl    %edi
+        ret
+
+#if defined( GAS_ELF )
+/* elf info */
+.type inflate_fast,@function
+.size inflate_fast,.-inflate_fast
+#endif
diff --git a/8.x/zlib/contrib/iostream/test.cpp b/8.x/zlib/contrib/iostream/test.cpp
new file mode 100644 (file)
index 0000000..7d265b3
--- /dev/null
@@ -0,0 +1,24 @@
+
+#include "zfstream.h"
+
+int main() {
+
+  // Construct a stream object with this filebuffer.  Anything sent
+  // to this stream will go to standard out.
+  gzofstream os( 1, ios::out );
+
+  // This text is getting compressed and sent to stdout.
+  // To prove this, run 'test | zcat'.
+  os << "Hello, Mommy" << endl;
+
+  os << setcompressionlevel( Z_NO_COMPRESSION );
+  os << "hello, hello, hi, ho!" << endl;
+
+  setcompressionlevel( os, Z_DEFAULT_COMPRESSION )
+    << "I'm compressing again" << endl;
+
+  os.close();
+
+  return 0;
+
+}
diff --git a/8.x/zlib/contrib/iostream/zfstream.cpp b/8.x/zlib/contrib/iostream/zfstream.cpp
new file mode 100644 (file)
index 0000000..d0cd85f
--- /dev/null
@@ -0,0 +1,329 @@
+
+#include "zfstream.h"
+
+gzfilebuf::gzfilebuf() :
+  file(NULL),
+  mode(0),
+  own_file_descriptor(0)
+{ }
+
+gzfilebuf::~gzfilebuf() {
+
+  sync();
+  if ( own_file_descriptor )
+    close();
+
+}
+
+gzfilebuf *gzfilebuf::open( const char *name,
+                            int io_mode ) {
+
+  if ( is_open() )
+    return NULL;
+
+  char char_mode[10];
+  char *p = char_mode;
+
+  if ( io_mode & ios::in ) {
+    mode = ios::in;
+    *p++ = 'r';
+  } else if ( io_mode & ios::app ) {
+    mode = ios::app;
+    *p++ = 'a';
+  } else {
+    mode = ios::out;
+    *p++ = 'w';
+  }
+
+  if ( io_mode & ios::binary ) {
+    mode |= ios::binary;
+    *p++ = 'b';
+  }
+
+  // Hard code the compression level
+  if ( io_mode & (ios::out|ios::app )) {
+    *p++ = '9';
+  }
+
+  // Put the end-of-string indicator
+  *p = '\0';
+
+  if ( (file = gzopen(name, char_mode)) == NULL )
+    return NULL;
+
+  own_file_descriptor = 1;
+
+  return this;
+
+}
+
+gzfilebuf *gzfilebuf::attach( int file_descriptor,
+                              int io_mode ) {
+
+  if ( is_open() )
+    return NULL;
+
+  char char_mode[10];
+  char *p = char_mode;
+
+  if ( io_mode & ios::in ) {
+    mode = ios::in;
+    *p++ = 'r';
+  } else if ( io_mode & ios::app ) {
+    mode = ios::app;
+    *p++ = 'a';
+  } else {
+    mode = ios::out;
+    *p++ = 'w';
+  }
+
+  if ( io_mode & ios::binary ) {
+    mode |= ios::binary;
+    *p++ = 'b';
+  }
+
+  // Hard code the compression level
+  if ( io_mode & (ios::out|ios::app )) {
+    *p++ = '9';
+  }
+
+  // Put the end-of-string indicator
+  *p = '\0';
+
+  if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
+    return NULL;
+
+  own_file_descriptor = 0;
+
+  return this;
+
+}
+
+gzfilebuf *gzfilebuf::close() {
+
+  if ( is_open() ) {
+
+    sync();
+    gzclose( file );
+    file = NULL;
+
+  }
+
+  return this;
+
+}
+
+int gzfilebuf::setcompressionlevel( int comp_level ) {
+
+  return gzsetparams(file, comp_level, -2);
+
+}
+
+int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
+
+  return gzsetparams(file, -2, comp_strategy);
+
+}
+
+
+streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
+
+  return streampos(EOF);
+
+}
+
+int gzfilebuf::underflow() {
+
+  // If the file hasn't been opened for reading, error.
+  if ( !is_open() || !(mode & ios::in) )
+    return EOF;
+
+  // if a buffer doesn't exists, allocate one.
+  if ( !base() ) {
+
+    if ( (allocate()) == EOF )
+      return EOF;
+    setp(0,0);
+
+  } else {
+
+    if ( in_avail() )
+      return (unsigned char) *gptr();
+
+    if ( out_waiting() ) {
+      if ( flushbuf() == EOF )
+        return EOF;
+    }
+
+  }
+
+  // Attempt to fill the buffer.
+
+  int result = fillbuf();
+  if ( result == EOF ) {
+    // disable get area
+    setg(0,0,0);
+    return EOF;
+  }
+
+  return (unsigned char) *gptr();
+
+}
+
+int gzfilebuf::overflow( int c ) {
+
+  if ( !is_open() || !(mode & ios::out) )
+    return EOF;
+
+  if ( !base() ) {
+    if ( allocate() == EOF )
+      return EOF;
+    setg(0,0,0);
+  } else {
+    if (in_avail()) {
+        return EOF;
+    }
+    if (out_waiting()) {
+      if (flushbuf() == EOF)
+        return EOF;
+    }
+  }
+
+  int bl = blen();
+  setp( base(), base() + bl);
+
+  if ( c != EOF ) {
+
+    *pptr() = c;
+    pbump(1);
+
+  }
+
+  return 0;
+
+}
+
+int gzfilebuf::sync() {
+
+  if ( !is_open() )
+    return EOF;
+
+  if ( out_waiting() )
+    return flushbuf();
+
+  return 0;
+
+}
+
+int gzfilebuf::flushbuf() {
+
+  int n;
+  char *q;
+
+  q = pbase();
+  n = pptr() - q;
+
+  if ( gzwrite( file, q, n) < n )
+    return EOF;
+
+  setp(0,0);
+
+  return 0;
+
+}
+
+int gzfilebuf::fillbuf() {
+
+  int required;
+  char *p;
+
+  p = base();
+
+  required = blen();
+
+  int t = gzread( file, p, required );
+
+  if ( t <= 0) return EOF;
+
+  setg( base(), base(), base()+t);
+
+  return t;
+
+}
+
+gzfilestream_common::gzfilestream_common() :
+  ios( gzfilestream_common::rdbuf() )
+{ }
+
+gzfilestream_common::~gzfilestream_common()
+{ }
+
+void gzfilestream_common::attach( int fd, int io_mode ) {
+
+  if ( !buffer.attach( fd, io_mode) )
+    clear( ios::failbit | ios::badbit );
+  else
+    clear();
+
+}
+
+void gzfilestream_common::open( const char *name, int io_mode ) {
+
+  if ( !buffer.open( name, io_mode ) )
+    clear( ios::failbit | ios::badbit );
+  else
+    clear();
+
+}
+
+void gzfilestream_common::close() {
+
+  if ( !buffer.close() )
+    clear( ios::failbit | ios::badbit );
+
+}
+
+gzfilebuf *gzfilestream_common::rdbuf()
+{
+  return &buffer;
+}
+
+gzifstream::gzifstream() :
+  ios( gzfilestream_common::rdbuf() )
+{
+  clear( ios::badbit );
+}
+
+gzifstream::gzifstream( const char *name, int io_mode ) :
+  ios( gzfilestream_common::rdbuf() )
+{
+  gzfilestream_common::open( name, io_mode );
+}
+
+gzifstream::gzifstream( int fd, int io_mode ) :
+  ios( gzfilestream_common::rdbuf() )
+{
+  gzfilestream_common::attach( fd, io_mode );
+}
+
+gzifstream::~gzifstream() { }
+
+gzofstream::gzofstream() :
+  ios( gzfilestream_common::rdbuf() )
+{
+  clear( ios::badbit );
+}
+
+gzofstream::gzofstream( const char *name, int io_mode ) :
+  ios( gzfilestream_common::rdbuf() )
+{
+  gzfilestream_common::open( name, io_mode );
+}
+
+gzofstream::gzofstream( int fd, int io_mode ) :
+  ios( gzfilestream_common::rdbuf() )
+{
+  gzfilestream_common::attach( fd, io_mode );
+}
+
+gzofstream::~gzofstream() { }
diff --git a/8.x/zlib/contrib/iostream/zfstream.h b/8.x/zlib/contrib/iostream/zfstream.h
new file mode 100644 (file)
index 0000000..ed79098
--- /dev/null
@@ -0,0 +1,128 @@
+
+#ifndef zfstream_h
+#define zfstream_h
+
+#include <fstream.h>
+#include "zlib.h"
+
+class gzfilebuf : public streambuf {
+
+public:
+
+  gzfilebuf( );
+  virtual ~gzfilebuf();
+
+  gzfilebuf *open( const char *name, int io_mode );
+  gzfilebuf *attach( int file_descriptor, int io_mode );
+  gzfilebuf *close();
+
+  int setcompressionlevel( int comp_level );
+  int setcompressionstrategy( int comp_strategy );
+
+  inline int is_open() const { return (file !=NULL); }
+
+  virtual streampos seekoff( streamoff, ios::seek_dir, int );
+
+  virtual int sync();
+
+protected:
+
+  virtual int underflow();
+  virtual int overflow( int = EOF );
+
+private:
+
+  gzFile file;
+  short mode;
+  short own_file_descriptor;
+
+  int flushbuf();
+  int fillbuf();
+
+};
+
+class gzfilestream_common : virtual public ios {
+
+  friend class gzifstream;
+  friend class gzofstream;
+  friend gzofstream &setcompressionlevel( gzofstream &, int );
+  friend gzofstream &setcompressionstrategy( gzofstream &, int );
+
+public:
+  virtual ~gzfilestream_common();
+
+  void attach( int fd, int io_mode );
+  void open( const char *name, int io_mode );
+  void close();
+
+protected:
+  gzfilestream_common();
+
+private:
+  gzfilebuf *rdbuf();
+
+  gzfilebuf buffer;
+
+};
+
+class gzifstream : public gzfilestream_common, public istream {
+
+public:
+
+  gzifstream();
+  gzifstream( const char *name, int io_mode = ios::in );
+  gzifstream( int fd, int io_mode = ios::in );
+
+  virtual ~gzifstream();
+
+};
+
+class gzofstream : public gzfilestream_common, public ostream {
+
+public:
+
+  gzofstream();
+  gzofstream( const char *name, int io_mode = ios::out );
+  gzofstream( int fd, int io_mode = ios::out );
+
+  virtual ~gzofstream();
+
+};
+
+template<class T> class gzomanip {
+  friend gzofstream &operator<<(gzofstream &, const gzomanip<T> &);
+public:
+  gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }
+private:
+  gzofstream &(*func)(gzofstream &, T);
+  T val;
+};
+
+template<class T> gzofstream &operator<<(gzofstream &s, const gzomanip<T> &m)
+{
+  return (*m.func)(s, m.val);
+}
+
+inline gzofstream &setcompressionlevel( gzofstream &s, int l )
+{
+  (s.rdbuf())->setcompressionlevel(l);
+  return s;
+}
+
+inline gzofstream &setcompressionstrategy( gzofstream &s, int l )
+{
+  (s.rdbuf())->setcompressionstrategy(l);
+  return s;
+}
+
+inline gzomanip<int> setcompressionlevel(int l)
+{
+  return gzomanip<int>(&setcompressionlevel,l);
+}
+
+inline gzomanip<int> setcompressionstrategy(int l)
+{
+  return gzomanip<int>(&setcompressionstrategy,l);
+}
+
+#endif
diff --git a/8.x/zlib/contrib/iostream2/zstream.h b/8.x/zlib/contrib/iostream2/zstream.h
new file mode 100644 (file)
index 0000000..43d2332
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ *
+ * Copyright (c) 1997
+ * Christian Michelsen Research AS
+ * Advanced Computing
+ * Fantoftvegen 38, 5036 BERGEN, Norway
+ * http://www.cmr.no
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Christian Michelsen Research AS makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef ZSTREAM__H
+#define ZSTREAM__H
+
+/*
+ * zstream.h - C++ interface to the 'zlib' general purpose compression library
+ * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
+ */
+
+#include <strstream.h>
+#include <string.h>
+#include <stdio.h>
+#include "zlib.h"
+
+#if defined(_WIN32)
+#   include <fcntl.h>
+#   include <io.h>
+#   define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#   define SET_BINARY_MODE(file)
+#endif
+
+class zstringlen {
+public:
+    zstringlen(class izstream&);
+    zstringlen(class ozstream&, const char*);
+    size_t value() const { return val.word; }
+private:
+    struct Val { unsigned char byte; size_t word; } val;
+};
+
+//  ----------------------------- izstream -----------------------------
+
+class izstream
+{
+    public:
+        izstream() : m_fp(0) {}
+        izstream(FILE* fp) : m_fp(0) { open(fp); }
+        izstream(const char* name) : m_fp(0) { open(name); }
+        ~izstream() { close(); }
+
+        /* Opens a gzip (.gz) file for reading.
+         * open() can be used to read a file which is not in gzip format;
+         * in this case read() will directly read from the file without
+         * decompression. errno can be checked to distinguish two error
+         * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
+         */
+        void open(const char* name) {
+            if (m_fp) close();
+            m_fp = ::gzopen(name, "rb");
+        }
+
+        void open(FILE* fp) {
+            SET_BINARY_MODE(fp);
+            if (m_fp) close();
+            m_fp = ::gzdopen(fileno(fp), "rb");
+        }
+
+        /* Flushes all pending input if necessary, closes the compressed file
+         * and deallocates all the (de)compression state. The return value is
+         * the zlib error number (see function error() below).
+         */
+        int close() {
+            int r = ::gzclose(m_fp);
+            m_fp = 0; return r;
+        }
+
+        /* Binary read the given number of bytes from the compressed file.
+         */
+        int read(void* buf, size_t len) {
+            return ::gzread(m_fp, buf, len);
+        }
+
+        /* Returns the error message for the last error which occurred on the
+         * given compressed file. errnum is set to zlib error number. If an
+         * error occurred in the file system and not in the compression library,
+         * errnum is set to Z_ERRNO and the application may consult errno
+         * to get the exact error code.
+         */
+        const char* error(int* errnum) {
+            return ::gzerror(m_fp, errnum);
+        }
+
+        gzFile fp() { return m_fp; }
+
+    private:
+        gzFile m_fp;
+};
+
+/*
+ * Binary read the given (array of) object(s) from the compressed file.
+ * If the input file was not in gzip format, read() copies the objects number
+ * of bytes into the buffer.
+ * returns the number of uncompressed bytes actually read
+ * (0 for end of file, -1 for error).
+ */
+template <class T, class Items>
+inline int read(izstream& zs, T* x, Items items) {
+    return ::gzread(zs.fp(), x, items*sizeof(T));
+}
+
+/*
+ * Binary input with the '>' operator.
+ */
+template <class T>
+inline izstream& operator>(izstream& zs, T& x) {
+    ::gzread(zs.fp(), &x, sizeof(T));
+    return zs;
+}
+
+
+inline zstringlen::zstringlen(izstream& zs) {
+    zs > val.byte;
+    if (val.byte == 255) zs > val.word;
+    else val.word = val.byte;
+}
+
+/*
+ * Read length of string + the string with the '>' operator.
+ */
+inline izstream& operator>(izstream& zs, char* x) {
+    zstringlen len(zs);
+    ::gzread(zs.fp(), x, len.value());
+    x[len.value()] = '\0';
+    return zs;
+}
+
+inline char* read_string(izstream& zs) {
+    zstringlen len(zs);
+    char* x = new char[len.value()+1];
+    ::gzread(zs.fp(), x, len.value());
+    x[len.value()] = '\0';
+    return x;
+}
+
+// ----------------------------- ozstream -----------------------------
+
+class ozstream
+{
+    public:
+        ozstream() : m_fp(0), m_os(0) {
+        }
+        ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
+            : m_fp(0), m_os(0) {
+            open(fp, level);
+        }
+        ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
+            : m_fp(0), m_os(0) {
+            open(name, level);
+        }
+        ~ozstream() {
+            close();
+        }
+
+        /* Opens a gzip (.gz) file for writing.
+         * The compression level parameter should be in 0..9
+         * errno can be checked to distinguish two error cases
+         * (if errno is zero, the zlib error is Z_MEM_ERROR).
+         */
+        void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
+            char mode[4] = "wb\0";
+            if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
+            if (m_fp) close();
+            m_fp = ::gzopen(name, mode);
+        }
+
+        /* open from a FILE pointer.
+         */
+        void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
+            SET_BINARY_MODE(fp);
+            char mode[4] = "wb\0";
+            if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
+            if (m_fp) close();
+            m_fp = ::gzdopen(fileno(fp), mode);
+        }
+
+        /* Flushes all pending output if necessary, closes the compressed file
+         * and deallocates all the (de)compression state. The return value is
+         * the zlib error number (see function error() below).
+         */
+        int close() {
+            if (m_os) {
+                ::gzwrite(m_fp, m_os->str(), m_os->pcount());
+                delete[] m_os->str(); delete m_os; m_os = 0;
+            }
+            int r = ::gzclose(m_fp); m_fp = 0; return r;
+        }
+
+        /* Binary write the given number of bytes into the compressed file.
+         */
+        int write(const void* buf, size_t len) {
+            return ::gzwrite(m_fp, (voidp) buf, len);
+        }
+
+        /* Flushes all pending output into the compressed file. The parameter
+         * _flush is as in the deflate() function. The return value is the zlib
+         * error number (see function gzerror below). flush() returns Z_OK if
+         * the flush_ parameter is Z_FINISH and all output could be flushed.
+         * flush() should be called only when strictly necessary because it can
+         * degrade compression.
+         */
+        int flush(int _flush) {
+            os_flush();
+            return ::gzflush(m_fp, _flush);
+        }
+
+        /* Returns the error message for the last error which occurred on the
+         * given compressed file. errnum is set to zlib error number. If an
+         * error occurred in the file system and not in the compression library,
+         * errnum is set to Z_ERRNO and the application may consult errno
+         * to get the exact error code.
+         */
+        const char* error(int* errnum) {
+            return ::gzerror(m_fp, errnum);
+        }
+
+        gzFile fp() { return m_fp; }
+
+        ostream& os() {
+            if (m_os == 0) m_os = new ostrstream;
+            return *m_os;
+        }
+
+        void os_flush() {
+            if (m_os && m_os->pcount()>0) {
+                ostrstream* oss = new ostrstream;
+                oss->fill(m_os->fill());
+                oss->flags(m_os->flags());
+                oss->precision(m_os->precision());
+                oss->width(m_os->width());
+                ::gzwrite(m_fp, m_os->str(), m_os->pcount());
+                delete[] m_os->str(); delete m_os; m_os = oss;
+            }
+        }
+
+    private:
+        gzFile m_fp;
+        ostrstream* m_os;
+};
+
+/*
+ * Binary write the given (array of) object(s) into the compressed file.
+ * returns the number of uncompressed bytes actually written
+ * (0 in case of error).
+ */
+template <class T, class Items>
+inline int write(ozstream& zs, const T* x, Items items) {
+    return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
+}
+
+/*
+ * Binary output with the '<' operator.
+ */
+template <class T>
+inline ozstream& operator<(ozstream& zs, const T& x) {
+    ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
+    return zs;
+}
+
+inline zstringlen::zstringlen(ozstream& zs, const char* x) {
+    val.byte = 255;  val.word = ::strlen(x);
+    if (val.word < 255) zs < (val.byte = val.word);
+    else zs < val;
+}
+
+/*
+ * Write length of string + the string with the '<' operator.
+ */
+inline ozstream& operator<(ozstream& zs, const char* x) {
+    zstringlen len(zs, x);
+    ::gzwrite(zs.fp(), (voidp) x, len.value());
+    return zs;
+}
+
+#ifdef _MSC_VER
+inline ozstream& operator<(ozstream& zs, char* const& x) {
+    return zs < (const char*) x;
+}
+#endif
+
+/*
+ * Ascii write with the << operator;
+ */
+template <class T>
+inline ostream& operator<<(ozstream& zs, const T& x) {
+    zs.os_flush();
+    return zs.os() << x;
+}
+
+#endif
diff --git a/8.x/zlib/contrib/iostream2/zstream_test.cpp b/8.x/zlib/contrib/iostream2/zstream_test.cpp
new file mode 100644 (file)
index 0000000..6273f62
--- /dev/null
@@ -0,0 +1,25 @@
+#include "zstream.h"
+#include <math.h>
+#include <stdlib.h>
+#include <iomanip.h>
+
+void main() {
+    char h[256] = "Hello";
+    char* g = "Goodbye";
+    ozstream out("temp.gz");
+    out < "This works well" < h < g;
+    out.close();
+
+    izstream in("temp.gz"); // read it back
+    char *x = read_string(in), *y = new char[256], z[256];
+    in > y > z;
+    in.close();
+    cout << x << endl << y << endl << z << endl;
+
+    out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results
+    out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl;
+    out << z << endl << y << endl << x << endl;
+    out << 1.1234567890123456789 << endl;
+
+    delete[] x; delete[] y;
+}
diff --git a/8.x/zlib/contrib/iostream3/README b/8.x/zlib/contrib/iostream3/README
new file mode 100644 (file)
index 0000000..f7b319a
--- /dev/null
@@ -0,0 +1,35 @@
+These classes provide a C++ stream interface to the zlib library. It allows you
+to do things like:
+
+  gzofstream outf("blah.gz");
+  outf << "These go into the gzip file " << 123 << endl;
+
+It does this by deriving a specialized stream buffer for gzipped files, which is
+the way Stroustrup would have done it. :->
+
+The gzifstream and gzofstream classes were originally written by Kevin Ruland
+and made available in the zlib contrib/iostream directory. The older version still
+compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of
+this version.
+
+The new classes are as standard-compliant as possible, closely following the
+approach of the standard library's fstream classes. It compiles under gcc versions
+3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard
+library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs
+from the previous one in the following respects:
+- added showmanyc
+- added setbuf, with support for unbuffered output via setbuf(0,0)
+- a few bug fixes of stream behavior
+- gzipped output file opened with default compression level instead of maximum level
+- setcompressionlevel()/strategy() members replaced by single setcompression()
+
+The code is provided "as is", with the permission to use, copy, modify, distribute
+and sell it for any purpose without fee.
+
+Ludwig Schwardt
+<schwardt@sun.ac.za>
+
+DSP Lab
+Electrical & Electronic Engineering Department
+University of Stellenbosch
+South Africa
diff --git a/8.x/zlib/contrib/iostream3/TODO b/8.x/zlib/contrib/iostream3/TODO
new file mode 100644 (file)
index 0000000..7032f97
--- /dev/null
@@ -0,0 +1,17 @@
+Possible upgrades to gzfilebuf:
+
+- The ability to do putback (e.g. putbackfail)
+
+- The ability to seek (zlib supports this, but could be slow/tricky)
+
+- Simultaneous read/write access (does it make sense?)
+
+- Support for ios_base::ate open mode
+
+- Locale support?
+
+- Check public interface to see which calls give problems
+  (due to dependence on library internals)
+
+- Override operator<<(ostream&, gzfilebuf*) to allow direct copying
+  of stream buffer to stream ( i.e. os << is.rdbuf(); )
diff --git a/8.x/zlib/contrib/iostream3/test.cc b/8.x/zlib/contrib/iostream3/test.cc
new file mode 100644 (file)
index 0000000..9423533
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Test program for gzifstream and gzofstream
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ */
+
+#include "zfstream.h"
+#include <iostream>      // for cout
+
+int main() {
+
+  gzofstream outf;
+  gzifstream inf;
+  char buf[80];
+
+  outf.open("test1.txt.gz");
+  outf << "The quick brown fox sidestepped the lazy canine\n"
+       << 1.3 << "\nPlan " << 9 << std::endl;
+  outf.close();
+  std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n"
+            << "The quick brown fox sidestepped the lazy canine\n"
+            << 1.3 << "\nPlan " << 9 << std::endl;
+
+  std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n";
+  inf.open("test1.txt.gz");
+  while (inf.getline(buf,80,'\n')) {
+    std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+  }
+  inf.close();
+
+  outf.rdbuf()->pubsetbuf(0,0);
+  outf.open("test2.txt.gz");
+  outf << setcompression(Z_NO_COMPRESSION)
+       << "The quick brown fox sidestepped the lazy canine\n"
+       << 1.3 << "\nPlan " << 9 << std::endl;
+  outf.close();
+  std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form";
+
+  std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n";
+  inf.rdbuf()->pubsetbuf(0,0);
+  inf.open("test2.txt.gz");
+  while (inf.getline(buf,80,'\n')) {
+    std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+  }
+  inf.close();
+
+  return 0;
+
+}
diff --git a/8.x/zlib/contrib/iostream3/zfstream.cc b/8.x/zlib/contrib/iostream3/zfstream.cc
new file mode 100644 (file)
index 0000000..94eb933
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * A C++ I/O streams interface to the zlib gz* functions
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ *
+ * This version is standard-compliant and compatible with gcc 3.x.
+ */
+
+#include "zfstream.h"
+#include <cstring>          // for strcpy, strcat, strlen (mode strings)
+#include <cstdio>           // for BUFSIZ
+
+// Internal buffer sizes (default and "unbuffered" versions)
+#define BIGBUFSIZE BUFSIZ
+#define SMALLBUFSIZE 1
+
+/*****************************************************************************/
+
+// Default constructor
+gzfilebuf::gzfilebuf()
+: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
+  buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
+{
+  // No buffers to start with
+  this->disable_buffer();
+}
+
+// Destructor
+gzfilebuf::~gzfilebuf()
+{
+  // Sync output buffer and close only if responsible for file
+  // (i.e. attached streams should be left open at this stage)
+  this->sync();
+  if (own_fd)
+    this->close();
+  // Make sure internal buffer is deallocated
+  this->disable_buffer();
+}
+
+// Set compression level and strategy
+int
+gzfilebuf::setcompression(int comp_level,
+                          int comp_strategy)
+{
+  return gzsetparams(file, comp_level, comp_strategy);
+}
+
+// Open gzipped file
+gzfilebuf*
+gzfilebuf::open(const char *name,
+                std::ios_base::openmode mode)
+{
+  // Fail if file already open
+  if (this->is_open())
+    return NULL;
+  // Don't support simultaneous read/write access (yet)
+  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+    return NULL;
+
+  // Build mode string for gzopen and check it [27.8.1.3.2]
+  char char_mode[6] = "\0\0\0\0\0";
+  if (!this->open_mode(mode, char_mode))
+    return NULL;
+
+  // Attempt to open file
+  if ((file = gzopen(name, char_mode)) == NULL)
+    return NULL;
+
+  // On success, allocate internal buffer and set flags
+  this->enable_buffer();
+  io_mode = mode;
+  own_fd = true;
+  return this;
+}
+
+// Attach to gzipped file
+gzfilebuf*
+gzfilebuf::attach(int fd,
+                  std::ios_base::openmode mode)
+{
+  // Fail if file already open
+  if (this->is_open())
+    return NULL;
+  // Don't support simultaneous read/write access (yet)
+  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+    return NULL;
+
+  // Build mode string for gzdopen and check it [27.8.1.3.2]
+  char char_mode[6] = "\0\0\0\0\0";
+  if (!this->open_mode(mode, char_mode))
+    return NULL;
+
+  // Attempt to attach to file
+  if ((file = gzdopen(fd, char_mode)) == NULL)
+    return NULL;
+
+  // On success, allocate internal buffer and set flags
+  this->enable_buffer();
+  io_mode = mode;
+  own_fd = false;
+  return this;
+}
+
+// Close gzipped file
+gzfilebuf*
+gzfilebuf::close()
+{
+  // Fail immediately if no file is open
+  if (!this->is_open())
+    return NULL;
+  // Assume success
+  gzfilebuf* retval = this;
+  // Attempt to sync and close gzipped file
+  if (this->sync() == -1)
+    retval = NULL;
+  if (gzclose(file) < 0)
+    retval = NULL;
+  // File is now gone anyway (postcondition [27.8.1.3.8])
+  file = NULL;
+  own_fd = false;
+  // Destroy internal buffer if it exists
+  this->disable_buffer();
+  return retval;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Convert int open mode to mode string
+bool
+gzfilebuf::open_mode(std::ios_base::openmode mode,
+                     char* c_mode) const
+{
+  bool testb = mode & std::ios_base::binary;
+  bool testi = mode & std::ios_base::in;
+  bool testo = mode & std::ios_base::out;
+  bool testt = mode & std::ios_base::trunc;
+  bool testa = mode & std::ios_base::app;
+
+  // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
+  // Original zfstream hardcoded the compression level to maximum here...
+  // Double the time for less than 1% size improvement seems
+  // excessive though - keeping it at the default level
+  // To change back, just append "9" to the next three mode strings
+  if (!testi && testo && !testt && !testa)
+    strcpy(c_mode, "w");
+  if (!testi && testo && !testt && testa)
+    strcpy(c_mode, "a");
+  if (!testi && testo && testt && !testa)
+    strcpy(c_mode, "w");
+  if (testi && !testo && !testt && !testa)
+    strcpy(c_mode, "r");
+  // No read/write mode yet
+//  if (testi && testo && !testt && !testa)
+//    strcpy(c_mode, "r+");
+//  if (testi && testo && testt && !testa)
+//    strcpy(c_mode, "w+");
+
+  // Mode string should be empty for invalid combination of flags
+  if (strlen(c_mode) == 0)
+    return false;
+  if (testb)
+    strcat(c_mode, "b");
+  return true;
+}
+
+// Determine number of characters in internal get buffer
+std::streamsize
+gzfilebuf::showmanyc()
+{
+  // Calls to underflow will fail if file not opened for reading
+  if (!this->is_open() || !(io_mode & std::ios_base::in))
+    return -1;
+  // Make sure get area is in use
+  if (this->gptr() && (this->gptr() < this->egptr()))
+    return std::streamsize(this->egptr() - this->gptr());
+  else
+    return 0;
+}
+
+// Fill get area from gzipped file
+gzfilebuf::int_type
+gzfilebuf::underflow()
+{
+  // If something is left in the get area by chance, return it
+  // (this shouldn't normally happen, as underflow is only supposed
+  // to be called when gptr >= egptr, but it serves as error check)
+  if (this->gptr() && (this->gptr() < this->egptr()))
+    return traits_type::to_int_type(*(this->gptr()));
+
+  // If the file hasn't been opened for reading, produce error
+  if (!this->is_open() || !(io_mode & std::ios_base::in))
+    return traits_type::eof();
+
+  // Attempt to fill internal buffer from gzipped file
+  // (buffer must be guaranteed to exist...)
+  int bytes_read = gzread(file, buffer, buffer_size);
+  // Indicates error or EOF
+  if (bytes_read <= 0)
+  {
+    // Reset get area
+    this->setg(buffer, buffer, buffer);
+    return traits_type::eof();
+  }
+  // Make all bytes read from file available as get area
+  this->setg(buffer, buffer, buffer + bytes_read);
+
+  // Return next character in get area
+  return traits_type::to_int_type(*(this->gptr()));
+}
+
+// Write put area to gzipped file
+gzfilebuf::int_type
+gzfilebuf::overflow(int_type c)
+{
+  // Determine whether put area is in use
+  if (this->pbase())
+  {
+    // Double-check pointer range
+    if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
+      return traits_type::eof();
+    // Add extra character to buffer if not EOF
+    if (!traits_type::eq_int_type(c, traits_type::eof()))
+    {
+      *(this->pptr()) = traits_type::to_char_type(c);
+      this->pbump(1);
+    }
+    // Number of characters to write to file
+    int bytes_to_write = this->pptr() - this->pbase();
+    // Overflow doesn't fail if nothing is to be written
+    if (bytes_to_write > 0)
+    {
+      // If the file hasn't been opened for writing, produce error
+      if (!this->is_open() || !(io_mode & std::ios_base::out))
+        return traits_type::eof();
+      // If gzipped file won't accept all bytes written to it, fail
+      if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
+        return traits_type::eof();
+      // Reset next pointer to point to pbase on success
+      this->pbump(-bytes_to_write);
+    }
+  }
+  // Write extra character to file if not EOF
+  else if (!traits_type::eq_int_type(c, traits_type::eof()))
+  {
+    // If the file hasn't been opened for writing, produce error
+    if (!this->is_open() || !(io_mode & std::ios_base::out))
+      return traits_type::eof();
+    // Impromptu char buffer (allows "unbuffered" output)
+    char_type last_char = traits_type::to_char_type(c);
+    // If gzipped file won't accept this character, fail
+    if (gzwrite(file, &last_char, 1) != 1)
+      return traits_type::eof();
+  }
+
+  // If you got here, you have succeeded (even if c was EOF)
+  // The return value should therefore be non-EOF
+  if (traits_type::eq_int_type(c, traits_type::eof()))
+    return traits_type::not_eof(c);
+  else
+    return c;
+}
+
+// Assign new buffer
+std::streambuf*
+gzfilebuf::setbuf(char_type* p,
+                  std::streamsize n)
+{
+  // First make sure stuff is sync'ed, for safety
+  if (this->sync() == -1)
+    return NULL;
+  // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
+  // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
+  // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
+  // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
+  if (!p || !n)
+  {
+    // Replace existing buffer (if any) with small internal buffer
+    this->disable_buffer();
+    buffer = NULL;
+    buffer_size = 0;
+    own_buffer = true;
+    this->enable_buffer();
+  }
+  else
+  {
+    // Replace existing buffer (if any) with external buffer
+    this->disable_buffer();
+    buffer = p;
+    buffer_size = n;
+    own_buffer = false;
+    this->enable_buffer();
+  }
+  return this;
+}
+
+// Write put area to gzipped file (i.e. ensures that put area is empty)
+int
+gzfilebuf::sync()
+{
+  return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Allocate internal buffer
+void
+gzfilebuf::enable_buffer()
+{
+  // If internal buffer required, allocate one
+  if (own_buffer && !buffer)
+  {
+    // Check for buffered vs. "unbuffered"
+    if (buffer_size > 0)
+    {
+      // Allocate internal buffer
+      buffer = new char_type[buffer_size];
+      // Get area starts empty and will be expanded by underflow as need arises
+      this->setg(buffer, buffer, buffer);
+      // Setup entire internal buffer as put area.
+      // The one-past-end pointer actually points to the last element of the buffer,
+      // so that overflow(c) can safely add the extra character c to the sequence.
+      // These pointers remain in place for the duration of the buffer
+      this->setp(buffer, buffer + buffer_size - 1);
+    }
+    else
+    {
+      // Even in "unbuffered" case, (small?) get buffer is still required
+      buffer_size = SMALLBUFSIZE;
+      buffer = new char_type[buffer_size];
+      this->setg(buffer, buffer, buffer);
+      // "Unbuffered" means no put buffer
+      this->setp(0, 0);
+    }
+  }
+  else
+  {
+    // If buffer already allocated, reset buffer pointers just to make sure no
+    // stale chars are lying around
+    this->setg(buffer, buffer, buffer);
+    this->setp(buffer, buffer + buffer_size - 1);
+  }
+}
+
+// Destroy internal buffer
+void
+gzfilebuf::disable_buffer()
+{
+  // If internal buffer exists, deallocate it
+  if (own_buffer && buffer)
+  {
+    // Preserve unbuffered status by zeroing size
+    if (!this->pbase())
+      buffer_size = 0;
+    delete[] buffer;
+    buffer = NULL;
+    this->setg(0, 0, 0);
+    this->setp(0, 0);
+  }
+  else
+  {
+    // Reset buffer pointers to initial state if external buffer exists
+    this->setg(buffer, buffer, buffer);
+    if (buffer)
+      this->setp(buffer, buffer + buffer_size - 1);
+    else
+      this->setp(0, 0);
+  }
+}
+
+/*****************************************************************************/
+
+// Default constructor initializes stream buffer
+gzifstream::gzifstream()
+: std::istream(NULL), sb()
+{ this->init(&sb); }
+
+// Initialize stream buffer and open file
+gzifstream::gzifstream(const char* name,
+                       std::ios_base::openmode mode)
+: std::istream(NULL), sb()
+{
+  this->init(&sb);
+  this->open(name, mode);
+}
+
+// Initialize stream buffer and attach to file
+gzifstream::gzifstream(int fd,
+                       std::ios_base::openmode mode)
+: std::istream(NULL), sb()
+{
+  this->init(&sb);
+  this->attach(fd, mode);
+}
+
+// Open file and go into fail() state if unsuccessful
+void
+gzifstream::open(const char* name,
+                 std::ios_base::openmode mode)
+{
+  if (!sb.open(name, mode | std::ios_base::in))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Attach to file and go into fail() state if unsuccessful
+void
+gzifstream::attach(int fd,
+                   std::ios_base::openmode mode)
+{
+  if (!sb.attach(fd, mode | std::ios_base::in))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Close file
+void
+gzifstream::close()
+{
+  if (!sb.close())
+    this->setstate(std::ios_base::failbit);
+}
+
+/*****************************************************************************/
+
+// Default constructor initializes stream buffer
+gzofstream::gzofstream()
+: std::ostream(NULL), sb()
+{ this->init(&sb); }
+
+// Initialize stream buffer and open file
+gzofstream::gzofstream(const char* name,
+                       std::ios_base::openmode mode)
+: std::ostream(NULL), sb()
+{
+  this->init(&sb);
+  this->open(name, mode);
+}
+
+// Initialize stream buffer and attach to file
+gzofstream::gzofstream(int fd,
+                       std::ios_base::openmode mode)
+: std::ostream(NULL), sb()
+{
+  this->init(&sb);
+  this->attach(fd, mode);
+}
+
+// Open file and go into fail() state if unsuccessful
+void
+gzofstream::open(const char* name,
+                 std::ios_base::openmode mode)
+{
+  if (!sb.open(name, mode | std::ios_base::out))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Attach to file and go into fail() state if unsuccessful
+void
+gzofstream::attach(int fd,
+                   std::ios_base::openmode mode)
+{
+  if (!sb.attach(fd, mode | std::ios_base::out))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Close file
+void
+gzofstream::close()
+{
+  if (!sb.close())
+    this->setstate(std::ios_base::failbit);
+}
diff --git a/8.x/zlib/contrib/iostream3/zfstream.h b/8.x/zlib/contrib/iostream3/zfstream.h
new file mode 100644 (file)
index 0000000..8574479
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * A C++ I/O streams interface to the zlib gz* functions
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ *
+ * This version is standard-compliant and compatible with gcc 3.x.
+ */
+
+#ifndef ZFSTREAM_H
+#define ZFSTREAM_H
+
+#include <istream>  // not iostream, since we don't need cin/cout
+#include <ostream>
+#include "zlib.h"
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file stream buffer class.
+ *
+ *  This class implements basic_filebuf for gzipped files. It doesn't yet support
+ *  seeking (allowed by zlib but slow/limited), putback and read/write access
+ *  (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
+ *  file streambuf.
+*/
+class gzfilebuf : public std::streambuf
+{
+public:
+  //  Default constructor.
+  gzfilebuf();
+
+  //  Destructor.
+  virtual
+  ~gzfilebuf();
+
+  /**
+   *  @brief  Set compression level and strategy on the fly.
+   *  @param  comp_level  Compression level (see zlib.h for allowed values)
+   *  @param  comp_strategy  Compression strategy (see zlib.h for allowed values)
+   *  @return  Z_OK on success, Z_STREAM_ERROR otherwise.
+   *
+   *  Unfortunately, these parameters cannot be modified separately, as the
+   *  previous zfstream version assumed. Since the strategy is seldom changed,
+   *  it can default and setcompression(level) then becomes like the old
+   *  setcompressionlevel(level).
+  */
+  int
+  setcompression(int comp_level,
+                 int comp_strategy = Z_DEFAULT_STRATEGY);
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() const { return (file != NULL); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  open(const char* name,
+       std::ios_base::openmode mode);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  attach(int fd,
+         std::ios_base::openmode mode);
+
+  /**
+   *  @brief  Close gzipped file.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  close();
+
+protected:
+  /**
+   *  @brief  Convert ios open mode int to mode string used by zlib.
+   *  @return  True if valid mode flag combination.
+  */
+  bool
+  open_mode(std::ios_base::openmode mode,
+            char* c_mode) const;
+
+  /**
+   *  @brief  Number of characters available in stream buffer.
+   *  @return  Number of characters.
+   *
+   *  This indicates number of characters in get area of stream buffer.
+   *  These characters can be read without accessing the gzipped file.
+  */
+  virtual std::streamsize
+  showmanyc();
+
+  /**
+   *  @brief  Fill get area from gzipped file.
+   *  @return  First character in get area on success, EOF on error.
+   *
+   *  This actually reads characters from gzipped file to stream
+   *  buffer. Always buffered.
+  */
+  virtual int_type
+  underflow();
+
+  /**
+   *  @brief  Write put area to gzipped file.
+   *  @param  c  Extra character to add to buffer contents.
+   *  @return  Non-EOF on success, EOF on error.
+   *
+   *  This actually writes characters in stream buffer to
+   *  gzipped file. With unbuffered output this is done one
+   *  character at a time.
+  */
+  virtual int_type
+  overflow(int_type c = traits_type::eof());
+
+  /**
+   *  @brief  Installs external stream buffer.
+   *  @param  p  Pointer to char buffer.
+   *  @param  n  Size of external buffer.
+   *  @return  @c this on success, NULL on failure.
+   *
+   *  Call setbuf(0,0) to enable unbuffered output.
+  */
+  virtual std::streambuf*
+  setbuf(char_type* p,
+         std::streamsize n);
+
+  /**
+   *  @brief  Flush stream buffer to file.
+   *  @return  0 on success, -1 on error.
+   *
+   *  This calls underflow(EOF) to do the job.
+  */
+  virtual int
+  sync();
+
+//
+// Some future enhancements
+//
+//  virtual int_type uflow();
+//  virtual int_type pbackfail(int_type c = traits_type::eof());
+//  virtual pos_type
+//  seekoff(off_type off,
+//          std::ios_base::seekdir way,
+//          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
+//  virtual pos_type
+//  seekpos(pos_type sp,
+//          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
+
+private:
+  /**
+   *  @brief  Allocate internal buffer.
+   *
+   *  This function is safe to call multiple times. It will ensure
+   *  that a proper internal buffer exists if it is required. If the
+   *  buffer already exists or is external, the buffer pointers will be
+   *  reset to their original state.
+  */
+  void
+  enable_buffer();
+
+  /**
+   *  @brief  Destroy internal buffer.
+   *
+   *  This function is safe to call multiple times. It will ensure
+   *  that the internal buffer is deallocated if it exists. In any
+   *  case, it will also reset the buffer pointers.
+  */
+  void
+  disable_buffer();
+
+  /**
+   *  Underlying file pointer.
+  */
+  gzFile file;
+
+  /**
+   *  Mode in which file was opened.
+  */
+  std::ios_base::openmode io_mode;
+
+  /**
+   *  @brief  True if this object owns file descriptor.
+   *
+   *  This makes the class responsible for closing the file
+   *  upon destruction.
+  */
+  bool own_fd;
+
+  /**
+   *  @brief  Stream buffer.
+   *
+   *  For simplicity this remains allocated on the free store for the
+   *  entire life span of the gzfilebuf object, unless replaced by setbuf.
+  */
+  char_type* buffer;
+
+  /**
+   *  @brief  Stream buffer size.
+   *
+   *  Defaults to system default buffer size (typically 8192 bytes).
+   *  Modified by setbuf.
+  */
+  std::streamsize buffer_size;
+
+  /**
+   *  @brief  True if this object owns stream buffer.
+   *
+   *  This makes the class responsible for deleting the buffer
+   *  upon destruction.
+  */
+  bool own_buffer;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file input stream class.
+ *
+ *  This class implements ifstream for gzipped files. Seeking and putback
+ *  is not supported yet.
+*/
+class gzifstream : public std::istream
+{
+public:
+  //  Default constructor
+  gzifstream();
+
+  /**
+   *  @brief  Construct stream on gzipped file to be opened.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+  */
+  explicit
+  gzifstream(const char* name,
+             std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Construct stream on already open gzipped file.
+   *  @param  fd    File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+  */
+  explicit
+  gzifstream(int fd,
+             std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  Obtain underlying stream buffer.
+  */
+  gzfilebuf*
+  rdbuf() const
+  { return const_cast<gzfilebuf*>(&sb); }
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() { return sb.is_open(); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+   *
+   *  Stream will be in state good() if file opens successfully;
+   *  otherwise in state fail(). This differs from the behavior of
+   *  ifstream, which never sets the state to good() and therefore
+   *  won't allow you to reuse the stream for a second file unless
+   *  you manually clear() the state. The choice is a matter of
+   *  convenience.
+  */
+  void
+  open(const char* name,
+       std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+   *
+   *  Stream will be in state good() if attach succeeded; otherwise
+   *  in state fail().
+  */
+  void
+  attach(int fd,
+         std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Close gzipped file.
+   *
+   *  Stream will be in state fail() if close failed.
+  */
+  void
+  close();
+
+private:
+  /**
+   *  Underlying stream buffer.
+  */
+  gzfilebuf sb;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file output stream class.
+ *
+ *  This class implements ofstream for gzipped files. Seeking and putback
+ *  is not supported yet.
+*/
+class gzofstream : public std::ostream
+{
+public:
+  //  Default constructor
+  gzofstream();
+
+  /**
+   *  @brief  Construct stream on gzipped file to be opened.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+  */
+  explicit
+  gzofstream(const char* name,
+             std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Construct stream on already open gzipped file.
+   *  @param  fd    File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+  */
+  explicit
+  gzofstream(int fd,
+             std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  Obtain underlying stream buffer.
+  */
+  gzfilebuf*
+  rdbuf() const
+  { return const_cast<gzfilebuf*>(&sb); }
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() { return sb.is_open(); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+   *
+   *  Stream will be in state good() if file opens successfully;
+   *  otherwise in state fail(). This differs from the behavior of
+   *  ofstream, which never sets the state to good() and therefore
+   *  won't allow you to reuse the stream for a second file unless
+   *  you manually clear() the state. The choice is a matter of
+   *  convenience.
+  */
+  void
+  open(const char* name,
+       std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+   *
+   *  Stream will be in state good() if attach succeeded; otherwise
+   *  in state fail().
+  */
+  void
+  attach(int fd,
+         std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Close gzipped file.
+   *
+   *  Stream will be in state fail() if close failed.
+  */
+  void
+  close();
+
+private:
+  /**
+   *  Underlying stream buffer.
+  */
+  gzfilebuf sb;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file output stream manipulator class.
+ *
+ *  This class defines a two-argument manipulator for gzofstream. It is used
+ *  as base for the setcompression(int,int) manipulator.
+*/
+template<typename T1, typename T2>
+  class gzomanip2
+  {
+  public:
+    // Allows insertor to peek at internals
+    template <typename Ta, typename Tb>
+      friend gzofstream&
+      operator<<(gzofstream&,
+                 const gzomanip2<Ta,Tb>&);
+
+    // Constructor
+    gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
+              T1 v1,
+              T2 v2);
+  private:
+    // Underlying manipulator function
+    gzofstream&
+    (*func)(gzofstream&, T1, T2);
+
+    // Arguments for manipulator function
+    T1 val1;
+    T2 val2;
+  };
+
+/*****************************************************************************/
+
+// Manipulator function thunks through to stream buffer
+inline gzofstream&
+setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
+{
+  (gzs.rdbuf())->setcompression(l, s);
+  return gzs;
+}
+
+// Manipulator constructor stores arguments
+template<typename T1, typename T2>
+  inline
+  gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
+                              T1 v1,
+                              T2 v2)
+  : func(f), val1(v1), val2(v2)
+  { }
+
+// Insertor applies underlying manipulator function to stream
+template<typename T1, typename T2>
+  inline gzofstream&
+  operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
+  { return (*m.func)(s, m.val1, m.val2); }
+
+// Insert this onto stream to simplify setting of compression level
+inline gzomanip2<int,int>
+setcompression(int l, int s = Z_DEFAULT_STRATEGY)
+{ return gzomanip2<int,int>(&setcompression, l, s); }
+
+#endif // ZFSTREAM_H
diff --git a/8.x/zlib/contrib/masmx64/bld_ml64.bat b/8.x/zlib/contrib/masmx64/bld_ml64.bat
new file mode 100644 (file)
index 0000000..8f9343d
--- /dev/null
@@ -0,0 +1,2 @@
+ml64.exe /Flinffasx64 /c /Zi inffasx64.asm\r
+ml64.exe /Flgvmat64   /c /Zi gvmat64.asm\r
diff --git a/8.x/zlib/contrib/masmx64/gvmat64.asm b/8.x/zlib/contrib/masmx64/gvmat64.asm
new file mode 100644 (file)
index 0000000..9879c28
--- /dev/null
@@ -0,0 +1,553 @@
+;uInt longest_match_x64(\r
+;    deflate_state *s,\r
+;    IPos cur_match);                             /* current match */\r
+\r
+; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86_64\r
+;  (AMD64 on Athlon 64, Opteron, Phenom\r
+;     and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)\r
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.\r
+;\r
+; File written by Gilles Vollant, by converting to assembly the longest_match\r
+;  from Jean-loup Gailly in deflate.c of zLib and infoZip zip.\r
+;\r
+;  and by taking inspiration on asm686 with masm, optimised assembly code\r
+;        from Brian Raiter, written 1998\r
+;\r
+;  This software is provided 'as-is', without any express or implied\r
+;  warranty.  In no event will the authors be held liable for any damages\r
+;  arising from the use of this software.\r
+;\r
+;  Permission is granted to anyone to use this software for any purpose,\r
+;  including commercial applications, and to alter it and redistribute it\r
+;  freely, subject to the following restrictions:\r
+;\r
+;  1. The origin of this software must not be misrepresented; you must not\r
+;     claim that you wrote the original software. If you use this software\r
+;     in a product, an acknowledgment in the product documentation would be\r
+;     appreciated but is not required.\r
+;  2. Altered source versions must be plainly marked as such, and must not be\r
+;     misrepresented as being the original software\r
+;  3. This notice may not be removed or altered from any source distribution.\r
+;\r
+;\r
+;\r
+;         http://www.zlib.net\r
+;         http://www.winimage.com/zLibDll\r
+;         http://www.muppetlabs.com/~breadbox/software/assembly.html\r
+;\r
+; to compile this file for infozip Zip, I use option:\r
+;   ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm\r
+;\r
+; to compile this file for zLib, I use option:\r
+;   ml64.exe /Flgvmat64 /c /Zi gvmat64.asm\r
+; Be carrefull to adapt zlib1222add below to your version of zLib\r
+;   (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change\r
+;    value of zlib1222add later)\r
+;\r
+; This file compile with Microsoft Macro Assembler (x64) for AMD64\r
+;\r
+;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK\r
+;\r
+;   (you can get Windows WDK with ml64 for AMD64 from\r
+;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)\r
+;\r
+\r
+\r
+;uInt longest_match(s, cur_match)\r
+;    deflate_state *s;\r
+;    IPos cur_match;                             /* current match */\r
+.code\r
+longest_match PROC\r
+\r
+\r
+;LocalVarsSize   equ 88\r
+ LocalVarsSize   equ 72\r
+\r
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12\r
+; free register :  r14,r15\r
+; register can be saved : rsp\r
+\r
+ chainlenwmask   equ  rsp + 8 - LocalVarsSize    ; high word: current chain len\r
+                                                 ; low word: s->wmask\r
+;window          equ  rsp + xx - LocalVarsSize   ; local copy of s->window ; stored in r10\r
+;windowbestlen   equ  rsp + xx - LocalVarsSize   ; s->window + bestlen , use r10+r11\r
+;scanstart       equ  rsp + xx - LocalVarsSize   ; first two bytes of string ; stored in r12w\r
+;scanend         equ  rsp + xx - LocalVarsSize   ; last two bytes of string use ebx\r
+;scanalign       equ  rsp + xx - LocalVarsSize   ; dword-misalignment of string r13\r
+;bestlen         equ  rsp + xx - LocalVarsSize   ; size of best match so far -> r11d\r
+;scan            equ  rsp + xx - LocalVarsSize   ; ptr to string wanting match -> r9\r
+IFDEF INFOZIP\r
+ELSE\r
+ nicematch       equ  (rsp + 16 - LocalVarsSize) ; a good enough match size\r
+ENDIF\r
+\r
+save_rdi        equ  rsp + 24 - LocalVarsSize\r
+save_rsi        equ  rsp + 32 - LocalVarsSize\r
+save_rbx        equ  rsp + 40 - LocalVarsSize\r
+save_rbp        equ  rsp + 48 - LocalVarsSize\r
+save_r12        equ  rsp + 56 - LocalVarsSize\r
+save_r13        equ  rsp + 64 - LocalVarsSize\r
+;save_r14        equ  rsp + 72 - LocalVarsSize\r
+;save_r15        equ  rsp + 80 - LocalVarsSize\r
+\r
+\r
+; summary of register usage\r
+; scanend     ebx\r
+; scanendw    bx\r
+; chainlenwmask   edx\r
+; curmatch    rsi\r
+; curmatchd   esi\r
+; windowbestlen   r8\r
+; scanalign   r9\r
+; scanalignd  r9d\r
+; window      r10\r
+; bestlen     r11\r
+; bestlend    r11d\r
+; scanstart   r12d\r
+; scanstartw  r12w\r
+; scan        r13\r
+; nicematch   r14d\r
+; limit       r15\r
+; limitd      r15d\r
+; prev        rcx\r
+\r
+;  all the +4 offsets are due to the addition of pending_buf_size (in zlib\r
+;  in the deflate_state structure since the asm code was first written\r
+;  (if you compile with zlib 1.0.4 or older, remove the +4).\r
+;  Note : these value are good with a 8 bytes boundary pack structure\r
+\r
+\r
+    MAX_MATCH           equ     258\r
+    MIN_MATCH           equ     3\r
+    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)\r
+\r
+\r
+;;; Offsets for fields in the deflate_state structure. These numbers\r
+;;; are calculated from the definition of deflate_state, with the\r
+;;; assumption that the compiler will dword-align the fields. (Thus,\r
+;;; changing the definition of deflate_state could easily cause this\r
+;;; program to crash horribly, without so much as a warning at\r
+;;; compile time. Sigh.)\r
+\r
+;  all the +zlib1222add offsets are due to the addition of fields\r
+;  in zlib in the deflate_state structure since the asm code was first written\r
+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").\r
+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").\r
+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").\r
+\r
+\r
+IFDEF INFOZIP\r
+\r
+_DATA   SEGMENT\r
+COMM    window_size:DWORD\r
+; WMask ; 7fff\r
+COMM    window:BYTE:010040H\r
+COMM    prev:WORD:08000H\r
+; MatchLen : unused\r
+; PrevMatch : unused\r
+COMM    strstart:DWORD\r
+COMM    match_start:DWORD\r
+; Lookahead : ignore\r
+COMM    prev_length:DWORD ; PrevLen\r
+COMM    max_chain_length:DWORD\r
+COMM    good_match:DWORD\r
+COMM    nice_match:DWORD\r
+prev_ad equ OFFSET prev\r
+window_ad equ OFFSET window\r
+nicematch equ nice_match\r
+_DATA ENDS\r
+WMask equ 07fffh\r
+\r
+ELSE\r
+\r
+  IFNDEF zlib1222add\r
+    zlib1222add equ 8\r
+  ENDIF\r
+dsWSize         equ 56+zlib1222add+(zlib1222add/2)\r
+dsWMask         equ 64+zlib1222add+(zlib1222add/2)\r
+dsWindow        equ 72+zlib1222add\r
+dsPrev          equ 88+zlib1222add\r
+dsMatchLen      equ 128+zlib1222add\r
+dsPrevMatch     equ 132+zlib1222add\r
+dsStrStart      equ 140+zlib1222add\r
+dsMatchStart    equ 144+zlib1222add\r
+dsLookahead     equ 148+zlib1222add\r
+dsPrevLen       equ 152+zlib1222add\r
+dsMaxChainLen   equ 156+zlib1222add\r
+dsGoodMatch     equ 172+zlib1222add\r
+dsNiceMatch     equ 176+zlib1222add\r
+\r
+window_size     equ [ rcx + dsWSize]\r
+WMask           equ [ rcx + dsWMask]\r
+window_ad       equ [ rcx + dsWindow]\r
+prev_ad         equ [ rcx + dsPrev]\r
+strstart        equ [ rcx + dsStrStart]\r
+match_start     equ [ rcx + dsMatchStart]\r
+Lookahead       equ [ rcx + dsLookahead] ; 0ffffffffh on infozip\r
+prev_length     equ [ rcx + dsPrevLen]\r
+max_chain_length equ [ rcx + dsMaxChainLen]\r
+good_match      equ [ rcx + dsGoodMatch]\r
+nice_match      equ [ rcx + dsNiceMatch]\r
+ENDIF\r
+\r
+; parameter 1 in r8(deflate state s), param 2 in rdx (cur match)\r
+\r
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and\r
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp\r
+;\r
+; All registers must be preserved across the call, except for\r
+;   rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.\r
+\r
+\r
+\r
+;;; Save registers that the compiler may be using, and adjust esp to\r
+;;; make room for our stack frame.\r
+\r
+\r
+;;; Retrieve the function arguments. r8d will hold cur_match\r
+;;; throughout the entire function. edx will hold the pointer to the\r
+;;; deflate_state structure during the function's setup (before\r
+;;; entering the main loop.\r
+\r
+; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)\r
+\r
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx\r
+\r
+        mov [save_rdi],rdi\r
+        mov [save_rsi],rsi\r
+        mov [save_rbx],rbx\r
+        mov [save_rbp],rbp\r
+IFDEF INFOZIP\r
+        mov r8d,ecx\r
+ELSE\r
+        mov r8d,edx\r
+ENDIF\r
+        mov [save_r12],r12\r
+        mov [save_r13],r13\r
+;        mov [save_r14],r14\r
+;        mov [save_r15],r15\r
+\r
+\r
+;;; uInt wmask = s->w_mask;\r
+;;; unsigned chain_length = s->max_chain_length;\r
+;;; if (s->prev_length >= s->good_match) {\r
+;;;     chain_length >>= 2;\r
+;;; }\r
+\r
+        mov edi, prev_length\r
+        mov esi, good_match\r
+        mov eax, WMask\r
+        mov ebx, max_chain_length\r
+        cmp edi, esi\r
+        jl  LastMatchGood\r
+        shr ebx, 2\r
+LastMatchGood:\r
+\r
+;;; chainlen is decremented once beforehand so that the function can\r
+;;; use the sign flag instead of the zero flag for the exit test.\r
+;;; It is then shifted into the high word, to make room for the wmask\r
+;;; value, which it will always accompany.\r
+\r
+        dec ebx\r
+        shl ebx, 16\r
+        or  ebx, eax\r
+\r
+;;; on zlib only\r
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\r
+\r
+IFDEF INFOZIP\r
+        mov [chainlenwmask], ebx\r
+; on infozip nice_match = [nice_match]\r
+ELSE\r
+        mov eax, nice_match\r
+        mov [chainlenwmask], ebx\r
+        mov r10d, Lookahead\r
+        cmp r10d, eax\r
+        cmovnl r10d, eax\r
+        mov [nicematch],r10d\r
+ENDIF\r
+\r
+;;; register Bytef *scan = s->window + s->strstart;\r
+        mov r10, window_ad\r
+        mov ebp, strstart\r
+        lea r13, [r10 + rbp]\r
+\r
+;;; Determine how many bytes the scan ptr is off from being\r
+;;; dword-aligned.\r
+\r
+         mov r9,r13\r
+         neg r13\r
+         and r13,3\r
+\r
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\r
+;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;\r
+IFDEF INFOZIP\r
+        mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1))\r
+ELSE\r
+        mov eax, window_size\r
+        sub eax, MIN_LOOKAHEAD\r
+ENDIF\r
+        xor edi,edi\r
+        sub ebp, eax\r
+\r
+        mov r11d, prev_length\r
+\r
+        cmovng ebp,edi\r
+\r
+;;; int best_len = s->prev_length;\r
+\r
+\r
+;;; Store the sum of s->window + best_len in esi locally, and in esi.\r
+\r
+       lea  rsi,[r10+r11]\r
+\r
+;;; register ush scan_start = *(ushf*)scan;\r
+;;; register ush scan_end   = *(ushf*)(scan+best_len-1);\r
+;;; Posf *prev = s->prev;\r
+\r
+        movzx r12d,word ptr [r9]\r
+        movzx ebx, word ptr [r9 + r11 - 1]\r
+\r
+        mov rdi, prev_ad\r
+\r
+;;; Jump into the main loop.\r
+\r
+        mov edx, [chainlenwmask]\r
+\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+        jz  LookupLoopIsZero\r
+\r
+LookupLoop1:\r
+        and r8d, edx\r
+\r
+        movzx   r8d, word ptr [rdi + r8*2]\r
+        cmp r8d, ebp\r
+        jbe LeaveNow\r
+        sub edx, 00010000h\r
+        js  LeaveNow\r
+\r
+LoopEntry1:\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+        jz  LookupLoopIsZero\r
+\r
+LookupLoop2:\r
+        and r8d, edx\r
+\r
+        movzx   r8d, word ptr [rdi + r8*2]\r
+        cmp r8d, ebp\r
+        jbe LeaveNow\r
+        sub edx, 00010000h\r
+        js  LeaveNow\r
+\r
+LoopEntry2:\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+        jz  LookupLoopIsZero\r
+\r
+LookupLoop4:\r
+        and r8d, edx\r
+\r
+        movzx   r8d, word ptr [rdi + r8*2]\r
+        cmp r8d, ebp\r
+        jbe LeaveNow\r
+        sub edx, 00010000h\r
+        js  LeaveNow\r
+\r
+LoopEntry4:\r
+\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+        jnz LookupLoop1\r
+        jmp LookupLoopIsZero\r
+\r
+\r
+;;; do {\r
+;;;     match = s->window + cur_match;\r
+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||\r
+;;;         *(ushf*)match != scan_start) continue;\r
+;;;     [...]\r
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit\r
+;;;          && --chain_length != 0);\r
+;;;\r
+;;; Here is the inner loop of the function. The function will spend the\r
+;;; majority of its time in this loop, and majority of that time will\r
+;;; be spent in the first ten instructions.\r
+;;;\r
+;;; Within this loop:\r
+;;; ebx = scanend\r
+;;; r8d = curmatch\r
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)\r
+;;; esi = windowbestlen - i.e., (window + bestlen)\r
+;;; edi = prev\r
+;;; ebp = limit\r
+\r
+LookupLoop:\r
+        and r8d, edx\r
+\r
+        movzx   r8d, word ptr [rdi + r8*2]\r
+        cmp r8d, ebp\r
+        jbe LeaveNow\r
+        sub edx, 00010000h\r
+        js  LeaveNow\r
+\r
+LoopEntry:\r
+\r
+        cmp bx,word ptr [rsi + r8 - 1]\r
+        jnz LookupLoop1\r
+LookupLoopIsZero:\r
+        cmp     r12w, word ptr [r10 + r8]\r
+        jnz LookupLoop1\r
+\r
+\r
+;;; Store the current value of chainlen.\r
+        mov [chainlenwmask], edx\r
+\r
+;;; Point edi to the string under scrutiny, and esi to the string we\r
+;;; are hoping to match it up with. In actuality, esi and edi are\r
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is\r
+;;; initialized to -(MAX_MATCH_8 - scanalign).\r
+\r
+        lea rsi,[r8+r10]\r
+        mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8)\r
+        lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8]\r
+        lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8]\r
+\r
+        prefetcht1 [rsi+rdx]\r
+        prefetcht1 [rdi+rdx]\r
+\r
+\r
+;;; Test the strings for equality, 8 bytes at a time. At the end,\r
+;;; adjust rdx so that it is offset to the exact byte that mismatched.\r
+;;;\r
+;;; We already know at this point that the first three bytes of the\r
+;;; strings match each other, and they can be safely passed over before\r
+;;; starting the compare loop. So what this code does is skip over 0-3\r
+;;; bytes, as much as necessary in order to dword-align the edi\r
+;;; pointer. (rsi will still be misaligned three times out of four.)\r
+;;;\r
+;;; It should be confessed that this loop usually does not represent\r
+;;; much of the total running time. Replacing it with a more\r
+;;; straightforward "rep cmpsb" would not drastically degrade\r
+;;; performance.\r
+\r
+\r
+LoopCmps:\r
+        mov rax, [rsi + rdx]\r
+        xor rax, [rdi + rdx]\r
+        jnz LeaveLoopCmps\r
+\r
+        mov rax, [rsi + rdx + 8]\r
+        xor rax, [rdi + rdx + 8]\r
+        jnz LeaveLoopCmps8\r
+\r
+\r
+        mov rax, [rsi + rdx + 8+8]\r
+        xor rax, [rdi + rdx + 8+8]\r
+        jnz LeaveLoopCmps16\r
+\r
+        add rdx,8+8+8\r
+\r
+        jnz short LoopCmps\r
+        jmp short LenMaximum\r
+LeaveLoopCmps16: add rdx,8\r
+LeaveLoopCmps8: add rdx,8\r
+LeaveLoopCmps:\r
+\r
+        test    eax, 0000FFFFh\r
+        jnz LenLower\r
+\r
+        test eax,0ffffffffh\r
+\r
+        jnz LenLower32\r
+\r
+        add rdx,4\r
+        shr rax,32\r
+        or ax,ax\r
+        jnz LenLower\r
+\r
+LenLower32:\r
+        shr eax,16\r
+        add rdx,2\r
+LenLower:   sub al, 1\r
+        adc rdx, 0\r
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,\r
+;;; then automatically accept it as the best possible match and leave.\r
+\r
+        lea rax, [rdi + rdx]\r
+        sub rax, r9\r
+        cmp eax, MAX_MATCH\r
+        jge LenMaximum\r
+\r
+;;; If the length of the match is not longer than the best match we\r
+;;; have so far, then forget it and return to the lookup loop.\r
+;///////////////////////////////////\r
+\r
+        cmp eax, r11d\r
+        jg  LongerMatch\r
+\r
+        lea rsi,[r10+r11]\r
+\r
+        mov rdi, prev_ad\r
+        mov edx, [chainlenwmask]\r
+        jmp LookupLoop\r
+\r
+;;;         s->match_start = cur_match;\r
+;;;         best_len = len;\r
+;;;         if (len >= nice_match) break;\r
+;;;         scan_end = *(ushf*)(scan+best_len-1);\r
+\r
+LongerMatch:\r
+        mov r11d, eax\r
+        mov match_start, r8d\r
+        cmp eax, [nicematch]\r
+        jge LeaveNow\r
+\r
+        lea rsi,[r10+rax]\r
+\r
+        movzx   ebx, word ptr [r9 + rax - 1]\r
+        mov rdi, prev_ad\r
+        mov edx, [chainlenwmask]\r
+        jmp LookupLoop\r
+\r
+;;; Accept the current string, with the maximum possible length.\r
+\r
+LenMaximum:\r
+        mov r11d,MAX_MATCH\r
+        mov match_start, r8d\r
+\r
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\r
+;;; return s->lookahead;\r
+\r
+LeaveNow:\r
+IFDEF INFOZIP\r
+        mov eax,r11d\r
+ELSE\r
+        mov eax, Lookahead\r
+        cmp r11d, eax\r
+        cmovng eax, r11d\r
+ENDIF\r
+\r
+;;; Restore the stack and return from whence we came.\r
+\r
+\r
+        mov rsi,[save_rsi]\r
+        mov rdi,[save_rdi]\r
+        mov rbx,[save_rbx]\r
+        mov rbp,[save_rbp]\r
+        mov r12,[save_r12]\r
+        mov r13,[save_r13]\r
+;        mov r14,[save_r14]\r
+;        mov r15,[save_r15]\r
+\r
+\r
+        ret 0\r
+; please don't remove this string !\r
+; Your can freely use gvmat64 in any free or commercial app\r
+; but it is far better don't remove the string in the binary!\r
+    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0\r
+longest_match   ENDP\r
+\r
+match_init PROC\r
+  ret 0\r
+match_init ENDP\r
+\r
+\r
+END\r
diff --git a/8.x/zlib/contrib/masmx64/inffas8664.c b/8.x/zlib/contrib/masmx64/inffas8664.c
new file mode 100644 (file)
index 0000000..e8af06f
--- /dev/null
@@ -0,0 +1,186 @@
+/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding\r
+ * version for AMD64 on Windows using Microsoft C compiler\r
+ *\r
+ * Copyright (C) 1995-2003 Mark Adler\r
+ * For conditions of distribution and use, see copyright notice in zlib.h\r
+ *\r
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>\r
+ * Please use the copyright conditions above.\r
+ *\r
+ * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant\r
+ *\r
+ * inffas8664.c call function inffas8664fnc in inffasx64.asm\r
+ *  inffasx64.asm is automatically convert from AMD64 portion of inffas86.c\r
+ *\r
+ * Dec-29-2003 -- I added AMD64 inflate asm support.  This version is also\r
+ * slightly quicker on x86 systems because, instead of using rep movsb to copy\r
+ * data, it uses rep movsw, which moves data in 2-byte chunks instead of single\r
+ * bytes.  I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates\r
+ * from http://fedora.linux.duke.edu/fc1_x86_64\r
+ * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with\r
+ * 1GB ram.  The 64-bit version is about 4% faster than the 32-bit version,\r
+ * when decompressing mozilla-source-1.3.tar.gz.\r
+ *\r
+ * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from\r
+ * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at\r
+ * the moment.  I have successfully compiled and tested this code with gcc2.96,\r
+ * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S\r
+ * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX\r
+ * enabled.  I will attempt to merge the MMX code into this version.  Newer\r
+ * versions of this and inffast.S can be found at\r
+ * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/\r
+ *\r
+ */\r
+\r
+#include <stdio.h>\r
+#include "zutil.h"\r
+#include "inftrees.h"\r
+#include "inflate.h"\r
+#include "inffast.h"\r
+\r
+/* Mark Adler's comments from inffast.c: */\r
+\r
+/*\r
+   Decode literal, length, and distance codes and write out the resulting\r
+   literal and match bytes until either not enough input or output is\r
+   available, an end-of-block is encountered, or a data error is encountered.\r
+   When large enough input and output buffers are supplied to inflate(), for\r
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the\r
+   inflate execution time is spent in this routine.\r
+\r
+   Entry assumptions:\r
+\r
+        state->mode == LEN\r
+        strm->avail_in >= 6\r
+        strm->avail_out >= 258\r
+        start >= strm->avail_out\r
+        state->bits < 8\r
+\r
+   On return, state->mode is one of:\r
+\r
+        LEN -- ran out of enough output space or enough available input\r
+        TYPE -- reached end of block code, inflate() to interpret next block\r
+        BAD -- error in block data\r
+\r
+   Notes:\r
+\r
+    - The maximum input bits used by a length/distance pair is 15 bits for the\r
+      length code, 5 bits for the length extra, 15 bits for the distance code,\r
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.\r
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid\r
+      checking for available input while decoding.\r
+\r
+    - The maximum bytes that a single length/distance pair can output is 258\r
+      bytes, which is the maximum length that can be coded.  inflate_fast()\r
+      requires strm->avail_out >= 258 for each loop to avoid checking for\r
+      output space.\r
+ */\r
+\r
+\r
+\r
+    typedef struct inffast_ar {\r
+/* 64   32                               x86  x86_64 */\r
+/* ar offset                              register */\r
+/*  0    0 */ void *esp;                /* esp save */\r
+/*  8    4 */ void *ebp;                /* ebp save */\r
+/* 16    8 */ unsigned char FAR *in;    /* esi rsi  local strm->next_in */\r
+/* 24   12 */ unsigned char FAR *last;  /*     r9   while in < last */\r
+/* 32   16 */ unsigned char FAR *out;   /* edi rdi  local strm->next_out */\r
+/* 40   20 */ unsigned char FAR *beg;   /*          inflate()'s init next_out */\r
+/* 48   24 */ unsigned char FAR *end;   /*     r10  while out < end */\r
+/* 56   28 */ unsigned char FAR *window;/*          size of window, wsize!=0 */\r
+/* 64   32 */ code const FAR *lcode;    /* ebp rbp  local strm->lencode */\r
+/* 72   36 */ code const FAR *dcode;    /*     r11  local strm->distcode */\r
+/* 80   40 */ size_t /*unsigned long */hold;       /* edx rdx  local strm->hold */\r
+/* 88   44 */ unsigned bits;            /* ebx rbx  local strm->bits */\r
+/* 92   48 */ unsigned wsize;           /*          window size */\r
+/* 96   52 */ unsigned write;           /*          window write index */\r
+/*100   56 */ unsigned lmask;           /*     r12  mask for lcode */\r
+/*104   60 */ unsigned dmask;           /*     r13  mask for dcode */\r
+/*108   64 */ unsigned len;             /*     r14  match length */\r
+/*112   68 */ unsigned dist;            /*     r15  match distance */\r
+/*116   72 */ unsigned status;          /*          set when state chng*/\r
+    } type_ar;\r
+#ifdef ASMINF\r
+\r
+void inflate_fast(strm, start)\r
+z_streamp strm;\r
+unsigned start;         /* inflate()'s starting value for strm->avail_out */\r
+{\r
+    struct inflate_state FAR *state;\r
+    type_ar ar;\r
+    void inffas8664fnc(struct inffast_ar * par);\r
+\r
+\r
+\r
+#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))\r
+#define PAD_AVAIL_IN 6\r
+#define PAD_AVAIL_OUT 258\r
+#else\r
+#define PAD_AVAIL_IN 5\r
+#define PAD_AVAIL_OUT 257\r
+#endif\r
+\r
+    /* copy state to local variables */\r
+    state = (struct inflate_state FAR *)strm->state;\r
+\r
+    ar.in = strm->next_in;\r
+    ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);\r
+    ar.out = strm->next_out;\r
+    ar.beg = ar.out - (start - strm->avail_out);\r
+    ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);\r
+    ar.wsize = state->wsize;\r
+    ar.write = state->wnext;\r
+    ar.window = state->window;\r
+    ar.hold = state->hold;\r
+    ar.bits = state->bits;\r
+    ar.lcode = state->lencode;\r
+    ar.dcode = state->distcode;\r
+    ar.lmask = (1U << state->lenbits) - 1;\r
+    ar.dmask = (1U << state->distbits) - 1;\r
+\r
+    /* decode literals and length/distances until end-of-block or not enough\r
+       input data or output space */\r
+\r
+    /* align in on 1/2 hold size boundary */\r
+    while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {\r
+        ar.hold += (unsigned long)*ar.in++ << ar.bits;\r
+        ar.bits += 8;\r
+    }\r
+\r
+    inffas8664fnc(&ar);\r
+\r
+    if (ar.status > 1) {\r
+        if (ar.status == 2)\r
+            strm->msg = "invalid literal/length code";\r
+        else if (ar.status == 3)\r
+            strm->msg = "invalid distance code";\r
+        else\r
+            strm->msg = "invalid distance too far back";\r
+        state->mode = BAD;\r
+    }\r
+    else if ( ar.status == 1 ) {\r
+        state->mode = TYPE;\r
+    }\r
+\r
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */\r
+    ar.len = ar.bits >> 3;\r
+    ar.in -= ar.len;\r
+    ar.bits -= ar.len << 3;\r
+    ar.hold &= (1U << ar.bits) - 1;\r
+\r
+    /* update state and return */\r
+    strm->next_in = ar.in;\r
+    strm->next_out = ar.out;\r
+    strm->avail_in = (unsigned)(ar.in < ar.last ?\r
+                                PAD_AVAIL_IN + (ar.last - ar.in) :\r
+                                PAD_AVAIL_IN - (ar.in - ar.last));\r
+    strm->avail_out = (unsigned)(ar.out < ar.end ?\r
+                                 PAD_AVAIL_OUT + (ar.end - ar.out) :\r
+                                 PAD_AVAIL_OUT - (ar.out - ar.end));\r
+    state->hold = (unsigned long)ar.hold;\r
+    state->bits = ar.bits;\r
+    return;\r
+}\r
+\r
+#endif\r
diff --git a/8.x/zlib/contrib/masmx64/inffasx64.asm b/8.x/zlib/contrib/masmx64/inffasx64.asm
new file mode 100644 (file)
index 0000000..60a8d89
--- /dev/null
@@ -0,0 +1,396 @@
+; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding\r
+; version for AMD64 on Windows using Microsoft C compiler\r
+;\r
+; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c\r
+; inffasx64.asm is called by inffas8664.c, which contain more info.\r
+\r
+\r
+; to compile this file, I use option\r
+;   ml64.exe /Flinffasx64 /c /Zi inffasx64.asm\r
+;   with Microsoft Macro Assembler (x64) for AMD64\r
+;\r
+\r
+; This file compile with Microsoft Macro Assembler (x64) for AMD64\r
+;\r
+;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK\r
+;\r
+;   (you can get Windows WDK with ml64 for AMD64 from\r
+;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)\r
+;\r
+\r
+\r
+.code\r
+inffas8664fnc PROC\r
+\r
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and\r
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp\r
+;\r
+; All registers must be preserved across the call, except for\r
+;   rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.\r
+\r
+\r
+       mov [rsp-8],rsi\r
+       mov [rsp-16],rdi\r
+       mov [rsp-24],r12\r
+       mov [rsp-32],r13\r
+       mov [rsp-40],r14\r
+       mov [rsp-48],r15\r
+       mov [rsp-56],rbx\r
+\r
+       mov rax,rcx\r
+\r
+       mov     [rax+8], rbp       ; /* save regs rbp and rsp */\r
+       mov     [rax], rsp\r
+\r
+       mov     rsp, rax          ; /* make rsp point to &ar */\r
+\r
+       mov     rsi, [rsp+16]      ; /* rsi  = in */\r
+       mov     rdi, [rsp+32]      ; /* rdi  = out */\r
+       mov     r9, [rsp+24]       ; /* r9   = last */\r
+       mov     r10, [rsp+48]      ; /* r10  = end */\r
+       mov     rbp, [rsp+64]      ; /* rbp  = lcode */\r
+       mov     r11, [rsp+72]      ; /* r11  = dcode */\r
+       mov     rdx, [rsp+80]      ; /* rdx  = hold */\r
+       mov     ebx, [rsp+88]      ; /* ebx  = bits */\r
+       mov     r12d, [rsp+100]    ; /* r12d = lmask */\r
+       mov     r13d, [rsp+104]    ; /* r13d = dmask */\r
+                                          ; /* r14d = len */\r
+                                          ; /* r15d = dist */\r
+\r
+\r
+       cld\r
+       cmp     r10, rdi\r
+       je      L_one_time           ; /* if only one decode left */\r
+       cmp     r9, rsi\r
+\r
+    jne L_do_loop\r
+\r
+\r
+L_one_time:\r
+       mov     r8, r12           ; /* r8 = lmask */\r
+       cmp     bl, 32\r
+       ja      L_get_length_code_one_time\r
+\r
+       lodsd                         ; /* eax = *(uint *)in++ */\r
+       mov     cl, bl            ; /* cl = bits, needs it for shifting */\r
+       add     bl, 32             ; /* bits += 32 */\r
+       shl     rax, cl\r
+       or      rdx, rax          ; /* hold |= *((uint *)in)++ << bits */\r
+       jmp     L_get_length_code_one_time\r
+\r
+ALIGN 4\r
+L_while_test:\r
+       cmp     r10, rdi\r
+       jbe     L_break_loop\r
+       cmp     r9, rsi\r
+       jbe     L_break_loop\r
+\r
+L_do_loop:\r
+       mov     r8, r12           ; /* r8 = lmask */\r
+       cmp     bl, 32\r
+       ja      L_get_length_code    ; /* if (32 < bits) */\r
+\r
+       lodsd                         ; /* eax = *(uint *)in++ */\r
+       mov     cl, bl            ; /* cl = bits, needs it for shifting */\r
+       add     bl, 32             ; /* bits += 32 */\r
+       shl     rax, cl\r
+       or      rdx, rax          ; /* hold |= *((uint *)in)++ << bits */\r
+\r
+L_get_length_code:\r
+       and     r8, rdx            ; /* r8 &= hold */\r
+       mov     eax, [rbp+r8*4]  ; /* eax = lcode[hold & lmask] */\r
+\r
+       mov     cl, ah            ; /* cl = this.bits */\r
+       sub     bl, ah            ; /* bits -= this.bits */\r
+       shr     rdx, cl           ; /* hold >>= this.bits */\r
+\r
+       test    al, al\r
+       jnz     L_test_for_length_base ; /* if (op != 0) 45.7% */\r
+\r
+       mov     r8, r12            ; /* r8 = lmask */\r
+       shr     eax, 16            ; /* output this.val char */\r
+       stosb\r
+\r
+L_get_length_code_one_time:\r
+       and     r8, rdx            ; /* r8 &= hold */\r
+       mov     eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */\r
+\r
+L_dolen:\r
+       mov     cl, ah            ; /* cl = this.bits */\r
+       sub     bl, ah            ; /* bits -= this.bits */\r
+       shr     rdx, cl           ; /* hold >>= this.bits */\r
+\r
+       test    al, al\r
+       jnz     L_test_for_length_base ; /* if (op != 0) 45.7% */\r
+\r
+       shr     eax, 16            ; /* output this.val char */\r
+       stosb\r
+       jmp     L_while_test\r
+\r
+ALIGN 4\r
+L_test_for_length_base:\r
+       mov     r14d, eax         ; /* len = this */\r
+       shr     r14d, 16           ; /* len = this.val */\r
+       mov     cl, al\r
+\r
+       test    al, 16\r
+       jz      L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */\r
+       and     cl, 15             ; /* op &= 15 */\r
+       jz      L_decode_distance    ; /* if (!op) */\r
+\r
+L_add_bits_to_len:\r
+       sub     bl, cl\r
+       xor     eax, eax\r
+       inc     eax\r
+       shl     eax, cl\r
+       dec     eax\r
+       and     eax, edx          ; /* eax &= hold */\r
+       shr     rdx, cl\r
+       add     r14d, eax         ; /* len += hold & mask[op] */\r
+\r
+L_decode_distance:\r
+       mov     r8, r13           ; /* r8 = dmask */\r
+       cmp     bl, 32\r
+       ja      L_get_distance_code  ; /* if (32 < bits) */\r
+\r
+       lodsd                         ; /* eax = *(uint *)in++ */\r
+       mov     cl, bl            ; /* cl = bits, needs it for shifting */\r
+       add     bl, 32             ; /* bits += 32 */\r
+       shl     rax, cl\r
+       or      rdx, rax          ; /* hold |= *((uint *)in)++ << bits */\r
+\r
+L_get_distance_code:\r
+       and     r8, rdx           ; /* r8 &= hold */\r
+       mov     eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */\r
+\r
+L_dodist:\r
+       mov     r15d, eax         ; /* dist = this */\r
+       shr     r15d, 16           ; /* dist = this.val */\r
+       mov     cl, ah\r
+       sub     bl, ah            ; /* bits -= this.bits */\r
+       shr     rdx, cl           ; /* hold >>= this.bits */\r
+       mov     cl, al            ; /* cl = this.op */\r
+\r
+       test    al, 16             ; /* if ((op & 16) == 0) */\r
+       jz      L_test_for_second_level_dist\r
+       and     cl, 15             ; /* op &= 15 */\r
+       jz      L_check_dist_one\r
+\r
+L_add_bits_to_dist:\r
+       sub     bl, cl\r
+       xor     eax, eax\r
+       inc     eax\r
+       shl     eax, cl\r
+       dec     eax                 ; /* (1 << op) - 1 */\r
+       and     eax, edx          ; /* eax &= hold */\r
+       shr     rdx, cl\r
+       add     r15d, eax         ; /* dist += hold & ((1 << op) - 1) */\r
+\r
+L_check_window:\r
+       mov     r8, rsi           ; /* save in so from can use it's reg */\r
+       mov     rax, rdi\r
+       sub     rax, [rsp+40]      ; /* nbytes = out - beg */\r
+\r
+       cmp     eax, r15d\r
+       jb      L_clip_window        ; /* if (dist > nbytes) 4.2% */\r
+\r
+       mov     ecx, r14d         ; /* ecx = len */\r
+       mov     rsi, rdi\r
+       sub     rsi, r15          ; /* from = out - dist */\r
+\r
+       sar     ecx, 1\r
+       jnc     L_copy_two           ; /* if len % 2 == 0 */\r
+\r
+       rep     movsw\r
+       mov     al, [rsi]\r
+       mov     [rdi], al\r
+       inc     rdi\r
+\r
+       mov     rsi, r8           ; /* move in back to %rsi, toss from */\r
+       jmp     L_while_test\r
+\r
+L_copy_two:\r
+       rep     movsw\r
+       mov     rsi, r8           ; /* move in back to %rsi, toss from */\r
+       jmp     L_while_test\r
+\r
+ALIGN 4\r
+L_check_dist_one:\r
+       cmp     r15d, 1            ; /* if dist 1, is a memset */\r
+       jne     L_check_window\r
+       cmp     [rsp+40], rdi      ; /* if out == beg, outside window */\r
+       je      L_check_window\r
+\r
+       mov     ecx, r14d         ; /* ecx = len */\r
+       mov     al, [rdi-1]\r
+       mov     ah, al\r
+\r
+       sar     ecx, 1\r
+       jnc     L_set_two\r
+       mov     [rdi], al\r
+       inc     rdi\r
+\r
+L_set_two:\r
+       rep     stosw\r
+       jmp     L_while_test\r
+\r
+ALIGN 4\r
+L_test_for_second_level_length:\r
+       test    al, 64\r
+       jnz     L_test_for_end_of_block ; /* if ((op & 64) != 0) */\r
+\r
+       xor     eax, eax\r
+       inc     eax\r
+       shl     eax, cl\r
+       dec     eax\r
+       and     eax, edx         ; /* eax &= hold */\r
+       add     eax, r14d        ; /* eax += len */\r
+       mov     eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/\r
+       jmp     L_dolen\r
+\r
+ALIGN 4\r
+L_test_for_second_level_dist:\r
+       test    al, 64\r
+       jnz     L_invalid_distance_code ; /* if ((op & 64) != 0) */\r
+\r
+       xor     eax, eax\r
+       inc     eax\r
+       shl     eax, cl\r
+       dec     eax\r
+       and     eax, edx         ; /* eax &= hold */\r
+       add     eax, r15d        ; /* eax += dist */\r
+       mov     eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/\r
+       jmp     L_dodist\r
+\r
+ALIGN 4\r
+L_clip_window:\r
+       mov     ecx, eax         ; /* ecx = nbytes */\r
+       mov     eax, [rsp+92]     ; /* eax = wsize, prepare for dist cmp */\r
+       neg     ecx                ; /* nbytes = -nbytes */\r
+\r
+       cmp     eax, r15d\r
+       jb      L_invalid_distance_too_far ; /* if (dist > wsize) */\r
+\r
+       add     ecx, r15d         ; /* nbytes = dist - nbytes */\r
+       cmp     dword ptr [rsp+96], 0\r
+       jne     L_wrap_around_window ; /* if (write != 0) */\r
+\r
+       mov     rsi, [rsp+56]     ; /* from  = window */\r
+       sub     eax, ecx         ; /* eax  -= nbytes */\r
+       add     rsi, rax         ; /* from += wsize - nbytes */\r
+\r
+       mov     eax, r14d        ; /* eax = len */\r
+       cmp     r14d, ecx\r
+       jbe     L_do_copy           ; /* if (nbytes >= len) */\r
+\r
+       sub     eax, ecx         ; /* eax -= nbytes */\r
+       rep     movsb\r
+       mov     rsi, rdi\r
+       sub     rsi, r15         ; /* from = &out[ -dist ] */\r
+       jmp     L_do_copy\r
+\r
+ALIGN 4\r
+L_wrap_around_window:\r
+       mov     eax, [rsp+96]     ; /* eax = write */\r
+       cmp     ecx, eax\r
+       jbe     L_contiguous_in_window ; /* if (write >= nbytes) */\r
+\r
+       mov     esi, [rsp+92]     ; /* from  = wsize */\r
+       add     rsi, [rsp+56]     ; /* from += window */\r
+       add     rsi, rax         ; /* from += write */\r
+       sub     rsi, rcx         ; /* from -= nbytes */\r
+       sub     ecx, eax         ; /* nbytes -= write */\r
+\r
+       mov     eax, r14d        ; /* eax = len */\r
+       cmp     eax, ecx\r
+       jbe     L_do_copy           ; /* if (nbytes >= len) */\r
+\r
+       sub     eax, ecx         ; /* len -= nbytes */\r
+       rep     movsb\r
+       mov     rsi, [rsp+56]     ; /* from = window */\r
+       mov     ecx, [rsp+96]     ; /* nbytes = write */\r
+       cmp     eax, ecx\r
+       jbe     L_do_copy           ; /* if (nbytes >= len) */\r
+\r
+       sub     eax, ecx         ; /* len -= nbytes */\r
+       rep     movsb\r
+       mov     rsi, rdi\r
+       sub     rsi, r15         ; /* from = out - dist */\r
+       jmp     L_do_copy\r
+\r
+ALIGN 4\r
+L_contiguous_in_window:\r
+       mov     rsi, [rsp+56]     ; /* rsi = window */\r
+       add     rsi, rax\r
+       sub     rsi, rcx         ; /* from += write - nbytes */\r
+\r
+       mov     eax, r14d        ; /* eax = len */\r
+       cmp     eax, ecx\r
+       jbe     L_do_copy           ; /* if (nbytes >= len) */\r
+\r
+       sub     eax, ecx         ; /* len -= nbytes */\r
+       rep     movsb\r
+       mov     rsi, rdi\r
+       sub     rsi, r15         ; /* from = out - dist */\r
+       jmp     L_do_copy           ; /* if (nbytes >= len) */\r
+\r
+ALIGN 4\r
+L_do_copy:\r
+       mov     ecx, eax         ; /* ecx = len */\r
+       rep     movsb\r
+\r
+       mov     rsi, r8          ; /* move in back to %esi, toss from */\r
+       jmp     L_while_test\r
+\r
+L_test_for_end_of_block:\r
+       test    al, 32\r
+       jz      L_invalid_literal_length_code\r
+       mov     dword ptr [rsp+116], 1\r
+       jmp     L_break_loop_with_status\r
+\r
+L_invalid_literal_length_code:\r
+       mov     dword ptr [rsp+116], 2\r
+       jmp     L_break_loop_with_status\r
+\r
+L_invalid_distance_code:\r
+       mov     dword ptr [rsp+116], 3\r
+       jmp     L_break_loop_with_status\r
+\r
+L_invalid_distance_too_far:\r
+       mov     dword ptr [rsp+116], 4\r
+       jmp     L_break_loop_with_status\r
+\r
+L_break_loop:\r
+       mov     dword ptr [rsp+116], 0\r
+\r
+L_break_loop_with_status:\r
+; /* put in, out, bits, and hold back into ar and pop esp */\r
+       mov     [rsp+16], rsi     ; /* in */\r
+       mov     [rsp+32], rdi     ; /* out */\r
+       mov     [rsp+88], ebx     ; /* bits */\r
+       mov     [rsp+80], rdx     ; /* hold */\r
+\r
+       mov     rax, [rsp]       ; /* restore rbp and rsp */\r
+       mov     rbp, [rsp+8]\r
+       mov     rsp, rax\r
+\r
+\r
+\r
+       mov rsi,[rsp-8]\r
+       mov rdi,[rsp-16]\r
+       mov r12,[rsp-24]\r
+       mov r13,[rsp-32]\r
+       mov r14,[rsp-40]\r
+       mov r15,[rsp-48]\r
+       mov rbx,[rsp-56]\r
+\r
+    ret 0\r
+;          :\r
+;          : "m" (ar)\r
+;          : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",\r
+;            "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"\r
+;    );\r
+\r
+inffas8664fnc  ENDP\r
+;_TEXT ENDS\r
+END\r
diff --git a/8.x/zlib/contrib/masmx64/readme.txt b/8.x/zlib/contrib/masmx64/readme.txt
new file mode 100644 (file)
index 0000000..2da6733
--- /dev/null
@@ -0,0 +1,31 @@
+Summary\r
+-------\r
+This directory contains ASM implementations of the functions\r
+longest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t),\r
+for use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits.\r
+\r
+gvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits\r
+   assembly optimized version from Jean-loup Gailly original longest_match function\r
+\r
+inffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing\r
+   original function from Mark Adler\r
+\r
+Use instructions\r
+----------------\r
+Assemble the .asm files using MASM and put the object files into the zlib source\r
+directory.  You can also get object files here:\r
+\r
+     http://www.winimage.com/zLibDll/zlib124_masm_obj.zip\r
+\r
+define ASMV and ASMINF in your project. Include inffas8664.c in your source tree,\r
+and inffasx64.obj and gvmat64.obj as object to link.\r
+\r
+\r
+Build instructions\r
+------------------\r
+run bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe)\r
+\r
+ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK\r
+\r
+You can get Windows 2003 server DDK with ml64 and cl for AMD64 from\r
+  http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)\r
diff --git a/8.x/zlib/contrib/masmx86/bld_ml32.bat b/8.x/zlib/contrib/masmx86/bld_ml32.bat
new file mode 100644 (file)
index 0000000..e1b86bf
--- /dev/null
@@ -0,0 +1,2 @@
+ml /coff /Zi /c /Flmatch686.lst match686.asm\r
+ml /coff /Zi /c /Flinffas32.lst inffas32.asm\r
diff --git a/8.x/zlib/contrib/masmx86/inffas32.asm b/8.x/zlib/contrib/masmx86/inffas32.asm
new file mode 100644 (file)
index 0000000..92ac22a
--- /dev/null
@@ -0,0 +1,1083 @@
+;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding\r
+; *\r
+; * inffas32.asm is derivated from inffas86.c, with translation of assembly code\r
+; *\r
+; * Copyright (C) 1995-2003 Mark Adler\r
+; * For conditions of distribution and use, see copyright notice in zlib.h\r
+; *\r
+; * Copyright (C) 2003 Chris Anderson <christop@charm.net>\r
+; * Please use the copyright conditions above.\r
+; *\r
+; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from\r
+; * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at\r
+; * the moment.  I have successfully compiled and tested this code with gcc2.96,\r
+; * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S\r
+; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX\r
+; * enabled.  I will attempt to merge the MMX code into this version.  Newer\r
+; * versions of this and inffast.S can be found at\r
+; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/\r
+; *\r
+; * 2005 : modification by Gilles Vollant\r
+; */\r
+; For Visual C++ 4.x and higher and ML 6.x and higher\r
+;   ml.exe is in directory \MASM611C of Win95 DDK\r
+;   ml.exe is also distributed in http://www.masm32.com/masmdl.htm\r
+;    and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/\r
+;\r
+;\r
+;   compile with command line option\r
+;   ml  /coff /Zi /c /Flinffas32.lst inffas32.asm\r
+\r
+;   if you define NO_GZIP (see inflate.h), compile with\r
+;   ml  /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm\r
+\r
+\r
+; zlib122sup is 0 fort zlib 1.2.2.1 and lower\r
+; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head\r
+;        in inflate_state in inflate.h)\r
+zlib1222sup      equ    8\r
+\r
+\r
+IFDEF GUNZIP\r
+  INFLATE_MODE_TYPE    equ 11\r
+  INFLATE_MODE_BAD     equ 26\r
+ELSE\r
+  IFNDEF NO_GUNZIP\r
+    INFLATE_MODE_TYPE    equ 11\r
+    INFLATE_MODE_BAD     equ 26\r
+  ELSE\r
+    INFLATE_MODE_TYPE    equ 3\r
+    INFLATE_MODE_BAD     equ 17\r
+  ENDIF\r
+ENDIF\r
+\r
+\r
+; 75 "inffast.S"\r
+;FILE "inffast.S"\r
+\r
+;;;GLOBAL _inflate_fast\r
+\r
+;;;SECTION .text\r
+\r
+\r
+\r
+       .586p\r
+       .mmx\r
+\r
+       name    inflate_fast_x86\r
+       .MODEL  FLAT\r
+\r
+_DATA                  segment\r
+inflate_fast_use_mmx:\r
+       dd      1\r
+\r
+\r
+_TEXT                  segment\r
+PUBLIC _inflate_fast\r
+\r
+ALIGN 4\r
+_inflate_fast:\r
+       jmp inflate_fast_entry\r
+\r
+\r
+\r
+ALIGN 4\r
+       db      'Fast decoding Code from Chris Anderson'\r
+       db      0\r
+\r
+ALIGN 4\r
+invalid_literal_length_code_msg:\r
+       db      'invalid literal/length code'\r
+       db      0\r
+\r
+ALIGN 4\r
+invalid_distance_code_msg:\r
+       db      'invalid distance code'\r
+       db      0\r
+\r
+ALIGN 4\r
+invalid_distance_too_far_msg:\r
+       db      'invalid distance too far back'\r
+       db      0\r
+\r
+\r
+ALIGN 4\r
+inflate_fast_mask:\r
+dd     0\r
+dd     1\r
+dd     3\r
+dd     7\r
+dd     15\r
+dd     31\r
+dd     63\r
+dd     127\r
+dd     255\r
+dd     511\r
+dd     1023\r
+dd     2047\r
+dd     4095\r
+dd     8191\r
+dd     16383\r
+dd     32767\r
+dd     65535\r
+dd     131071\r
+dd     262143\r
+dd     524287\r
+dd     1048575\r
+dd     2097151\r
+dd     4194303\r
+dd     8388607\r
+dd     16777215\r
+dd     33554431\r
+dd     67108863\r
+dd     134217727\r
+dd     268435455\r
+dd     536870911\r
+dd     1073741823\r
+dd     2147483647\r
+dd     4294967295\r
+\r
+\r
+mode_state      equ    0       ;/* state->mode */\r
+wsize_state     equ    (32+zlib1222sup)        ;/* state->wsize */\r
+write_state     equ    (36+4+zlib1222sup)      ;/* state->write */\r
+window_state    equ    (40+4+zlib1222sup)      ;/* state->window */\r
+hold_state      equ    (44+4+zlib1222sup)      ;/* state->hold */\r
+bits_state      equ    (48+4+zlib1222sup)      ;/* state->bits */\r
+lencode_state   equ    (64+4+zlib1222sup)      ;/* state->lencode */\r
+distcode_state  equ    (68+4+zlib1222sup)      ;/* state->distcode */\r
+lenbits_state   equ    (72+4+zlib1222sup)      ;/* state->lenbits */\r
+distbits_state  equ    (76+4+zlib1222sup)      ;/* state->distbits */\r
+\r
+\r
+;;SECTION .text\r
+; 205 "inffast.S"\r
+;GLOBAL        inflate_fast_use_mmx\r
+\r
+;SECTION .data\r
+\r
+\r
+; GLOBAL inflate_fast_use_mmx:object\r
+;.size inflate_fast_use_mmx, 4\r
+; 226 "inffast.S"\r
+;SECTION .text\r
+\r
+ALIGN 4\r
+inflate_fast_entry:\r
+       push  edi\r
+       push  esi\r
+       push  ebp\r
+       push  ebx\r
+       pushfd\r
+       sub  esp,64\r
+       cld\r
+\r
+\r
+\r
+\r
+       mov  esi, [esp+88]\r
+       mov  edi, [esi+28]\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+       mov  edx, [esi+4]\r
+       mov  eax, [esi+0]\r
+\r
+       add  edx,eax\r
+       sub  edx,11\r
+\r
+       mov  [esp+44],eax\r
+       mov  [esp+20],edx\r
+\r
+       mov  ebp, [esp+92]\r
+       mov  ecx, [esi+16]\r
+       mov  ebx, [esi+12]\r
+\r
+       sub  ebp,ecx\r
+       neg  ebp\r
+       add  ebp,ebx\r
+\r
+       sub  ecx,257\r
+       add  ecx,ebx\r
+\r
+       mov  [esp+60],ebx\r
+       mov  [esp+40],ebp\r
+       mov  [esp+16],ecx\r
+; 285 "inffast.S"\r
+       mov  eax, [edi+lencode_state]\r
+       mov  ecx, [edi+distcode_state]\r
+\r
+       mov  [esp+8],eax\r
+       mov  [esp+12],ecx\r
+\r
+       mov  eax,1\r
+       mov  ecx, [edi+lenbits_state]\r
+       shl  eax,cl\r
+       dec  eax\r
+       mov  [esp+0],eax\r
+\r
+       mov  eax,1\r
+       mov  ecx, [edi+distbits_state]\r
+       shl  eax,cl\r
+       dec  eax\r
+       mov  [esp+4],eax\r
+\r
+       mov  eax, [edi+wsize_state]\r
+       mov  ecx, [edi+write_state]\r
+       mov  edx, [edi+window_state]\r
+\r
+       mov  [esp+52],eax\r
+       mov  [esp+48],ecx\r
+       mov  [esp+56],edx\r
+\r
+       mov  ebp, [edi+hold_state]\r
+       mov  ebx, [edi+bits_state]\r
+; 321 "inffast.S"\r
+       mov  esi, [esp+44]\r
+       mov  ecx, [esp+20]\r
+       cmp  ecx,esi\r
+       ja   L_align_long\r
+\r
+       add  ecx,11\r
+       sub  ecx,esi\r
+       mov  eax,12\r
+       sub  eax,ecx\r
+       lea  edi, [esp+28]\r
+       rep movsb\r
+       mov  ecx,eax\r
+       xor  eax,eax\r
+       rep stosb\r
+       lea  esi, [esp+28]\r
+       mov  [esp+20],esi\r
+       jmp  L_is_aligned\r
+\r
+\r
+L_align_long:\r
+       test  esi,3\r
+       jz   L_is_aligned\r
+       xor  eax,eax\r
+       mov  al, [esi]\r
+       inc  esi\r
+       mov  ecx,ebx\r
+       add  ebx,8\r
+       shl  eax,cl\r
+       or  ebp,eax\r
+       jmp L_align_long\r
+\r
+L_is_aligned:\r
+       mov  edi, [esp+60]\r
+; 366 "inffast.S"\r
+L_check_mmx:\r
+       cmp  dword ptr [inflate_fast_use_mmx],2\r
+       je   L_init_mmx\r
+       ja   L_do_loop\r
+\r
+       push  eax\r
+       push  ebx\r
+       push  ecx\r
+       push  edx\r
+       pushfd\r
+       mov  eax, [esp]\r
+       xor  dword ptr [esp],0200000h\r
+\r
+\r
+\r
+\r
+       popfd\r
+       pushfd\r
+       pop  edx\r
+       xor  edx,eax\r
+       jz   L_dont_use_mmx\r
+       xor  eax,eax\r
+       cpuid\r
+       cmp  ebx,0756e6547h\r
+       jne  L_dont_use_mmx\r
+       cmp  ecx,06c65746eh\r
+       jne  L_dont_use_mmx\r
+       cmp  edx,049656e69h\r
+       jne  L_dont_use_mmx\r
+       mov  eax,1\r
+       cpuid\r
+       shr  eax,8\r
+       and  eax,15\r
+       cmp  eax,6\r
+       jne  L_dont_use_mmx\r
+       test  edx,0800000h\r
+       jnz  L_use_mmx\r
+       jmp  L_dont_use_mmx\r
+L_use_mmx:\r
+       mov  dword ptr [inflate_fast_use_mmx],2\r
+       jmp  L_check_mmx_pop\r
+L_dont_use_mmx:\r
+       mov  dword ptr [inflate_fast_use_mmx],3\r
+L_check_mmx_pop:\r
+       pop  edx\r
+       pop  ecx\r
+       pop  ebx\r
+       pop  eax\r
+       jmp  L_check_mmx\r
+; 426 "inffast.S"\r
+ALIGN 4\r
+L_do_loop:\r
+; 437 "inffast.S"\r
+       cmp  bl,15\r
+       ja   L_get_length_code\r
+\r
+       xor  eax,eax\r
+       lodsw\r
+       mov  cl,bl\r
+       add  bl,16\r
+       shl  eax,cl\r
+       or  ebp,eax\r
+\r
+L_get_length_code:\r
+       mov  edx, [esp+0]\r
+       mov  ecx, [esp+8]\r
+       and  edx,ebp\r
+       mov  eax, [ecx+edx*4]\r
+\r
+L_dolen:\r
+\r
+\r
+\r
+\r
+\r
+\r
+       mov  cl,ah\r
+       sub  bl,ah\r
+       shr  ebp,cl\r
+\r
+\r
+\r
+\r
+\r
+\r
+       test  al,al\r
+       jnz   L_test_for_length_base\r
+\r
+       shr  eax,16\r
+       stosb\r
+\r
+L_while_test:\r
+\r
+\r
+       cmp  [esp+16],edi\r
+       jbe  L_break_loop\r
+\r
+       cmp  [esp+20],esi\r
+       ja   L_do_loop\r
+       jmp  L_break_loop\r
+\r
+L_test_for_length_base:\r
+; 502 "inffast.S"\r
+       mov  edx,eax\r
+       shr  edx,16\r
+       mov  cl,al\r
+\r
+       test  al,16\r
+       jz   L_test_for_second_level_length\r
+       and  cl,15\r
+       jz   L_save_len\r
+       cmp  bl,cl\r
+       jae  L_add_bits_to_len\r
+\r
+       mov  ch,cl\r
+       xor  eax,eax\r
+       lodsw\r
+       mov  cl,bl\r
+       add  bl,16\r
+       shl  eax,cl\r
+       or  ebp,eax\r
+       mov  cl,ch\r
+\r
+L_add_bits_to_len:\r
+       mov  eax,1\r
+       shl  eax,cl\r
+       dec  eax\r
+       sub  bl,cl\r
+       and  eax,ebp\r
+       shr  ebp,cl\r
+       add  edx,eax\r
+\r
+L_save_len:\r
+       mov  [esp+24],edx\r
+\r
+\r
+L_decode_distance:\r
+; 549 "inffast.S"\r
+       cmp  bl,15\r
+       ja   L_get_distance_code\r
+\r
+       xor  eax,eax\r
+       lodsw\r
+       mov  cl,bl\r
+       add  bl,16\r
+       shl  eax,cl\r
+       or  ebp,eax\r
+\r
+L_get_distance_code:\r
+       mov  edx, [esp+4]\r
+       mov  ecx, [esp+12]\r
+       and  edx,ebp\r
+       mov  eax, [ecx+edx*4]\r
+\r
+\r
+L_dodist:\r
+       mov  edx,eax\r
+       shr  edx,16\r
+       mov  cl,ah\r
+       sub  bl,ah\r
+       shr  ebp,cl\r
+; 584 "inffast.S"\r
+       mov  cl,al\r
+\r
+       test  al,16\r
+       jz  L_test_for_second_level_dist\r
+       and  cl,15\r
+       jz  L_check_dist_one\r
+       cmp  bl,cl\r
+       jae  L_add_bits_to_dist\r
+\r
+       mov  ch,cl\r
+       xor  eax,eax\r
+       lodsw\r
+       mov  cl,bl\r
+       add  bl,16\r
+       shl  eax,cl\r
+       or  ebp,eax\r
+       mov  cl,ch\r
+\r
+L_add_bits_to_dist:\r
+       mov  eax,1\r
+       shl  eax,cl\r
+       dec  eax\r
+       sub  bl,cl\r
+       and  eax,ebp\r
+       shr  ebp,cl\r
+       add  edx,eax\r
+       jmp  L_check_window\r
+\r
+L_check_window:\r
+; 625 "inffast.S"\r
+       mov  [esp+44],esi\r
+       mov  eax,edi\r
+       sub  eax, [esp+40]\r
+\r
+       cmp  eax,edx\r
+       jb   L_clip_window\r
+\r
+       mov  ecx, [esp+24]\r
+       mov  esi,edi\r
+       sub  esi,edx\r
+\r
+       sub  ecx,3\r
+       mov  al, [esi]\r
+       mov  [edi],al\r
+       mov  al, [esi+1]\r
+       mov  dl, [esi+2]\r
+       add  esi,3\r
+       mov  [edi+1],al\r
+       mov  [edi+2],dl\r
+       add  edi,3\r
+       rep movsb\r
+\r
+       mov  esi, [esp+44]\r
+       jmp  L_while_test\r
+\r
+ALIGN 4\r
+L_check_dist_one:\r
+       cmp  edx,1\r
+       jne  L_check_window\r
+       cmp  [esp+40],edi\r
+       je  L_check_window\r
+\r
+       dec  edi\r
+       mov  ecx, [esp+24]\r
+       mov  al, [edi]\r
+       sub  ecx,3\r
+\r
+       mov  [edi+1],al\r
+       mov  [edi+2],al\r
+       mov  [edi+3],al\r
+       add  edi,4\r
+       rep stosb\r
+\r
+       jmp  L_while_test\r
+\r
+ALIGN 4\r
+L_test_for_second_level_length:\r
+\r
+\r
+\r
+\r
+       test  al,64\r
+       jnz   L_test_for_end_of_block\r
+\r
+       mov  eax,1\r
+       shl  eax,cl\r
+       dec  eax\r
+       and  eax,ebp\r
+       add  eax,edx\r
+       mov  edx, [esp+8]\r
+       mov  eax, [edx+eax*4]\r
+       jmp  L_dolen\r
+\r
+ALIGN 4\r
+L_test_for_second_level_dist:\r
+\r
+\r
+\r
+\r
+       test  al,64\r
+       jnz   L_invalid_distance_code\r
+\r
+       mov  eax,1\r
+       shl  eax,cl\r
+       dec  eax\r
+       and  eax,ebp\r
+       add  eax,edx\r
+       mov  edx, [esp+12]\r
+       mov  eax, [edx+eax*4]\r
+       jmp  L_dodist\r
+\r
+ALIGN 4\r
+L_clip_window:\r
+; 721 "inffast.S"\r
+       mov  ecx,eax\r
+       mov  eax, [esp+52]\r
+       neg  ecx\r
+       mov  esi, [esp+56]\r
+\r
+       cmp  eax,edx\r
+       jb   L_invalid_distance_too_far\r
+\r
+       add  ecx,edx\r
+       cmp  dword ptr [esp+48],0\r
+       jne  L_wrap_around_window\r
+\r
+       sub  eax,ecx\r
+       add  esi,eax\r
+; 749 "inffast.S"\r
+       mov  eax, [esp+24]\r
+       cmp  eax,ecx\r
+       jbe  L_do_copy1\r
+\r
+       sub  eax,ecx\r
+       rep movsb\r
+       mov  esi,edi\r
+       sub  esi,edx\r
+       jmp  L_do_copy1\r
+\r
+       cmp  eax,ecx\r
+       jbe  L_do_copy1\r
+\r
+       sub  eax,ecx\r
+       rep movsb\r
+       mov  esi,edi\r
+       sub  esi,edx\r
+       jmp  L_do_copy1\r
+\r
+L_wrap_around_window:\r
+; 793 "inffast.S"\r
+       mov  eax, [esp+48]\r
+       cmp  ecx,eax\r
+       jbe  L_contiguous_in_window\r
+\r
+       add  esi, [esp+52]\r
+       add  esi,eax\r
+       sub  esi,ecx\r
+       sub  ecx,eax\r
+\r
+\r
+       mov  eax, [esp+24]\r
+       cmp  eax,ecx\r
+       jbe  L_do_copy1\r
+\r
+       sub  eax,ecx\r
+       rep movsb\r
+       mov  esi, [esp+56]\r
+       mov  ecx, [esp+48]\r
+       cmp  eax,ecx\r
+       jbe  L_do_copy1\r
+\r
+       sub  eax,ecx\r
+       rep movsb\r
+       mov  esi,edi\r
+       sub  esi,edx\r
+       jmp  L_do_copy1\r
+\r
+L_contiguous_in_window:\r
+; 836 "inffast.S"\r
+       add  esi,eax\r
+       sub  esi,ecx\r
+\r
+\r
+       mov  eax, [esp+24]\r
+       cmp  eax,ecx\r
+       jbe  L_do_copy1\r
+\r
+       sub  eax,ecx\r
+       rep movsb\r
+       mov  esi,edi\r
+       sub  esi,edx\r
+\r
+L_do_copy1:\r
+; 862 "inffast.S"\r
+       mov  ecx,eax\r
+       rep movsb\r
+\r
+       mov  esi, [esp+44]\r
+       jmp  L_while_test\r
+; 878 "inffast.S"\r
+ALIGN 4\r
+L_init_mmx:\r
+       emms\r
+\r
+\r
+\r
+\r
+\r
+       movd mm0,ebp\r
+       mov  ebp,ebx\r
+; 896 "inffast.S"\r
+       movd mm4,dword ptr [esp+0]\r
+       movq mm3,mm4\r
+       movd mm5,dword ptr [esp+4]\r
+       movq mm2,mm5\r
+       pxor mm1,mm1\r
+       mov  ebx, [esp+8]\r
+       jmp  L_do_loop_mmx\r
+\r
+ALIGN 4\r
+L_do_loop_mmx:\r
+       psrlq mm0,mm1\r
+\r
+       cmp  ebp,32\r
+       ja  L_get_length_code_mmx\r
+\r
+       movd mm6,ebp\r
+       movd mm7,dword ptr [esi]\r
+       add  esi,4\r
+       psllq mm7,mm6\r
+       add  ebp,32\r
+       por mm0,mm7\r
+\r
+L_get_length_code_mmx:\r
+       pand mm4,mm0\r
+       movd eax,mm4\r
+       movq mm4,mm3\r
+       mov  eax, [ebx+eax*4]\r
+\r
+L_dolen_mmx:\r
+       movzx  ecx,ah\r
+       movd mm1,ecx\r
+       sub  ebp,ecx\r
+\r
+       test  al,al\r
+       jnz L_test_for_length_base_mmx\r
+\r
+       shr  eax,16\r
+       stosb\r
+\r
+L_while_test_mmx:\r
+\r
+\r
+       cmp  [esp+16],edi\r
+       jbe L_break_loop\r
+\r
+       cmp  [esp+20],esi\r
+       ja L_do_loop_mmx\r
+       jmp L_break_loop\r
+\r
+L_test_for_length_base_mmx:\r
+\r
+       mov  edx,eax\r
+       shr  edx,16\r
+\r
+       test  al,16\r
+       jz  L_test_for_second_level_length_mmx\r
+       and  eax,15\r
+       jz L_decode_distance_mmx\r
+\r
+       psrlq mm0,mm1\r
+       movd mm1,eax\r
+       movd ecx,mm0\r
+       sub  ebp,eax\r
+       and  ecx, [inflate_fast_mask+eax*4]\r
+       add  edx,ecx\r
+\r
+L_decode_distance_mmx:\r
+       psrlq mm0,mm1\r
+\r
+       cmp  ebp,32\r
+       ja L_get_dist_code_mmx\r
+\r
+       movd mm6,ebp\r
+       movd mm7,dword ptr [esi]\r
+       add  esi,4\r
+       psllq mm7,mm6\r
+       add  ebp,32\r
+       por mm0,mm7\r
+\r
+L_get_dist_code_mmx:\r
+       mov  ebx, [esp+12]\r
+       pand mm5,mm0\r
+       movd eax,mm5\r
+       movq mm5,mm2\r
+       mov  eax, [ebx+eax*4]\r
+\r
+L_dodist_mmx:\r
+\r
+       movzx  ecx,ah\r
+       mov  ebx,eax\r
+       shr  ebx,16\r
+       sub  ebp,ecx\r
+       movd mm1,ecx\r
+\r
+       test  al,16\r
+       jz L_test_for_second_level_dist_mmx\r
+       and  eax,15\r
+       jz L_check_dist_one_mmx\r
+\r
+L_add_bits_to_dist_mmx:\r
+       psrlq mm0,mm1\r
+       movd mm1,eax\r
+       movd ecx,mm0\r
+       sub  ebp,eax\r
+       and  ecx, [inflate_fast_mask+eax*4]\r
+       add  ebx,ecx\r
+\r
+L_check_window_mmx:\r
+       mov  [esp+44],esi\r
+       mov  eax,edi\r
+       sub  eax, [esp+40]\r
+\r
+       cmp  eax,ebx\r
+       jb L_clip_window_mmx\r
+\r
+       mov  ecx,edx\r
+       mov  esi,edi\r
+       sub  esi,ebx\r
+\r
+       sub  ecx,3\r
+       mov  al, [esi]\r
+       mov  [edi],al\r
+       mov  al, [esi+1]\r
+       mov  dl, [esi+2]\r
+       add  esi,3\r
+       mov  [edi+1],al\r
+       mov  [edi+2],dl\r
+       add  edi,3\r
+       rep movsb\r
+\r
+       mov  esi, [esp+44]\r
+       mov  ebx, [esp+8]\r
+       jmp  L_while_test_mmx\r
+\r
+ALIGN 4\r
+L_check_dist_one_mmx:\r
+       cmp  ebx,1\r
+       jne  L_check_window_mmx\r
+       cmp  [esp+40],edi\r
+       je   L_check_window_mmx\r
+\r
+       dec  edi\r
+       mov  ecx,edx\r
+       mov  al, [edi]\r
+       sub  ecx,3\r
+\r
+       mov  [edi+1],al\r
+       mov  [edi+2],al\r
+       mov  [edi+3],al\r
+       add  edi,4\r
+       rep stosb\r
+\r
+       mov  ebx, [esp+8]\r
+       jmp  L_while_test_mmx\r
+\r
+ALIGN 4\r
+L_test_for_second_level_length_mmx:\r
+       test  al,64\r
+       jnz L_test_for_end_of_block\r
+\r
+       and  eax,15\r
+       psrlq mm0,mm1\r
+       movd ecx,mm0\r
+       and  ecx, [inflate_fast_mask+eax*4]\r
+       add  ecx,edx\r
+       mov  eax, [ebx+ecx*4]\r
+       jmp L_dolen_mmx\r
+\r
+ALIGN 4\r
+L_test_for_second_level_dist_mmx:\r
+       test  al,64\r
+       jnz L_invalid_distance_code\r
+\r
+       and  eax,15\r
+       psrlq mm0,mm1\r
+       movd ecx,mm0\r
+       and  ecx, [inflate_fast_mask+eax*4]\r
+       mov  eax, [esp+12]\r
+       add  ecx,ebx\r
+       mov  eax, [eax+ecx*4]\r
+       jmp  L_dodist_mmx\r
+\r
+ALIGN 4\r
+L_clip_window_mmx:\r
+\r
+       mov  ecx,eax\r
+       mov  eax, [esp+52]\r
+       neg  ecx\r
+       mov  esi, [esp+56]\r
+\r
+       cmp  eax,ebx\r
+       jb  L_invalid_distance_too_far\r
+\r
+       add  ecx,ebx\r
+       cmp  dword ptr [esp+48],0\r
+       jne  L_wrap_around_window_mmx\r
+\r
+       sub  eax,ecx\r
+       add  esi,eax\r
+\r
+       cmp  edx,ecx\r
+       jbe  L_do_copy1_mmx\r
+\r
+       sub  edx,ecx\r
+       rep movsb\r
+       mov  esi,edi\r
+       sub  esi,ebx\r
+       jmp  L_do_copy1_mmx\r
+\r
+       cmp  edx,ecx\r
+       jbe  L_do_copy1_mmx\r
+\r
+       sub  edx,ecx\r
+       rep movsb\r
+       mov  esi,edi\r
+       sub  esi,ebx\r
+       jmp  L_do_copy1_mmx\r
+\r
+L_wrap_around_window_mmx:\r
+\r
+       mov  eax, [esp+48]\r
+       cmp  ecx,eax\r
+       jbe  L_contiguous_in_window_mmx\r
+\r
+       add  esi, [esp+52]\r
+       add  esi,eax\r
+       sub  esi,ecx\r
+       sub  ecx,eax\r
+\r
+\r
+       cmp  edx,ecx\r
+       jbe  L_do_copy1_mmx\r
+\r
+       sub  edx,ecx\r
+       rep movsb\r
+       mov  esi, [esp+56]\r
+       mov  ecx, [esp+48]\r
+       cmp  edx,ecx\r
+       jbe  L_do_copy1_mmx\r
+\r
+       sub  edx,ecx\r
+       rep movsb\r
+       mov  esi,edi\r
+       sub  esi,ebx\r
+       jmp  L_do_copy1_mmx\r
+\r
+L_contiguous_in_window_mmx:\r
+\r
+       add  esi,eax\r
+       sub  esi,ecx\r
+\r
+\r
+       cmp  edx,ecx\r
+       jbe  L_do_copy1_mmx\r
+\r
+       sub  edx,ecx\r
+       rep movsb\r
+       mov  esi,edi\r
+       sub  esi,ebx\r
+\r
+L_do_copy1_mmx:\r
+\r
+\r
+       mov  ecx,edx\r
+       rep movsb\r
+\r
+       mov  esi, [esp+44]\r
+       mov  ebx, [esp+8]\r
+       jmp  L_while_test_mmx\r
+; 1174 "inffast.S"\r
+L_invalid_distance_code:\r
+\r
+\r
+\r
+\r
+\r
+       mov  ecx, invalid_distance_code_msg\r
+       mov  edx,INFLATE_MODE_BAD\r
+       jmp  L_update_stream_state\r
+\r
+L_test_for_end_of_block:\r
+\r
+\r
+\r
+\r
+\r
+       test  al,32\r
+       jz  L_invalid_literal_length_code\r
+\r
+       mov  ecx,0\r
+       mov  edx,INFLATE_MODE_TYPE\r
+       jmp  L_update_stream_state\r
+\r
+L_invalid_literal_length_code:\r
+\r
+\r
+\r
+\r
+\r
+       mov  ecx, invalid_literal_length_code_msg\r
+       mov  edx,INFLATE_MODE_BAD\r
+       jmp  L_update_stream_state\r
+\r
+L_invalid_distance_too_far:\r
+\r
+\r
+\r
+       mov  esi, [esp+44]\r
+       mov  ecx, invalid_distance_too_far_msg\r
+       mov  edx,INFLATE_MODE_BAD\r
+       jmp  L_update_stream_state\r
+\r
+L_update_stream_state:\r
+\r
+       mov  eax, [esp+88]\r
+       test  ecx,ecx\r
+       jz  L_skip_msg\r
+       mov  [eax+24],ecx\r
+L_skip_msg:\r
+       mov  eax, [eax+28]\r
+       mov  [eax+mode_state],edx\r
+       jmp  L_break_loop\r
+\r
+ALIGN 4\r
+L_break_loop:\r
+; 1243 "inffast.S"\r
+       cmp  dword ptr [inflate_fast_use_mmx],2\r
+       jne  L_update_next_in\r
+\r
+\r
+\r
+       mov  ebx,ebp\r
+\r
+L_update_next_in:\r
+; 1266 "inffast.S"\r
+       mov  eax, [esp+88]\r
+       mov  ecx,ebx\r
+       mov  edx, [eax+28]\r
+       shr  ecx,3\r
+       sub  esi,ecx\r
+       shl  ecx,3\r
+       sub  ebx,ecx\r
+       mov  [eax+12],edi\r
+       mov  [edx+bits_state],ebx\r
+       mov  ecx,ebx\r
+\r
+       lea  ebx, [esp+28]\r
+       cmp  [esp+20],ebx\r
+       jne  L_buf_not_used\r
+\r
+       sub  esi,ebx\r
+       mov  ebx, [eax+0]\r
+       mov  [esp+20],ebx\r
+       add  esi,ebx\r
+       mov  ebx, [eax+4]\r
+       sub  ebx,11\r
+       add  [esp+20],ebx\r
+\r
+L_buf_not_used:\r
+       mov  [eax+0],esi\r
+\r
+       mov  ebx,1\r
+       shl  ebx,cl\r
+       dec  ebx\r
+\r
+\r
+\r
+\r
+\r
+       cmp  dword ptr [inflate_fast_use_mmx],2\r
+       jne  L_update_hold\r
+\r
+\r
+\r
+       psrlq mm0,mm1\r
+       movd ebp,mm0\r
+\r
+       emms\r
+\r
+L_update_hold:\r
+\r
+\r
+\r
+       and  ebp,ebx\r
+       mov  [edx+hold_state],ebp\r
+\r
+\r
+\r
+\r
+       mov  ebx, [esp+20]\r
+       cmp  ebx,esi\r
+       jbe  L_last_is_smaller\r
+\r
+       sub  ebx,esi\r
+       add  ebx,11\r
+       mov  [eax+4],ebx\r
+       jmp  L_fixup_out\r
+L_last_is_smaller:\r
+       sub  esi,ebx\r
+       neg  esi\r
+       add  esi,11\r
+       mov  [eax+4],esi\r
+\r
+\r
+\r
+\r
+L_fixup_out:\r
+\r
+       mov  ebx, [esp+16]\r
+       cmp  ebx,edi\r
+       jbe  L_end_is_smaller\r
+\r
+       sub  ebx,edi\r
+       add  ebx,257\r
+       mov  [eax+16],ebx\r
+       jmp  L_done\r
+L_end_is_smaller:\r
+       sub  edi,ebx\r
+       neg  edi\r
+       add  edi,257\r
+       mov  [eax+16],edi\r
+\r
+\r
+\r
+\r
+\r
+L_done:\r
+       add  esp,64\r
+       popfd\r
+       pop  ebx\r
+       pop  ebp\r
+       pop  esi\r
+       pop  edi\r
+       ret\r
+\r
+_TEXT  ends\r
+end\r
diff --git a/8.x/zlib/contrib/masmx86/match686.asm b/8.x/zlib/contrib/masmx86/match686.asm
new file mode 100644 (file)
index 0000000..1eaf555
--- /dev/null
@@ -0,0 +1,478 @@
+; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86\r
+; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant.\r
+; File written by Gilles Vollant, by converting match686.S from Brian Raiter\r
+; for MASM. This is as assembly version of longest_match\r
+;  from Jean-loup Gailly in deflate.c\r
+;\r
+;         http://www.zlib.net\r
+;         http://www.winimage.com/zLibDll\r
+;         http://www.muppetlabs.com/~breadbox/software/assembly.html\r
+;\r
+; For Visual C++ 4.x and higher and ML 6.x and higher\r
+;   ml.exe is distributed in\r
+;  http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64\r
+;\r
+; this file contain two implementation of longest_match\r
+;\r
+;  this longest_match was written by Brian raiter (1998), optimized for Pentium Pro\r
+;   (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom)\r
+;\r
+;  for using an assembly version of longest_match, you need define ASMV in project\r
+;\r
+;    compile the asm file running\r
+;           ml /coff /Zi /c /Flmatch686.lst match686.asm\r
+;    and do not include match686.obj in your project\r
+;\r
+; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for\r
+;  Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor\r
+;  with autoselect (with cpu detection code)\r
+;  if you want support the old pentium optimization, you can still use these version\r
+;\r
+; this file is not optimized for old pentium, but it compatible with all x86 32 bits\r
+; processor (starting 80386)\r
+;\r
+;\r
+; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2\r
+\r
+;uInt longest_match(s, cur_match)\r
+;    deflate_state *s;\r
+;    IPos cur_match;                             /* current match */\r
+\r
+    NbStack         equ     76\r
+    cur_match       equ     dword ptr[esp+NbStack-0]\r
+    str_s           equ     dword ptr[esp+NbStack-4]\r
+; 5 dword on top (ret,ebp,esi,edi,ebx)\r
+    adrret          equ     dword ptr[esp+NbStack-8]\r
+    pushebp         equ     dword ptr[esp+NbStack-12]\r
+    pushedi         equ     dword ptr[esp+NbStack-16]\r
+    pushesi         equ     dword ptr[esp+NbStack-20]\r
+    pushebx         equ     dword ptr[esp+NbStack-24]\r
+\r
+    chain_length    equ     dword ptr [esp+NbStack-28]\r
+    limit           equ     dword ptr [esp+NbStack-32]\r
+    best_len        equ     dword ptr [esp+NbStack-36]\r
+    window          equ     dword ptr [esp+NbStack-40]\r
+    prev            equ     dword ptr [esp+NbStack-44]\r
+    scan_start      equ      word ptr [esp+NbStack-48]\r
+    wmask           equ     dword ptr [esp+NbStack-52]\r
+    match_start_ptr equ     dword ptr [esp+NbStack-56]\r
+    nice_match      equ     dword ptr [esp+NbStack-60]\r
+    scan            equ     dword ptr [esp+NbStack-64]\r
+\r
+    windowlen       equ     dword ptr [esp+NbStack-68]\r
+    match_start     equ     dword ptr [esp+NbStack-72]\r
+    strend          equ     dword ptr [esp+NbStack-76]\r
+    NbStackAdd      equ     (NbStack-24)\r
+\r
+    .386p\r
+\r
+    name    gvmatch\r
+    .MODEL  FLAT\r
+\r
+\r
+\r
+;  all the +zlib1222add offsets are due to the addition of fields\r
+;  in zlib in the deflate_state structure since the asm code was first written\r
+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").\r
+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").\r
+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").\r
+\r
+    zlib1222add         equ     8\r
+\r
+;  Note : these value are good with a 8 bytes boundary pack structure\r
+    dep_chain_length    equ     74h+zlib1222add\r
+    dep_window          equ     30h+zlib1222add\r
+    dep_strstart        equ     64h+zlib1222add\r
+    dep_prev_length     equ     70h+zlib1222add\r
+    dep_nice_match      equ     88h+zlib1222add\r
+    dep_w_size          equ     24h+zlib1222add\r
+    dep_prev            equ     38h+zlib1222add\r
+    dep_w_mask          equ     2ch+zlib1222add\r
+    dep_good_match      equ     84h+zlib1222add\r
+    dep_match_start     equ     68h+zlib1222add\r
+    dep_lookahead       equ     6ch+zlib1222add\r
+\r
+\r
+_TEXT                   segment\r
+\r
+IFDEF NOUNDERLINE\r
+            public  longest_match\r
+            public  match_init\r
+ELSE\r
+            public  _longest_match\r
+            public  _match_init\r
+ENDIF\r
+\r
+    MAX_MATCH           equ     258\r
+    MIN_MATCH           equ     3\r
+    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)\r
+\r
+\r
+\r
+MAX_MATCH       equ     258\r
+MIN_MATCH       equ     3\r
+MIN_LOOKAHEAD   equ     (MAX_MATCH + MIN_MATCH + 1)\r
+MAX_MATCH_8_     equ     ((MAX_MATCH + 7) AND 0FFF0h)\r
+\r
+\r
+;;; stack frame offsets\r
+\r
+chainlenwmask   equ  esp + 0    ; high word: current chain len\r
+                    ; low word: s->wmask\r
+window      equ  esp + 4    ; local copy of s->window\r
+windowbestlen   equ  esp + 8    ; s->window + bestlen\r
+scanstart   equ  esp + 16   ; first two bytes of string\r
+scanend     equ  esp + 12   ; last two bytes of string\r
+scanalign   equ  esp + 20   ; dword-misalignment of string\r
+nicematch   equ  esp + 24   ; a good enough match size\r
+bestlen     equ  esp + 28   ; size of best match so far\r
+scan        equ  esp + 32   ; ptr to string wanting match\r
+\r
+LocalVarsSize   equ 36\r
+;   saved ebx   byte esp + 36\r
+;   saved edi   byte esp + 40\r
+;   saved esi   byte esp + 44\r
+;   saved ebp   byte esp + 48\r
+;   return address  byte esp + 52\r
+deflatestate    equ  esp + 56   ; the function arguments\r
+curmatch    equ  esp + 60\r
+\r
+;;; Offsets for fields in the deflate_state structure. These numbers\r
+;;; are calculated from the definition of deflate_state, with the\r
+;;; assumption that the compiler will dword-align the fields. (Thus,\r
+;;; changing the definition of deflate_state could easily cause this\r
+;;; program to crash horribly, without so much as a warning at\r
+;;; compile time. Sigh.)\r
+\r
+dsWSize     equ 36+zlib1222add\r
+dsWMask     equ 44+zlib1222add\r
+dsWindow    equ 48+zlib1222add\r
+dsPrev      equ 56+zlib1222add\r
+dsMatchLen  equ 88+zlib1222add\r
+dsPrevMatch equ 92+zlib1222add\r
+dsStrStart  equ 100+zlib1222add\r
+dsMatchStart    equ 104+zlib1222add\r
+dsLookahead equ 108+zlib1222add\r
+dsPrevLen   equ 112+zlib1222add\r
+dsMaxChainLen   equ 116+zlib1222add\r
+dsGoodMatch equ 132+zlib1222add\r
+dsNiceMatch equ 136+zlib1222add\r
+\r
+\r
+;;; match686.asm -- Pentium-Pro-optimized version of longest_match()\r
+;;; Written for zlib 1.1.2\r
+;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>\r
+;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html\r
+;;;\r
+;;\r
+;;  This software is provided 'as-is', without any express or implied\r
+;;  warranty.  In no event will the authors be held liable for any damages\r
+;;  arising from the use of this software.\r
+;;\r
+;;  Permission is granted to anyone to use this software for any purpose,\r
+;;  including commercial applications, and to alter it and redistribute it\r
+;;  freely, subject to the following restrictions:\r
+;;\r
+;;  1. The origin of this software must not be misrepresented; you must not\r
+;;     claim that you wrote the original software. If you use this software\r
+;;     in a product, an acknowledgment in the product documentation would be\r
+;;     appreciated but is not required.\r
+;;  2. Altered source versions must be plainly marked as such, and must not be\r
+;;     misrepresented as being the original software\r
+;;  3. This notice may not be removed or altered from any source distribution.\r
+;;\r
+\r
+;GLOBAL _longest_match, _match_init\r
+\r
+\r
+;SECTION    .text\r
+\r
+;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)\r
+\r
+;_longest_match:\r
+    IFDEF NOUNDERLINE\r
+    longest_match       proc near\r
+    ELSE\r
+    _longest_match      proc near\r
+    ENDIF\r
+\r
+;;; Save registers that the compiler may be using, and adjust esp to\r
+;;; make room for our stack frame.\r
+\r
+        push    ebp\r
+        push    edi\r
+        push    esi\r
+        push    ebx\r
+        sub esp, LocalVarsSize\r
+\r
+;;; Retrieve the function arguments. ecx will hold cur_match\r
+;;; throughout the entire function. edx will hold the pointer to the\r
+;;; deflate_state structure during the function's setup (before\r
+;;; entering the main loop.\r
+\r
+        mov edx, [deflatestate]\r
+        mov ecx, [curmatch]\r
+\r
+;;; uInt wmask = s->w_mask;\r
+;;; unsigned chain_length = s->max_chain_length;\r
+;;; if (s->prev_length >= s->good_match) {\r
+;;;     chain_length >>= 2;\r
+;;; }\r
+\r
+        mov eax, [edx + dsPrevLen]\r
+        mov ebx, [edx + dsGoodMatch]\r
+        cmp eax, ebx\r
+        mov eax, [edx + dsWMask]\r
+        mov ebx, [edx + dsMaxChainLen]\r
+        jl  LastMatchGood\r
+        shr ebx, 2\r
+LastMatchGood:\r
+\r
+;;; chainlen is decremented once beforehand so that the function can\r
+;;; use the sign flag instead of the zero flag for the exit test.\r
+;;; It is then shifted into the high word, to make room for the wmask\r
+;;; value, which it will always accompany.\r
+\r
+        dec ebx\r
+        shl ebx, 16\r
+        or  ebx, eax\r
+        mov [chainlenwmask], ebx\r
+\r
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;\r
+\r
+        mov eax, [edx + dsNiceMatch]\r
+        mov ebx, [edx + dsLookahead]\r
+        cmp ebx, eax\r
+        jl  LookaheadLess\r
+        mov ebx, eax\r
+LookaheadLess:  mov [nicematch], ebx\r
+\r
+;;; register Bytef *scan = s->window + s->strstart;\r
+\r
+        mov esi, [edx + dsWindow]\r
+        mov [window], esi\r
+        mov ebp, [edx + dsStrStart]\r
+        lea edi, [esi + ebp]\r
+        mov [scan], edi\r
+\r
+;;; Determine how many bytes the scan ptr is off from being\r
+;;; dword-aligned.\r
+\r
+        mov eax, edi\r
+        neg eax\r
+        and eax, 3\r
+        mov [scanalign], eax\r
+\r
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\r
+;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;\r
+\r
+        mov eax, [edx + dsWSize]\r
+        sub eax, MIN_LOOKAHEAD\r
+        sub ebp, eax\r
+        jg  LimitPositive\r
+        xor ebp, ebp\r
+LimitPositive:\r
+\r
+;;; int best_len = s->prev_length;\r
+\r
+        mov eax, [edx + dsPrevLen]\r
+        mov [bestlen], eax\r
+\r
+;;; Store the sum of s->window + best_len in esi locally, and in esi.\r
+\r
+        add esi, eax\r
+        mov [windowbestlen], esi\r
+\r
+;;; register ush scan_start = *(ushf*)scan;\r
+;;; register ush scan_end   = *(ushf*)(scan+best_len-1);\r
+;;; Posf *prev = s->prev;\r
+\r
+        movzx   ebx, word ptr [edi]\r
+        mov [scanstart], ebx\r
+        movzx   ebx, word ptr [edi + eax - 1]\r
+        mov [scanend], ebx\r
+        mov edi, [edx + dsPrev]\r
+\r
+;;; Jump into the main loop.\r
+\r
+        mov edx, [chainlenwmask]\r
+        jmp short LoopEntry\r
+\r
+align 4\r
+\r
+;;; do {\r
+;;;     match = s->window + cur_match;\r
+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||\r
+;;;         *(ushf*)match != scan_start) continue;\r
+;;;     [...]\r
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit\r
+;;;          && --chain_length != 0);\r
+;;;\r
+;;; Here is the inner loop of the function. The function will spend the\r
+;;; majority of its time in this loop, and majority of that time will\r
+;;; be spent in the first ten instructions.\r
+;;;\r
+;;; Within this loop:\r
+;;; ebx = scanend\r
+;;; ecx = curmatch\r
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)\r
+;;; esi = windowbestlen - i.e., (window + bestlen)\r
+;;; edi = prev\r
+;;; ebp = limit\r
+\r
+LookupLoop:\r
+        and ecx, edx\r
+        movzx   ecx, word ptr [edi + ecx*2]\r
+        cmp ecx, ebp\r
+        jbe LeaveNow\r
+        sub edx, 00010000h\r
+        js  LeaveNow\r
+LoopEntry:  movzx   eax, word ptr [esi + ecx - 1]\r
+        cmp eax, ebx\r
+        jnz LookupLoop\r
+        mov eax, [window]\r
+        movzx   eax, word ptr [eax + ecx]\r
+        cmp eax, [scanstart]\r
+        jnz LookupLoop\r
+\r
+;;; Store the current value of chainlen.\r
+\r
+        mov [chainlenwmask], edx\r
+\r
+;;; Point edi to the string under scrutiny, and esi to the string we\r
+;;; are hoping to match it up with. In actuality, esi and edi are\r
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is\r
+;;; initialized to -(MAX_MATCH_8 - scanalign).\r
+\r
+        mov esi, [window]\r
+        mov edi, [scan]\r
+        add esi, ecx\r
+        mov eax, [scanalign]\r
+        mov edx, 0fffffef8h; -(MAX_MATCH_8)\r
+        lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]\r
+        lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]\r
+\r
+;;; Test the strings for equality, 8 bytes at a time. At the end,\r
+;;; adjust edx so that it is offset to the exact byte that mismatched.\r
+;;;\r
+;;; We already know at this point that the first three bytes of the\r
+;;; strings match each other, and they can be safely passed over before\r
+;;; starting the compare loop. So what this code does is skip over 0-3\r
+;;; bytes, as much as necessary in order to dword-align the edi\r
+;;; pointer. (esi will still be misaligned three times out of four.)\r
+;;;\r
+;;; It should be confessed that this loop usually does not represent\r
+;;; much of the total running time. Replacing it with a more\r
+;;; straightforward "rep cmpsb" would not drastically degrade\r
+;;; performance.\r
+\r
+LoopCmps:\r
+        mov eax, [esi + edx]\r
+        xor eax, [edi + edx]\r
+        jnz LeaveLoopCmps\r
+        mov eax, [esi + edx + 4]\r
+        xor eax, [edi + edx + 4]\r
+        jnz LeaveLoopCmps4\r
+        add edx, 8\r
+        jnz LoopCmps\r
+        jmp short LenMaximum\r
+LeaveLoopCmps4: add edx, 4\r
+LeaveLoopCmps:  test    eax, 0000FFFFh\r
+        jnz LenLower\r
+        add edx,  2\r
+        shr eax, 16\r
+LenLower:   sub al, 1\r
+        adc edx, 0\r
+\r
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,\r
+;;; then automatically accept it as the best possible match and leave.\r
+\r
+        lea eax, [edi + edx]\r
+        mov edi, [scan]\r
+        sub eax, edi\r
+        cmp eax, MAX_MATCH\r
+        jge LenMaximum\r
+\r
+;;; If the length of the match is not longer than the best match we\r
+;;; have so far, then forget it and return to the lookup loop.\r
+\r
+        mov edx, [deflatestate]\r
+        mov ebx, [bestlen]\r
+        cmp eax, ebx\r
+        jg  LongerMatch\r
+        mov esi, [windowbestlen]\r
+        mov edi, [edx + dsPrev]\r
+        mov ebx, [scanend]\r
+        mov edx, [chainlenwmask]\r
+        jmp LookupLoop\r
+\r
+;;;         s->match_start = cur_match;\r
+;;;         best_len = len;\r
+;;;         if (len >= nice_match) break;\r
+;;;         scan_end = *(ushf*)(scan+best_len-1);\r
+\r
+LongerMatch:    mov ebx, [nicematch]\r
+        mov [bestlen], eax\r
+        mov [edx + dsMatchStart], ecx\r
+        cmp eax, ebx\r
+        jge LeaveNow\r
+        mov esi, [window]\r
+        add esi, eax\r
+        mov [windowbestlen], esi\r
+        movzx   ebx, word ptr [edi + eax - 1]\r
+        mov edi, [edx + dsPrev]\r
+        mov [scanend], ebx\r
+        mov edx, [chainlenwmask]\r
+        jmp LookupLoop\r
+\r
+;;; Accept the current string, with the maximum possible length.\r
+\r
+LenMaximum: mov edx, [deflatestate]\r
+        mov dword ptr [bestlen], MAX_MATCH\r
+        mov [edx + dsMatchStart], ecx\r
+\r
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\r
+;;; return s->lookahead;\r
+\r
+LeaveNow:\r
+        mov edx, [deflatestate]\r
+        mov ebx, [bestlen]\r
+        mov eax, [edx + dsLookahead]\r
+        cmp ebx, eax\r
+        jg  LookaheadRet\r
+        mov eax, ebx\r
+LookaheadRet:\r
+\r
+;;; Restore the stack and return from whence we came.\r
+\r
+        add esp, LocalVarsSize\r
+        pop ebx\r
+        pop esi\r
+        pop edi\r
+        pop ebp\r
+\r
+        ret\r
+; please don't remove this string !\r
+; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary!\r
+    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah\r
+\r
+\r
+    IFDEF NOUNDERLINE\r
+    longest_match       endp\r
+    ELSE\r
+    _longest_match      endp\r
+    ENDIF\r
+\r
+    IFDEF NOUNDERLINE\r
+    match_init      proc near\r
+                    ret\r
+    match_init      endp\r
+    ELSE\r
+    _match_init     proc near\r
+                    ret\r
+    _match_init     endp\r
+    ENDIF\r
+\r
+\r
+_TEXT   ends\r
+end\r
diff --git a/8.x/zlib/contrib/masmx86/readme.txt b/8.x/zlib/contrib/masmx86/readme.txt
new file mode 100644 (file)
index 0000000..3271f72
--- /dev/null
@@ -0,0 +1,27 @@
+\r
+Summary\r
+-------\r
+This directory contains ASM implementations of the functions\r
+longest_match() and inflate_fast().\r
+\r
+\r
+Use instructions\r
+----------------\r
+Assemble using MASM, and copy the object files into the zlib source\r
+directory, then run the appropriate makefile, as suggested below.  You can\r
+donwload MASM from here:\r
+\r
+    http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64\r
+\r
+You can also get objects files here:\r
+\r
+    http://www.winimage.com/zLibDll/zlib124_masm_obj.zip\r
+\r
+Build instructions\r
+------------------\r
+* With Microsoft C and MASM:\r
+nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj"\r
+\r
+* With Borland C and TASM:\r
+make -f win32/Makefile.bor LOCAL_ZLIB="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" OBJPA="+match686c.obj+match686.obj+inffas32.obj"\r
+\r
diff --git a/8.x/zlib/contrib/minizip/Makefile b/8.x/zlib/contrib/minizip/Makefile
new file mode 100644 (file)
index 0000000..84eaad2
--- /dev/null
@@ -0,0 +1,25 @@
+CC=cc
+CFLAGS=-O -I../..
+
+UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
+ZIP_OBJS = minizip.o zip.o   ioapi.o ../../libz.a
+
+.c.o:
+       $(CC) -c $(CFLAGS) $*.c
+
+all: miniunz minizip
+
+miniunz:  $(UNZ_OBJS)
+       $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
+
+minizip:  $(ZIP_OBJS)
+       $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
+
+test:  miniunz minizip
+       ./minizip test readme.txt
+       ./miniunz -l test.zip
+       mv readme.txt readme.old
+       ./miniunz test.zip
+
+clean:
+       /bin/rm -f *.o *~ minizip miniunz
diff --git a/8.x/zlib/contrib/minizip/MiniZip64_Changes.txt b/8.x/zlib/contrib/minizip/MiniZip64_Changes.txt
new file mode 100644 (file)
index 0000000..13a1bd9
--- /dev/null
@@ -0,0 +1,6 @@
+
+MiniZip 1.1 was derrived from MiniZip at version 1.01f
+
+Change in 1.0 (Okt 2009)
+ - **TODO - Add history**
+
diff --git a/8.x/zlib/contrib/minizip/MiniZip64_info.txt b/8.x/zlib/contrib/minizip/MiniZip64_info.txt
new file mode 100644 (file)
index 0000000..57d7152
--- /dev/null
@@ -0,0 +1,74 @@
+MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson
+
+Introduction
+---------------------
+MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html )
+
+When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0.
+All possible work was done for compatibility.
+
+
+Background
+---------------------
+When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64 
+support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ )
+
+That was used as a starting point. And after that ZIP64 support was added to zip.c
+some refactoring and code cleanup was also done.
+
+
+Changed from MiniZip 1.0 to MiniZip 1.1
+---------------------------------------
+* Added ZIP64 support for unzip ( by Even Rouault )
+* Added ZIP64 support for zip ( by Mathias Svensson )
+* Reverted some changed that Even Rouault did.
+* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users.
+* Added unzip patch for BZIP Compression method (patch create by Daniel Borca)
+* Added BZIP Compress method for zip
+* Did some refactoring and code cleanup
+
+
+Credits
+
+ Gilles Vollant    - Original MiniZip author
+ Even Rouault      - ZIP64 unzip Support
+ Daniel Borca      - BZip Compression method support in unzip
+ Mathias Svensson  - ZIP64 zip support
+ Mathias Svensson  - BZip Compression method support in zip
+
+ Resources
+
+ ZipLayout   http://result42.com/projects/ZipFileLayout
+             Command line tool for Windows that shows the layout and information of the headers in a zip archive.
+             Used when debugging and validating the creation of zip files using MiniZip64
+
+
+ ZIP App Note  http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+               Zip File specification
+
+
+Notes.
+ * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined.
+
+License
+----------------------------------------------------------
+   Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+----------------------------------------------------------
+
diff --git a/8.x/zlib/contrib/minizip/crypt.h b/8.x/zlib/contrib/minizip/crypt.h
new file mode 100644 (file)
index 0000000..a01d08d
--- /dev/null
@@ -0,0 +1,131 @@
+/* crypt.h -- base code for crypt/uncrypt ZIPfile
+
+
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   This code is a modified version of crypting code in Infozip distribution
+
+   The encryption/decryption parts of this source code (as opposed to the
+   non-echoing password parts) were originally written in Europe.  The
+   whole source package can be freely distributed, including from the USA.
+   (Prior to January 2000, re-export from the US was a violation of US law.)
+
+   This encryption code is a direct transcription of the algorithm from
+   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
+   file (appnote.txt) is distributed with the PKZIP program (even in the
+   version without encryption capabilities).
+
+   If you don't need crypting in your application, just define symbols
+   NOCRYPT and NOUNCRYPT.
+
+   This code support the "Traditional PKWARE Encryption".
+
+   The new AES encryption added on Zip format by Winzip (see the page
+   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
+   Encryption is not supported.
+*/
+
+#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
+
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+ */
+static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
+{
+    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
+                     * unpredictable manner on 16-bit systems; not a problem
+                     * with any known compiler so far, though */
+
+    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
+    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/***********************************************************************
+ * Update the encryption keys with the next byte of plain text
+ */
+static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
+{
+    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
+    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
+    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
+    {
+      register int keyshift = (int)((*(pkeys+1)) >> 24);
+      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
+    }
+    return c;
+}
+
+
+/***********************************************************************
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
+{
+    *(pkeys+0) = 305419896L;
+    *(pkeys+1) = 591751049L;
+    *(pkeys+2) = 878082192L;
+    while (*passwd != '\0') {
+        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
+        passwd++;
+    }
+}
+
+#define zdecode(pkeys,pcrc_32_tab,c) \
+    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
+
+#define zencode(pkeys,pcrc_32_tab,c,t) \
+    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
+
+#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+
+#define RAND_HEAD_LEN  12
+   /* "last resort" source for second part of crypt seed pattern */
+#  ifndef ZCR_SEED2
+#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
+#  endif
+
+static int crypthead(const char* passwd,      /* password string */
+                     unsigned char* buf,      /* where to write header */
+                     int bufSize,
+                     unsigned long* pkeys,
+                     const unsigned long* pcrc_32_tab,
+                     unsigned long crcForCrypting)
+{
+    int n;                       /* index in random header */
+    int t;                       /* temporary */
+    int c;                       /* random byte */
+    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
+    static unsigned calls = 0;   /* ensure different random header each time */
+
+    if (bufSize<RAND_HEAD_LEN)
+      return 0;
+
+    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+     * output of rand() to get less predictability, since rand() is
+     * often poorly implemented.
+     */
+    if (++calls == 1)
+    {
+        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
+    }
+    init_keys(passwd, pkeys, pcrc_32_tab);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++)
+    {
+        c = (rand() >> 7) & 0xff;
+        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
+    }
+    /* Encrypt random header (last two bytes is high word of crc) */
+    init_keys(passwd, pkeys, pcrc_32_tab);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++)
+    {
+        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
+    }
+    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
+    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
+    return n;
+}
+
+#endif
diff --git a/8.x/zlib/contrib/minizip/ioapi.c b/8.x/zlib/contrib/minizip/ioapi.c
new file mode 100644 (file)
index 0000000..49958f6
--- /dev/null
@@ -0,0 +1,235 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+*/
+
+#if (defined(_WIN32))
+        #define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include "ioapi.h"
+
+voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
+{
+    if (pfilefunc->zfile_func64.zopen64_file != NULL)
+        return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
+    else
+    {
+        return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
+    }
+}
+
+long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
+{
+    if (pfilefunc->zfile_func64.zseek64_file != NULL)
+        return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
+    else
+    {
+        uLong offsetTruncated = (uLong)offset;
+        if (offsetTruncated != offset)
+            return -1;
+        else
+            return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
+    }
+}
+
+ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
+{
+    if (pfilefunc->zfile_func64.zseek64_file != NULL)
+        return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
+    else
+    {
+        uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
+        if ((tell_uLong) == ((uLong)-1))
+            return (ZPOS64_T)-1;
+        else
+            return tell_uLong;
+    }
+}
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
+{
+    p_filefunc64_32->zfile_func64.zopen64_file = NULL;
+    p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
+    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+    p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
+    p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
+    p_filefunc64_32->zfile_func64.ztell64_file = NULL;
+    p_filefunc64_32->zfile_func64.zseek64_file = NULL;
+    p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
+    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+    p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
+    p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
+    p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
+}
+
+
+
+static voidpf  ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
+static uLong   ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+static uLong   ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
+static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
+static long    ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+static int     ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
+static int     ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
+
+static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
+{
+    FILE* file = NULL;
+    const char* mode_fopen = NULL;
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+        mode_fopen = "rb";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+        mode_fopen = "r+b";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+        mode_fopen = "wb";
+
+    if ((filename!=NULL) && (mode_fopen != NULL))
+        file = fopen(filename, mode_fopen);
+    return file;
+}
+
+static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
+{
+    FILE* file = NULL;
+    const char* mode_fopen = NULL;
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+        mode_fopen = "rb";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+        mode_fopen = "r+b";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+        mode_fopen = "wb";
+
+    if ((filename!=NULL) && (mode_fopen != NULL))
+        file = fopen64((const char*)filename, mode_fopen);
+    return file;
+}
+
+
+static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
+{
+    uLong ret;
+    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
+{
+    uLong ret;
+    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
+{
+    long ret;
+    ret = ftell((FILE *)stream);
+    return ret;
+}
+
+
+static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
+{
+    ZPOS64_T ret;
+    ret = ftello64((FILE *)stream);
+    return ret;
+}
+
+static long ZCALLBACK fseek_file_func (voidpf  opaque, voidpf stream, uLong offset, int origin)
+{
+    int fseek_origin=0;
+    long ret;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        fseek_origin = SEEK_CUR;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        fseek_origin = SEEK_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        fseek_origin = SEEK_SET;
+        break;
+    default: return -1;
+    }
+    ret = 0;
+    if (fseek((FILE *)stream, offset, fseek_origin) != 0)
+        ret = -1;
+    return ret;
+}
+
+static long ZCALLBACK fseek64_file_func (voidpf  opaque, voidpf stream, ZPOS64_T offset, int origin)
+{
+    int fseek_origin=0;
+    long ret;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        fseek_origin = SEEK_CUR;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        fseek_origin = SEEK_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        fseek_origin = SEEK_SET;
+        break;
+    default: return -1;
+    }
+    ret = 0;
+
+    if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
+                        ret = -1;
+
+    return ret;
+}
+
+
+static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
+{
+    int ret;
+    ret = fclose((FILE *)stream);
+    return ret;
+}
+
+static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
+{
+    int ret;
+    ret = ferror((FILE *)stream);
+    return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+  zlib_filefunc_def* pzlib_filefunc_def;
+{
+    pzlib_filefunc_def->zopen_file = fopen_file_func;
+    pzlib_filefunc_def->zread_file = fread_file_func;
+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+    pzlib_filefunc_def->ztell_file = ftell_file_func;
+    pzlib_filefunc_def->zseek_file = fseek_file_func;
+    pzlib_filefunc_def->zclose_file = fclose_file_func;
+    pzlib_filefunc_def->zerror_file = ferror_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_fopen64_filefunc (zlib_filefunc64_def*  pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = fopen64_file_func;
+    pzlib_filefunc_def->zread_file = fread_file_func;
+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+    pzlib_filefunc_def->ztell64_file = ftell64_file_func;
+    pzlib_filefunc_def->zseek64_file = fseek64_file_func;
+    pzlib_filefunc_def->zclose_file = fclose_file_func;
+    pzlib_filefunc_def->zerror_file = ferror_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/8.x/zlib/contrib/minizip/ioapi.h b/8.x/zlib/contrib/minizip/ioapi.h
new file mode 100644 (file)
index 0000000..8309c4c
--- /dev/null
@@ -0,0 +1,200 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         Changes
+
+    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
+    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
+               More if/def section may be needed to support other platforms
+    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
+                          (but you should use iowin32.c for windows instead)
+
+*/
+
+#ifndef _ZLIBIOAPI64_H
+#define _ZLIBIOAPI64_H
+
+#if (!defined(_WIN32)) && (!defined(WIN32))
+
+  // Linux needs this to support file operation on files larger then 4+GB
+  // But might need better if/def to select just the platforms that needs them.
+
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zlib.h"
+
+#if defined(USE_FILE32API)
+#define fopen64 fopen
+#define ftello64 ftell
+#define fseeko64 fseek
+#else
+#ifdef _MSC_VER
+ #define fopen64 fopen
+ #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
+  #define ftello64 _ftelli64
+  #define fseeko64 _fseeki64
+ #else // old MSC
+  #define ftello64 ftell
+  #define fseeko64 fseek
+ #endif
+#endif
+#endif
+
+/*
+#ifndef ZPOS64_T
+  #ifdef _WIN32
+                #define ZPOS64_T fpos_t
+  #else
+    #include <stdint.h>
+    #define ZPOS64_T uint64_t
+  #endif
+#endif
+*/
+
+#ifdef HAVE_MINIZIP64_CONF_H
+#include "mz64conf.h"
+#endif
+
+/* a type choosen by DEFINE */
+#ifdef HAVE_64BIT_INT_CUSTOM
+typedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;
+#else
+#ifdef HAS_STDINT_H
+#include "stdint.h"
+typedef uint64_t ZPOS64_T;
+#else
+
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 ZPOS64_T;
+#else
+typedef unsigned long long int ZPOS64_T;
+#endif
+#endif
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ      (1)
+#define ZLIB_FILEFUNC_MODE_WRITE     (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE   (8)
+
+
+#ifndef ZCALLBACK
+ #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+   #define ZCALLBACK CALLBACK
+ #else
+   #define ZCALLBACK
+ #endif
+#endif
+
+
+
+
+typedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));
+typedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));
+typedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));
+typedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+
+
+/* here is the "old" 32 bits structure structure */
+typedef struct zlib_filefunc_def_s
+{
+    open_file_func      zopen_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell_file_func      ztell_file;
+    seek_file_func      zseek_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc_def;
+
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
+typedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+typedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));
+
+typedef struct zlib_filefunc64_def_s
+{
+    open64_file_func    zopen64_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell64_file_func    ztell64_file;
+    seek64_file_func    zseek64_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc64_def;
+
+void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+/* now internal definition, only for zip.c and unzip.h */
+typedef struct zlib_filefunc64_32_def_s
+{
+    zlib_filefunc64_def zfile_func64;
+    open_file_func      zopen32_file;
+    tell_file_func      ztell32_file;
+    seek_file_func      zseek32_file;
+} zlib_filefunc64_32_def;
+
+
+#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))
+#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))
+//#define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
+//#define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))
+#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))
+
+voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
+long    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
+ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+
+void    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+
+#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))
+#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))
+#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/8.x/zlib/contrib/minizip/iowin32.c b/8.x/zlib/contrib/minizip/iowin32.c
new file mode 100644 (file)
index 0000000..6a2a883
--- /dev/null
@@ -0,0 +1,389 @@
+/* iowin32.c -- IO base function header for compress/uncompress .zip
+     Version 1.1, February 14h, 2010
+     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+     For more info read MiniZip_info.txt
+
+*/
+
+#include <stdlib.h>
+
+#include "zlib.h"
+#include "ioapi.h"
+#include "iowin32.h"
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
+#endif
+
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
+
+voidpf  ZCALLBACK win32_open_file_func  OF((voidpf opaque, const char* filename, int mode));
+uLong   ZCALLBACK win32_read_file_func  OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+uLong   ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+ZPOS64_T ZCALLBACK win32_tell64_file_func  OF((voidpf opaque, voidpf stream));
+long    ZCALLBACK win32_seek64_file_func  OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+int     ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream));
+int     ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream));
+
+typedef struct
+{
+    HANDLE hf;
+    int error;
+} WIN32FILE_IOWIN;
+
+
+static void win32_translate_open_mode(int mode,
+                                      DWORD* lpdwDesiredAccess,
+                                      DWORD* lpdwCreationDisposition,
+                                      DWORD* lpdwShareMode,
+                                      DWORD* lpdwFlagsAndAttributes)
+{
+    *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;
+
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+    {
+        *lpdwDesiredAccess = GENERIC_READ;
+        *lpdwCreationDisposition = OPEN_EXISTING;
+        *lpdwShareMode = FILE_SHARE_READ;
+    }
+    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+    {
+        *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+        *lpdwCreationDisposition = OPEN_EXISTING;
+    }
+    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+    {
+        *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+        *lpdwCreationDisposition = CREATE_ALWAYS;
+    }
+}
+
+static voidpf win32_build_iowin(HANDLE hFile)
+{
+    voidpf ret=NULL;
+
+    if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
+    {
+        WIN32FILE_IOWIN w32fiow;
+        w32fiow.hf = hFile;
+        w32fiow.error = 0;
+        ret = malloc(sizeof(WIN32FILE_IOWIN));
+
+        if (ret==NULL)
+            CloseHandle(hFile);
+        else
+            *((WIN32FILE_IOWIN*)ret) = w32fiow;
+    }
+    return ret;
+}
+
+voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode)
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = NULL;
+
+    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+    return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode)
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = NULL;
+
+    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+    return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode)
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = NULL;
+
+    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+    return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode)
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = NULL;
+
+    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+    return win32_build_iowin(hFile);
+}
+
+
+uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size)
+{
+    uLong ret=0;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+    if (hFile != NULL)
+    {
+        if (!ReadFile(hFile, buf, size, &ret, NULL))
+        {
+            DWORD dwErr = GetLastError();
+            if (dwErr == ERROR_HANDLE_EOF)
+                dwErr = 0;
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+        }
+    }
+
+    return ret;
+}
+
+
+uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size)
+{
+    uLong ret=0;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+    if (hFile != NULL)
+    {
+        if (!WriteFile(hFile, buf, size, &ret, NULL))
+        {
+            DWORD dwErr = GetLastError();
+            if (dwErr == ERROR_HANDLE_EOF)
+                dwErr = 0;
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+        }
+    }
+
+    return ret;
+}
+
+long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
+{
+    long ret=-1;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+    if (hFile != NULL)
+    {
+        DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+        if (dwSet == INVALID_SET_FILE_POINTER)
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = -1;
+        }
+        else
+            ret=(long)dwSet;
+    }
+    return ret;
+}
+
+ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)
+{
+    ZPOS64_T ret= (ZPOS64_T)-1;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream)->hf;
+
+    if (hFile)
+    {
+        LARGE_INTEGER li;
+        li.QuadPart = 0;
+        li.u.LowPart = SetFilePointer(hFile, li.u.LowPart, &li.u.HighPart, FILE_CURRENT);
+        if ( (li.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = (ZPOS64_T)-1;
+        }
+        else
+            ret=li.QuadPart;
+    }
+    return ret;
+}
+
+
+long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin)
+{
+    DWORD dwMoveMethod=0xFFFFFFFF;
+    HANDLE hFile = NULL;
+
+    long ret=-1;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        dwMoveMethod = FILE_CURRENT;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        dwMoveMethod = FILE_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        dwMoveMethod = FILE_BEGIN;
+        break;
+    default: return -1;
+    }
+
+    if (hFile != NULL)
+    {
+        DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
+        if (dwSet == INVALID_SET_FILE_POINTER)
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = -1;
+        }
+        else
+            ret=0;
+    }
+    return ret;
+}
+
+long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin)
+{
+    DWORD dwMoveMethod=0xFFFFFFFF;
+    HANDLE hFile = NULL;
+    long ret=-1;
+
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream)->hf;
+
+    switch (origin)
+    {
+        case ZLIB_FILEFUNC_SEEK_CUR :
+            dwMoveMethod = FILE_CURRENT;
+            break;
+        case ZLIB_FILEFUNC_SEEK_END :
+            dwMoveMethod = FILE_END;
+            break;
+        case ZLIB_FILEFUNC_SEEK_SET :
+            dwMoveMethod = FILE_BEGIN;
+            break;
+        default: return -1;
+    }
+
+    if (hFile)
+    {
+        LARGE_INTEGER* li = (LARGE_INTEGER*)&offset;
+        DWORD dwSet = SetFilePointer(hFile, li->u.LowPart, &li->u.HighPart, dwMoveMethod);
+        if (dwSet == INVALID_SET_FILE_POINTER)
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = -1;
+        }
+        else
+            ret=0;
+    }
+    return ret;
+}
+
+int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream)
+{
+    int ret=-1;
+
+    if (stream!=NULL)
+    {
+        HANDLE hFile;
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+        if (hFile != NULL)
+        {
+            CloseHandle(hFile);
+            ret=0;
+        }
+        free(stream);
+    }
+    return ret;
+}
+
+int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream)
+{
+    int ret=-1;
+    if (stream!=NULL)
+    {
+        ret = ((WIN32FILE_IOWIN*)stream) -> error;
+    }
+    return ret;
+}
+
+void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen_file = win32_open_file_func;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell_file = win32_tell_file_func;
+    pzlib_filefunc_def->zseek_file = win32_seek_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+
+void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+
+void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/8.x/zlib/contrib/minizip/iowin32.h b/8.x/zlib/contrib/minizip/iowin32.h
new file mode 100644 (file)
index 0000000..0ca0969
--- /dev/null
@@ -0,0 +1,28 @@
+/* iowin32.h -- IO base function header for compress/uncompress .zip
+     Version 1.1, February 14h, 2010
+     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+*/
+
+#include <windows.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def));
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/8.x/zlib/contrib/minizip/make_vms.com b/8.x/zlib/contrib/minizip/make_vms.com
new file mode 100644 (file)
index 0000000..9ac13a9
--- /dev/null
@@ -0,0 +1,25 @@
+$ if f$search("ioapi.h_orig") .eqs. "" then copy ioapi.h ioapi.h_orig
+$ open/write zdef vmsdefs.h
+$ copy sys$input: zdef
+$ deck
+#define unix
+#define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from
+#define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator
+#define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord
+#define Write_EndOfCentralDirectoryRecord Write_EoDRecord
+$ eod
+$ close zdef
+$ copy vmsdefs.h,ioapi.h_orig ioapi.h
+$ cc/include=[--]/prefix=all ioapi.c
+$ cc/include=[--]/prefix=all miniunz.c
+$ cc/include=[--]/prefix=all unzip.c
+$ cc/include=[--]/prefix=all minizip.c
+$ cc/include=[--]/prefix=all zip.c
+$ link miniunz,unzip,ioapi,[--]libz.olb/lib
+$ link minizip,zip,ioapi,[--]libz.olb/lib
+$ mcr []minizip test minizip_info.txt
+$ mcr []miniunz -l test.zip
+$ rename minizip_info.txt; minizip_info.txt_old
+$ mcr []miniunz test.zip
+$ delete test.zip;*
+$exit
diff --git a/8.x/zlib/contrib/minizip/miniunz.c b/8.x/zlib/contrib/minizip/miniunz.c
new file mode 100644 (file)
index 0000000..9ed009f
--- /dev/null
@@ -0,0 +1,648 @@
+/*
+   miniunz.c
+   Version 1.1, February 14h, 2010
+   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+#ifndef _WIN32
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef unix
+# include <unistd.h>
+# include <utime.h>
+#else
+# include <direct.h>
+# include <io.h>
+#endif
+
+#include "unzip.h"
+
+#define CASESENSITIVITY (0)
+#define WRITEBUFFERSIZE (8192)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+#define USEWIN32IOAPI
+#include "iowin32.h"
+#endif
+/*
+  mini unzip, demo of unzip package
+
+  usage :
+  Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
+
+  list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
+    if it exists
+*/
+
+
+/* change_file_date : change the date/time of a file
+    filename : the filename of the file where date/time must be modified
+    dosdate : the new date at the MSDos format (4 bytes)
+    tmu_date : the SAME new date at the tm_unz format */
+void change_file_date(filename,dosdate,tmu_date)
+    const char *filename;
+    uLong dosdate;
+    tm_unz tmu_date;
+{
+#ifdef _WIN32
+  HANDLE hFile;
+  FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
+
+  hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
+                      0,NULL,OPEN_EXISTING,0,NULL);
+  GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
+  DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
+  LocalFileTimeToFileTime(&ftLocal,&ftm);
+  SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
+  CloseHandle(hFile);
+#else
+#ifdef unix
+  struct utimbuf ut;
+  struct tm newdate;
+  newdate.tm_sec = tmu_date.tm_sec;
+  newdate.tm_min=tmu_date.tm_min;
+  newdate.tm_hour=tmu_date.tm_hour;
+  newdate.tm_mday=tmu_date.tm_mday;
+  newdate.tm_mon=tmu_date.tm_mon;
+  if (tmu_date.tm_year > 1900)
+      newdate.tm_year=tmu_date.tm_year - 1900;
+  else
+      newdate.tm_year=tmu_date.tm_year ;
+  newdate.tm_isdst=-1;
+
+  ut.actime=ut.modtime=mktime(&newdate);
+  utime(filename,&ut);
+#endif
+#endif
+}
+
+
+/* mymkdir and change_file_date are not 100 % portable
+   As I don't know well Unix, I wait feedback for the unix portion */
+
+int mymkdir(dirname)
+    const char* dirname;
+{
+    int ret=0;
+#ifdef _WIN32
+    ret = _mkdir(dirname);
+#else
+#ifdef unix
+    ret = mkdir (dirname,0775);
+#endif
+#endif
+    return ret;
+}
+
+int makedir (newdir)
+    char *newdir;
+{
+  char *buffer ;
+  char *p;
+  int  len = (int)strlen(newdir);
+
+  if (len <= 0)
+    return 0;
+
+  buffer = (char*)malloc(len+1);
+        if (buffer==NULL)
+        {
+                printf("Error allocating memory\n");
+                return UNZ_INTERNALERROR;
+        }
+  strcpy(buffer,newdir);
+
+  if (buffer[len-1] == '/') {
+    buffer[len-1] = '\0';
+  }
+  if (mymkdir(buffer) == 0)
+    {
+      free(buffer);
+      return 1;
+    }
+
+  p = buffer+1;
+  while (1)
+    {
+      char hold;
+
+      while(*p && *p != '\\' && *p != '/')
+        p++;
+      hold = *p;
+      *p = 0;
+      if ((mymkdir(buffer) == -1) && (errno == ENOENT))
+        {
+          printf("couldn't create directory %s\n",buffer);
+          free(buffer);
+          return 0;
+        }
+      if (hold == 0)
+        break;
+      *p++ = hold;
+    }
+  free(buffer);
+  return 1;
+}
+
+void do_banner()
+{
+    printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
+    printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
+}
+
+void do_help()
+{
+    printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
+           "  -e  Extract without pathname (junk paths)\n" \
+           "  -x  Extract with pathname\n" \
+           "  -v  list files\n" \
+           "  -l  list files\n" \
+           "  -d  directory to extract into\n" \
+           "  -o  overwrite files without prompting\n" \
+           "  -p  extract crypted file using password\n\n");
+}
+
+void Display64BitsSize(ZPOS64_T n, int size_char)
+{
+  /* to avoid compatibility problem , we do here the conversion */
+  char number[21];
+  int offset=19;
+  int pos_string = 19;
+  number[20]=0;
+  for (;;) {
+      number[offset]=(char)((n%10)+'0');
+      if (number[offset] != '0')
+          pos_string=offset;
+      n/=10;
+      if (offset==0)
+          break;
+      offset--;
+  }
+  {
+      int size_display_string = 19-pos_string;
+      while (size_char > size_display_string)
+      {
+          size_char--;
+          printf(" ");
+      }
+  }
+
+  printf("%s",&number[pos_string]);
+}
+
+int do_list(uf)
+    unzFile uf;
+{
+    uLong i;
+    unz_global_info64 gi;
+    int err;
+
+    err = unzGetGlobalInfo64(uf,&gi);
+    if (err!=UNZ_OK)
+        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+    printf("  Length  Method     Size Ratio   Date    Time   CRC-32     Name\n");
+    printf("  ------  ------     ---- -----   ----    ----   ------     ----\n");
+    for (i=0;i<gi.number_entry;i++)
+    {
+        char filename_inzip[256];
+        unz_file_info64 file_info;
+        uLong ratio=0;
+        const char *string_method;
+        char charCrypt=' ';
+        err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+        if (err!=UNZ_OK)
+        {
+            printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+            break;
+        }
+        if (file_info.uncompressed_size>0)
+            ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);
+
+        /* display a '*' if the file is crypted */
+        if ((file_info.flag & 1) != 0)
+            charCrypt='*';
+
+        if (file_info.compression_method==0)
+            string_method="Stored";
+        else
+        if (file_info.compression_method==Z_DEFLATED)
+        {
+            uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
+            if (iLevel==0)
+              string_method="Defl:N";
+            else if (iLevel==1)
+              string_method="Defl:X";
+            else if ((iLevel==2) || (iLevel==3))
+              string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
+        }
+        else
+        if (file_info.compression_method==Z_BZIP2ED)
+        {
+              string_method="BZip2 ";
+        }
+        else
+            string_method="Unkn. ";
+
+        Display64BitsSize(file_info.uncompressed_size,7);
+        printf("  %6s%c",string_method,charCrypt);
+        Display64BitsSize(file_info.compressed_size,7);
+        printf(" %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %s\n",
+                ratio,
+                (uLong)file_info.tmu_date.tm_mon + 1,
+                (uLong)file_info.tmu_date.tm_mday,
+                (uLong)file_info.tmu_date.tm_year % 100,
+                (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
+                (uLong)file_info.crc,filename_inzip);
+        if ((i+1)<gi.number_entry)
+        {
+            err = unzGoToNextFile(uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzGoToNextFile\n",err);
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+
+int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
+    unzFile uf;
+    const int* popt_extract_without_path;
+    int* popt_overwrite;
+    const char* password;
+{
+    char filename_inzip[256];
+    char* filename_withoutpath;
+    char* p;
+    int err=UNZ_OK;
+    FILE *fout=NULL;
+    void* buf;
+    uInt size_buf;
+
+    unz_file_info64 file_info;
+    uLong ratio=0;
+    err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+    if (err!=UNZ_OK)
+    {
+        printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+        return err;
+    }
+
+    size_buf = WRITEBUFFERSIZE;
+    buf = (void*)malloc(size_buf);
+    if (buf==NULL)
+    {
+        printf("Error allocating memory\n");
+        return UNZ_INTERNALERROR;
+    }
+
+    p = filename_withoutpath = filename_inzip;
+    while ((*p) != '\0')
+    {
+        if (((*p)=='/') || ((*p)=='\\'))
+            filename_withoutpath = p+1;
+        p++;
+    }
+
+    if ((*filename_withoutpath)=='\0')
+    {
+        if ((*popt_extract_without_path)==0)
+        {
+            printf("creating directory: %s\n",filename_inzip);
+            mymkdir(filename_inzip);
+        }
+    }
+    else
+    {
+        const char* write_filename;
+        int skip=0;
+
+        if ((*popt_extract_without_path)==0)
+            write_filename = filename_inzip;
+        else
+            write_filename = filename_withoutpath;
+
+        err = unzOpenCurrentFilePassword(uf,password);
+        if (err!=UNZ_OK)
+        {
+            printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
+        }
+
+        if (((*popt_overwrite)==0) && (err==UNZ_OK))
+        {
+            char rep=0;
+            FILE* ftestexist;
+            ftestexist = fopen64(write_filename,"rb");
+            if (ftestexist!=NULL)
+            {
+                fclose(ftestexist);
+                do
+                {
+                    char answer[128];
+                    int ret;
+
+                    printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
+                    ret = scanf("%1s",answer);
+                    if (ret != 1)
+                    {
+                       exit(EXIT_FAILURE);
+                    }
+                    rep = answer[0] ;
+                    if ((rep>='a') && (rep<='z'))
+                        rep -= 0x20;
+                }
+                while ((rep!='Y') && (rep!='N') && (rep!='A'));
+            }
+
+            if (rep == 'N')
+                skip = 1;
+
+            if (rep == 'A')
+                *popt_overwrite=1;
+        }
+
+        if ((skip==0) && (err==UNZ_OK))
+        {
+            fout=fopen64(write_filename,"wb");
+
+            /* some zipfile don't contain directory alone before file */
+            if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
+                                (filename_withoutpath!=(char*)filename_inzip))
+            {
+                char c=*(filename_withoutpath-1);
+                *(filename_withoutpath-1)='\0';
+                makedir(write_filename);
+                *(filename_withoutpath-1)=c;
+                fout=fopen64(write_filename,"wb");
+            }
+
+            if (fout==NULL)
+            {
+                printf("error opening %s\n",write_filename);
+            }
+        }
+
+        if (fout!=NULL)
+        {
+            printf(" extracting: %s\n",write_filename);
+
+            do
+            {
+                err = unzReadCurrentFile(uf,buf,size_buf);
+                if (err<0)
+                {
+                    printf("error %d with zipfile in unzReadCurrentFile\n",err);
+                    break;
+                }
+                if (err>0)
+                    if (fwrite(buf,err,1,fout)!=1)
+                    {
+                        printf("error in writing extracted file\n");
+                        err=UNZ_ERRNO;
+                        break;
+                    }
+            }
+            while (err>0);
+            if (fout)
+                    fclose(fout);
+
+            if (err==0)
+                change_file_date(write_filename,file_info.dosDate,
+                                 file_info.tmu_date);
+        }
+
+        if (err==UNZ_OK)
+        {
+            err = unzCloseCurrentFile (uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzCloseCurrentFile\n",err);
+            }
+        }
+        else
+            unzCloseCurrentFile(uf); /* don't lose the error */
+    }
+
+    free(buf);
+    return err;
+}
+
+
+int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
+    unzFile uf;
+    int opt_extract_without_path;
+    int opt_overwrite;
+    const char* password;
+{
+    uLong i;
+    unz_global_info64 gi;
+    int err;
+    FILE* fout=NULL;
+
+    err = unzGetGlobalInfo64(uf,&gi);
+    if (err!=UNZ_OK)
+        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+
+    for (i=0;i<gi.number_entry;i++)
+    {
+        if (do_extract_currentfile(uf,&opt_extract_without_path,
+                                      &opt_overwrite,
+                                      password) != UNZ_OK)
+            break;
+
+        if ((i+1)<gi.number_entry)
+        {
+            err = unzGoToNextFile(uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzGoToNextFile\n",err);
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
+    unzFile uf;
+    const char* filename;
+    int opt_extract_without_path;
+    int opt_overwrite;
+    const char* password;
+{
+    int err = UNZ_OK;
+    if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
+    {
+        printf("file %s not found in the zipfile\n",filename);
+        return 2;
+    }
+
+    if (do_extract_currentfile(uf,&opt_extract_without_path,
+                                      &opt_overwrite,
+                                      password) == UNZ_OK)
+        return 0;
+    else
+        return 1;
+}
+
+
+int main(argc,argv)
+    int argc;
+    char *argv[];
+{
+    const char *zipfilename=NULL;
+    const char *filename_to_extract=NULL;
+    const char *password=NULL;
+    char filename_try[MAXFILENAME+16] = "";
+    int i;
+    int ret_value=0;
+    int opt_do_list=0;
+    int opt_do_extract=1;
+    int opt_do_extract_withoutpath=0;
+    int opt_overwrite=0;
+    int opt_extractdir=0;
+    const char *dirname=NULL;
+    unzFile uf=NULL;
+
+    do_banner();
+    if (argc==1)
+    {
+        do_help();
+        return 0;
+    }
+    else
+    {
+        for (i=1;i<argc;i++)
+        {
+            if ((*argv[i])=='-')
+            {
+                const char *p=argv[i]+1;
+
+                while ((*p)!='\0')
+                {
+                    char c=*(p++);;
+                    if ((c=='l') || (c=='L'))
+                        opt_do_list = 1;
+                    if ((c=='v') || (c=='V'))
+                        opt_do_list = 1;
+                    if ((c=='x') || (c=='X'))
+                        opt_do_extract = 1;
+                    if ((c=='e') || (c=='E'))
+                        opt_do_extract = opt_do_extract_withoutpath = 1;
+                    if ((c=='o') || (c=='O'))
+                        opt_overwrite=1;
+                    if ((c=='d') || (c=='D'))
+                    {
+                        opt_extractdir=1;
+                        dirname=argv[i+1];
+                    }
+
+                    if (((c=='p') || (c=='P')) && (i+1<argc))
+                    {
+                        password=argv[i+1];
+                        i++;
+                    }
+                }
+            }
+            else
+            {
+                if (zipfilename == NULL)
+                    zipfilename = argv[i];
+                else if ((filename_to_extract==NULL) && (!opt_extractdir))
+                        filename_to_extract = argv[i] ;
+            }
+        }
+    }
+
+    if (zipfilename!=NULL)
+    {
+
+#        ifdef USEWIN32IOAPI
+        zlib_filefunc64_def ffunc;
+#        endif
+
+        strncpy(filename_try, zipfilename,MAXFILENAME-1);
+        /* strncpy doesnt append the trailing NULL, of the string is too long. */
+        filename_try[ MAXFILENAME ] = '\0';
+
+#        ifdef USEWIN32IOAPI
+        fill_win32_filefunc64A(&ffunc);
+        uf = unzOpen2_64(zipfilename,&ffunc);
+#        else
+        uf = unzOpen64(zipfilename);
+#        endif
+        if (uf==NULL)
+        {
+            strcat(filename_try,".zip");
+#            ifdef USEWIN32IOAPI
+            uf = unzOpen2_64(filename_try,&ffunc);
+#            else
+            uf = unzOpen64(filename_try);
+#            endif
+        }
+    }
+
+    if (uf==NULL)
+    {
+        printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
+        return 1;
+    }
+    printf("%s opened\n",filename_try);
+
+    if (opt_do_list==1)
+        ret_value = do_list(uf);
+    else if (opt_do_extract==1)
+    {
+#ifdef _WIN32
+        if (opt_extractdir && _chdir(dirname))
+#else
+        if (opt_extractdir && chdir(dirname))
+#endif
+        {
+          printf("Error changing into %s, aborting\n", dirname);
+          exit(-1);
+        }
+
+        if (filename_to_extract == NULL)
+            ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
+        else
+            ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
+    }
+
+    unzClose(uf);
+
+    return ret_value;
+}
diff --git a/8.x/zlib/contrib/minizip/minizip.c b/8.x/zlib/contrib/minizip/minizip.c
new file mode 100644 (file)
index 0000000..7a4fa5a
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+   minizip.c
+   Version 1.1, February 14h, 2010
+   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+
+#ifndef _WIN32
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef unix
+# include <unistd.h>
+# include <utime.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#else
+# include <direct.h>
+# include <io.h>
+#endif
+
+#include "zip.h"
+
+#ifdef _WIN32
+        #define USEWIN32IOAPI
+        #include "iowin32.h"
+#endif
+
+
+
+#define WRITEBUFFERSIZE (16384)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+uLong filetime(f, tmzip, dt)
+    char *f;                /* name of file to get info on */
+    tm_zip *tmzip;             /* return value: access, modific. and creation times */
+    uLong *dt;             /* dostime */
+{
+  int ret = 0;
+  {
+      FILETIME ftLocal;
+      HANDLE hFind;
+      WIN32_FIND_DATAA ff32;
+
+      hFind = FindFirstFileA(f,&ff32);
+      if (hFind != INVALID_HANDLE_VALUE)
+      {
+        FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
+        FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
+        FindClose(hFind);
+        ret = 1;
+      }
+  }
+  return ret;
+}
+#else
+#ifdef unix
+uLong filetime(f, tmzip, dt)
+    char *f;               /* name of file to get info on */
+    tm_zip *tmzip;         /* return value: access, modific. and creation times */
+    uLong *dt;             /* dostime */
+{
+  int ret=0;
+  struct stat s;        /* results of stat() */
+  struct tm* filedate;
+  time_t tm_t=0;
+
+  if (strcmp(f,"-")!=0)
+  {
+    char name[MAXFILENAME+1];
+    int len = strlen(f);
+    if (len > MAXFILENAME)
+      len = MAXFILENAME;
+
+    strncpy(name, f,MAXFILENAME-1);
+    /* strncpy doesnt append the trailing NULL, of the string is too long. */
+    name[ MAXFILENAME ] = '\0';
+
+    if (name[len - 1] == '/')
+      name[len - 1] = '\0';
+    /* not all systems allow stat'ing a file with / appended */
+    if (stat(name,&s)==0)
+    {
+      tm_t = s.st_mtime;
+      ret = 1;
+    }
+  }
+  filedate = localtime(&tm_t);
+
+  tmzip->tm_sec  = filedate->tm_sec;
+  tmzip->tm_min  = filedate->tm_min;
+  tmzip->tm_hour = filedate->tm_hour;
+  tmzip->tm_mday = filedate->tm_mday;
+  tmzip->tm_mon  = filedate->tm_mon ;
+  tmzip->tm_year = filedate->tm_year;
+
+  return ret;
+}
+#else
+uLong filetime(f, tmzip, dt)
+    char *f;                /* name of file to get info on */
+    tm_zip *tmzip;             /* return value: access, modific. and creation times */
+    uLong *dt;             /* dostime */
+{
+    return 0;
+}
+#endif
+#endif
+
+
+
+
+int check_exist_file(filename)
+    const char* filename;
+{
+    FILE* ftestexist;
+    int ret = 1;
+    ftestexist = fopen64(filename,"rb");
+    if (ftestexist==NULL)
+        ret = 0;
+    else
+        fclose(ftestexist);
+    return ret;
+}
+
+void do_banner()
+{
+    printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
+    printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
+}
+
+void do_help()
+{
+    printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
+           "  -o  Overwrite existing file.zip\n" \
+           "  -a  Append to existing file.zip\n" \
+           "  -0  Store only\n" \
+           "  -1  Compress faster\n" \
+           "  -9  Compress better\n\n" \
+           "  -j  exclude path. store only the file name.\n\n");
+}
+
+/* calculate the CRC32 of a file,
+   because to encrypt a file, we need known the CRC32 of the file before */
+int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
+{
+   unsigned long calculate_crc=0;
+   int err=ZIP_OK;
+   FILE * fin = fopen64(filenameinzip,"rb");
+   unsigned long size_read = 0;
+   unsigned long total_read = 0;
+   if (fin==NULL)
+   {
+       err = ZIP_ERRNO;
+   }
+
+    if (err == ZIP_OK)
+        do
+        {
+            err = ZIP_OK;
+            size_read = (int)fread(buf,1,size_buf,fin);
+            if (size_read < size_buf)
+                if (feof(fin)==0)
+            {
+                printf("error in reading %s\n",filenameinzip);
+                err = ZIP_ERRNO;
+            }
+
+            if (size_read>0)
+                calculate_crc = crc32(calculate_crc,buf,size_read);
+            total_read += size_read;
+
+        } while ((err == ZIP_OK) && (size_read>0));
+
+    if (fin)
+        fclose(fin);
+
+    *result_crc=calculate_crc;
+    printf("file %s crc %lx\n", filenameinzip, calculate_crc);
+    return err;
+}
+
+int isLargeFile(const char* filename)
+{
+  int largeFile = 0;
+  ZPOS64_T pos = 0;
+  FILE* pFile = fopen64(filename, "rb");
+
+  if(pFile != NULL)
+  {
+    int n = fseeko64(pFile, 0, SEEK_END);
+
+    pos = ftello64(pFile);
+
+                printf("File : %s is %lld bytes\n", filename, pos);
+
+    if(pos >= 0xffffffff)
+     largeFile = 1;
+
+                fclose(pFile);
+  }
+
+ return largeFile;
+}
+
+int main(argc,argv)
+    int argc;
+    char *argv[];
+{
+    int i;
+    int opt_overwrite=0;
+    int opt_compress_level=Z_DEFAULT_COMPRESSION;
+    int opt_exclude_path=0;
+    int zipfilenamearg = 0;
+    char filename_try[MAXFILENAME+16];
+    int zipok;
+    int err=0;
+    int size_buf=0;
+    void* buf=NULL;
+    const char* password=NULL;
+
+
+    do_banner();
+    if (argc==1)
+    {
+        do_help();
+        return 0;
+    }
+    else
+    {
+        for (i=1;i<argc;i++)
+        {
+            if ((*argv[i])=='-')
+            {
+                const char *p=argv[i]+1;
+
+                while ((*p)!='\0')
+                {
+                    char c=*(p++);;
+                    if ((c=='o') || (c=='O'))
+                        opt_overwrite = 1;
+                    if ((c=='a') || (c=='A'))
+                        opt_overwrite = 2;
+                    if ((c>='0') && (c<='9'))
+                        opt_compress_level = c-'0';
+                    if ((c=='j') || (c=='J'))
+                        opt_exclude_path = 1;
+
+                    if (((c=='p') || (c=='P')) && (i+1<argc))
+                    {
+                        password=argv[i+1];
+                        i++;
+                    }
+                }
+            }
+            else
+            {
+                if (zipfilenamearg == 0)
+                {
+                    zipfilenamearg = i ;
+                }
+            }
+        }
+    }
+
+    size_buf = WRITEBUFFERSIZE;
+    buf = (void*)malloc(size_buf);
+    if (buf==NULL)
+    {
+        printf("Error allocating memory\n");
+        return ZIP_INTERNALERROR;
+    }
+
+    if (zipfilenamearg==0)
+    {
+        zipok=0;
+    }
+    else
+    {
+        int i,len;
+        int dot_found=0;
+
+        zipok = 1 ;
+        strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
+        /* strncpy doesnt append the trailing NULL, of the string is too long. */
+        filename_try[ MAXFILENAME ] = '\0';
+
+        len=(int)strlen(filename_try);
+        for (i=0;i<len;i++)
+            if (filename_try[i]=='.')
+                dot_found=1;
+
+        if (dot_found==0)
+            strcat(filename_try,".zip");
+
+        if (opt_overwrite==2)
+        {
+            /* if the file don't exist, we not append file */
+            if (check_exist_file(filename_try)==0)
+                opt_overwrite=1;
+        }
+        else
+        if (opt_overwrite==0)
+            if (check_exist_file(filename_try)!=0)
+            {
+                char rep=0;
+                do
+                {
+                    char answer[128];
+                    int ret;
+                    printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
+                    ret = scanf("%1s",answer);
+                    if (ret != 1)
+                    {
+                       exit(EXIT_FAILURE);
+                    }
+                    rep = answer[0] ;
+                    if ((rep>='a') && (rep<='z'))
+                        rep -= 0x20;
+                }
+                while ((rep!='Y') && (rep!='N') && (rep!='A'));
+                if (rep=='N')
+                    zipok = 0;
+                if (rep=='A')
+                    opt_overwrite = 2;
+            }
+    }
+
+    if (zipok==1)
+    {
+        zipFile zf;
+        int errclose;
+#        ifdef USEWIN32IOAPI
+        zlib_filefunc64_def ffunc;
+        fill_win32_filefunc64A(&ffunc);
+        zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
+#        else
+        zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
+#        endif
+
+        if (zf == NULL)
+        {
+            printf("error opening %s\n",filename_try);
+            err= ZIP_ERRNO;
+        }
+        else
+            printf("creating %s\n",filename_try);
+
+        for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
+        {
+            if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
+                  ((argv[i][1]=='o') || (argv[i][1]=='O') ||
+                   (argv[i][1]=='a') || (argv[i][1]=='A') ||
+                   (argv[i][1]=='p') || (argv[i][1]=='P') ||
+                   ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
+                  (strlen(argv[i]) == 2)))
+            {
+                FILE * fin;
+                int size_read;
+                const char* filenameinzip = argv[i];
+                const char *savefilenameinzip;
+                zip_fileinfo zi;
+                unsigned long crcFile=0;
+                int zip64 = 0;
+
+                zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
+                zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
+                zi.dosDate = 0;
+                zi.internal_fa = 0;
+                zi.external_fa = 0;
+                filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
+
+/*
+                err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
+                                 NULL,0,NULL,0,NULL / * comment * /,
+                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
+                                 opt_compress_level);
+*/
+                if ((password != NULL) && (err==ZIP_OK))
+                    err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
+
+                zip64 = isLargeFile(filenameinzip);
+
+                                                         /* The path name saved, should not include a leading slash. */
+               /*if it did, windows/xp and dynazip couldn't read the zip file. */
+                 savefilenameinzip = filenameinzip;
+                 while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
+                 {
+                     savefilenameinzip++;
+                 }
+
+                 /*should the zip file contain any path at all?*/
+                 if( opt_exclude_path )
+                 {
+                     const char *tmpptr;
+                     const char *lastslash = 0;
+                     for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
+                     {
+                         if( *tmpptr == '\\' || *tmpptr == '/')
+                         {
+                             lastslash = tmpptr;
+                         }
+                     }
+                     if( lastslash != NULL )
+                     {
+                         savefilenameinzip = lastslash+1; // base filename follows last slash.
+                     }
+                 }
+
+                 /**/
+                err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
+                                 NULL,0,NULL,0,NULL /* comment*/,
+                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
+                                 opt_compress_level,0,
+                                 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 password,crcFile, zip64);
+
+                if (err != ZIP_OK)
+                    printf("error in opening %s in zipfile\n",filenameinzip);
+                else
+                {
+                    fin = fopen64(filenameinzip,"rb");
+                    if (fin==NULL)
+                    {
+                        err=ZIP_ERRNO;
+                        printf("error in opening %s for reading\n",filenameinzip);
+                    }
+                }
+
+                if (err == ZIP_OK)
+                    do
+                    {
+                        err = ZIP_OK;
+                        size_read = (int)fread(buf,1,size_buf,fin);
+                        if (size_read < size_buf)
+                            if (feof(fin)==0)
+                        {
+                            printf("error in reading %s\n",filenameinzip);
+                            err = ZIP_ERRNO;
+                        }
+
+                        if (size_read>0)
+                        {
+                            err = zipWriteInFileInZip (zf,buf,size_read);
+                            if (err<0)
+                            {
+                                printf("error in writing %s in the zipfile\n",
+                                                 filenameinzip);
+                            }
+
+                        }
+                    } while ((err == ZIP_OK) && (size_read>0));
+
+                if (fin)
+                    fclose(fin);
+
+                if (err<0)
+                    err=ZIP_ERRNO;
+                else
+                {
+                    err = zipCloseFileInZip(zf);
+                    if (err!=ZIP_OK)
+                        printf("error in closing %s in the zipfile\n",
+                                    filenameinzip);
+                }
+            }
+        }
+        errclose = zipClose(zf,NULL);
+        if (errclose != ZIP_OK)
+            printf("error in closing %s\n",filename_try);
+    }
+    else
+    {
+       do_help();
+    }
+
+    free(buf);
+    return 0;
+}
diff --git a/8.x/zlib/contrib/minizip/mztools.c b/8.x/zlib/contrib/minizip/mztools.c
new file mode 100644 (file)
index 0000000..f9092e6
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+  Additional tools for Minizip
+  Code: Xavier Roche '2004
+  License: Same as ZLIB (www.gzip.org)
+*/
+
+/* Code */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+#include "unzip.h"
+
+#define READ_8(adr)  ((unsigned char)*(adr))
+#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
+#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
+
+#define WRITE_8(buff, n) do { \
+  *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
+} while(0)
+#define WRITE_16(buff, n) do { \
+  WRITE_8((unsigned char*)(buff), n); \
+  WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
+} while(0)
+#define WRITE_32(buff, n) do { \
+  WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
+  WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
+} while(0)
+
+extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
+const char* file;
+const char* fileOut;
+const char* fileOutTmp;
+uLong* nRecovered;
+uLong* bytesRecovered;
+{
+  int err = Z_OK;
+  FILE* fpZip = fopen(file, "rb");
+  FILE* fpOut = fopen(fileOut, "wb");
+  FILE* fpOutCD = fopen(fileOutTmp, "wb");
+  if (fpZip != NULL &&  fpOut != NULL) {
+    int entries = 0;
+    uLong totalBytes = 0;
+    char header[30];
+    char filename[256];
+    char extra[1024];
+    int offset = 0;
+    int offsetCD = 0;
+    while ( fread(header, 1, 30, fpZip) == 30 ) {
+      int currentOffset = offset;
+
+      /* File entry */
+      if (READ_32(header) == 0x04034b50) {
+        unsigned int version = READ_16(header + 4);
+        unsigned int gpflag = READ_16(header + 6);
+        unsigned int method = READ_16(header + 8);
+        unsigned int filetime = READ_16(header + 10);
+        unsigned int filedate = READ_16(header + 12);
+        unsigned int crc = READ_32(header + 14); /* crc */
+        unsigned int cpsize = READ_32(header + 18); /* compressed size */
+        unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
+        unsigned int fnsize = READ_16(header + 26); /* file name length */
+        unsigned int extsize = READ_16(header + 28); /* extra field length */
+        filename[0] = extra[0] = '\0';
+
+        /* Header */
+        if (fwrite(header, 1, 30, fpOut) == 30) {
+          offset += 30;
+        } else {
+          err = Z_ERRNO;
+          break;
+        }
+
+        /* Filename */
+        if (fnsize > 0) {
+          if (fread(filename, 1, fnsize, fpZip) == fnsize) {
+            if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
+              offset += fnsize;
+            } else {
+              err = Z_ERRNO;
+              break;
+            }
+          } else {
+            err = Z_ERRNO;
+            break;
+          }
+        } else {
+          err = Z_STREAM_ERROR;
+          break;
+        }
+
+        /* Extra field */
+        if (extsize > 0) {
+          if (fread(extra, 1, extsize, fpZip) == extsize) {
+            if (fwrite(extra, 1, extsize, fpOut) == extsize) {
+              offset += extsize;
+            } else {
+              err = Z_ERRNO;
+              break;
+            }
+          } else {
+            err = Z_ERRNO;
+            break;
+          }
+        }
+
+        /* Data */
+        {
+          int dataSize = cpsize;
+          if (dataSize == 0) {
+            dataSize = uncpsize;
+          }
+          if (dataSize > 0) {
+            char* data = malloc(dataSize);
+            if (data != NULL) {
+              if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
+                if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
+                  offset += dataSize;
+                  totalBytes += dataSize;
+                } else {
+                  err = Z_ERRNO;
+                }
+              } else {
+                err = Z_ERRNO;
+              }
+              free(data);
+              if (err != Z_OK) {
+                break;
+              }
+            } else {
+              err = Z_MEM_ERROR;
+              break;
+            }
+          }
+        }
+
+        /* Central directory entry */
+        {
+          char header[46];
+          char* comment = "";
+          int comsize = (int) strlen(comment);
+          WRITE_32(header, 0x02014b50);
+          WRITE_16(header + 4, version);
+          WRITE_16(header + 6, version);
+          WRITE_16(header + 8, gpflag);
+          WRITE_16(header + 10, method);
+          WRITE_16(header + 12, filetime);
+          WRITE_16(header + 14, filedate);
+          WRITE_32(header + 16, crc);
+          WRITE_32(header + 20, cpsize);
+          WRITE_32(header + 24, uncpsize);
+          WRITE_16(header + 28, fnsize);
+          WRITE_16(header + 30, extsize);
+          WRITE_16(header + 32, comsize);
+          WRITE_16(header + 34, 0);     /* disk # */
+          WRITE_16(header + 36, 0);     /* int attrb */
+          WRITE_32(header + 38, 0);     /* ext attrb */
+          WRITE_32(header + 42, currentOffset);
+          /* Header */
+          if (fwrite(header, 1, 46, fpOutCD) == 46) {
+            offsetCD += 46;
+
+            /* Filename */
+            if (fnsize > 0) {
+              if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
+                offsetCD += fnsize;
+              } else {
+                err = Z_ERRNO;
+                break;
+              }
+            } else {
+              err = Z_STREAM_ERROR;
+              break;
+            }
+
+            /* Extra field */
+            if (extsize > 0) {
+              if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
+                offsetCD += extsize;
+              } else {
+                err = Z_ERRNO;
+                break;
+              }
+            }
+
+            /* Comment field */
+            if (comsize > 0) {
+              if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
+                offsetCD += comsize;
+              } else {
+                err = Z_ERRNO;
+                break;
+              }
+            }
+
+
+          } else {
+            err = Z_ERRNO;
+            break;
+          }
+        }
+
+        /* Success */
+        entries++;
+
+      } else {
+        break;
+      }
+    }
+
+    /* Final central directory  */
+    {
+      int entriesZip = entries;
+      char header[22];
+      char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
+      int comsize = (int) strlen(comment);
+      if (entriesZip > 0xffff) {
+        entriesZip = 0xffff;
+      }
+      WRITE_32(header, 0x06054b50);
+      WRITE_16(header + 4, 0);    /* disk # */
+      WRITE_16(header + 6, 0);    /* disk # */
+      WRITE_16(header + 8, entriesZip);   /* hack */
+      WRITE_16(header + 10, entriesZip);  /* hack */
+      WRITE_32(header + 12, offsetCD);    /* size of CD */
+      WRITE_32(header + 16, offset);      /* offset to CD */
+      WRITE_16(header + 20, comsize);     /* comment */
+
+      /* Header */
+      if (fwrite(header, 1, 22, fpOutCD) == 22) {
+
+        /* Comment field */
+        if (comsize > 0) {
+          if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
+            err = Z_ERRNO;
+          }
+        }
+
+      } else {
+        err = Z_ERRNO;
+      }
+    }
+
+    /* Final merge (file + central directory) */
+    fclose(fpOutCD);
+    if (err == Z_OK) {
+      fpOutCD = fopen(fileOutTmp, "rb");
+      if (fpOutCD != NULL) {
+        int nRead;
+        char buffer[8192];
+        while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
+          if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
+            err = Z_ERRNO;
+            break;
+          }
+        }
+        fclose(fpOutCD);
+      }
+    }
+
+    /* Close */
+    fclose(fpZip);
+    fclose(fpOut);
+
+    /* Wipe temporary file */
+    (void)remove(fileOutTmp);
+
+    /* Number of recovered entries */
+    if (err == Z_OK) {
+      if (nRecovered != NULL) {
+        *nRecovered = entries;
+      }
+      if (bytesRecovered != NULL) {
+        *bytesRecovered = totalBytes;
+      }
+    }
+  } else {
+    err = Z_STREAM_ERROR;
+  }
+  return err;
+}
diff --git a/8.x/zlib/contrib/minizip/mztools.h b/8.x/zlib/contrib/minizip/mztools.h
new file mode 100644 (file)
index 0000000..88b3459
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+  Additional tools for Minizip
+  Code: Xavier Roche '2004
+  License: Same as ZLIB (www.gzip.org)
+*/
+
+#ifndef _zip_tools_H
+#define _zip_tools_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#include "unzip.h"
+
+/* Repair a ZIP file (missing central directory)
+   file: file to recover
+   fileOut: output file after recovery
+   fileOutTmp: temporary file name used for recovery
+*/
+extern int ZEXPORT unzRepair(const char* file,
+                             const char* fileOut,
+                             const char* fileOutTmp,
+                             uLong* nRecovered,
+                             uLong* bytesRecovered);
+
+#endif
diff --git a/8.x/zlib/contrib/minizip/unzip.c b/8.x/zlib/contrib/minizip/unzip.c
new file mode 100644 (file)
index 0000000..7617f41
--- /dev/null
@@ -0,0 +1,2125 @@
+/* unzip.c -- IO for uncompress .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+
+  ------------------------------------------------------------------------------------
+  Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
+  compatibility with older software. The following is from the original crypt.c.
+  Code woven in by Terry Thorsen 1/2003.
+
+  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  (the contents of which are also included in zip.h) for terms of use.
+  If, for some reason, all these files are missing, the Info-ZIP license
+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
+
+        crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
+
+  The encryption/decryption parts of this source code (as opposed to the
+  non-echoing password parts) were originally written in Europe.  The
+  whole source package can be freely distributed, including from the USA.
+  (Prior to January 2000, re-export from the US was a violation of US law.)
+
+        This encryption code is a direct transcription of the algorithm from
+  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
+  file (appnote.txt) is distributed with the PKZIP program (even in the
+  version without encryption capabilities).
+
+        ------------------------------------------------------------------------------------
+
+        Changes in unzip.c
+
+        2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
+  2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
+  2007-2008 - Even Rouault - Remove old C style function prototypes
+  2007-2008 - Even Rouault - Add unzip support for ZIP64
+
+        Copyright (C) 2007-2008 Even Rouault
+
+
+        Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
+  Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
+                                should only read the compressed/uncompressed size from the Zip64 format if
+                                the size from normal header was 0xFFFFFFFF
+  Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
+        Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
+                                Patch created by Daniel Borca
+
+  Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+  Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef NOUNCRYPT
+        #define NOUNCRYPT
+#endif
+
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+#ifndef CASESENSITIVITYDEFAULT_NO
+#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
+#    define CASESENSITIVITYDEFAULT_NO
+#  endif
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+const char unz_copyright[] =
+   " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info64_internal_s
+{
+    ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
+} unz_file_info64_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+    when reading and decompress it */
+typedef struct
+{
+    char  *read_buffer;         /* internal buffer for compressed data */
+    z_stream stream;            /* zLib stream structure for inflate */
+
+#ifdef HAVE_BZIP2
+    bz_stream bstream;          /* bzLib stream structure for bziped */
+#endif
+
+    ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
+    uLong stream_initialised;   /* flag set if stream structure is initialised*/
+
+    ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
+    uInt  size_local_extrafield;/* size of the local extra field */
+    ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/
+    ZPOS64_T total_out_64;
+
+    uLong crc32;                /* crc32 of all data uncompressed */
+    uLong crc32_wait;           /* crc32 we must obtain after decompress all */
+    ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
+    ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+    zlib_filefunc64_32_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    uLong compression_method;   /* compression method (0==store) */
+    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+    int   raw;
+} file_in_zip64_read_info_s;
+
+
+/* unz64_s contain internal information about the zipfile
+*/
+typedef struct
+{
+    zlib_filefunc64_32_def z_filefunc;
+    int is64bitOpenFunction;
+    voidpf filestream;        /* io structore of the zipfile */
+    unz_global_info64 gi;       /* public global information */
+    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+    ZPOS64_T num_file;             /* number of the current file in the zipfile*/
+    ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/
+    ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/
+    ZPOS64_T central_pos;          /* position of the beginning of the central dir*/
+
+    ZPOS64_T size_central_dir;     /* size of the central directory  */
+    ZPOS64_T offset_central_dir;   /* offset of start of central directory with
+                                   respect to the starting disk number */
+
+    unz_file_info64 cur_file_info; /* public info about the current file in zip*/
+    unz_file_info64_internal cur_file_info_internal; /* private info about it*/
+    file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
+                                        file if we are decompressing it */
+    int encrypted;
+
+    int isZip64;
+
+#    ifndef NOUNCRYPT
+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
+    const unsigned long* pcrc_32_tab;
+#    endif
+} unz64_s;
+
+
+#ifndef NOUNCRYPT
+#include "crypt.h"
+#endif
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+
+
+local int unz64local_getByte OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream,
+    int *pi));
+
+local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
+{
+    unsigned char c;
+    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return UNZ_OK;
+    }
+    else
+    {
+        if (ZERROR64(*pzlib_filefunc_def,filestream))
+            return UNZ_ERRNO;
+        else
+            return UNZ_EOF;
+    }
+}
+
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int unz64local_getShort OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream,
+    uLong *pX));
+
+local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                             voidpf filestream,
+                             uLong *pX)
+{
+    uLong x ;
+    int i = 0;
+    int err;
+
+    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int unz64local_getLong OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream,
+    uLong *pX));
+
+local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                            voidpf filestream,
+                            uLong *pX)
+{
+    uLong x ;
+    int i = 0;
+    int err;
+
+    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((uLong)i)<<16;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<24;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int unz64local_getLong64 OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream,
+    ZPOS64_T *pX));
+
+
+local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                            voidpf filestream,
+                            ZPOS64_T *pX)
+{
+    ZPOS64_T x ;
+    int i = 0;
+    int err;
+
+    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (ZPOS64_T)i;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<8;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<16;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<24;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<32;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<40;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<48;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<56;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
+{
+    for (;;)
+    {
+        char c1=*(fileName1++);
+        char c2=*(fileName2++);
+        if ((c1>='a') && (c1<='z'))
+            c1 -= 0x20;
+        if ((c2>='a') && (c2<='z'))
+            c2 -= 0x20;
+        if (c1=='\0')
+            return ((c2=='\0') ? 0 : -1);
+        if (c2=='\0')
+            return 1;
+        if (c1<c2)
+            return -1;
+        if (c1>c2)
+            return 1;
+    }
+}
+
+
+#ifdef  CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+        (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,
+                                                 const char*  fileName2,
+                                                 int iCaseSensitivity)
+
+{
+    if (iCaseSensitivity==0)
+        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+    if (iCaseSensitivity==1)
+        return strcmp(fileName1,fileName2);
+
+    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+
+/*
+  Locate the Central directory of a zipfile (at the end, just before
+    the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+    unsigned char* buf;
+    ZPOS64_T uSizeFile;
+    ZPOS64_T uBackRead;
+    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+    ZPOS64_T uPosFound=0;
+
+    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+        return 0;
+
+
+    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+    if (uMaxBack>uSizeFile)
+        uMaxBack = uSizeFile;
+
+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+    if (buf==NULL)
+        return 0;
+
+    uBackRead = 4;
+    while (uBackRead<uMaxBack)
+    {
+        uLong uReadSize;
+        ZPOS64_T uReadPos ;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            uBackRead = uMaxBack;
+        else
+            uBackRead+=BUFREADCOMMENT;
+        uReadPos = uSizeFile-uBackRead ;
+
+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            break;
+
+        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+            break;
+
+        for (i=(int)uReadSize-3; (i--)>0;)
+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+            {
+                uPosFound = uReadPos+i;
+                break;
+            }
+
+        if (uPosFound!=0)
+            break;
+    }
+    TRYFREE(buf);
+    return uPosFound;
+}
+
+
+/*
+  Locate the Central directory 64 of a zipfile (at the end, just before
+    the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir64 OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream));
+
+local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                                      voidpf filestream)
+{
+    unsigned char* buf;
+    ZPOS64_T uSizeFile;
+    ZPOS64_T uBackRead;
+    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+    ZPOS64_T uPosFound=0;
+    uLong uL;
+                ZPOS64_T relativeOffset;
+
+    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+        return 0;
+
+
+    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+    if (uMaxBack>uSizeFile)
+        uMaxBack = uSizeFile;
+
+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+    if (buf==NULL)
+        return 0;
+
+    uBackRead = 4;
+    while (uBackRead<uMaxBack)
+    {
+        uLong uReadSize;
+        ZPOS64_T uReadPos;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            uBackRead = uMaxBack;
+        else
+            uBackRead+=BUFREADCOMMENT;
+        uReadPos = uSizeFile-uBackRead ;
+
+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            break;
+
+        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+            break;
+
+        for (i=(int)uReadSize-3; (i--)>0;)
+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+                ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+            {
+                uPosFound = uReadPos+i;
+                break;
+            }
+
+        if (uPosFound!=0)
+            break;
+    }
+    TRYFREE(buf);
+    if (uPosFound == 0)
+        return 0;
+
+    /* Zip64 end of central directory locator */
+    if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return 0;
+
+    /* the signature, already checked */
+    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+        return 0;
+
+    /* number of the disk with the start of the zip64 end of  central directory */
+    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+        return 0;
+    if (uL != 0)
+        return 0;
+
+    /* relative offset of the zip64 end of central directory record */
+    if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
+        return 0;
+
+    /* total number of disks */
+    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+        return 0;
+    if (uL != 1)
+        return 0;
+
+    /* Goto end of central directory record */
+    if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return 0;
+
+     /* the signature */
+    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+        return 0;
+
+    if (uL != 0x06064b50)
+        return 0;
+
+    return relativeOffset;
+}
+
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
+     "zlib/zlib114.zip".
+     If the zipfile cannot be opened (file doesn't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+*/
+local unzFile unzOpenInternal (const void *path,
+                               zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
+                               int is64bitOpenFunction)
+{
+    unz64_s us;
+    unz64_s *s;
+    ZPOS64_T central_pos;
+    uLong   uL;
+
+    uLong number_disk;          /* number of the current dist, used for
+                                   spaning ZIP, unsupported, always 0*/
+    uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                                   for spaning ZIP, unsupported, always 0*/
+    ZPOS64_T number_entry_CD;      /* total number of entries in
+                                   the central dir
+                                   (same than number_entry on nospan) */
+
+    int err=UNZ_OK;
+
+    if (unz_copyright[0]!=' ')
+        return NULL;
+
+    us.z_filefunc.zseek32_file = NULL;
+    us.z_filefunc.ztell32_file = NULL;
+    if (pzlib_filefunc64_32_def==NULL)
+        fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
+    else
+        us.z_filefunc = *pzlib_filefunc64_32_def;
+    us.is64bitOpenFunction = is64bitOpenFunction;
+
+
+
+    us.filestream = ZOPEN64(us.z_filefunc,
+                                                 path,
+                                                 ZLIB_FILEFUNC_MODE_READ |
+                                                 ZLIB_FILEFUNC_MODE_EXISTING);
+    if (us.filestream==NULL)
+        return NULL;
+
+    central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
+    if (central_pos)
+    {
+        uLong uS;
+        ZPOS64_T uL64;
+
+        us.isZip64 = 1;
+
+        if (ZSEEK64(us.z_filefunc, us.filestream,
+                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        err=UNZ_ERRNO;
+
+        /* the signature, already checked */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* size of zip64 end of central directory record */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* version made by */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* version needed to extract */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* number of this disk */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* number of the disk with the start of the central directory */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* total number of entries in the central directory on this disk */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* total number of entries in the central directory */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        if ((number_entry_CD!=us.gi.number_entry) ||
+            (number_disk_with_CD!=0) ||
+            (number_disk!=0))
+            err=UNZ_BADZIPFILE;
+
+        /* size of the central directory */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* offset of start of central directory with respect to the
+          starting disk number */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        us.gi.size_comment = 0;
+    }
+    else
+    {
+        central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
+        if (central_pos==0)
+            err=UNZ_ERRNO;
+
+        us.isZip64 = 0;
+
+        if (ZSEEK64(us.z_filefunc, us.filestream,
+                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err=UNZ_ERRNO;
+
+        /* the signature, already checked */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* number of this disk */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* number of the disk with the start of the central directory */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* total number of entries in the central dir on this disk */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+        us.gi.number_entry = uL;
+
+        /* total number of entries in the central dir */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+        number_entry_CD = uL;
+
+        if ((number_entry_CD!=us.gi.number_entry) ||
+            (number_disk_with_CD!=0) ||
+            (number_disk!=0))
+            err=UNZ_BADZIPFILE;
+
+        /* size of the central directory */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+        us.size_central_dir = uL;
+
+        /* offset of start of central directory with respect to the
+            starting disk number */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+        us.offset_central_dir = uL;
+
+        /* zipfile comment length */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
+            err=UNZ_ERRNO;
+    }
+
+    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
+        (err==UNZ_OK))
+        err=UNZ_BADZIPFILE;
+
+    if (err!=UNZ_OK)
+    {
+        ZCLOSE64(us.z_filefunc, us.filestream);
+        return NULL;
+    }
+
+    us.byte_before_the_zipfile = central_pos -
+                            (us.offset_central_dir+us.size_central_dir);
+    us.central_pos = central_pos;
+    us.pfile_in_zip_read = NULL;
+    us.encrypted = 0;
+
+
+    s=(unz64_s*)ALLOC(sizeof(unz64_s));
+    if( s != NULL)
+    {
+        *s=us;
+        unzGoToFirstFile((unzFile)s);
+    }
+    return (unzFile)s;
+}
+
+
+extern unzFile ZEXPORT unzOpen2 (const char *path,
+                                        zlib_filefunc_def* pzlib_filefunc32_def)
+{
+    if (pzlib_filefunc32_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
+    }
+    else
+        return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen2_64 (const void *path,
+                                     zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    if (pzlib_filefunc_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
+    }
+    else
+        return unzOpenInternal(path, NULL, 1);
+}
+
+extern unzFile ZEXPORT unzOpen (const char *path)
+{
+    return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen64 (const void *path)
+{
+    return unzOpenInternal(path, NULL, 1);
+}
+
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (unzFile file)
+{
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    if (s->pfile_in_zip_read!=NULL)
+        unzCloseCurrentFile(file);
+
+    ZCLOSE64(s->z_filefunc, s->filestream);
+    TRYFREE(s);
+    return UNZ_OK;
+}
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
+{
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    *pglobal_info=s->gi;
+    return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
+{
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    /* to do : check if number_entry is not truncated */
+    pglobal_info32->number_entry = (uLong)s->gi.number_entry;
+    pglobal_info32->size_comment = s->gi.size_comment;
+    return UNZ_OK;
+}
+/*
+   Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
+{
+    ZPOS64_T uDate;
+    uDate = (ZPOS64_T)(ulDosDate>>16);
+    ptm->tm_mday = (uInt)(uDate&0x1f) ;
+    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
+    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+  Get Info about the current file in the zipfile, with internal only info
+*/
+local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
+                                                  unz_file_info64 *pfile_info,
+                                                  unz_file_info64_internal
+                                                  *pfile_info_internal,
+                                                  char *szFileName,
+                                                  uLong fileNameBufferSize,
+                                                  void *extraField,
+                                                  uLong extraFieldBufferSize,
+                                                  char *szComment,
+                                                  uLong commentBufferSize));
+
+local int unz64local_GetCurrentFileInfoInternal (unzFile file,
+                                                  unz_file_info64 *pfile_info,
+                                                  unz_file_info64_internal
+                                                  *pfile_info_internal,
+                                                  char *szFileName,
+                                                  uLong fileNameBufferSize,
+                                                  void *extraField,
+                                                  uLong extraFieldBufferSize,
+                                                  char *szComment,
+                                                  uLong commentBufferSize)
+{
+    unz64_s* s;
+    unz_file_info64 file_info;
+    unz_file_info64_internal file_info_internal;
+    int err=UNZ_OK;
+    uLong uMagic;
+    long lSeek=0;
+    uLong uL;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (ZSEEK64(s->z_filefunc, s->filestream,
+              s->pos_in_central_dir+s->byte_before_the_zipfile,
+              ZLIB_FILEFUNC_SEEK_SET)!=0)
+        err=UNZ_ERRNO;
+
+
+    /* we check the magic */
+    if (err==UNZ_OK)
+    {
+        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+            err=UNZ_ERRNO;
+        else if (uMagic!=0x02014b50)
+            err=UNZ_BADZIPFILE;
+    }
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+        err=UNZ_ERRNO;
+    file_info.compressed_size = uL;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+        err=UNZ_ERRNO;
+    file_info.uncompressed_size = uL;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+                // relative offset of local header
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+        err=UNZ_ERRNO;
+    file_info_internal.offset_curfile = uL;
+
+    lSeek+=file_info.size_filename;
+    if ((err==UNZ_OK) && (szFileName!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_filename<fileNameBufferSize)
+        {
+            *(szFileName+file_info.size_filename)='\0';
+            uSizeRead = file_info.size_filename;
+        }
+        else
+            uSizeRead = fileNameBufferSize;
+
+        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+            if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+        lSeek -= uSizeRead;
+    }
+
+    // Read extrafield
+    if ((err==UNZ_OK) && (extraField!=NULL))
+    {
+        ZPOS64_T uSizeRead ;
+        if (file_info.size_file_extra<extraFieldBufferSize)
+            uSizeRead = file_info.size_file_extra;
+        else
+            uSizeRead = extraFieldBufferSize;
+
+        if (lSeek!=0)
+        {
+            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+                lSeek=0;
+            else
+                err=UNZ_ERRNO;
+        }
+
+        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+            if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+
+        lSeek += file_info.size_file_extra - (uLong)uSizeRead;
+    }
+    else
+        lSeek += file_info.size_file_extra;
+
+
+    if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
+    {
+                                uLong acc = 0;
+
+        // since lSeek now points to after the extra field we need to move back
+        lSeek -= file_info.size_file_extra;
+
+        if (lSeek!=0)
+        {
+            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+                lSeek=0;
+            else
+                err=UNZ_ERRNO;
+        }
+
+        while(acc < file_info.size_file_extra)
+        {
+            uLong headerId;
+                                                uLong dataSize;
+
+            if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
+                err=UNZ_ERRNO;
+
+            if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
+                err=UNZ_ERRNO;
+
+            /* ZIP64 extra fields */
+            if (headerId == 0x0001)
+            {
+                                                        uLong uL;
+
+                                                                if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
+                                                                {
+                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+                                                                                        err=UNZ_ERRNO;
+                                                                }
+
+                                                                if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
+                                                                {
+                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+                                                                                  err=UNZ_ERRNO;
+                                                                }
+
+                                                                if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
+                                                                {
+                                                                        /* Relative Header offset */
+                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+                                                                                err=UNZ_ERRNO;
+                                                                }
+
+                                                                if(file_info.disk_num_start == (unsigned long)-1)
+                                                                {
+                                                                        /* Disk Start Number */
+                                                                        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+                                                                                err=UNZ_ERRNO;
+                                                                }
+
+            }
+            else
+            {
+                if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
+                    err=UNZ_ERRNO;
+            }
+
+            acc += 2 + 2 + dataSize;
+        }
+    }
+
+    if ((err==UNZ_OK) && (szComment!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_file_comment<commentBufferSize)
+        {
+            *(szComment+file_info.size_file_comment)='\0';
+            uSizeRead = file_info.size_file_comment;
+        }
+        else
+            uSizeRead = commentBufferSize;
+
+        if (lSeek!=0)
+        {
+            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+                lSeek=0;
+            else
+                err=UNZ_ERRNO;
+        }
+
+        if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+            if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+        lSeek+=file_info.size_file_comment - uSizeRead;
+    }
+    else
+        lSeek+=file_info.size_file_comment;
+
+
+    if ((err==UNZ_OK) && (pfile_info!=NULL))
+        *pfile_info=file_info;
+
+    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+        *pfile_info_internal=file_info_internal;
+
+    return err;
+}
+
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
+                                          unz_file_info64 * pfile_info,
+                                          char * szFileName, uLong fileNameBufferSize,
+                                          void *extraField, uLong extraFieldBufferSize,
+                                          char* szComment,  uLong commentBufferSize)
+{
+    return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+                                                szFileName,fileNameBufferSize,
+                                                extraField,extraFieldBufferSize,
+                                                szComment,commentBufferSize);
+}
+
+extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
+                                          unz_file_info * pfile_info,
+                                          char * szFileName, uLong fileNameBufferSize,
+                                          void *extraField, uLong extraFieldBufferSize,
+                                          char* szComment,  uLong commentBufferSize)
+{
+    int err;
+    unz_file_info64 file_info64;
+    err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
+                                                szFileName,fileNameBufferSize,
+                                                extraField,extraFieldBufferSize,
+                                                szComment,commentBufferSize);
+    if (err==UNZ_OK)
+    {
+        pfile_info->version = file_info64.version;
+        pfile_info->version_needed = file_info64.version_needed;
+        pfile_info->flag = file_info64.flag;
+        pfile_info->compression_method = file_info64.compression_method;
+        pfile_info->dosDate = file_info64.dosDate;
+        pfile_info->crc = file_info64.crc;
+
+        pfile_info->size_filename = file_info64.size_filename;
+        pfile_info->size_file_extra = file_info64.size_file_extra;
+        pfile_info->size_file_comment = file_info64.size_file_comment;
+
+        pfile_info->disk_num_start = file_info64.disk_num_start;
+        pfile_info->internal_fa = file_info64.internal_fa;
+        pfile_info->external_fa = file_info64.external_fa;
+
+        pfile_info->tmu_date = file_info64.tmu_date,
+
+
+        pfile_info->compressed_size = (uLong)file_info64.compressed_size;
+        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
+
+    }
+    return err;
+}
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (unzFile file)
+{
+    int err=UNZ_OK;
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    s->pos_in_central_dir=s->offset_central_dir;
+    s->num_file=0;
+    err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                             &s->cur_file_info_internal,
+                                             NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (unzFile  file)
+{
+    unz64_s* s;
+    int err;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
+      if (s->num_file+1==s->gi.number_entry)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+    s->num_file++;
+    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                               &s->cur_file_info_internal,
+                                               NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzipStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
+{
+    unz64_s* s;
+    int err;
+
+    /* We remember the 'current' position in the file so that we can jump
+     * back there if we fail.
+     */
+    unz_file_info64 cur_file_infoSaved;
+    unz_file_info64_internal cur_file_info_internalSaved;
+    ZPOS64_T num_fileSaved;
+    ZPOS64_T pos_in_central_dirSaved;
+
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+
+    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+        return UNZ_PARAMERROR;
+
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    /* Save the current state */
+    num_fileSaved = s->num_file;
+    pos_in_central_dirSaved = s->pos_in_central_dir;
+    cur_file_infoSaved = s->cur_file_info;
+    cur_file_info_internalSaved = s->cur_file_info_internal;
+
+    err = unzGoToFirstFile(file);
+
+    while (err == UNZ_OK)
+    {
+        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+        err = unzGetCurrentFileInfo64(file,NULL,
+                                    szCurrentFileName,sizeof(szCurrentFileName)-1,
+                                    NULL,0,NULL,0);
+        if (err == UNZ_OK)
+        {
+            if (unzStringFileNameCompare(szCurrentFileName,
+                                            szFileName,iCaseSensitivity)==0)
+                return UNZ_OK;
+            err = unzGoToNextFile(file);
+        }
+    }
+
+    /* We failed, so restore the state of the 'current file' to where we
+     * were.
+     */
+    s->num_file = num_fileSaved ;
+    s->pos_in_central_dir = pos_in_central_dirSaved ;
+    s->cur_file_info = cur_file_infoSaved;
+    s->cur_file_info_internal = cur_file_info_internalSaved;
+    return err;
+}
+
+
+/*
+///////////////////////////////////////////
+// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
+// I need random access
+//
+// Further optimization could be realized by adding an ability
+// to cache the directory in memory. The goal being a single
+// comprehensive file read to put the file I need in a memory.
+*/
+
+/*
+typedef struct unz_file_pos_s
+{
+    ZPOS64_T pos_in_zip_directory;   // offset in file
+    ZPOS64_T num_of_file;            // # of file
+} unz_file_pos;
+*/
+
+extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)
+{
+    unz64_s* s;
+
+    if (file==NULL || file_pos==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
+    file_pos->num_of_file           = s->num_file;
+
+    return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetFilePos(
+    unzFile file,
+    unz_file_pos* file_pos)
+{
+    unz64_file_pos file_pos64;
+    int err = unzGetFilePos64(file,&file_pos64);
+    if (err==UNZ_OK)
+    {
+        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
+        file_pos->num_of_file = (uLong)file_pos64.num_of_file;
+    }
+    return err;
+}
+
+extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
+{
+    unz64_s* s;
+    int err;
+
+    if (file==NULL || file_pos==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    /* jump to the right spot */
+    s->pos_in_central_dir = file_pos->pos_in_zip_directory;
+    s->num_file           = file_pos->num_of_file;
+
+    /* set the current file */
+    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                               &s->cur_file_info_internal,
+                                               NULL,0,NULL,0,NULL,0);
+    /* return results */
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+extern int ZEXPORT unzGoToFilePos(
+    unzFile file,
+    unz_file_pos* file_pos)
+{
+    unz64_file_pos file_pos64;
+    if (file_pos == NULL)
+        return UNZ_PARAMERROR;
+
+    file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
+    file_pos64.num_of_file = file_pos->num_of_file;
+    return unzGoToFilePos64(file,&file_pos64);
+}
+
+/*
+// Unzip Helper Functions - should be here?
+///////////////////////////////////////////
+*/
+
+/*
+  Read the local header of the current zipfile
+  Check the coherency of the local header and info in the end of central
+        directory about this file
+  store in *piSizeVar the size of extra info in local header
+        (filename and size of extra field data)
+*/
+local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
+                                                    ZPOS64_T * poffset_local_extrafield,
+                                                    uInt  * psize_local_extrafield)
+{
+    uLong uMagic,uData,uFlags;
+    uLong size_filename;
+    uLong size_extra_field;
+    int err=UNZ_OK;
+
+    *piSizeVar = 0;
+    *poffset_local_extrafield = 0;
+    *psize_local_extrafield = 0;
+
+    if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
+                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+
+    if (err==UNZ_OK)
+    {
+        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+            err=UNZ_ERRNO;
+        else if (uMagic!=0x04034b50)
+            err=UNZ_BADZIPFILE;
+    }
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+        err=UNZ_ERRNO;
+/*
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+        err=UNZ_BADZIPFILE;
+*/
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+        err=UNZ_BADZIPFILE;
+
+    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+                         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+                         (s->cur_file_info.compression_method!=Z_DEFLATED))
+        err=UNZ_BADZIPFILE;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
+        err=UNZ_ERRNO;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
+        err=UNZ_ERRNO;
+    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
+        err=UNZ_ERRNO;
+    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+        err=UNZ_BADZIPFILE;
+
+    *piSizeVar += (uInt)size_filename;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
+        err=UNZ_ERRNO;
+    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+                                    SIZEZIPLOCALHEADER + size_filename;
+    *psize_local_extrafield = (uInt)size_extra_field;
+
+    *piSizeVar += (uInt)size_extra_field;
+
+    return err;
+}
+
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
+                                            int* level, int raw, const char* password)
+{
+    int err=UNZ_OK;
+    uInt iSizeVar;
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */
+    uInt  size_local_extrafield;    /* size of the local extra field */
+#    ifndef NOUNCRYPT
+    char source[12];
+#    else
+    if (password != NULL)
+        return UNZ_PARAMERROR;
+#    endif
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_PARAMERROR;
+
+    if (s->pfile_in_zip_read != NULL)
+        unzCloseCurrentFile(file);
+
+    if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+        return UNZ_BADZIPFILE;
+
+    pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_INTERNALERROR;
+
+    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+    pfile_in_zip_read_info->pos_local_extrafield=0;
+    pfile_in_zip_read_info->raw=raw;
+
+    if (pfile_in_zip_read_info->read_buffer==NULL)
+    {
+        TRYFREE(pfile_in_zip_read_info);
+        return UNZ_INTERNALERROR;
+    }
+
+    pfile_in_zip_read_info->stream_initialised=0;
+
+    if (method!=NULL)
+        *method = (int)s->cur_file_info.compression_method;
+
+    if (level!=NULL)
+    {
+        *level = 6;
+        switch (s->cur_file_info.flag & 0x06)
+        {
+          case 6 : *level = 1; break;
+          case 4 : *level = 2; break;
+          case 2 : *level = 9; break;
+        }
+    }
+
+    if ((s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+        (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+        (s->cur_file_info.compression_method!=Z_DEFLATED))
+
+        err=UNZ_BADZIPFILE;
+
+    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+    pfile_in_zip_read_info->crc32=0;
+    pfile_in_zip_read_info->total_out_64=0;
+    pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
+    pfile_in_zip_read_info->filestream=s->filestream;
+    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
+    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+    pfile_in_zip_read_info->stream.total_out = 0;
+
+    if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
+    {
+#ifdef HAVE_BZIP2
+      pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
+      pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
+      pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->bstream.state = (voidpf)0;
+
+      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+      pfile_in_zip_read_info->stream.zfree = (free_func)0;
+      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+      pfile_in_zip_read_info->stream.avail_in = 0;
+
+      err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
+      if (err == Z_OK)
+        pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
+      else
+      {
+        TRYFREE(pfile_in_zip_read_info);
+        return err;
+      }
+#else
+      pfile_in_zip_read_info->raw=1;
+#endif
+    }
+    else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
+    {
+      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+      pfile_in_zip_read_info->stream.zfree = (free_func)0;
+      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->stream.next_in = 0;
+      pfile_in_zip_read_info->stream.avail_in = 0;
+
+      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+      if (err == Z_OK)
+        pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
+      else
+      {
+        TRYFREE(pfile_in_zip_read_info);
+        return err;
+      }
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END.
+         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
+         * size of both compressed and uncompressed data
+         */
+    }
+    pfile_in_zip_read_info->rest_read_compressed =
+            s->cur_file_info.compressed_size ;
+    pfile_in_zip_read_info->rest_read_uncompressed =
+            s->cur_file_info.uncompressed_size ;
+
+
+    pfile_in_zip_read_info->pos_in_zipfile =
+            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+              iSizeVar;
+
+    pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+    s->pfile_in_zip_read = pfile_in_zip_read_info;
+                s->encrypted = 0;
+
+#    ifndef NOUNCRYPT
+    if (password != NULL)
+    {
+        int i;
+        s->pcrc_32_tab = get_crc_table();
+        init_keys(password,s->keys,s->pcrc_32_tab);
+        if (ZSEEK64(s->z_filefunc, s->filestream,
+                  s->pfile_in_zip_read->pos_in_zipfile +
+                     s->pfile_in_zip_read->byte_before_the_zipfile,
+                  SEEK_SET)!=0)
+            return UNZ_INTERNALERROR;
+        if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
+            return UNZ_INTERNALERROR;
+
+        for (i = 0; i<12; i++)
+            zdecode(s->keys,s->pcrc_32_tab,source[i]);
+
+        s->pfile_in_zip_read->pos_in_zipfile+=12;
+        s->encrypted=1;
+    }
+#    endif
+
+
+    return UNZ_OK;
+}
+
+extern int ZEXPORT unzOpenCurrentFile (unzFile file)
+{
+    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
+}
+
+extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)
+{
+    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
+}
+
+extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
+{
+    return unzOpenCurrentFile3(file, method, level, raw, NULL);
+}
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
+{
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    s=(unz64_s*)file;
+    if (file==NULL)
+        return 0; //UNZ_PARAMERROR;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+    if (pfile_in_zip_read_info==NULL)
+        return 0; //UNZ_PARAMERROR;
+    return pfile_in_zip_read_info->pos_in_zipfile +
+                         pfile_in_zip_read_info->byte_before_the_zipfile;
+}
+
+/** Addition for GDAL : END */
+
+/*
+  Read bytes from the current file.
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)
+{
+    int err=UNZ_OK;
+    uInt iRead = 0;
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+
+    if ((pfile_in_zip_read_info->read_buffer == NULL))
+        return UNZ_END_OF_LIST_OF_FILE;
+    if (len==0)
+        return 0;
+
+    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+    pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+
+    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
+        (!(pfile_in_zip_read_info->raw)))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+    if ((len>pfile_in_zip_read_info->rest_read_compressed+
+           pfile_in_zip_read_info->stream.avail_in) &&
+         (pfile_in_zip_read_info->raw))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_compressed+
+            pfile_in_zip_read_info->stream.avail_in;
+
+    while (pfile_in_zip_read_info->stream.avail_out>0)
+    {
+        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+            (pfile_in_zip_read_info->rest_read_compressed>0))
+        {
+            uInt uReadThis = UNZ_BUFSIZE;
+            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+            if (uReadThis == 0)
+                return UNZ_EOF;
+            if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+                      pfile_in_zip_read_info->filestream,
+                      pfile_in_zip_read_info->pos_in_zipfile +
+                         pfile_in_zip_read_info->byte_before_the_zipfile,
+                         ZLIB_FILEFUNC_SEEK_SET)!=0)
+                return UNZ_ERRNO;
+            if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+                      pfile_in_zip_read_info->filestream,
+                      pfile_in_zip_read_info->read_buffer,
+                      uReadThis)!=uReadThis)
+                return UNZ_ERRNO;
+
+
+#            ifndef NOUNCRYPT
+            if(s->encrypted)
+            {
+                uInt i;
+                for(i=0;i<uReadThis;i++)
+                  pfile_in_zip_read_info->read_buffer[i] =
+                      zdecode(s->keys,s->pcrc_32_tab,
+                              pfile_in_zip_read_info->read_buffer[i]);
+            }
+#            endif
+
+
+            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+
+            pfile_in_zip_read_info->stream.next_in =
+                (Bytef*)pfile_in_zip_read_info->read_buffer;
+            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+        }
+
+        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
+        {
+            uInt uDoCopy,i ;
+
+            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+                (pfile_in_zip_read_info->rest_read_compressed == 0))
+                return (iRead==0) ? UNZ_EOF : iRead;
+
+            if (pfile_in_zip_read_info->stream.avail_out <
+                            pfile_in_zip_read_info->stream.avail_in)
+                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+            else
+                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+
+            for (i=0;i<uDoCopy;i++)
+                *(pfile_in_zip_read_info->stream.next_out+i) =
+                        *(pfile_in_zip_read_info->stream.next_in+i);
+
+            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
+
+            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+                                pfile_in_zip_read_info->stream.next_out,
+                                uDoCopy);
+            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+            pfile_in_zip_read_info->stream.next_out += uDoCopy;
+            pfile_in_zip_read_info->stream.next_in += uDoCopy;
+            pfile_in_zip_read_info->stream.total_out += uDoCopy;
+            iRead += uDoCopy;
+        }
+        else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
+        {
+#ifdef HAVE_BZIP2
+            uLong uTotalOutBefore,uTotalOutAfter;
+            const Bytef *bufBefore;
+            uLong uOutThis;
+
+            pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;
+            pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;
+            pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;
+            pfile_in_zip_read_info->bstream.total_in_hi32  = 0;
+            pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;
+            pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;
+            pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
+            pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
+
+            uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
+            bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
+
+            err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
+
+            uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
+            uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
+            pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
+            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+            pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
+            pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;
+            pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;
+            pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
+            pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
+            pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
+
+            if (err==BZ_STREAM_END)
+              return (iRead==0) ? UNZ_EOF : iRead;
+            if (err!=BZ_OK)
+              break;
+#endif
+        } // end Z_BZIP2ED
+        else
+        {
+            ZPOS64_T uTotalOutBefore,uTotalOutAfter;
+            const Bytef *bufBefore;
+            ZPOS64_T uOutThis;
+            int flush=Z_SYNC_FLUSH;
+
+            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+            bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+            /*
+            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+                     pfile_in_zip_read_info->stream.avail_out) &&
+                (pfile_in_zip_read_info->rest_read_compressed == 0))
+                flush = Z_FINISH;
+            */
+            err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
+              err = Z_DATA_ERROR;
+
+            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+            uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+            pfile_in_zip_read_info->crc32 =
+                crc32(pfile_in_zip_read_info->crc32,bufBefore,
+                        (uInt)(uOutThis));
+
+            pfile_in_zip_read_info->rest_read_uncompressed -=
+                uOutThis;
+
+            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+            if (err==Z_STREAM_END)
+                return (iRead==0) ? UNZ_EOF : iRead;
+            if (err!=Z_OK)
+                break;
+        }
+    }
+
+    if (err==Z_OK)
+        return iRead;
+    return err;
+}
+
+
+/*
+  Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (unzFile file)
+{
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
+{
+
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return (ZPOS64_T)-1;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return (ZPOS64_T)-1;
+
+    return pfile_in_zip_read_info->total_out_64;
+}
+
+
+/*
+  return 1 if the end of file was reached, 0 elsewhere
+*/
+extern int ZEXPORT unzeof (unzFile file)
+{
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+        return 1;
+    else
+        return 0;
+}
+
+
+
+/*
+Read extra field from the current file (opened by unzOpenCurrentFile)
+This is the local-header version of the extra field (sometimes, there is
+more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field that can be read
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+    buf.
+  the return value is the number of bytes copied in buf, or (if <0)
+    the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
+{
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    uInt read_now;
+    ZPOS64_T size_to_read;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
+                pfile_in_zip_read_info->pos_local_extrafield);
+
+    if (buf==NULL)
+        return (int)size_to_read;
+
+    if (len>size_to_read)
+        read_now = (uInt)size_to_read;
+    else
+        read_now = (uInt)len ;
+
+    if (read_now==0)
+        return 0;
+
+    if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+              pfile_in_zip_read_info->filestream,
+              pfile_in_zip_read_info->offset_local_extrafield +
+              pfile_in_zip_read_info->pos_local_extrafield,
+              ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+    if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+              pfile_in_zip_read_info->filestream,
+              buf,read_now)!=read_now)
+        return UNZ_ERRNO;
+
+    return (int)read_now;
+}
+
+/*
+  Close the file in zip opened with unzipOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (unzFile file)
+{
+    int err=UNZ_OK;
+
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+
+    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
+        (!pfile_in_zip_read_info->raw))
+    {
+        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+            err=UNZ_CRCERROR;
+    }
+
+
+    TRYFREE(pfile_in_zip_read_info->read_buffer);
+    pfile_in_zip_read_info->read_buffer = NULL;
+    if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
+        inflateEnd(&pfile_in_zip_read_info->stream);
+#ifdef HAVE_BZIP2
+    else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
+        BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
+#endif
+
+
+    pfile_in_zip_read_info->stream_initialised = 0;
+    TRYFREE(pfile_in_zip_read_info);
+
+    s->pfile_in_zip_read=NULL;
+
+    return err;
+}
+
+
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
+{
+    unz64_s* s;
+    uLong uReadThis ;
+    if (file==NULL)
+        return (int)UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    uReadThis = uSizeBuf;
+    if (uReadThis>s->gi.size_comment)
+        uReadThis = s->gi.size_comment;
+
+    if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+    if (uReadThis>0)
+    {
+      *szComment='\0';
+      if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
+        return UNZ_ERRNO;
+    }
+
+    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+        *(szComment+s->gi.size_comment)='\0';
+    return (int)uReadThis;
+}
+
+/* Additions by RX '2004 */
+extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
+{
+    unz64_s* s;
+
+    if (file==NULL)
+          return 0; //UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+      return 0;
+    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
+      if (s->num_file==s->gi.number_entry)
+         return 0;
+    return s->pos_in_central_dir;
+}
+
+extern uLong ZEXPORT unzGetOffset (unzFile file)
+{
+    ZPOS64_T offset64;
+
+    if (file==NULL)
+          return 0; //UNZ_PARAMERROR;
+    offset64 = unzGetOffset64(file);
+    return (uLong)offset64;
+}
+
+extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
+{
+    unz64_s* s;
+    int err;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    s->pos_in_central_dir = pos;
+    s->num_file = s->gi.number_entry;      /* hack */
+    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                              &s->cur_file_info_internal,
+                                              NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
+{
+    return unzSetOffset64(file,pos);
+}
diff --git a/8.x/zlib/contrib/minizip/unzip.h b/8.x/zlib/contrib/minizip/unzip.h
new file mode 100644 (file)
index 0000000..3183968
--- /dev/null
@@ -0,0 +1,437 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         ---------------------------------------------------------------------------------
+
+        Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  ---------------------------------------------------------------------------------
+
+        Changes
+
+        See header of unzip64.c
+
+*/
+
+#ifndef _unz64_H
+#define _unz64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef  _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK                          (0)
+#define UNZ_END_OF_LIST_OF_FILE         (-100)
+#define UNZ_ERRNO                       (Z_ERRNO)
+#define UNZ_EOF                         (0)
+#define UNZ_PARAMERROR                  (-102)
+#define UNZ_BADZIPFILE                  (-103)
+#define UNZ_INTERNALERROR               (-104)
+#define UNZ_CRCERROR                    (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+    uInt tm_sec;            /* seconds after the minute - [0,59] */
+    uInt tm_min;            /* minutes after the hour - [0,59] */
+    uInt tm_hour;           /* hours since midnight - [0,23] */
+    uInt tm_mday;           /* day of the month - [1,31] */
+    uInt tm_mon;            /* months since January - [0,11] */
+    uInt tm_year;           /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+   These data comes from the end of central dir */
+typedef struct unz_global_info64_s
+{
+    ZPOS64_T number_entry;         /* total number of entries in
+                                     the central dir on this disk */
+    uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info64;
+
+typedef struct unz_global_info_s
+{
+    uLong number_entry;         /* total number of entries in
+                                     the central dir on this disk */
+    uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info;
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info64_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    ZPOS64_T compressed_size;   /* compressed size                 8 bytes */
+    ZPOS64_T uncompressed_size; /* uncompressed size               8 bytes */
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info64;
+
+typedef struct unz_file_info_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    uLong compressed_size;      /* compressed size                 4 bytes */
+    uLong uncompressed_size;    /* uncompressed size               4 bytes */
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+                                                 const char* fileName2,
+                                                 int iCaseSensitivity));
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+    (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+extern unzFile ZEXPORT unzOpen64 OF((const void *path));
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+     "zlib/zlib113.zip".
+     If the zipfile cannot be opened (file don't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+     the "64" function take a const void* pointer, because the path is just the
+       value passed to the open64_file_func callback.
+     Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
+       is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
+       does not describe the reality
+*/
+
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+                                    zlib_filefunc_def* pzlib_filefunc_def));
+/*
+   Open a Zip file, like unzOpen, but provide a set of file low level API
+      for read/write the zip file (see ioapi.h)
+*/
+
+extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
+                                    zlib_filefunc64_def* pzlib_filefunc_def));
+/*
+   Open a Zip file, like unz64Open, but provide a set of file low level API
+      for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+                                        unz_global_info *pglobal_info));
+
+extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
+                                        unz_global_info64 *pglobal_info));
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+                                           char *szComment,
+                                           uLong uSizeBuf));
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+                     const char *szFileName,
+                     int iCaseSensitivity));
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+    uLong pos_in_zip_directory;   /* offset in zip file directory */
+    uLong num_of_file;            /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+typedef struct unz64_file_pos_s
+{
+    ZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */
+    ZPOS64_T num_of_file;            /* # of file */
+} unz64_file_pos;
+
+extern int ZEXPORT unzGetFilePos64(
+    unzFile file,
+    unz64_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos64(
+    unzFile file,
+    const unz64_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
+                         unz_file_info64 *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize));
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+                         unz_file_info *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize));
+/*
+  Get Info about the current file
+  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+        the current file
+  if szFileName!=NULL, the filemane string will be copied in szFileName
+            (fileNameBufferSize is the size of the buffer)
+  if extraField!=NULL, the extra field information will be copied in extraField
+            (extraFieldBufferSize is the size of the buffer).
+            This is the Central-header version of the extra field
+  if szComment!=NULL, the comment string of the file will be copied in szComment
+            (commentBufferSize is the size of the buffer)
+*/
+
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
+
+/** Addition for GDAL : END */
+
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+   from it, and close it (you can close it before reading all the file)
+   */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+                                                  const char* password));
+/*
+  Open for reading data the current file in the zipfile.
+  password is a crypting password
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw,
+                                           const char* password));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+  Close the file in zip opened with unzOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+                      voidp buf,
+                      unsigned len));
+/*
+  Read bytes from the current file (opened by unzOpenCurrentFile)
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+
+extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
+/*
+  Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+  return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+                                             voidp buf,
+                                             unsigned len));
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+    buf.
+  the return value is the number of bytes copied in buf, or (if <0)
+    the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz64_H */
diff --git a/8.x/zlib/contrib/minizip/zip.c b/8.x/zlib/contrib/minizip/zip.c
new file mode 100644 (file)
index 0000000..3c34fc8
--- /dev/null
@@ -0,0 +1,2004 @@
+/* zip.c -- IO on .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         Changes
+   Oct-2009 - Mathias Svensson - Remove old C style function prototypes
+   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
+   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
+   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
+                                 It is used when recreting zip archive with RAW when deleting items from a zip.
+                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
+   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
+   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "zlib.h"
+#include "zip.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#ifndef VERSIONMADEBY
+# define VERSIONMADEBY   (0x0) /* platform depedent */
+#endif
+
+#ifndef Z_BUFSIZE
+#define Z_BUFSIZE (64*1024) //(16384)
+#endif
+
+#ifndef Z_MAXFILENAMEINZIP
+#define Z_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+/*
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+*/
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+
+// NOT sure that this work on ALL platform
+#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
+
+#ifndef SEEK_CUR
+#define SEEK_CUR    1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END    2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET    0
+#endif
+
+#ifndef DEF_MEM_LEVEL
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+#endif
+const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+
+#define SIZEDATA_INDATABLOCK (4096-(4*4))
+
+#define LOCALHEADERMAGIC    (0x04034b50)
+#define CENTRALHEADERMAGIC  (0x02014b50)
+#define ENDHEADERMAGIC      (0x06054b50)
+#define ZIP64ENDHEADERMAGIC      (0x6064b50)
+#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
+
+#define FLAG_LOCALHEADER_OFFSET (0x06)
+#define CRC_LOCALHEADER_OFFSET  (0x0e)
+
+#define SIZECENTRALHEADER (0x2e) /* 46 */
+
+typedef struct linkedlist_datablock_internal_s
+{
+  struct linkedlist_datablock_internal_s* next_datablock;
+  uLong  avail_in_this_block;
+  uLong  filled_in_this_block;
+  uLong  unused; /* for future use and alignement */
+  unsigned char data[SIZEDATA_INDATABLOCK];
+} linkedlist_datablock_internal;
+
+typedef struct linkedlist_data_s
+{
+    linkedlist_datablock_internal* first_block;
+    linkedlist_datablock_internal* last_block;
+} linkedlist_data;
+
+
+typedef struct
+{
+    z_stream stream;            /* zLib stream structure for inflate */
+#ifdef HAVE_BZIP2
+    bz_stream bstream;          /* bzLib stream structure for bziped */
+#endif
+
+    int  stream_initialised;    /* 1 is stream is initialised */
+    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
+
+    ZPOS64_T pos_local_header;     /* offset of the local header of the file
+                                     currenty writing */
+    char* central_header;       /* central header data for the current file */
+    uLong size_centralExtra;
+    uLong size_centralheader;   /* size of the central header for cur file */
+    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
+    uLong flag;                 /* flag of the file currently writing */
+
+    int  method;                /* compression method of file currenty wr.*/
+    int  raw;                   /* 1 for directly writing raw data */
+    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
+    uLong dosDate;
+    uLong crc32;
+    int  encrypt;
+    int  zip64;               /* Add ZIP64 extened information in the extra field */
+    ZPOS64_T pos_zip64extrainfo;
+    ZPOS64_T totalCompressedData;
+    ZPOS64_T totalUncompressedData;
+#ifndef NOCRYPT
+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
+    const unsigned long* pcrc_32_tab;
+    int crypt_header_size;
+#endif
+} curfile64_info;
+
+typedef struct
+{
+    zlib_filefunc64_32_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    linkedlist_data central_dir;/* datablock with central dir in construction*/
+    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
+    curfile64_info ci;            /* info on the file curretly writing */
+
+    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
+    ZPOS64_T add_position_when_writting_offset;
+    ZPOS64_T number_entry;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+    char *globalcomment;
+#endif
+
+} zip64_internal;
+
+
+#ifndef NOCRYPT
+#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+#include "crypt.h"
+#endif
+
+local linkedlist_datablock_internal* allocate_new_datablock()
+{
+    linkedlist_datablock_internal* ldi;
+    ldi = (linkedlist_datablock_internal*)
+                 ALLOC(sizeof(linkedlist_datablock_internal));
+    if (ldi!=NULL)
+    {
+        ldi->next_datablock = NULL ;
+        ldi->filled_in_this_block = 0 ;
+        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
+    }
+    return ldi;
+}
+
+local void free_datablock(linkedlist_datablock_internal* ldi)
+{
+    while (ldi!=NULL)
+    {
+        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
+        TRYFREE(ldi);
+        ldi = ldinext;
+    }
+}
+
+local void init_linkedlist(linkedlist_data* ll)
+{
+    ll->first_block = ll->last_block = NULL;
+}
+
+local void free_linkedlist(linkedlist_data* ll)
+{
+    free_datablock(ll->first_block);
+    ll->first_block = ll->last_block = NULL;
+}
+
+
+local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
+{
+    linkedlist_datablock_internal* ldi;
+    const unsigned char* from_copy;
+
+    if (ll==NULL)
+        return ZIP_INTERNALERROR;
+
+    if (ll->last_block == NULL)
+    {
+        ll->first_block = ll->last_block = allocate_new_datablock();
+        if (ll->first_block == NULL)
+            return ZIP_INTERNALERROR;
+    }
+
+    ldi = ll->last_block;
+    from_copy = (unsigned char*)buf;
+
+    while (len>0)
+    {
+        uInt copy_this;
+        uInt i;
+        unsigned char* to_copy;
+
+        if (ldi->avail_in_this_block==0)
+        {
+            ldi->next_datablock = allocate_new_datablock();
+            if (ldi->next_datablock == NULL)
+                return ZIP_INTERNALERROR;
+            ldi = ldi->next_datablock ;
+            ll->last_block = ldi;
+        }
+
+        if (ldi->avail_in_this_block < len)
+            copy_this = (uInt)ldi->avail_in_this_block;
+        else
+            copy_this = (uInt)len;
+
+        to_copy = &(ldi->data[ldi->filled_in_this_block]);
+
+        for (i=0;i<copy_this;i++)
+            *(to_copy+i)=*(from_copy+i);
+
+        ldi->filled_in_this_block += copy_this;
+        ldi->avail_in_this_block -= copy_this;
+        from_copy += copy_this ;
+        len -= copy_this;
+    }
+    return ZIP_OK;
+}
+
+
+
+/****************************************************************************/
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+/* ===========================================================================
+   Inputs a long in LSB order to the given file
+   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
+*/
+
+local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
+local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
+{
+    unsigned char buf[8];
+    int n;
+    for (n = 0; n < nbByte; n++)
+    {
+        buf[n] = (unsigned char)(x & 0xff);
+        x >>= 8;
+    }
+    if (x != 0)
+      {     /* data overflow - hack for ZIP64 (X Roche) */
+      for (n = 0; n < nbByte; n++)
+        {
+          buf[n] = 0xff;
+        }
+      }
+
+    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
+        return ZIP_ERRNO;
+    else
+        return ZIP_OK;
+}
+
+local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
+local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
+{
+    unsigned char* buf=(unsigned char*)dest;
+    int n;
+    for (n = 0; n < nbByte; n++) {
+        buf[n] = (unsigned char)(x & 0xff);
+        x >>= 8;
+    }
+
+    if (x != 0)
+    {     /* data overflow - hack for ZIP64 */
+       for (n = 0; n < nbByte; n++)
+       {
+          buf[n] = 0xff;
+       }
+    }
+}
+
+/****************************************************************************/
+
+
+local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
+{
+    uLong year = (uLong)ptm->tm_year;
+    if (year>=1980)
+        year-=1980;
+    else if (year>=80)
+        year-=80;
+    return
+      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
+        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
+}
+
+
+/****************************************************************************/
+
+local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
+
+local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
+{
+    unsigned char c;
+    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return ZIP_OK;
+    }
+    else
+    {
+        if (ZERROR64(*pzlib_filefunc_def,filestream))
+            return ZIP_ERRNO;
+        else
+            return ZIP_EOF;
+    }
+}
+
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+    uLong x ;
+    int i = 0;
+    int err;
+
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==ZIP_OK)
+        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==ZIP_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+    uLong x ;
+    int i = 0;
+    int err;
+
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==ZIP_OK)
+        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==ZIP_OK)
+        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<16;
+
+    if (err==ZIP_OK)
+        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<24;
+
+    if (err==ZIP_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
+
+
+local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
+{
+  ZPOS64_T x;
+  int i = 0;
+  int err;
+
+  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x = (ZPOS64_T)i;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<8;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<16;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<24;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<32;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<40;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<48;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<56;
+
+  if (err==ZIP_OK)
+    *pX = x;
+  else
+    *pX = 0;
+
+  return err;
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+/*
+  Locate the Central directory of a zipfile (at the end, just before
+    the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+  unsigned char* buf;
+  ZPOS64_T uSizeFile;
+  ZPOS64_T uBackRead;
+  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+  ZPOS64_T uPosFound=0;
+
+  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+    return 0;
+
+
+  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+  if (uMaxBack>uSizeFile)
+    uMaxBack = uSizeFile;
+
+  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+  if (buf==NULL)
+    return 0;
+
+  uBackRead = 4;
+  while (uBackRead<uMaxBack)
+  {
+    uLong uReadSize;
+    ZPOS64_T uReadPos ;
+    int i;
+    if (uBackRead+BUFREADCOMMENT>uMaxBack)
+      uBackRead = uMaxBack;
+    else
+      uBackRead+=BUFREADCOMMENT;
+    uReadPos = uSizeFile-uBackRead ;
+
+    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+      break;
+
+    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+      break;
+
+    for (i=(int)uReadSize-3; (i--)>0;)
+      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+      {
+        uPosFound = uReadPos+i;
+        break;
+      }
+
+      if (uPosFound!=0)
+        break;
+  }
+  TRYFREE(buf);
+  return uPosFound;
+}
+
+/*
+Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
+the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+  unsigned char* buf;
+  ZPOS64_T uSizeFile;
+  ZPOS64_T uBackRead;
+  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+  ZPOS64_T uPosFound=0;
+  uLong uL;
+  ZPOS64_T relativeOffset;
+
+  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+    return 0;
+
+  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+  if (uMaxBack>uSizeFile)
+    uMaxBack = uSizeFile;
+
+  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+  if (buf==NULL)
+    return 0;
+
+  uBackRead = 4;
+  while (uBackRead<uMaxBack)
+  {
+    uLong uReadSize;
+    ZPOS64_T uReadPos;
+    int i;
+    if (uBackRead+BUFREADCOMMENT>uMaxBack)
+      uBackRead = uMaxBack;
+    else
+      uBackRead+=BUFREADCOMMENT;
+    uReadPos = uSizeFile-uBackRead ;
+
+    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+      break;
+
+    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+      break;
+
+    for (i=(int)uReadSize-3; (i--)>0;)
+    {
+      // Signature "0x07064b50" Zip64 end of central directory locater
+      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+      {
+        uPosFound = uReadPos+i;
+        break;
+      }
+    }
+
+      if (uPosFound!=0)
+        break;
+  }
+
+  TRYFREE(buf);
+  if (uPosFound == 0)
+    return 0;
+
+  /* Zip64 end of central directory locator */
+  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+    return 0;
+
+  /* the signature, already checked */
+  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+    return 0;
+
+  /* number of the disk with the start of the zip64 end of  central directory */
+  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+    return 0;
+  if (uL != 0)
+    return 0;
+
+  /* relative offset of the zip64 end of central directory record */
+  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
+    return 0;
+
+  /* total number of disks */
+  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+    return 0;
+  if (uL != 1)
+    return 0;
+
+  /* Goto Zip64 end of central directory record */
+  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+    return 0;
+
+  /* the signature */
+  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+    return 0;
+
+  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
+    return 0;
+
+  return relativeOffset;
+}
+
+int LoadCentralDirectoryRecord(zip64_internal* pziinit)
+{
+  int err=ZIP_OK;
+  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+
+  ZPOS64_T size_central_dir;     /* size of the central directory  */
+  ZPOS64_T offset_central_dir;   /* offset of start of central directory */
+  ZPOS64_T central_pos;
+  uLong uL;
+
+  uLong number_disk;          /* number of the current dist, used for
+                              spaning ZIP, unsupported, always 0*/
+  uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                              for spaning ZIP, unsupported, always 0*/
+  ZPOS64_T number_entry;
+  ZPOS64_T number_entry_CD;      /* total number of entries in
+                                the central dir
+                                (same than number_entry on nospan) */
+  uLong VersionMadeBy;
+  uLong VersionNeeded;
+  uLong size_comment;
+
+  int hasZIP64Record = 0;
+
+  // check first if we find a ZIP64 record
+  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
+  if(central_pos > 0)
+  {
+    hasZIP64Record = 1;
+  }
+  else if(central_pos == 0)
+  {
+    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
+  }
+
+/* disable to allow appending to empty ZIP archive
+        if (central_pos==0)
+            err=ZIP_ERRNO;
+*/
+
+  if(hasZIP64Record)
+  {
+    ZPOS64_T sizeEndOfCentralDirectory;
+    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
+      err=ZIP_ERRNO;
+
+    /* the signature, already checked */
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* size of zip64 end of central directory record */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* version made by */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* version needed to extract */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* number of this disk */
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* number of the disk with the start of the central directory */
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* total number of entries in the central directory on this disk */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* total number of entries in the central directory */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+      err=ZIP_BADZIPFILE;
+
+    /* size of the central directory */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* offset of start of central directory with respect to the
+    starting disk number */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    // TODO..
+    // read the comment from the standard central header.
+    size_comment = 0;
+  }
+  else
+  {
+    // Read End of central Directory info
+    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+      err=ZIP_ERRNO;
+
+    /* the signature, already checked */
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* number of this disk */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* number of the disk with the start of the central directory */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* total number of entries in the central dir on this disk */
+    number_entry = 0;
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+    else
+      number_entry = uL;
+
+    /* total number of entries in the central dir */
+    number_entry_CD = 0;
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+    else
+      number_entry_CD = uL;
+
+    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+      err=ZIP_BADZIPFILE;
+
+    /* size of the central directory */
+    size_central_dir = 0;
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+    else
+      size_central_dir = uL;
+
+    /* offset of start of central directory with respect to the starting disk number */
+    offset_central_dir = 0;
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+    else
+      offset_central_dir = uL;
+
+
+    /* zipfile global comment length */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
+      err=ZIP_ERRNO;
+  }
+
+  if ((central_pos<offset_central_dir+size_central_dir) &&
+    (err==ZIP_OK))
+    err=ZIP_BADZIPFILE;
+
+  if (err!=ZIP_OK)
+  {
+    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
+    return ZIP_ERRNO;
+  }
+
+  if (size_comment>0)
+  {
+    pziinit->globalcomment = (char*)ALLOC(size_comment+1);
+    if (pziinit->globalcomment)
+    {
+      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
+      pziinit->globalcomment[size_comment]=0;
+    }
+  }
+
+  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
+  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
+
+  {
+    ZPOS64_T size_central_dir_to_read = size_central_dir;
+    size_t buf_size = SIZEDATA_INDATABLOCK;
+    void* buf_read = (void*)ALLOC(buf_size);
+    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
+      err=ZIP_ERRNO;
+
+    while ((size_central_dir_to_read>0) && (err==ZIP_OK))
+    {
+      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
+      if (read_this > size_central_dir_to_read)
+        read_this = size_central_dir_to_read;
+
+      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
+        err=ZIP_ERRNO;
+
+      if (err==ZIP_OK)
+        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
+
+      size_central_dir_to_read-=read_this;
+    }
+    TRYFREE(buf_read);
+  }
+  pziinit->begin_pos = byte_before_the_zipfile;
+  pziinit->number_entry = number_entry_CD;
+
+  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
+    err=ZIP_ERRNO;
+
+  return err;
+}
+
+
+#endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+
+/************************************************************/
+extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
+{
+    zip64_internal ziinit;
+    zip64_internal* zi;
+    int err=ZIP_OK;
+
+    ziinit.z_filefunc.zseek32_file = NULL;
+    ziinit.z_filefunc.ztell32_file = NULL;
+    if (pzlib_filefunc64_32_def==NULL)
+        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
+    else
+        ziinit.z_filefunc = *pzlib_filefunc64_32_def;
+
+    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
+                  pathname,
+                  (append == APPEND_STATUS_CREATE) ?
+                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
+                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
+
+    if (ziinit.filestream == NULL)
+        return NULL;
+
+    if (append == APPEND_STATUS_CREATEAFTER)
+        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
+
+    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
+    ziinit.in_opened_file_inzip = 0;
+    ziinit.ci.stream_initialised = 0;
+    ziinit.number_entry = 0;
+    ziinit.add_position_when_writting_offset = 0;
+    init_linkedlist(&(ziinit.central_dir));
+
+
+
+    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
+    if (zi==NULL)
+    {
+        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
+        return NULL;
+    }
+
+    /* now we add file in a zipfile */
+#    ifndef NO_ADDFILEINEXISTINGZIP
+    ziinit.globalcomment = NULL;
+    if (append == APPEND_STATUS_ADDINZIP)
+    {
+      // Read and Cache Central Directory Records
+      err = LoadCentralDirectoryRecord(&ziinit);
+    }
+
+    if (globalcomment)
+    {
+      *globalcomment = ziinit.globalcomment;
+    }
+#    endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+    if (err != ZIP_OK)
+    {
+#    ifndef NO_ADDFILEINEXISTINGZIP
+        TRYFREE(ziinit.globalcomment);
+#    endif /* !NO_ADDFILEINEXISTINGZIP*/
+        TRYFREE(zi);
+        return NULL;
+    }
+    else
+    {
+        *zi = ziinit;
+        return (zipFile)zi;
+    }
+}
+
+extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
+{
+    if (pzlib_filefunc32_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+    }
+    else
+        return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    if (pzlib_filefunc_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+    }
+    else
+        return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+
+
+extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
+{
+    return zipOpen3((const void*)pathname,append,NULL,NULL);
+}
+
+extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
+{
+    return zipOpen3(pathname,append,NULL,NULL);
+}
+
+int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
+{
+  /* write the local header */
+  int err;
+  uInt size_filename = (uInt)strlen(filename);
+  uInt size_extrafield = size_extrafield_local;
+
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
+
+  if (err==ZIP_OK)
+  {
+    if(zi->ci.zip64)
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
+  }
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
+
+  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
+  if (err==ZIP_OK)
+  {
+    if(zi->ci.zip64)
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
+  }
+  if (err==ZIP_OK)
+  {
+    if(zi->ci.zip64)
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
+  }
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
+
+  if(zi->ci.zip64)
+  {
+    size_extrafield += 20;
+  }
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
+
+  if ((err==ZIP_OK) && (size_filename > 0))
+  {
+    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
+      err = ZIP_ERRNO;
+  }
+
+  if ((err==ZIP_OK) && (size_extrafield_local > 0))
+  {
+    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
+      err = ZIP_ERRNO;
+  }
+
+
+  if ((err==ZIP_OK) && (zi->ci.zip64))
+  {
+      // write the Zip64 extended info
+      short HeaderID = 1;
+      short DataSize = 16;
+      ZPOS64_T CompressedSize = 0;
+      ZPOS64_T UncompressedSize = 0;
+
+      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
+      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
+
+      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
+      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
+
+      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
+      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
+  }
+
+  return err;
+}
+
+/*
+ NOTE.
+ When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
+ before calling this function it can be done with zipRemoveExtraInfoBlock
+
+ It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
+ unnecessary allocations.
+ */
+extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                         const void* extrafield_local, uInt size_extrafield_local,
+                                         const void* extrafield_global, uInt size_extrafield_global,
+                                         const char* comment, int method, int level, int raw,
+                                         int windowBits,int memLevel, int strategy,
+                                         const char* password, uLong crcForCrypting,
+                                         uLong versionMadeBy, uLong flagBase, int zip64)
+{
+    zip64_internal* zi;
+    uInt size_filename;
+    uInt size_comment;
+    uInt i;
+    int err = ZIP_OK;
+
+#    ifdef NOCRYPT
+    if (password != NULL)
+        return ZIP_PARAMERROR;
+#    endif
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+
+#ifdef HAVE_BZIP2
+    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
+      return ZIP_PARAMERROR;
+#else
+    if ((method!=0) && (method!=Z_DEFLATED))
+      return ZIP_PARAMERROR;
+#endif
+
+    zi = (zip64_internal*)file;
+
+    if (zi->in_opened_file_inzip == 1)
+    {
+        err = zipCloseFileInZip (file);
+        if (err != ZIP_OK)
+            return err;
+    }
+
+    if (filename==NULL)
+        filename="-";
+
+    if (comment==NULL)
+        size_comment = 0;
+    else
+        size_comment = (uInt)strlen(comment);
+
+    size_filename = (uInt)strlen(filename);
+
+    if (zipfi == NULL)
+        zi->ci.dosDate = 0;
+    else
+    {
+        if (zipfi->dosDate != 0)
+            zi->ci.dosDate = zipfi->dosDate;
+        else
+          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
+    }
+
+    zi->ci.flag = flagBase;
+    if ((level==8) || (level==9))
+      zi->ci.flag |= 2;
+    if ((level==2))
+      zi->ci.flag |= 4;
+    if ((level==1))
+      zi->ci.flag |= 6;
+    if (password != NULL)
+      zi->ci.flag |= 1;
+
+    zi->ci.crc32 = 0;
+    zi->ci.method = method;
+    zi->ci.encrypt = 0;
+    zi->ci.stream_initialised = 0;
+    zi->ci.pos_in_buffered_data = 0;
+    zi->ci.raw = raw;
+    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
+
+    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
+    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
+
+    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
+
+    zi->ci.size_centralExtra = size_extrafield_global;
+    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
+    /* version info */
+    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
+    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
+    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
+    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
+    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
+
+    if (zipfi==NULL)
+        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
+    else
+        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
+
+    if (zipfi==NULL)
+        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
+    else
+        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
+
+    if(zi->ci.pos_local_header >= 0xffffffff)
+      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
+    else
+      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
+
+    for (i=0;i<size_filename;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
+
+    for (i=0;i<size_extrafield_global;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
+              *(((const char*)extrafield_global)+i);
+
+    for (i=0;i<size_comment;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
+              size_extrafield_global+i) = *(comment+i);
+    if (zi->ci.central_header == NULL)
+        return ZIP_INTERNALERROR;
+
+    zi->ci.zip64 = zip64;
+    zi->ci.totalCompressedData = 0;
+    zi->ci.totalUncompressedData = 0;
+    zi->ci.pos_zip64extrainfo = 0;
+
+    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
+
+#ifdef HAVE_BZIP2
+    zi->ci.bstream.avail_in = (uInt)0;
+    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+    zi->ci.bstream.total_in_hi32 = 0;
+    zi->ci.bstream.total_in_lo32 = 0;
+    zi->ci.bstream.total_out_hi32 = 0;
+    zi->ci.bstream.total_out_lo32 = 0;
+#endif
+
+    zi->ci.stream.avail_in = (uInt)0;
+    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+    zi->ci.stream.next_out = zi->ci.buffered_data;
+    zi->ci.stream.total_in = 0;
+    zi->ci.stream.total_out = 0;
+    zi->ci.stream.data_type = Z_BINARY;
+
+#ifdef HAVE_BZIP2
+    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+#else
+    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+#endif
+    {
+        if(zi->ci.method == Z_DEFLATED)
+        {
+          zi->ci.stream.zalloc = (alloc_func)0;
+          zi->ci.stream.zfree = (free_func)0;
+          zi->ci.stream.opaque = (voidpf)0;
+
+          if (windowBits>0)
+              windowBits = -windowBits;
+
+          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
+
+          if (err==Z_OK)
+              zi->ci.stream_initialised = Z_DEFLATED;
+        }
+        else if(zi->ci.method == Z_BZIP2ED)
+        {
+#ifdef HAVE_BZIP2
+            // Init BZip stuff here
+          zi->ci.bstream.bzalloc = 0;
+          zi->ci.bstream.bzfree = 0;
+          zi->ci.bstream.opaque = (voidpf)0;
+
+          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
+          if(err == BZ_OK)
+            zi->ci.stream_initialised = Z_BZIP2ED;
+#endif
+        }
+
+    }
+
+#    ifndef NOCRYPT
+    zi->ci.crypt_header_size = 0;
+    if ((err==Z_OK) && (password != NULL))
+    {
+        unsigned char bufHead[RAND_HEAD_LEN];
+        unsigned int sizeHead;
+        zi->ci.encrypt = 1;
+        zi->ci.pcrc_32_tab = get_crc_table();
+        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
+
+        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
+        zi->ci.crypt_header_size = sizeHead;
+
+        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
+                err = ZIP_ERRNO;
+    }
+#    endif
+
+    if (err==Z_OK)
+        zi->in_opened_file_inzip = 1;
+    return err;
+}
+
+extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                         const void* extrafield_local, uInt size_extrafield_local,
+                                         const void* extrafield_global, uInt size_extrafield_global,
+                                         const char* comment, int method, int level, int raw,
+                                         int windowBits,int memLevel, int strategy,
+                                         const char* password, uLong crcForCrypting,
+                                         uLong versionMadeBy, uLong flagBase)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 windowBits, memLevel, strategy,
+                                 password, crcForCrypting, versionMadeBy, flagBase, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                         const void* extrafield_local, uInt size_extrafield_local,
+                                         const void* extrafield_global, uInt size_extrafield_global,
+                                         const char* comment, int method, int level, int raw,
+                                         int windowBits,int memLevel, int strategy,
+                                         const char* password, uLong crcForCrypting)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 windowBits, memLevel, strategy,
+                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                         const void* extrafield_local, uInt size_extrafield_local,
+                                         const void* extrafield_global, uInt size_extrafield_global,
+                                         const char* comment, int method, int level, int raw,
+                                         int windowBits,int memLevel, int strategy,
+                                         const char* password, uLong crcForCrypting, int zip64)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 windowBits, memLevel, strategy,
+                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                        const void* extrafield_local, uInt size_extrafield_local,
+                                        const void* extrafield_global, uInt size_extrafield_global,
+                                        const char* comment, int method, int level, int raw)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                        const void* extrafield_local, uInt size_extrafield_local,
+                                        const void* extrafield_global, uInt size_extrafield_global,
+                                        const char* comment, int method, int level, int raw, int zip64)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                        const void* extrafield_local, uInt size_extrafield_local,
+                                        const void*extrafield_global, uInt size_extrafield_global,
+                                        const char* comment, int method, int level, int zip64)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, 0,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                        const void* extrafield_local, uInt size_extrafield_local,
+                                        const void*extrafield_global, uInt size_extrafield_global,
+                                        const char* comment, int method, int level)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, 0,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+local int zip64FlushWriteBuffer(zip64_internal* zi)
+{
+    int err=ZIP_OK;
+
+    if (zi->ci.encrypt != 0)
+    {
+#ifndef NOCRYPT
+        uInt i;
+        int t;
+        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
+            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
+#endif
+    }
+
+    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
+      err = ZIP_ERRNO;
+
+    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
+
+#ifdef HAVE_BZIP2
+    if(zi->ci.method == Z_BZIP2ED)
+    {
+      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
+      zi->ci.bstream.total_in_lo32 = 0;
+      zi->ci.bstream.total_in_hi32 = 0;
+    }
+    else
+#endif
+    {
+      zi->ci.totalUncompressedData += zi->ci.stream.total_in;
+      zi->ci.stream.total_in = 0;
+    }
+
+
+    zi->ci.pos_in_buffered_data = 0;
+
+    return err;
+}
+
+extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
+{
+    zip64_internal* zi;
+    int err=ZIP_OK;
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+    zi = (zip64_internal*)file;
+
+    if (zi->in_opened_file_inzip == 0)
+        return ZIP_PARAMERROR;
+
+    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
+
+#ifdef HAVE_BZIP2
+    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
+    {
+      zi->ci.bstream.next_in = (void*)buf;
+      zi->ci.bstream.avail_in = len;
+      err = BZ_RUN_OK;
+
+      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
+      {
+        if (zi->ci.bstream.avail_out == 0)
+        {
+          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+            err = ZIP_ERRNO;
+          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+        }
+
+
+        if(err != BZ_RUN_OK)
+          break;
+
+        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+        {
+          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
+//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
+          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
+
+          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
+        }
+      }
+
+      if(err == BZ_RUN_OK)
+        err = ZIP_OK;
+    }
+    else
+#endif
+    {
+      zi->ci.stream.next_in = (Bytef*)buf;
+      zi->ci.stream.avail_in = len;
+
+      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
+      {
+          if (zi->ci.stream.avail_out == 0)
+          {
+              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+                  err = ZIP_ERRNO;
+              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+              zi->ci.stream.next_out = zi->ci.buffered_data;
+          }
+
+
+          if(err != ZIP_OK)
+              break;
+
+          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+          {
+              uLong uTotalOutBefore = zi->ci.stream.total_out;
+              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
+              if(uTotalOutBefore > zi->ci.stream.total_out)
+              {
+                int bBreak = 0;
+                bBreak++;
+              }
+
+              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+          }
+          else
+          {
+              uInt copy_this,i;
+              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
+                  copy_this = zi->ci.stream.avail_in;
+              else
+                  copy_this = zi->ci.stream.avail_out;
+
+              for (i = 0; i < copy_this; i++)
+                  *(((char*)zi->ci.stream.next_out)+i) =
+                      *(((const char*)zi->ci.stream.next_in)+i);
+              {
+                  zi->ci.stream.avail_in -= copy_this;
+                  zi->ci.stream.avail_out-= copy_this;
+                  zi->ci.stream.next_in+= copy_this;
+                  zi->ci.stream.next_out+= copy_this;
+                  zi->ci.stream.total_in+= copy_this;
+                  zi->ci.stream.total_out+= copy_this;
+                  zi->ci.pos_in_buffered_data += copy_this;
+              }
+          }
+      }// while(...)
+    }
+
+    return err;
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
+{
+    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
+{
+    zip64_internal* zi;
+    ZPOS64_T compressed_size;
+    uLong invalidValue = 0xffffffff;
+    short datasize = 0;
+    int err=ZIP_OK;
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+    zi = (zip64_internal*)file;
+
+    if (zi->in_opened_file_inzip == 0)
+        return ZIP_PARAMERROR;
+    zi->ci.stream.avail_in = 0;
+
+    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+                {
+                        while (err==ZIP_OK)
+                        {
+                                uLong uTotalOutBefore;
+                                if (zi->ci.stream.avail_out == 0)
+                                {
+                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+                                                err = ZIP_ERRNO;
+                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+                                        zi->ci.stream.next_out = zi->ci.buffered_data;
+                                }
+                                uTotalOutBefore = zi->ci.stream.total_out;
+                                err=deflate(&zi->ci.stream,  Z_FINISH);
+                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+                        }
+                }
+    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+    {
+#ifdef HAVE_BZIP2
+      err = BZ_FINISH_OK;
+      while (err==BZ_FINISH_OK)
+      {
+        uLong uTotalOutBefore;
+        if (zi->ci.bstream.avail_out == 0)
+        {
+          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+            err = ZIP_ERRNO;
+          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+        }
+        uTotalOutBefore = zi->ci.bstream.total_out_lo32;
+        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
+        if(err == BZ_STREAM_END)
+          err = Z_STREAM_END;
+
+        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
+      }
+
+      if(err == BZ_FINISH_OK)
+        err = ZIP_OK;
+#endif
+    }
+
+    if (err==Z_STREAM_END)
+        err=ZIP_OK; /* this is normal */
+
+    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
+                {
+        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
+            err = ZIP_ERRNO;
+                }
+
+    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+    {
+        int tmp_err = deflateEnd(&zi->ci.stream);
+        if (err == ZIP_OK)
+            err = tmp_err;
+        zi->ci.stream_initialised = 0;
+    }
+#ifdef HAVE_BZIP2
+    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+    {
+      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
+                        if (err==ZIP_OK)
+                                err = tmperr;
+                        zi->ci.stream_initialised = 0;
+    }
+#endif
+
+    if (!zi->ci.raw)
+    {
+        crc32 = (uLong)zi->ci.crc32;
+        uncompressed_size = zi->ci.totalUncompressedData;
+    }
+    compressed_size = zi->ci.totalCompressedData;
+
+#    ifndef NOCRYPT
+    compressed_size += zi->ci.crypt_header_size;
+#    endif
+
+    // update Current Item crc and sizes,
+    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
+    {
+      /*version Made by*/
+      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
+      /*version needed*/
+      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
+
+    }
+
+    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
+
+
+    if(compressed_size >= 0xffffffff)
+      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
+    else
+      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
+
+    /// set internal file attributes field
+    if (zi->ci.stream.data_type == Z_ASCII)
+        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
+
+    if(uncompressed_size >= 0xffffffff)
+      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
+    else
+      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
+
+    // Add ZIP64 extra info field for uncompressed size
+    if(uncompressed_size >= 0xffffffff)
+      datasize += 8;
+
+    // Add ZIP64 extra info field for compressed size
+    if(compressed_size >= 0xffffffff)
+      datasize += 8;
+
+    // Add ZIP64 extra info field for relative offset to local file header of current file
+    if(zi->ci.pos_local_header >= 0xffffffff)
+      datasize += 8;
+
+    if(datasize > 0)
+    {
+      char* p = NULL;
+
+      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
+      {
+        // we can not write more data to the buffer that we have room for.
+        return ZIP_BADZIPFILE;
+      }
+
+      p = zi->ci.central_header + zi->ci.size_centralheader;
+
+      // Add Extra Information Header for 'ZIP64 information'
+      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
+      p += 2;
+      zip64local_putValue_inmemory(p, datasize, 2); // DataSize
+      p += 2;
+
+      if(uncompressed_size >= 0xffffffff)
+      {
+        zip64local_putValue_inmemory(p, uncompressed_size, 8);
+        p += 8;
+      }
+
+      if(compressed_size >= 0xffffffff)
+      {
+        zip64local_putValue_inmemory(p, compressed_size, 8);
+        p += 8;
+      }
+
+      if(zi->ci.pos_local_header >= 0xffffffff)
+      {
+        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
+        p += 8;
+      }
+
+      // Update how much extra free space we got in the memory buffer
+      // and increase the centralheader size so the new ZIP64 fields are included
+      // ( 4 below is the size of HeaderID and DataSize field )
+      zi->ci.size_centralExtraFree -= datasize + 4;
+      zi->ci.size_centralheader += datasize + 4;
+
+      // Update the extra info size field
+      zi->ci.size_centralExtra += datasize + 4;
+      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
+    }
+
+    if (err==ZIP_OK)
+        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
+
+    free(zi->ci.central_header);
+
+    if (err==ZIP_OK)
+    {
+        // Update the LocalFileHeader with the new values.
+
+        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err = ZIP_ERRNO;
+
+        if (err==ZIP_OK)
+            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
+
+        if(uncompressed_size >= 0xffffffff)
+        {
+          if(zi->ci.pos_zip64extrainfo > 0)
+          {
+            // Update the size in the ZIP64 extended field.
+            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
+              err = ZIP_ERRNO;
+
+            if (err==ZIP_OK) /* compressed size, unknown */
+              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
+
+            if (err==ZIP_OK) /* uncompressed size, unknown */
+              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
+          }
+        }
+        else
+        {
+          if (err==ZIP_OK) /* compressed size, unknown */
+              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
+
+          if (err==ZIP_OK) /* uncompressed size, unknown */
+              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
+        }
+
+        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err = ZIP_ERRNO;
+    }
+
+    zi->number_entry ++;
+    zi->in_opened_file_inzip = 0;
+
+    return err;
+}
+
+extern int ZEXPORT zipCloseFileInZip (zipFile file)
+{
+    return zipCloseFileInZipRaw (file,0,0);
+}
+
+int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
+{
+  int err = ZIP_OK;
+  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
+
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
+
+  /*num disks*/
+    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+  /*relative offset*/
+    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
+
+  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
+    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
+
+    return err;
+}
+
+int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+  int err = ZIP_OK;
+
+  uLong Zip64DataSize = 44;
+
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
+
+  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
+
+  if (err==ZIP_OK) /* version made by */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+  if (err==ZIP_OK) /* version needed */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+  if (err==ZIP_OK) /* number of this disk */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+  if (err==ZIP_OK) /* total number of entries in the central dir */
+    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+  if (err==ZIP_OK) /* size of the central directory */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
+
+  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+  {
+    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
+  }
+  return err;
+}
+int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+  int err = ZIP_OK;
+
+  /*signature*/
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
+
+  if (err==ZIP_OK) /* number of this disk */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+  {
+    {
+      if(zi->number_entry >= 0xFFFF)
+        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+      else
+        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+    }
+  }
+
+  if (err==ZIP_OK) /* total number of entries in the central dir */
+  {
+    if(zi->number_entry >= 0xFFFF)
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+  }
+
+  if (err==ZIP_OK) /* size of the central directory */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
+
+  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+  {
+    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+    if(pos >= 0xffffffff)
+    {
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
+    }
+    else
+                  err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
+  }
+
+   return err;
+}
+
+int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
+{
+  int err = ZIP_OK;
+  uInt size_global_comment = 0;
+
+  if(global_comment != NULL)
+    size_global_comment = (uInt)strlen(global_comment);
+
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
+
+  if (err == ZIP_OK && size_global_comment > 0)
+  {
+    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
+      err = ZIP_ERRNO;
+  }
+  return err;
+}
+
+extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
+{
+    zip64_internal* zi;
+    int err = 0;
+    uLong size_centraldir = 0;
+    ZPOS64_T centraldir_pos_inzip;
+    ZPOS64_T pos;
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+
+    zi = (zip64_internal*)file;
+
+    if (zi->in_opened_file_inzip == 1)
+    {
+        err = zipCloseFileInZip (file);
+    }
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+    if (global_comment==NULL)
+        global_comment = zi->globalcomment;
+#endif
+
+    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+    if (err==ZIP_OK)
+    {
+        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
+        while (ldi!=NULL)
+        {
+            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
+            {
+                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
+                    err = ZIP_ERRNO;
+            }
+
+            size_centraldir += ldi->filled_in_this_block;
+            ldi = ldi->next_datablock;
+        }
+    }
+    free_linkedlist(&(zi->central_dir));
+
+    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+    if(pos >= 0xffffffff)
+    {
+      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
+      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
+    }
+
+    if (err==ZIP_OK)
+      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+    if(err == ZIP_OK)
+      err = Write_GlobalComment(zi, global_comment);
+
+    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
+        if (err == ZIP_OK)
+            err = ZIP_ERRNO;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+    TRYFREE(zi->globalcomment);
+#endif
+    TRYFREE(zi);
+
+    return err;
+}
+
+extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
+{
+  char* p = pData;
+  int size = 0;
+  char* pNewHeader;
+  char* pTmp;
+  short header;
+  short dataSize;
+
+  int retVal = ZIP_OK;
+
+  if(pData == NULL || *dataLen < 4)
+    return ZIP_PARAMERROR;
+
+  pNewHeader = (char*)ALLOC(*dataLen);
+  pTmp = pNewHeader;
+
+  while(p < (pData + *dataLen))
+  {
+    header = *(short*)p;
+    dataSize = *(((short*)p)+1);
+
+    if( header == sHeader ) // Header found.
+    {
+      p += dataSize + 4; // skip it. do not copy to temp buffer
+    }
+    else
+    {
+      // Extra Info block should not be removed, So copy it to the temp buffer.
+      memcpy(pTmp, p, dataSize + 4);
+      p += dataSize + 4;
+      size += dataSize + 4;
+    }
+
+  }
+
+  if(size < *dataLen)
+  {
+    // clean old extra info block.
+    memset(pData,0, *dataLen);
+
+    // copy the new extra info block over the old
+    if(size > 0)
+      memcpy(pData, pNewHeader, size);
+
+    // set the new extra info size
+    *dataLen = size;
+
+    retVal = ZIP_OK;
+  }
+  else
+    retVal = ZIP_ERRNO;
+
+  TRYFREE(pNewHeader);
+
+  return retVal;
+}
diff --git a/8.x/zlib/contrib/minizip/zip.h b/8.x/zlib/contrib/minizip/zip.h
new file mode 100644 (file)
index 0000000..8aaebb6
--- /dev/null
@@ -0,0 +1,362 @@
+/* zip.h -- IO on .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         ---------------------------------------------------------------------------
+
+   Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+        ---------------------------------------------------------------------------
+
+        Changes
+
+        See header of zip.h
+
+*/
+
+#ifndef _zip12_H
+#define _zip12_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define HAVE_BZIP2
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagzipFile__ { int unused; } zipFile__;
+typedef zipFile__ *zipFile;
+#else
+typedef voidp zipFile;
+#endif
+
+#define ZIP_OK                          (0)
+#define ZIP_EOF                         (0)
+#define ZIP_ERRNO                       (Z_ERRNO)
+#define ZIP_PARAMERROR                  (-102)
+#define ZIP_BADZIPFILE                  (-103)
+#define ZIP_INTERNALERROR               (-104)
+
+#ifndef DEF_MEM_LEVEL
+#  if MAX_MEM_LEVEL >= 8
+#    define DEF_MEM_LEVEL 8
+#  else
+#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#  endif
+#endif
+/* default memLevel */
+
+/* tm_zip contain date/time info */
+typedef struct tm_zip_s
+{
+    uInt tm_sec;            /* seconds after the minute - [0,59] */
+    uInt tm_min;            /* minutes after the hour - [0,59] */
+    uInt tm_hour;           /* hours since midnight - [0,23] */
+    uInt tm_mday;           /* day of the month - [1,31] */
+    uInt tm_mon;            /* months since January - [0,11] */
+    uInt tm_year;           /* years - [1980..2044] */
+} tm_zip;
+
+typedef struct
+{
+    tm_zip      tmz_date;       /* date in understandable format           */
+    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */
+/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */
+
+    uLong       internal_fa;    /* internal file attributes        2 bytes */
+    uLong       external_fa;    /* external file attributes        4 bytes */
+} zip_fileinfo;
+
+typedef const char* zipcharpc;
+
+
+#define APPEND_STATUS_CREATE        (0)
+#define APPEND_STATUS_CREATEAFTER   (1)
+#define APPEND_STATUS_ADDINZIP      (2)
+
+extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
+extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
+/*
+  Create a zipfile.
+     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
+       an Unix computer "zlib/zlib113.zip".
+     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
+       will be created at the end of the file.
+         (useful if the file contain a self extractor code)
+     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
+       add files in existing zip (be sure you don't add file that doesn't exist)
+     If the zipfile cannot be opened, the return value is NULL.
+     Else, the return value is a zipFile Handle, usable with other function
+       of this zip package.
+*/
+
+/* Note : there is no delete function into a zipfile.
+   If you want delete file into a zipfile, you must open a zipfile, and create another
+   Of couse, you can use RAW reading and writing to copy the file you did not want delte
+*/
+
+extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
+                                   int append,
+                                   zipcharpc* globalcomment,
+                                   zlib_filefunc_def* pzlib_filefunc_def));
+
+extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
+                                   int append,
+                                   zipcharpc* globalcomment,
+                                   zlib_filefunc64_def* pzlib_filefunc_def));
+
+extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
+                       const char* filename,
+                       const zip_fileinfo* zipfi,
+                       const void* extrafield_local,
+                       uInt size_extrafield_local,
+                       const void* extrafield_global,
+                       uInt size_extrafield_global,
+                       const char* comment,
+                       int method,
+                       int level));
+
+extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
+                       const char* filename,
+                       const zip_fileinfo* zipfi,
+                       const void* extrafield_local,
+                       uInt size_extrafield_local,
+                       const void* extrafield_global,
+                       uInt size_extrafield_global,
+                       const char* comment,
+                       int method,
+                       int level,
+                       int zip64));
+
+/*
+  Open a file in the ZIP for writing.
+  filename : the filename in zip (if NULL, '-' without quote will be used
+  *zipfi contain supplemental information
+  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
+    contains the extrafield data the the local header
+  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
+    contains the extrafield data the the local header
+  if comment != NULL, comment contain the comment string
+  method contain the compression method (0 for store, Z_DEFLATED for deflate)
+  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
+  zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
+                    this MUST be '1' if the uncompressed size is >= 0xffffffff.
+
+*/
+
+
+extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw));
+
+
+extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int zip64));
+/*
+  Same than zipOpenNewFileInZip, except if raw=1, we write raw file
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCrypting));
+
+extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCrypting,
+                                            int zip64
+                                            ));
+
+/*
+  Same than zipOpenNewFileInZip2, except
+    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
+    password : crypting password (NULL for no crypting)
+    crcForCrypting : crc of file to compress (needed for crypting)
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCrypting,
+                                            uLong versionMadeBy,
+                                            uLong flagBase
+                                            ));
+
+
+extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCrypting,
+                                            uLong versionMadeBy,
+                                            uLong flagBase,
+                                            int zip64
+                                            ));
+/*
+  Same than zipOpenNewFileInZip4, except
+    versionMadeBy : value for Version made by field
+    flag : value for flag field (compression level info will be added)
+ */
+
+
+extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
+                       const void* buf,
+                       unsigned len));
+/*
+  Write data in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
+/*
+  Close the current file in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
+                                            uLong uncompressed_size,
+                                            uLong crc32));
+
+extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
+                                            ZPOS64_T uncompressed_size,
+                                            uLong crc32));
+
+/*
+  Close the current file in the zipfile, for file opened with
+    parameter raw=1 in zipOpenNewFileInZip2
+  uncompressed_size and crc32 are value for the uncompressed size
+*/
+
+extern int ZEXPORT zipClose OF((zipFile file,
+                const char* global_comment));
+/*
+  Close the zipfile
+*/
+
+
+extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
+/*
+  zipRemoveExtraInfoBlock -  Added by Mathias Svensson
+
+  Remove extra information block from a extra information data for the local file header or central directory header
+
+  It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
+
+  0x0001 is the signature header for the ZIP64 extra information blocks
+
+  usage.
+                        Remove ZIP64 Extra information from a central director extra field data
+              zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
+
+                        Remove ZIP64 Extra information from a Local File Header extra field data
+        zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _zip64_H */
diff --git a/8.x/zlib/contrib/pascal/example.pas b/8.x/zlib/contrib/pascal/example.pas
new file mode 100644 (file)
index 0000000..5518b36
--- /dev/null
@@ -0,0 +1,599 @@
+(* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Pascal translation
+ * Copyright (C) 1998 by Jacques Nomssi Nzali.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *
+ * Adaptation to the zlibpas interface
+ * Copyright (C) 2003 by Cosmin Truta.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *)
+
+program example;
+
+{$DEFINE TEST_COMPRESS}
+{DO NOT $DEFINE TEST_GZIO}
+{$DEFINE TEST_DEFLATE}
+{$DEFINE TEST_INFLATE}
+{$DEFINE TEST_FLUSH}
+{$DEFINE TEST_SYNC}
+{$DEFINE TEST_DICT}
+
+uses SysUtils, zlibpas;
+
+const TESTFILE = 'foo.gz';
+
+(* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ *)
+const hello: PChar = 'hello, hello!';
+
+const dictionary: PChar = 'hello';
+
+var dictId: LongInt; (* Adler32 value of the dictionary *)
+
+procedure CHECK_ERR(err: Integer; msg: String);
+begin
+  if err <> Z_OK then
+  begin
+    WriteLn(msg, ' error: ', err);
+    Halt(1);
+  end;
+end;
+
+procedure EXIT_ERR(const msg: String);
+begin
+  WriteLn('Error: ', msg);
+  Halt(1);
+end;
+
+(* ===========================================================================
+ * Test compress and uncompress
+ *)
+{$IFDEF TEST_COMPRESS}
+procedure test_compress(compr: Pointer; comprLen: LongInt;
+                        uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+    len: LongInt;
+begin
+  len := StrLen(hello)+1;
+
+  err := compress(compr, comprLen, hello, len);
+  CHECK_ERR(err, 'compress');
+
+  StrCopy(PChar(uncompr), 'garbage');
+
+  err := uncompress(uncompr, uncomprLen, compr, comprLen);
+  CHECK_ERR(err, 'uncompress');
+
+  if StrComp(PChar(uncompr), hello) <> 0 then
+    EXIT_ERR('bad uncompress')
+  else
+    WriteLn('uncompress(): ', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test read/write of .gz files
+ *)
+{$IFDEF TEST_GZIO}
+procedure test_gzio(const fname: PChar; (* compressed file name *)
+                    uncompr: Pointer;
+                    uncomprLen: LongInt);
+var err: Integer;
+    len: Integer;
+    zfile: gzFile;
+    pos: LongInt;
+begin
+  len := StrLen(hello)+1;
+
+  zfile := gzopen(fname, 'wb');
+  if zfile = NIL then
+  begin
+    WriteLn('gzopen error');
+    Halt(1);
+  end;
+  gzputc(zfile, 'h');
+  if gzputs(zfile, 'ello') <> 4 then
+  begin
+    WriteLn('gzputs err: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  {$IFDEF GZ_FORMAT_STRING}
+  if gzprintf(zfile, ', %s!', 'hello') <> 8 then
+  begin
+    WriteLn('gzprintf err: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  {$ELSE}
+  if gzputs(zfile, ', hello!') <> 8 then
+  begin
+    WriteLn('gzputs err: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  {$ENDIF}
+  gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *)
+  gzclose(zfile);
+
+  zfile := gzopen(fname, 'rb');
+  if zfile = NIL then
+  begin
+    WriteLn('gzopen error');
+    Halt(1);
+  end;
+
+  StrCopy(PChar(uncompr), 'garbage');
+
+  if gzread(zfile, uncompr, uncomprLen) <> len then
+  begin
+    WriteLn('gzread err: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  if StrComp(PChar(uncompr), hello) <> 0 then
+  begin
+    WriteLn('bad gzread: ', PChar(uncompr));
+    Halt(1);
+  end
+  else
+    WriteLn('gzread(): ', PChar(uncompr));
+
+  pos := gzseek(zfile, -8, SEEK_CUR);
+  if (pos <> 6) or (gztell(zfile) <> pos) then
+  begin
+    WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile));
+    Halt(1);
+  end;
+
+  if gzgetc(zfile) <> ' ' then
+  begin
+    WriteLn('gzgetc error');
+    Halt(1);
+  end;
+
+  if gzungetc(' ', zfile) <> ' ' then
+  begin
+    WriteLn('gzungetc error');
+    Halt(1);
+  end;
+
+  gzgets(zfile, PChar(uncompr), uncomprLen);
+  uncomprLen := StrLen(PChar(uncompr));
+  if uncomprLen <> 7 then (* " hello!" *)
+  begin
+    WriteLn('gzgets err after gzseek: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  if StrComp(PChar(uncompr), hello + 6) <> 0 then
+  begin
+    WriteLn('bad gzgets after gzseek');
+    Halt(1);
+  end
+  else
+    WriteLn('gzgets() after gzseek: ', PChar(uncompr));
+
+  gzclose(zfile);
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with small buffers
+ *)
+{$IFDEF TEST_DEFLATE}
+procedure test_deflate(compr: Pointer; comprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+    err: Integer;
+    len: LongInt;
+begin
+  len := StrLen(hello)+1;
+
+  c_stream.zalloc := NIL;
+  c_stream.zfree := NIL;
+  c_stream.opaque := NIL;
+
+  err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
+  CHECK_ERR(err, 'deflateInit');
+
+  c_stream.next_in := hello;
+  c_stream.next_out := compr;
+
+  while (c_stream.total_in <> len) and
+        (c_stream.total_out < comprLen) do
+  begin
+    c_stream.avail_out := 1; { force small buffers }
+    c_stream.avail_in := 1;
+    err := deflate(c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, 'deflate');
+  end;
+
+  (* Finish the stream, still forcing small buffers: *)
+  while TRUE do
+  begin
+    c_stream.avail_out := 1;
+    err := deflate(c_stream, Z_FINISH);
+    if err = Z_STREAM_END then
+      break;
+    CHECK_ERR(err, 'deflate');
+  end;
+
+  err := deflateEnd(c_stream);
+  CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with small buffers
+ *)
+{$IFDEF TEST_INFLATE}
+procedure test_inflate(compr: Pointer; comprLen : LongInt;
+                       uncompr: Pointer; uncomprLen : LongInt);
+var err: Integer;
+    d_stream: z_stream; (* decompression stream *)
+begin
+  StrCopy(PChar(uncompr), 'garbage');
+
+  d_stream.zalloc := NIL;
+  d_stream.zfree := NIL;
+  d_stream.opaque := NIL;
+
+  d_stream.next_in := compr;
+  d_stream.avail_in := 0;
+  d_stream.next_out := uncompr;
+
+  err := inflateInit(d_stream);
+  CHECK_ERR(err, 'inflateInit');
+
+  while (d_stream.total_out < uncomprLen) and
+        (d_stream.total_in < comprLen) do
+  begin
+    d_stream.avail_out := 1; (* force small buffers *)
+    d_stream.avail_in := 1;
+    err := inflate(d_stream, Z_NO_FLUSH);
+    if err = Z_STREAM_END then
+      break;
+    CHECK_ERR(err, 'inflate');
+  end;
+
+  err := inflateEnd(d_stream);
+  CHECK_ERR(err, 'inflateEnd');
+
+  if StrComp(PChar(uncompr), hello) <> 0 then
+    EXIT_ERR('bad inflate')
+  else
+    WriteLn('inflate(): ', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with large buffers and dynamic change of compression level
+ *)
+{$IFDEF TEST_DEFLATE}
+procedure test_large_deflate(compr: Pointer; comprLen: LongInt;
+                             uncompr: Pointer; uncomprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+    err: Integer;
+begin
+  c_stream.zalloc := NIL;
+  c_stream.zfree := NIL;
+  c_stream.opaque := NIL;
+
+  err := deflateInit(c_stream, Z_BEST_SPEED);
+  CHECK_ERR(err, 'deflateInit');
+
+  c_stream.next_out := compr;
+  c_stream.avail_out := Integer(comprLen);
+
+  (* At this point, uncompr is still mostly zeroes, so it should compress
+   * very well:
+   *)
+  c_stream.next_in := uncompr;
+  c_stream.avail_in := Integer(uncomprLen);
+  err := deflate(c_stream, Z_NO_FLUSH);
+  CHECK_ERR(err, 'deflate');
+  if c_stream.avail_in <> 0 then
+    EXIT_ERR('deflate not greedy');
+
+  (* Feed in already compressed data and switch to no compression: *)
+  deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+  c_stream.next_in := compr;
+  c_stream.avail_in := Integer(comprLen div 2);
+  err := deflate(c_stream, Z_NO_FLUSH);
+  CHECK_ERR(err, 'deflate');
+
+  (* Switch back to compressing mode: *)
+  deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+  c_stream.next_in := uncompr;
+  c_stream.avail_in := Integer(uncomprLen);
+  err := deflate(c_stream, Z_NO_FLUSH);
+  CHECK_ERR(err, 'deflate');
+
+  err := deflate(c_stream, Z_FINISH);
+  if err <> Z_STREAM_END then
+    EXIT_ERR('deflate should report Z_STREAM_END');
+
+  err := deflateEnd(c_stream);
+  CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with large buffers
+ *)
+{$IFDEF TEST_INFLATE}
+procedure test_large_inflate(compr: Pointer; comprLen: LongInt;
+                             uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+    d_stream: z_stream; (* decompression stream *)
+begin
+  StrCopy(PChar(uncompr), 'garbage');
+
+  d_stream.zalloc := NIL;
+  d_stream.zfree := NIL;
+  d_stream.opaque := NIL;
+
+  d_stream.next_in := compr;
+  d_stream.avail_in := Integer(comprLen);
+
+  err := inflateInit(d_stream);
+  CHECK_ERR(err, 'inflateInit');
+
+  while TRUE do
+  begin
+    d_stream.next_out := uncompr;            (* discard the output *)
+    d_stream.avail_out := Integer(uncomprLen);
+    err := inflate(d_stream, Z_NO_FLUSH);
+    if err = Z_STREAM_END then
+      break;
+    CHECK_ERR(err, 'large inflate');
+  end;
+
+  err := inflateEnd(d_stream);
+  CHECK_ERR(err, 'inflateEnd');
+
+  if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then
+  begin
+    WriteLn('bad large inflate: ', d_stream.total_out);
+    Halt(1);
+  end
+  else
+    WriteLn('large_inflate(): OK');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with full flush
+ *)
+{$IFDEF TEST_FLUSH}
+procedure test_flush(compr: Pointer; var comprLen : LongInt);
+var c_stream: z_stream; (* compression stream *)
+    err: Integer;
+    len: Integer;
+begin
+  len := StrLen(hello)+1;
+
+  c_stream.zalloc := NIL;
+  c_stream.zfree := NIL;
+  c_stream.opaque := NIL;
+
+  err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
+  CHECK_ERR(err, 'deflateInit');
+
+  c_stream.next_in := hello;
+  c_stream.next_out := compr;
+  c_stream.avail_in := 3;
+  c_stream.avail_out := Integer(comprLen);
+  err := deflate(c_stream, Z_FULL_FLUSH);
+  CHECK_ERR(err, 'deflate');
+
+  Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *)
+  c_stream.avail_in := len - 3;
+
+  err := deflate(c_stream, Z_FINISH);
+  if err <> Z_STREAM_END then
+    CHECK_ERR(err, 'deflate');
+
+  err := deflateEnd(c_stream);
+  CHECK_ERR(err, 'deflateEnd');
+
+  comprLen := c_stream.total_out;
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflateSync()
+ *)
+{$IFDEF TEST_SYNC}
+procedure test_sync(compr: Pointer; comprLen: LongInt;
+                    uncompr: Pointer; uncomprLen : LongInt);
+var err: Integer;
+    d_stream: z_stream; (* decompression stream *)
+begin
+  StrCopy(PChar(uncompr), 'garbage');
+
+  d_stream.zalloc := NIL;
+  d_stream.zfree := NIL;
+  d_stream.opaque := NIL;
+
+  d_stream.next_in := compr;
+  d_stream.avail_in := 2; (* just read the zlib header *)
+
+  err := inflateInit(d_stream);
+  CHECK_ERR(err, 'inflateInit');
+
+  d_stream.next_out := uncompr;
+  d_stream.avail_out := Integer(uncomprLen);
+
+  inflate(d_stream, Z_NO_FLUSH);
+  CHECK_ERR(err, 'inflate');
+
+  d_stream.avail_in := Integer(comprLen-2);   (* read all compressed data *)
+  err := inflateSync(d_stream);               (* but skip the damaged part *)
+  CHECK_ERR(err, 'inflateSync');
+
+  err := inflate(d_stream, Z_FINISH);
+  if err <> Z_DATA_ERROR then
+    EXIT_ERR('inflate should report DATA_ERROR');
+    (* Because of incorrect adler32 *)
+
+  err := inflateEnd(d_stream);
+  CHECK_ERR(err, 'inflateEnd');
+
+  WriteLn('after inflateSync(): hel', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with preset dictionary
+ *)
+{$IFDEF TEST_DICT}
+procedure test_dict_deflate(compr: Pointer; comprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+    err: Integer;
+begin
+  c_stream.zalloc := NIL;
+  c_stream.zfree := NIL;
+  c_stream.opaque := NIL;
+
+  err := deflateInit(c_stream, Z_BEST_COMPRESSION);
+  CHECK_ERR(err, 'deflateInit');
+
+  err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary));
+  CHECK_ERR(err, 'deflateSetDictionary');
+
+  dictId := c_stream.adler;
+  c_stream.next_out := compr;
+  c_stream.avail_out := Integer(comprLen);
+
+  c_stream.next_in := hello;
+  c_stream.avail_in := StrLen(hello)+1;
+
+  err := deflate(c_stream, Z_FINISH);
+  if err <> Z_STREAM_END then
+    EXIT_ERR('deflate should report Z_STREAM_END');
+
+  err := deflateEnd(c_stream);
+  CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with a preset dictionary
+ *)
+{$IFDEF TEST_DICT}
+procedure test_dict_inflate(compr: Pointer; comprLen: LongInt;
+                            uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+    d_stream: z_stream; (* decompression stream *)
+begin
+  StrCopy(PChar(uncompr), 'garbage');
+
+  d_stream.zalloc := NIL;
+  d_stream.zfree := NIL;
+  d_stream.opaque := NIL;
+
+  d_stream.next_in := compr;
+  d_stream.avail_in := Integer(comprLen);
+
+  err := inflateInit(d_stream);
+  CHECK_ERR(err, 'inflateInit');
+
+  d_stream.next_out := uncompr;
+  d_stream.avail_out := Integer(uncomprLen);
+
+  while TRUE do
+  begin
+    err := inflate(d_stream, Z_NO_FLUSH);
+    if err = Z_STREAM_END then
+      break;
+    if err = Z_NEED_DICT then
+    begin
+      if d_stream.adler <> dictId then
+        EXIT_ERR('unexpected dictionary');
+      err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary));
+    end;
+    CHECK_ERR(err, 'inflate with dict');
+  end;
+
+  err := inflateEnd(d_stream);
+  CHECK_ERR(err, 'inflateEnd');
+
+  if StrComp(PChar(uncompr), hello) <> 0 then
+    EXIT_ERR('bad inflate with dict')
+  else
+    WriteLn('inflate with dictionary: ', PChar(uncompr));
+end;
+{$ENDIF}
+
+var compr, uncompr: Pointer;
+    comprLen, uncomprLen: LongInt;
+
+begin
+  if zlibVersion^ <> ZLIB_VERSION[1] then
+    EXIT_ERR('Incompatible zlib version');
+
+  WriteLn('zlib version: ', zlibVersion);
+  WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags]));
+
+  comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *)
+  uncomprLen := comprLen;
+  GetMem(compr, comprLen);
+  GetMem(uncompr, uncomprLen);
+  if (compr = NIL) or (uncompr = NIL) then
+    EXIT_ERR('Out of memory');
+  (* compr and uncompr are cleared to avoid reading uninitialized
+   * data and to ensure that uncompr compresses well.
+   *)
+  FillChar(compr^, comprLen, 0);
+  FillChar(uncompr^, uncomprLen, 0);
+
+  {$IFDEF TEST_COMPRESS}
+  WriteLn('** Testing compress');
+  test_compress(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+
+  {$IFDEF TEST_GZIO}
+  WriteLn('** Testing gzio');
+  if ParamCount >= 1 then
+    test_gzio(ParamStr(1), uncompr, uncomprLen)
+  else
+    test_gzio(TESTFILE, uncompr, uncomprLen);
+  {$ENDIF}
+
+  {$IFDEF TEST_DEFLATE}
+  WriteLn('** Testing deflate with small buffers');
+  test_deflate(compr, comprLen);
+  {$ENDIF}
+  {$IFDEF TEST_INFLATE}
+  WriteLn('** Testing inflate with small buffers');
+  test_inflate(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+
+  {$IFDEF TEST_DEFLATE}
+  WriteLn('** Testing deflate with large buffers');
+  test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+  {$IFDEF TEST_INFLATE}
+  WriteLn('** Testing inflate with large buffers');
+  test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+
+  {$IFDEF TEST_FLUSH}
+  WriteLn('** Testing deflate with full flush');
+  test_flush(compr, comprLen);
+  {$ENDIF}
+  {$IFDEF TEST_SYNC}
+  WriteLn('** Testing inflateSync');
+  test_sync(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+  comprLen := uncomprLen;
+
+  {$IFDEF TEST_DICT}
+  WriteLn('** Testing deflate and inflate with preset dictionary');
+  test_dict_deflate(compr, comprLen);
+  test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+
+  FreeMem(compr, comprLen);
+  FreeMem(uncompr, uncomprLen);
+end.
diff --git a/8.x/zlib/contrib/pascal/readme.txt b/8.x/zlib/contrib/pascal/readme.txt
new file mode 100644 (file)
index 0000000..60e87c8
--- /dev/null
@@ -0,0 +1,76 @@
+
+This directory contains a Pascal (Delphi, Kylix) interface to the
+zlib data compression library.
+
+
+Directory listing
+=================
+
+zlibd32.mak     makefile for Borland C++
+example.pas     usage example of zlib
+zlibpas.pas     the Pascal interface to zlib
+readme.txt      this file
+
+
+Compatibility notes
+===================
+
+- Although the name "zlib" would have been more normal for the
+  zlibpas unit, this name is already taken by Borland's ZLib unit.
+  This is somehow unfortunate, because that unit is not a genuine
+  interface to the full-fledged zlib functionality, but a suite of
+  class wrappers around zlib streams.  Other essential features,
+  such as checksums, are missing.
+  It would have been more appropriate for that unit to have a name
+  like "ZStreams", or something similar.
+
+- The C and zlib-supplied types int, uInt, long, uLong, etc. are
+  translated directly into Pascal types of similar sizes (Integer,
+  LongInt, etc.), to avoid namespace pollution.  In particular,
+  there is no conversion of unsigned int into a Pascal unsigned
+  integer.  The Word type is non-portable and has the same size
+  (16 bits) both in a 16-bit and in a 32-bit environment, unlike
+  Integer.  Even if there is a 32-bit Cardinal type, there is no
+  real need for unsigned int in zlib under a 32-bit environment.
+
+- Except for the callbacks, the zlib function interfaces are
+  assuming the calling convention normally used in Pascal
+  (__pascal for DOS and Windows16, __fastcall for Windows32).
+  Since the cdecl keyword is used, the old Turbo Pascal does
+  not work with this interface.
+
+- The gz* function interfaces are not translated, to avoid
+  interfacing problems with the C runtime library.  Besides,
+    gzprintf(gzFile file, const char *format, ...)
+  cannot be translated into Pascal.
+
+
+Legal issues
+============
+
+The zlibpas interface is:
+  Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler.
+  Copyright (C) 1998 by Bob Dellaca.
+  Copyright (C) 2003 by Cosmin Truta.
+
+The example program is:
+  Copyright (C) 1995-2003 by Jean-loup Gailly.
+  Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali.
+  Copyright (C) 2003 by Cosmin Truta.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
diff --git a/8.x/zlib/contrib/pascal/zlibd32.mak b/8.x/zlib/contrib/pascal/zlibd32.mak
new file mode 100644 (file)
index 0000000..0d0699a
--- /dev/null
@@ -0,0 +1,99 @@
+# Makefile for zlib
+# For use with Delphi and C++ Builder under Win32
+# Updated for zlib 1.2.x by Cosmin Truta
+
+# ------------ Borland C++ ------------
+
+# This project uses the Delphi (fastcall/register) calling convention:
+LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
+
+CC = bcc32
+LD = bcc32
+AR = tlib
+# do not use "-pr" in CFLAGS
+CFLAGS = -a -d -k- -O2 $(LOC)
+LDFLAGS =
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+       $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: example.c zlib.h zconf.h
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+       -del $(ZLIB_LIB)
+       $(AR) $(ZLIB_LIB) $(OBJP1)
+       $(AR) $(ZLIB_LIB) $(OBJP2)
+
+
+# testing
+test: example.exe minigzip.exe
+       example
+       echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+       -del *.obj
+       -del *.exe
+       -del *.lib
+       -del *.tds
+       -del zlib.bak
+       -del foo.gz
+
diff --git a/8.x/zlib/contrib/pascal/zlibpas.pas b/8.x/zlib/contrib/pascal/zlibpas.pas
new file mode 100644 (file)
index 0000000..637ae3a
--- /dev/null
@@ -0,0 +1,236 @@
+(* zlibpas -- Pascal interface to the zlib data compression library
+ *
+ * Copyright (C) 2003 Cosmin Truta.
+ * Derived from original sources by Bob Dellaca.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *)
+
+unit zlibpas;
+
+interface
+
+const
+  ZLIB_VERSION = '1.2.5';
+
+type
+  alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;
+                 cdecl;
+  free_func  = procedure(opaque, address: Pointer);
+                 cdecl;
+
+  in_func    = function(opaque: Pointer; var buf: PByte): Integer;
+                 cdecl;
+  out_func   = function(opaque: Pointer; buf: PByte; size: Integer): Integer;
+                 cdecl;
+
+  z_streamp = ^z_stream;
+  z_stream = packed record
+    next_in: PChar;       (* next input byte *)
+    avail_in: Integer;    (* number of bytes available at next_in *)
+    total_in: LongInt;    (* total nb of input bytes read so far *)
+
+    next_out: PChar;      (* next output byte should be put there *)
+    avail_out: Integer;   (* remaining free space at next_out *)
+    total_out: LongInt;   (* total nb of bytes output so far *)
+
+    msg: PChar;           (* last error message, NULL if no error *)
+    state: Pointer;       (* not visible by applications *)
+
+    zalloc: alloc_func;   (* used to allocate the internal state *)
+    zfree: free_func;     (* used to free the internal state *)
+    opaque: Pointer;      (* private data object passed to zalloc and zfree *)
+
+    data_type: Integer;   (* best guess about the data type: ascii or binary *)
+    adler: LongInt;       (* adler32 value of the uncompressed data *)
+    reserved: LongInt;    (* reserved for future use *)
+  end;
+
+(* constants *)
+const
+  Z_NO_FLUSH      = 0;
+  Z_PARTIAL_FLUSH = 1;
+  Z_SYNC_FLUSH    = 2;
+  Z_FULL_FLUSH    = 3;
+  Z_FINISH        = 4;
+
+  Z_OK            =  0;
+  Z_STREAM_END    =  1;
+  Z_NEED_DICT     =  2;
+  Z_ERRNO         = -1;
+  Z_STREAM_ERROR  = -2;
+  Z_DATA_ERROR    = -3;
+  Z_MEM_ERROR     = -4;
+  Z_BUF_ERROR     = -5;
+  Z_VERSION_ERROR = -6;
+
+  Z_NO_COMPRESSION       =  0;
+  Z_BEST_SPEED           =  1;
+  Z_BEST_COMPRESSION     =  9;
+  Z_DEFAULT_COMPRESSION  = -1;
+
+  Z_FILTERED            = 1;
+  Z_HUFFMAN_ONLY        = 2;
+  Z_RLE                 = 3;
+  Z_DEFAULT_STRATEGY    = 0;
+
+  Z_BINARY   = 0;
+  Z_ASCII    = 1;
+  Z_UNKNOWN  = 2;
+
+  Z_DEFLATED = 8;
+
+(* basic functions *)
+function zlibVersion: PChar;
+function deflateInit(var strm: z_stream; level: Integer): Integer;
+function deflate(var strm: z_stream; flush: Integer): Integer;
+function deflateEnd(var strm: z_stream): Integer;
+function inflateInit(var strm: z_stream): Integer;
+function inflate(var strm: z_stream; flush: Integer): Integer;
+function inflateEnd(var strm: z_stream): Integer;
+
+(* advanced functions *)
+function deflateInit2(var strm: z_stream; level, method, windowBits,
+                      memLevel, strategy: Integer): Integer;
+function deflateSetDictionary(var strm: z_stream; const dictionary: PChar;
+                              dictLength: Integer): Integer;
+function deflateCopy(var dest, source: z_stream): Integer;
+function deflateReset(var strm: z_stream): Integer;
+function deflateParams(var strm: z_stream; level, strategy: Integer): Integer;
+function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt;
+function deflatePrime(var strm: z_stream; bits, value: Integer): Integer;
+function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
+function inflateSetDictionary(var strm: z_stream; const dictionary: PChar;
+                              dictLength: Integer): Integer;
+function inflateSync(var strm: z_stream): Integer;
+function inflateCopy(var dest, source: z_stream): Integer;
+function inflateReset(var strm: z_stream): Integer;
+function inflateBackInit(var strm: z_stream;
+                         windowBits: Integer; window: PChar): Integer;
+function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer;
+                     out_fn: out_func; out_desc: Pointer): Integer;
+function inflateBackEnd(var strm: z_stream): Integer;
+function zlibCompileFlags: LongInt;
+
+(* utility functions *)
+function compress(dest: PChar; var destLen: LongInt;
+                  const source: PChar; sourceLen: LongInt): Integer;
+function compress2(dest: PChar; var destLen: LongInt;
+                  const source: PChar; sourceLen: LongInt;
+                  level: Integer): Integer;
+function compressBound(sourceLen: LongInt): LongInt;
+function uncompress(dest: PChar; var destLen: LongInt;
+                    const source: PChar; sourceLen: LongInt): Integer;
+
+(* checksum functions *)
+function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt;
+function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt;
+
+(* various hacks, don't look :) *)
+function deflateInit_(var strm: z_stream; level: Integer;
+                      const version: PChar; stream_size: Integer): Integer;
+function inflateInit_(var strm: z_stream; const version: PChar;
+                      stream_size: Integer): Integer;
+function deflateInit2_(var strm: z_stream;
+                       level, method, windowBits, memLevel, strategy: Integer;
+                       const version: PChar; stream_size: Integer): Integer;
+function inflateInit2_(var strm: z_stream; windowBits: Integer;
+                       const version: PChar; stream_size: Integer): Integer;
+function inflateBackInit_(var strm: z_stream;
+                          windowBits: Integer; window: PChar;
+                          const version: PChar; stream_size: Integer): Integer;
+
+
+implementation
+
+{$L adler32.obj}
+{$L compress.obj}
+{$L crc32.obj}
+{$L deflate.obj}
+{$L infback.obj}
+{$L inffast.obj}
+{$L inflate.obj}
+{$L inftrees.obj}
+{$L trees.obj}
+{$L uncompr.obj}
+{$L zutil.obj}
+
+function adler32; external;
+function compress; external;
+function compress2; external;
+function compressBound; external;
+function crc32; external;
+function deflate; external;
+function deflateBound; external;
+function deflateCopy; external;
+function deflateEnd; external;
+function deflateInit_; external;
+function deflateInit2_; external;
+function deflateParams; external;
+function deflatePrime; external;
+function deflateReset; external;
+function deflateSetDictionary; external;
+function inflate; external;
+function inflateBack; external;
+function inflateBackEnd; external;
+function inflateBackInit_; external;
+function inflateCopy; external;
+function inflateEnd; external;
+function inflateInit_; external;
+function inflateInit2_; external;
+function inflateReset; external;
+function inflateSetDictionary; external;
+function inflateSync; external;
+function uncompress; external;
+function zlibCompileFlags; external;
+function zlibVersion; external;
+
+function deflateInit(var strm: z_stream; level: Integer): Integer;
+begin
+  Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function deflateInit2(var strm: z_stream; level, method, windowBits, memLevel,
+                      strategy: Integer): Integer;
+begin
+  Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                          ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateInit(var strm: z_stream): Integer;
+begin
+  Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
+begin
+  Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateBackInit(var strm: z_stream;
+                         windowBits: Integer; window: PChar): Integer;
+begin
+  Result := inflateBackInit_(strm, windowBits, window,
+                             ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function _malloc(Size: Integer): Pointer; cdecl;
+begin
+  GetMem(Result, Size);
+end;
+
+procedure _free(Block: Pointer); cdecl;
+begin
+  FreeMem(Block);
+end;
+
+procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
+begin
+  FillChar(P^, count, B);
+end;
+
+procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
+begin
+  Move(source^, dest^, count);
+end;
+
+end.
diff --git a/8.x/zlib/contrib/puff/Makefile b/8.x/zlib/contrib/puff/Makefile
new file mode 100644 (file)
index 0000000..b6b6940
--- /dev/null
@@ -0,0 +1,8 @@
+puff: puff.c puff.h
+       cc -DTEST -o puff puff.c
+
+test: puff
+       puff zeros.raw
+
+clean:
+       rm -f puff puff.o
diff --git a/8.x/zlib/contrib/puff/README b/8.x/zlib/contrib/puff/README
new file mode 100644 (file)
index 0000000..bbc4cb5
--- /dev/null
@@ -0,0 +1,63 @@
+Puff -- A Simple Inflate
+3 Mar 2003
+Mark Adler
+madler@alumni.caltech.edu
+
+What this is --
+
+puff.c provides the routine puff() to decompress the deflate data format.  It
+does so more slowly than zlib, but the code is about one-fifth the size of the
+inflate code in zlib, and written to be very easy to read.
+
+Why I wrote this --
+
+puff.c was written to document the deflate format unambiguously, by virtue of
+being working C code.  It is meant to supplement RFC 1951, which formally
+describes the deflate format.  I have received many questions on details of the
+deflate format, and I hope that reading this code will answer those questions.
+puff.c is heavily commented with details of the deflate format, especially
+those little nooks and cranies of the format that might not be obvious from a
+specification.
+
+puff.c may also be useful in applications where code size or memory usage is a
+very limited resource, and speed is not as important.
+
+How to use it --
+
+Well, most likely you should just be reading puff.c and using zlib for actual
+applications, but if you must ...
+
+Include puff.h in your code, which provides this prototype:
+
+int puff(unsigned char *dest,           /* pointer to destination pointer */
+         unsigned long *destlen,        /* amount of output space */
+         unsigned char *source,         /* pointer to source data pointer */
+         unsigned long *sourcelen);     /* amount of input available */
+
+Then you can call puff() to decompress a deflate stream that is in memory in
+its entirety at source, to a sufficiently sized block of memory for the
+decompressed data at dest.  puff() is the only external symbol in puff.c  The
+only C library functions that puff.c needs are setjmp() and longjmp(), which
+are used to simplify error checking in the code to improve readabilty.  puff.c
+does no memory allocation, and uses less than 2K bytes off of the stack.
+
+If destlen is not enough space for the uncompressed data, then inflate will
+return an error without writing more than destlen bytes.  Note that this means
+that in order to decompress the deflate data successfully, you need to know
+the size of the uncompressed data ahead of time.
+
+If needed, puff() can determine the size of the uncompressed data with no
+output space.  This is done by passing dest equal to (unsigned char *)0.  Then
+the initial value of *destlen is ignored and *destlen is set to the length of
+the uncompressed data.  So if the size of the uncompressed data is not known,
+then two passes of puff() can be used--first to determine the size, and second
+to do the actual inflation after allocating the appropriate memory.  Not
+pretty, but it works.  (This is one of the reasons you should be using zlib.)
+
+The deflate format is self-terminating.  If the deflate stream does not end
+in *sourcelen bytes, puff() will return an error without reading at or past
+endsource.
+
+On return, *sourcelen is updated to the amount of input data consumed, and
+*destlen is updated to the size of the uncompressed data.  See the comments
+in puff.c for the possible return codes for puff().
diff --git a/8.x/zlib/contrib/puff/puff.c b/8.x/zlib/contrib/puff/puff.c
new file mode 100644 (file)
index 0000000..650694e
--- /dev/null
@@ -0,0 +1,955 @@
+/*
+ * puff.c
+ * Copyright (C) 2002-2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in puff.h
+ * version 2.1, 4 Apr 2010
+ *
+ * puff.c is a simple inflate written to be an unambiguous way to specify the
+ * deflate format.  It is not written for speed but rather simplicity.  As a
+ * side benefit, this code might actually be useful when small code is more
+ * important than speed, such as bootstrap applications.  For typical deflate
+ * data, zlib's inflate() is about four times as fast as puff().  zlib's
+ * inflate compiles to around 20K on my machine, whereas puff.c compiles to
+ * around 4K on my machine (a PowerPC using GNU cc).  If the faster decode()
+ * function here is used, then puff() is only twice as slow as zlib's
+ * inflate().
+ *
+ * All dynamically allocated memory comes from the stack.  The stack required
+ * is less than 2K bytes.  This code is compatible with 16-bit int's and
+ * assumes that long's are at least 32 bits.  puff.c uses the short data type,
+ * assumed to be 16 bits, for arrays in order to to conserve memory.  The code
+ * works whether integers are stored big endian or little endian.
+ *
+ * In the comments below are "Format notes" that describe the inflate process
+ * and document some of the less obvious aspects of the format.  This source
+ * code is meant to supplement RFC 1951, which formally describes the deflate
+ * format:
+ *
+ *    http://www.zlib.org/rfc-deflate.html
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0  10 Feb 2002     - First version
+ * 1.1  17 Feb 2002     - Clarifications of some comments and notes
+ *                      - Update puff() dest and source pointers on negative
+ *                        errors to facilitate debugging deflators
+ *                      - Remove longest from struct huffman -- not needed
+ *                      - Simplify offs[] index in construct()
+ *                      - Add input size and checking, using longjmp() to
+ *                        maintain easy readability
+ *                      - Use short data type for large arrays
+ *                      - Use pointers instead of long to specify source and
+ *                        destination sizes to avoid arbitrary 4 GB limits
+ * 1.2  17 Mar 2002     - Add faster version of decode(), doubles speed (!),
+ *                        but leave simple version for readabilty
+ *                      - Make sure invalid distances detected if pointers
+ *                        are 16 bits
+ *                      - Fix fixed codes table error
+ *                      - Provide a scanning mode for determining size of
+ *                        uncompressed data
+ * 1.3  20 Mar 2002     - Go back to lengths for puff() parameters [Jean-loup]
+ *                      - Add a puff.h file for the interface
+ *                      - Add braces in puff() for else do [Jean-loup]
+ *                      - Use indexes instead of pointers for readability
+ * 1.4  31 Mar 2002     - Simplify construct() code set check
+ *                      - Fix some comments
+ *                      - Add FIXLCODES #define
+ * 1.5   6 Apr 2002     - Minor comment fixes
+ * 1.6   7 Aug 2002     - Minor format changes
+ * 1.7   3 Mar 2003     - Added test code for distribution
+ *                      - Added zlib-like license
+ * 1.8   9 Jan 2004     - Added some comments on no distance codes case
+ * 1.9  21 Feb 2008     - Fix bug on 16-bit integer architectures [Pohland]
+ *                      - Catch missing end-of-block symbol error
+ * 2.0  25 Jul 2008     - Add #define to permit distance too far back
+ *                      - Add option in TEST code for puff to write the data
+ *                      - Add option in TEST code to skip input bytes
+ *                      - Allow TEST code to read from piped stdin
+ * 2.1   4 Apr 2010     - Avoid variable initialization for happier compilers
+ *                      - Avoid unsigned comparisons for even happier compilers
+ */
+
+#include <setjmp.h>             /* for setjmp(), longjmp(), and jmp_buf */
+#include "puff.h"               /* prototype for puff() */
+
+#define local static            /* for local function definitions */
+#define NIL ((unsigned char *)0)        /* for no output option */
+
+/*
+ * Maximums for allocations and loops.  It is not useful to change these --
+ * they are fixed by the deflate format.
+ */
+#define MAXBITS 15              /* maximum bits in a code */
+#define MAXLCODES 286           /* maximum number of literal/length codes */
+#define MAXDCODES 30            /* maximum number of distance codes */
+#define MAXCODES (MAXLCODES+MAXDCODES)  /* maximum codes lengths to read */
+#define FIXLCODES 288           /* number of fixed literal/length codes */
+
+/* input and output state */
+struct state {
+    /* output state */
+    unsigned char *out;         /* output buffer */
+    unsigned long outlen;       /* available space at out */
+    unsigned long outcnt;       /* bytes written to out so far */
+
+    /* input state */
+    unsigned char *in;          /* input buffer */
+    unsigned long inlen;        /* available input at in */
+    unsigned long incnt;        /* bytes read so far */
+    int bitbuf;                 /* bit buffer */
+    int bitcnt;                 /* number of bits in bit buffer */
+
+    /* input limit error return state for bits() and decode() */
+    jmp_buf env;
+};
+
+/*
+ * Return need bits from the input stream.  This always leaves less than
+ * eight bits in the buffer.  bits() works properly for need == 0.
+ *
+ * Format notes:
+ *
+ * - Bits are stored in bytes from the least significant bit to the most
+ *   significant bit.  Therefore bits are dropped from the bottom of the bit
+ *   buffer, using shift right, and new bytes are appended to the top of the
+ *   bit buffer, using shift left.
+ */
+local int bits(struct state *s, int need)
+{
+    long val;           /* bit accumulator (can use up to 20 bits) */
+
+    /* load at least need bits into val */
+    val = s->bitbuf;
+    while (s->bitcnt < need) {
+        if (s->incnt == s->inlen) longjmp(s->env, 1);   /* out of input */
+        val |= (long)(s->in[s->incnt++]) << s->bitcnt;  /* load eight bits */
+        s->bitcnt += 8;
+    }
+
+    /* drop need bits and update buffer, always zero to seven bits left */
+    s->bitbuf = (int)(val >> need);
+    s->bitcnt -= need;
+
+    /* return need bits, zeroing the bits above that */
+    return (int)(val & ((1L << need) - 1));
+}
+
+/*
+ * Process a stored block.
+ *
+ * Format notes:
+ *
+ * - After the two-bit stored block type (00), the stored block length and
+ *   stored bytes are byte-aligned for fast copying.  Therefore any leftover
+ *   bits in the byte that has the last bit of the type, as many as seven, are
+ *   discarded.  The value of the discarded bits are not defined and should not
+ *   be checked against any expectation.
+ *
+ * - The second inverted copy of the stored block length does not have to be
+ *   checked, but it's probably a good idea to do so anyway.
+ *
+ * - A stored block can have zero length.  This is sometimes used to byte-align
+ *   subsets of the compressed data for random access or partial recovery.
+ */
+local int stored(struct state *s)
+{
+    unsigned len;       /* length of stored block */
+
+    /* discard leftover bits from current byte (assumes s->bitcnt < 8) */
+    s->bitbuf = 0;
+    s->bitcnt = 0;
+
+    /* get length and check against its one's complement */
+    if (s->incnt + 4 > s->inlen) return 2;      /* not enough input */
+    len = s->in[s->incnt++];
+    len |= s->in[s->incnt++] << 8;
+    if (s->in[s->incnt++] != (~len & 0xff) ||
+        s->in[s->incnt++] != ((~len >> 8) & 0xff))
+        return -2;                              /* didn't match complement! */
+
+    /* copy len bytes from in to out */
+    if (s->incnt + len > s->inlen) return 2;    /* not enough input */
+    if (s->out != NIL) {
+        if (s->outcnt + len > s->outlen)
+            return 1;                           /* not enough output space */
+        while (len--)
+            s->out[s->outcnt++] = s->in[s->incnt++];
+    }
+    else {                                      /* just scanning */
+        s->outcnt += len;
+        s->incnt += len;
+    }
+
+    /* done with a valid stored block */
+    return 0;
+}
+
+/*
+ * Huffman code decoding tables.  count[1..MAXBITS] is the number of symbols of
+ * each length, which for a canonical code are stepped through in order.
+ * symbol[] are the symbol values in canonical order, where the number of
+ * entries is the sum of the counts in count[].  The decoding process can be
+ * seen in the function decode() below.
+ */
+struct huffman {
+    short *count;       /* number of symbols of each length */
+    short *symbol;      /* canonically ordered symbols */
+};
+
+/*
+ * Decode a code from the stream s using huffman table h.  Return the symbol or
+ * a negative value if there is an error.  If all of the lengths are zero, i.e.
+ * an empty code, or if the code is incomplete and an invalid code is received,
+ * then -10 is returned after reading MAXBITS bits.
+ *
+ * Format notes:
+ *
+ * - The codes as stored in the compressed data are bit-reversed relative to
+ *   a simple integer ordering of codes of the same lengths.  Hence below the
+ *   bits are pulled from the compressed data one at a time and used to
+ *   build the code value reversed from what is in the stream in order to
+ *   permit simple integer comparisons for decoding.  A table-based decoding
+ *   scheme (as used in zlib) does not need to do this reversal.
+ *
+ * - The first code for the shortest length is all zeros.  Subsequent codes of
+ *   the same length are simply integer increments of the previous code.  When
+ *   moving up a length, a zero bit is appended to the code.  For a complete
+ *   code, the last code of the longest length will be all ones.
+ *
+ * - Incomplete codes are handled by this decoder, since they are permitted
+ *   in the deflate format.  See the format notes for fixed() and dynamic().
+ */
+#ifdef SLOW
+local int decode(struct state *s, struct huffman *h)
+{
+    int len;            /* current number of bits in code */
+    int code;           /* len bits being decoded */
+    int first;          /* first code of length len */
+    int count;          /* number of codes of length len */
+    int index;          /* index of first code of length len in symbol table */
+
+    code = first = index = 0;
+    for (len = 1; len <= MAXBITS; len++) {
+        code |= bits(s, 1);             /* get next bit */
+        count = h->count[len];
+        if (code - count < first)       /* if length len, return symbol */
+            return h->symbol[index + (code - first)];
+        index += count;                 /* else update for next length */
+        first += count;
+        first <<= 1;
+        code <<= 1;
+    }
+    return -10;                         /* ran out of codes */
+}
+
+/*
+ * A faster version of decode() for real applications of this code.   It's not
+ * as readable, but it makes puff() twice as fast.  And it only makes the code
+ * a few percent larger.
+ */
+#else /* !SLOW */
+local int decode(struct state *s, struct huffman *h)
+{
+    int len;            /* current number of bits in code */
+    int code;           /* len bits being decoded */
+    int first;          /* first code of length len */
+    int count;          /* number of codes of length len */
+    int index;          /* index of first code of length len in symbol table */
+    int bitbuf;         /* bits from stream */
+    int left;           /* bits left in next or left to process */
+    short *next;        /* next number of codes */
+
+    bitbuf = s->bitbuf;
+    left = s->bitcnt;
+    code = first = index = 0;
+    len = 1;
+    next = h->count + 1;
+    while (1) {
+        while (left--) {
+            code |= bitbuf & 1;
+            bitbuf >>= 1;
+            count = *next++;
+            if (code - count < first) { /* if length len, return symbol */
+                s->bitbuf = bitbuf;
+                s->bitcnt = (s->bitcnt - len) & 7;
+                return h->symbol[index + (code - first)];
+            }
+            index += count;             /* else update for next length */
+            first += count;
+            first <<= 1;
+            code <<= 1;
+            len++;
+        }
+        left = (MAXBITS+1) - len;
+        if (left == 0) break;
+        if (s->incnt == s->inlen) longjmp(s->env, 1);   /* out of input */
+        bitbuf = s->in[s->incnt++];
+        if (left > 8) left = 8;
+    }
+    return -10;                         /* ran out of codes */
+}
+#endif /* SLOW */
+
+/*
+ * Given the list of code lengths length[0..n-1] representing a canonical
+ * Huffman code for n symbols, construct the tables required to decode those
+ * codes.  Those tables are the number of codes of each length, and the symbols
+ * sorted by length, retaining their original order within each length.  The
+ * return value is zero for a complete code set, negative for an over-
+ * subscribed code set, and positive for an incomplete code set.  The tables
+ * can be used if the return value is zero or positive, but they cannot be used
+ * if the return value is negative.  If the return value is zero, it is not
+ * possible for decode() using that table to return an error--any stream of
+ * enough bits will resolve to a symbol.  If the return value is positive, then
+ * it is possible for decode() using that table to return an error for received
+ * codes past the end of the incomplete lengths.
+ *
+ * Not used by decode(), but used for error checking, h->count[0] is the number
+ * of the n symbols not in the code.  So n - h->count[0] is the number of
+ * codes.  This is useful for checking for incomplete codes that have more than
+ * one symbol, which is an error in a dynamic block.
+ *
+ * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
+ * This is assured by the construction of the length arrays in dynamic() and
+ * fixed() and is not verified by construct().
+ *
+ * Format notes:
+ *
+ * - Permitted and expected examples of incomplete codes are one of the fixed
+ *   codes and any code with a single symbol which in deflate is coded as one
+ *   bit instead of zero bits.  See the format notes for fixed() and dynamic().
+ *
+ * - Within a given code length, the symbols are kept in ascending order for
+ *   the code bits definition.
+ */
+local int construct(struct huffman *h, short *length, int n)
+{
+    int symbol;         /* current symbol when stepping through length[] */
+    int len;            /* current length when stepping through h->count[] */
+    int left;           /* number of possible codes left of current length */
+    short offs[MAXBITS+1];      /* offsets in symbol table for each length */
+
+    /* count number of codes of each length */
+    for (len = 0; len <= MAXBITS; len++)
+        h->count[len] = 0;
+    for (symbol = 0; symbol < n; symbol++)
+        (h->count[length[symbol]])++;   /* assumes lengths are within bounds */
+    if (h->count[0] == n)               /* no codes! */
+        return 0;                       /* complete, but decode() will fail */
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;                           /* one possible code of zero length */
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;                     /* one more bit, double codes left */
+        left -= h->count[len];          /* deduct count from possible codes */
+        if (left < 0) return left;      /* over-subscribed--return negative */
+    }                                   /* left > 0 means incomplete */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + h->count[len];
+
+    /*
+     * put symbols in table sorted by length, by symbol order within each
+     * length
+     */
+    for (symbol = 0; symbol < n; symbol++)
+        if (length[symbol] != 0)
+            h->symbol[offs[length[symbol]]++] = symbol;
+
+    /* return zero for complete set, positive for incomplete set */
+    return left;
+}
+
+/*
+ * Decode literal/length and distance codes until an end-of-block code.
+ *
+ * Format notes:
+ *
+ * - Compressed data that is after the block type if fixed or after the code
+ *   description if dynamic is a combination of literals and length/distance
+ *   pairs terminated by and end-of-block code.  Literals are simply Huffman
+ *   coded bytes.  A length/distance pair is a coded length followed by a
+ *   coded distance to represent a string that occurs earlier in the
+ *   uncompressed data that occurs again at the current location.
+ *
+ * - Literals, lengths, and the end-of-block code are combined into a single
+ *   code of up to 286 symbols.  They are 256 literals (0..255), 29 length
+ *   symbols (257..285), and the end-of-block symbol (256).
+ *
+ * - There are 256 possible lengths (3..258), and so 29 symbols are not enough
+ *   to represent all of those.  Lengths 3..10 and 258 are in fact represented
+ *   by just a length symbol.  Lengths 11..257 are represented as a symbol and
+ *   some number of extra bits that are added as an integer to the base length
+ *   of the length symbol.  The number of extra bits is determined by the base
+ *   length symbol.  These are in the static arrays below, lens[] for the base
+ *   lengths and lext[] for the corresponding number of extra bits.
+ *
+ * - The reason that 258 gets its own symbol is that the longest length is used
+ *   often in highly redundant files.  Note that 258 can also be coded as the
+ *   base value 227 plus the maximum extra value of 31.  While a good deflate
+ *   should never do this, it is not an error, and should be decoded properly.
+ *
+ * - If a length is decoded, including its extra bits if any, then it is
+ *   followed a distance code.  There are up to 30 distance symbols.  Again
+ *   there are many more possible distances (1..32768), so extra bits are added
+ *   to a base value represented by the symbol.  The distances 1..4 get their
+ *   own symbol, but the rest require extra bits.  The base distances and
+ *   corresponding number of extra bits are below in the static arrays dist[]
+ *   and dext[].
+ *
+ * - Literal bytes are simply written to the output.  A length/distance pair is
+ *   an instruction to copy previously uncompressed bytes to the output.  The
+ *   copy is from distance bytes back in the output stream, copying for length
+ *   bytes.
+ *
+ * - Distances pointing before the beginning of the output data are not
+ *   permitted.
+ *
+ * - Overlapped copies, where the length is greater than the distance, are
+ *   allowed and common.  For example, a distance of one and a length of 258
+ *   simply copies the last byte 258 times.  A distance of four and a length of
+ *   twelve copies the last four bytes three times.  A simple forward copy
+ *   ignoring whether the length is greater than the distance or not implements
+ *   this correctly.  You should not use memcpy() since its behavior is not
+ *   defined for overlapped arrays.  You should not use memmove() or bcopy()
+ *   since though their behavior -is- defined for overlapping arrays, it is
+ *   defined to do the wrong thing in this case.
+ */
+local int codes(struct state *s,
+                struct huffman *lencode,
+                struct huffman *distcode)
+{
+    int symbol;         /* decoded symbol */
+    int len;            /* length for copy */
+    unsigned dist;      /* distance for copy */
+    static const short lens[29] = { /* Size base for length codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
+    static const short lext[29] = { /* Extra bits for length codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
+    static const short dists[30] = { /* Offset base for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+    static const short dext[30] = { /* Extra bits for distance codes 0..29 */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+    /* decode literals and length/distance pairs */
+    do {
+        symbol = decode(s, lencode);
+        if (symbol < 0) return symbol;  /* invalid symbol */
+        if (symbol < 256) {             /* literal: symbol is the byte */
+            /* write out the literal */
+            if (s->out != NIL) {
+                if (s->outcnt == s->outlen) return 1;
+                s->out[s->outcnt] = symbol;
+            }
+            s->outcnt++;
+        }
+        else if (symbol > 256) {        /* length */
+            /* get and compute length */
+            symbol -= 257;
+            if (symbol >= 29) return -10;       /* invalid fixed code */
+            len = lens[symbol] + bits(s, lext[symbol]);
+
+            /* get and check distance */
+            symbol = decode(s, distcode);
+            if (symbol < 0) return symbol;      /* invalid symbol */
+            dist = dists[symbol] + bits(s, dext[symbol]);
+#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+            if (dist > s->outcnt)
+                return -11;     /* distance too far back */
+#endif
+
+            /* copy length bytes from distance bytes back */
+            if (s->out != NIL) {
+                if (s->outcnt + len > s->outlen) return 1;
+                while (len--) {
+                    s->out[s->outcnt] =
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        dist > s->outcnt ? 0 :
+#endif
+                        s->out[s->outcnt - dist];
+                    s->outcnt++;
+                }
+            }
+            else
+                s->outcnt += len;
+        }
+    } while (symbol != 256);            /* end of block symbol */
+
+    /* done with a valid fixed or dynamic block */
+    return 0;
+}
+
+/*
+ * Process a fixed codes block.
+ *
+ * Format notes:
+ *
+ * - This block type can be useful for compressing small amounts of data for
+ *   which the size of the code descriptions in a dynamic block exceeds the
+ *   benefit of custom codes for that block.  For fixed codes, no bits are
+ *   spent on code descriptions.  Instead the code lengths for literal/length
+ *   codes and distance codes are fixed.  The specific lengths for each symbol
+ *   can be seen in the "for" loops below.
+ *
+ * - The literal/length code is complete, but has two symbols that are invalid
+ *   and should result in an error if received.  This cannot be implemented
+ *   simply as an incomplete code since those two symbols are in the "middle"
+ *   of the code.  They are eight bits long and the longest literal/length\
+ *   code is nine bits.  Therefore the code must be constructed with those
+ *   symbols, and the invalid symbols must be detected after decoding.
+ *
+ * - The fixed distance codes also have two invalid symbols that should result
+ *   in an error if received.  Since all of the distance codes are the same
+ *   length, this can be implemented as an incomplete code.  Then the invalid
+ *   codes are detected while decoding.
+ */
+local int fixed(struct state *s)
+{
+    static int virgin = 1;
+    static short lencnt[MAXBITS+1], lensym[FIXLCODES];
+    static short distcnt[MAXBITS+1], distsym[MAXDCODES];
+    static struct huffman lencode, distcode;
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        int symbol;
+        short lengths[FIXLCODES];
+
+        /* literal/length table */
+        for (symbol = 0; symbol < 144; symbol++)
+            lengths[symbol] = 8;
+        for (; symbol < 256; symbol++)
+            lengths[symbol] = 9;
+        for (; symbol < 280; symbol++)
+            lengths[symbol] = 7;
+        for (; symbol < FIXLCODES; symbol++)
+            lengths[symbol] = 8;
+        construct(&lencode, lengths, FIXLCODES);
+
+        /* distance table */
+        for (symbol = 0; symbol < MAXDCODES; symbol++)
+            lengths[symbol] = 5;
+        construct(&distcode, lengths, MAXDCODES);
+
+        /* construct lencode and distcode */
+        lencode.count = lencnt;
+        lencode.symbol = lensym;
+        distcode.count = distcnt;
+        distcode.symbol = distsym;
+
+        /* do this just once */
+        virgin = 0;
+    }
+
+    /* decode data until end-of-block code */
+    return codes(s, &lencode, &distcode);
+}
+
+/*
+ * Process a dynamic codes block.
+ *
+ * Format notes:
+ *
+ * - A dynamic block starts with a description of the literal/length and
+ *   distance codes for that block.  New dynamic blocks allow the compressor to
+ *   rapidly adapt to changing data with new codes optimized for that data.
+ *
+ * - The codes used by the deflate format are "canonical", which means that
+ *   the actual bits of the codes are generated in an unambiguous way simply
+ *   from the number of bits in each code.  Therefore the code descriptions
+ *   are simply a list of code lengths for each symbol.
+ *
+ * - The code lengths are stored in order for the symbols, so lengths are
+ *   provided for each of the literal/length symbols, and for each of the
+ *   distance symbols.
+ *
+ * - If a symbol is not used in the block, this is represented by a zero as
+ *   as the code length.  This does not mean a zero-length code, but rather
+ *   that no code should be created for this symbol.  There is no way in the
+ *   deflate format to represent a zero-length code.
+ *
+ * - The maximum number of bits in a code is 15, so the possible lengths for
+ *   any code are 1..15.
+ *
+ * - The fact that a length of zero is not permitted for a code has an
+ *   interesting consequence.  Normally if only one symbol is used for a given
+ *   code, then in fact that code could be represented with zero bits.  However
+ *   in deflate, that code has to be at least one bit.  So for example, if
+ *   only a single distance base symbol appears in a block, then it will be
+ *   represented by a single code of length one, in particular one 0 bit.  This
+ *   is an incomplete code, since if a 1 bit is received, it has no meaning,
+ *   and should result in an error.  So incomplete distance codes of one symbol
+ *   should be permitted, and the receipt of invalid codes should be handled.
+ *
+ * - It is also possible to have a single literal/length code, but that code
+ *   must be the end-of-block code, since every dynamic block has one.  This
+ *   is not the most efficient way to create an empty block (an empty fixed
+ *   block is fewer bits), but it is allowed by the format.  So incomplete
+ *   literal/length codes of one symbol should also be permitted.
+ *
+ * - If there are only literal codes and no lengths, then there are no distance
+ *   codes.  This is represented by one distance code with zero bits.
+ *
+ * - The list of up to 286 length/literal lengths and up to 30 distance lengths
+ *   are themselves compressed using Huffman codes and run-length encoding.  In
+ *   the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
+ *   that length, and the symbols 16, 17, and 18 are run-length instructions.
+ *   Each of 16, 17, and 18 are follwed by extra bits to define the length of
+ *   the run.  16 copies the last length 3 to 6 times.  17 represents 3 to 10
+ *   zero lengths, and 18 represents 11 to 138 zero lengths.  Unused symbols
+ *   are common, hence the special coding for zero lengths.
+ *
+ * - The symbols for 0..18 are Huffman coded, and so that code must be
+ *   described first.  This is simply a sequence of up to 19 three-bit values
+ *   representing no code (0) or the code length for that symbol (1..7).
+ *
+ * - A dynamic block starts with three fixed-size counts from which is computed
+ *   the number of literal/length code lengths, the number of distance code
+ *   lengths, and the number of code length code lengths (ok, you come up with
+ *   a better name!) in the code descriptions.  For the literal/length and
+ *   distance codes, lengths after those provided are considered zero, i.e. no
+ *   code.  The code length code lengths are received in a permuted order (see
+ *   the order[] array below) to make a short code length code length list more
+ *   likely.  As it turns out, very short and very long codes are less likely
+ *   to be seen in a dynamic code description, hence what may appear initially
+ *   to be a peculiar ordering.
+ *
+ * - Given the number of literal/length code lengths (nlen) and distance code
+ *   lengths (ndist), then they are treated as one long list of nlen + ndist
+ *   code lengths.  Therefore run-length coding can and often does cross the
+ *   boundary between the two sets of lengths.
+ *
+ * - So to summarize, the code description at the start of a dynamic block is
+ *   three counts for the number of code lengths for the literal/length codes,
+ *   the distance codes, and the code length codes.  This is followed by the
+ *   code length code lengths, three bits each.  This is used to construct the
+ *   code length code which is used to read the remainder of the lengths.  Then
+ *   the literal/length code lengths and distance lengths are read as a single
+ *   set of lengths using the code length codes.  Codes are constructed from
+ *   the resulting two sets of lengths, and then finally you can start
+ *   decoding actual compressed data in the block.
+ *
+ * - For reference, a "typical" size for the code description in a dynamic
+ *   block is around 80 bytes.
+ */
+local int dynamic(struct state *s)
+{
+    int nlen, ndist, ncode;             /* number of lengths in descriptor */
+    int index;                          /* index of lengths[] */
+    int err;                            /* construct() return value */
+    short lengths[MAXCODES];            /* descriptor code lengths */
+    short lencnt[MAXBITS+1], lensym[MAXLCODES];         /* lencode memory */
+    short distcnt[MAXBITS+1], distsym[MAXDCODES];       /* distcode memory */
+    struct huffman lencode, distcode;   /* length and distance codes */
+    static const short order[19] =      /* permutation of code length codes */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    /* construct lencode and distcode */
+    lencode.count = lencnt;
+    lencode.symbol = lensym;
+    distcode.count = distcnt;
+    distcode.symbol = distsym;
+
+    /* get number of lengths in each table, check lengths */
+    nlen = bits(s, 5) + 257;
+    ndist = bits(s, 5) + 1;
+    ncode = bits(s, 4) + 4;
+    if (nlen > MAXLCODES || ndist > MAXDCODES)
+        return -3;                      /* bad counts */
+
+    /* read code length code lengths (really), missing lengths are zero */
+    for (index = 0; index < ncode; index++)
+        lengths[order[index]] = bits(s, 3);
+    for (; index < 19; index++)
+        lengths[order[index]] = 0;
+
+    /* build huffman table for code lengths codes (use lencode temporarily) */
+    err = construct(&lencode, lengths, 19);
+    if (err != 0) return -4;            /* require complete code set here */
+
+    /* read length/literal and distance code length tables */
+    index = 0;
+    while (index < nlen + ndist) {
+        int symbol;             /* decoded value */
+        int len;                /* last length to repeat */
+
+        symbol = decode(s, &lencode);
+        if (symbol < 16)                /* length in 0..15 */
+            lengths[index++] = symbol;
+        else {                          /* repeat instruction */
+            len = 0;                    /* assume repeating zeros */
+            if (symbol == 16) {         /* repeat last length 3..6 times */
+                if (index == 0) return -5;      /* no last length! */
+                len = lengths[index - 1];       /* last length */
+                symbol = 3 + bits(s, 2);
+            }
+            else if (symbol == 17)      /* repeat zero 3..10 times */
+                symbol = 3 + bits(s, 3);
+            else                        /* == 18, repeat zero 11..138 times */
+                symbol = 11 + bits(s, 7);
+            if (index + symbol > nlen + ndist)
+                return -6;              /* too many lengths! */
+            while (symbol--)            /* repeat last or zero symbol times */
+                lengths[index++] = len;
+        }
+    }
+
+    /* check for end-of-block code -- there better be one! */
+    if (lengths[256] == 0)
+        return -9;
+
+    /* build huffman table for literal/length codes */
+    err = construct(&lencode, lengths, nlen);
+    if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1))
+        return -7;      /* only allow incomplete codes if just one code */
+
+    /* build huffman table for distance codes */
+    err = construct(&distcode, lengths + nlen, ndist);
+    if (err < 0 || (err > 0 && ndist - distcode.count[0] != 1))
+        return -8;      /* only allow incomplete codes if just one code */
+
+    /* decode data until end-of-block code */
+    return codes(s, &lencode, &distcode);
+}
+
+/*
+ * Inflate source to dest.  On return, destlen and sourcelen are updated to the
+ * size of the uncompressed data and the size of the deflate data respectively.
+ * On success, the return value of puff() is zero.  If there is an error in the
+ * source data, i.e. it is not in the deflate format, then a negative value is
+ * returned.  If there is not enough input available or there is not enough
+ * output space, then a positive error is returned.  In that case, destlen and
+ * sourcelen are not updated to facilitate retrying from the beginning with the
+ * provision of more input data or more output space.  In the case of invalid
+ * inflate data (a negative error), the dest and source pointers are updated to
+ * facilitate the debugging of deflators.
+ *
+ * puff() also has a mode to determine the size of the uncompressed output with
+ * no output written.  For this dest must be (unsigned char *)0.  In this case,
+ * the input value of *destlen is ignored, and on return *destlen is set to the
+ * size of the uncompressed output.
+ *
+ * The return codes are:
+ *
+ *   2:  available inflate data did not terminate
+ *   1:  output space exhausted before completing inflate
+ *   0:  successful inflate
+ *  -1:  invalid block type (type == 3)
+ *  -2:  stored block length did not match one's complement
+ *  -3:  dynamic block code description: too many length or distance codes
+ *  -4:  dynamic block code description: code lengths codes incomplete
+ *  -5:  dynamic block code description: repeat lengths with no first length
+ *  -6:  dynamic block code description: repeat more than specified lengths
+ *  -7:  dynamic block code description: invalid literal/length code lengths
+ *  -8:  dynamic block code description: invalid distance code lengths
+ *  -9:  dynamic block code description: missing end-of-block code
+ * -10:  invalid literal/length or distance code in fixed or dynamic block
+ * -11:  distance is too far back in fixed or dynamic block
+ *
+ * Format notes:
+ *
+ * - Three bits are read for each block to determine the kind of block and
+ *   whether or not it is the last block.  Then the block is decoded and the
+ *   process repeated if it was not the last block.
+ *
+ * - The leftover bits in the last byte of the deflate data after the last
+ *   block (if it was a fixed or dynamic block) are undefined and have no
+ *   expected values to check.
+ */
+int puff(unsigned char *dest,           /* pointer to destination pointer */
+         unsigned long *destlen,        /* amount of output space */
+         unsigned char *source,         /* pointer to source data pointer */
+         unsigned long *sourcelen)      /* amount of input available */
+{
+    struct state s;             /* input/output state */
+    int last, type;             /* block information */
+    int err;                    /* return value */
+
+    /* initialize output state */
+    s.out = dest;
+    s.outlen = *destlen;                /* ignored if dest is NIL */
+    s.outcnt = 0;
+
+    /* initialize input state */
+    s.in = source;
+    s.inlen = *sourcelen;
+    s.incnt = 0;
+    s.bitbuf = 0;
+    s.bitcnt = 0;
+
+    /* return if bits() or decode() tries to read past available input */
+    if (setjmp(s.env) != 0)             /* if came back here via longjmp() */
+        err = 2;                        /* then skip do-loop, return error */
+    else {
+        /* process blocks until last block or error */
+        do {
+            last = bits(&s, 1);         /* one if last block */
+            type = bits(&s, 2);         /* block type 0..3 */
+            err = type == 0 ? stored(&s) :
+                  (type == 1 ? fixed(&s) :
+                   (type == 2 ? dynamic(&s) :
+                    -1));               /* type == 3, invalid */
+            if (err != 0) break;        /* return with error */
+        } while (!last);
+    }
+
+    /* update the lengths and return */
+    if (err <= 0) {
+        *destlen = s.outcnt;
+        *sourcelen = s.incnt;
+    }
+    return err;
+}
+
+#ifdef TEST
+/* Examples of how to use puff().
+
+   Usage: puff [-w] [-nnn] file
+          ... | puff [-w] [-nnn]
+
+   where file is the input file with deflate data, nnn is the number of bytes
+   of input to skip before inflating (e.g. to skip a zlib or gzip header), and
+   -w is used to write the decompressed data to stdout */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Return size times approximately the cube root of 2, keeping the result as 1,
+   3, or 5 times a power of 2 -- the result is always > size, until the result
+   is the maximum value of an unsigned long, where it remains.  This is useful
+   to keep reallocations less than ~33% over the actual data. */
+local size_t bythirds(size_t size)
+{
+    int n;
+    size_t m;
+
+    m = size;
+    for (n = 0; m; n++)
+        m >>= 1;
+    if (n < 3)
+        return size + 1;
+    n -= 3;
+    m = size >> n;
+    m += m == 6 ? 2 : 1;
+    m <<= n;
+    return m > size ? m : (size_t)(-1);
+}
+
+/* Read the input file *name, or stdin if name is NULL, into allocated memory.
+   Reallocate to larger buffers until the entire file is read in.  Return a
+   pointer to the allocated data, or NULL if there was a memory allocation
+   failure.  *len is the number of bytes of data read from the input file (even
+   if load() returns NULL).  If the input file was empty or could not be opened
+   or read, *len is zero. */
+local void *load(char *name, size_t *len)
+{
+    size_t size;
+    void *buf, *swap;
+    FILE *in;
+
+    *len = 0;
+    buf = malloc(size = 4096);
+    if (buf == NULL)
+        return NULL;
+    in = name == NULL ? stdin : fopen(name, "rb");
+    if (in != NULL) {
+        for (;;) {
+            *len += fread((char *)buf + *len, 1, size - *len, in);
+            if (*len < size) break;
+            size = bythirds(size);
+            if (size == *len || (swap = realloc(buf, size)) == NULL) {
+                free(buf);
+                buf = NULL;
+                break;
+            }
+            buf = swap;
+        }
+        fclose(in);
+    }
+    return buf;
+}
+
+int main(int argc, char **argv)
+{
+    int ret, put = 0;
+    unsigned skip = 0;
+    char *arg, *name = NULL;
+    unsigned char *source = NULL, *dest;
+    size_t len = 0;
+    unsigned long sourcelen, destlen;
+
+    /* process arguments */
+    while (arg = *++argv, --argc)
+        if (arg[0] == '-') {
+            if (arg[1] == 'w' && arg[2] == 0)
+                put = 1;
+            else if (arg[1] >= '0' && arg[1] <= '9')
+                skip = (unsigned)atoi(arg + 1);
+            else {
+                fprintf(stderr, "invalid option %s\n", arg);
+                return 3;
+            }
+        }
+        else if (name != NULL) {
+            fprintf(stderr, "only one file name allowed\n");
+            return 3;
+        }
+        else
+            name = arg;
+    source = load(name, &len);
+    if (source == NULL) {
+        fprintf(stderr, "memory allocation failure\n");
+        return 4;
+    }
+    if (len == 0) {
+        fprintf(stderr, "could not read %s, or it was empty\n",
+                name == NULL ? "<stdin>" : name);
+        free(source);
+        return 3;
+    }
+    if (skip >= len) {
+        fprintf(stderr, "skip request of %d leaves no input\n", skip);
+        free(source);
+        return 3;
+    }
+
+    /* test inflate data with offset skip */
+    len -= skip;
+    sourcelen = (unsigned long)len;
+    ret = puff(NIL, &destlen, source + skip, &sourcelen);
+    if (ret)
+        fprintf(stderr, "puff() failed with return code %d\n", ret);
+    else {
+        fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
+        if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
+                                     len - sourcelen);
+    }
+
+    /* if requested, inflate again and write decompressd data to stdout */
+    if (put) {
+        dest = malloc(destlen);
+        if (dest == NULL) {
+            fprintf(stderr, "memory allocation failure\n");
+            free(source);
+            return 4;
+        }
+        puff(dest, &destlen, source + skip, &sourcelen);
+        fwrite(dest, 1, destlen, stdout);
+        free(dest);
+    }
+
+    /* clean up */
+    free(source);
+    return ret;
+}
+#endif
diff --git a/8.x/zlib/contrib/puff/puff.h b/8.x/zlib/contrib/puff/puff.h
new file mode 100644 (file)
index 0000000..88d1b38
--- /dev/null
@@ -0,0 +1,31 @@
+/* puff.h
+  Copyright (C) 2002-2010 Mark Adler, all rights reserved
+  version 2.1, 4 Apr 2010
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+
+/*
+ * See puff.c for purpose and usage.
+ */
+int puff(unsigned char *dest,           /* pointer to destination pointer */
+         unsigned long *destlen,        /* amount of output space */
+         unsigned char *source,         /* pointer to source data pointer */
+         unsigned long *sourcelen);     /* amount of input available */
diff --git a/8.x/zlib/contrib/puff/zeros.raw b/8.x/zlib/contrib/puff/zeros.raw
new file mode 100644 (file)
index 0000000..637b7be
Binary files /dev/null and b/8.x/zlib/contrib/puff/zeros.raw differ
diff --git a/8.x/zlib/contrib/testzlib/testzlib.c b/8.x/zlib/contrib/testzlib/testzlib.c
new file mode 100644 (file)
index 0000000..135888e
--- /dev/null
@@ -0,0 +1,275 @@
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <windows.h>\r
+\r
+#include "zlib.h"\r
+\r
+\r
+void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)\r
+{\r
+    R->HighPart = A.HighPart - B.HighPart;\r
+    if (A.LowPart >= B.LowPart)\r
+        R->LowPart = A.LowPart - B.LowPart;\r
+    else\r
+    {\r
+        R->LowPart = A.LowPart - B.LowPart;\r
+        R->HighPart --;\r
+    }\r
+}\r
+\r
+#ifdef _M_X64\r
+// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc\r
+unsigned __int64 __rdtsc(void);\r
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)\r
+{\r
+ //   printf("rdtsc = %I64x\n",__rdtsc());\r
+   pbeginTime64->QuadPart=__rdtsc();\r
+}\r
+\r
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)\r
+{\r
+    LARGE_INTEGER LIres;\r
+    unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart));\r
+    LIres.QuadPart=res;\r
+   // printf("rdtsc = %I64x\n",__rdtsc());\r
+    return LIres;\r
+}\r
+#else\r
+#ifdef _M_IX86\r
+void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)\r
+{\r
+    DWORD dwEdx,dwEax;\r
+    _asm\r
+    {\r
+        rdtsc\r
+        mov dwEax,eax\r
+        mov dwEdx,edx\r
+    }\r
+    pbeginTime64->LowPart=dwEax;\r
+    pbeginTime64->HighPart=dwEdx;\r
+}\r
+\r
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)\r
+{\r
+    myGetRDTSC32(pbeginTime64);\r
+}\r
+\r
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)\r
+{\r
+    LARGE_INTEGER LIres,endTime64;\r
+    myGetRDTSC32(&endTime64);\r
+\r
+    LIres.LowPart=LIres.HighPart=0;\r
+    MyDoMinus64(&LIres,endTime64,beginTime64);\r
+    return LIres;\r
+}\r
+#else\r
+void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)\r
+{\r
+}\r
+\r
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)\r
+{\r
+}\r
+\r
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)\r
+{\r
+    LARGE_INTEGER lr;\r
+    lr.QuadPart=0;\r
+    return lr;\r
+}\r
+#endif\r
+#endif\r
+\r
+void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)\r
+{\r
+    if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))\r
+    {\r
+        pbeginTime64->LowPart = GetTickCount();\r
+        pbeginTime64->HighPart = 0;\r
+    }\r
+}\r
+\r
+DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)\r
+{\r
+    LARGE_INTEGER endTime64,ticksPerSecond,ticks;\r
+    DWORDLONG ticksShifted,tickSecShifted;\r
+    DWORD dwLog=16+0;\r
+    DWORD dwRet;\r
+    if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))\r
+        dwRet = (GetTickCount() - beginTime64.LowPart)*1;\r
+    else\r
+    {\r
+        MyDoMinus64(&ticks,endTime64,beginTime64);\r
+        QueryPerformanceFrequency(&ticksPerSecond);\r
+\r
+\r
+        {\r
+            ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);\r
+            tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);\r
+\r
+        }\r
+\r
+        dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));\r
+        dwRet *=1;\r
+    }\r
+    return dwRet;\r
+}\r
+\r
+int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)\r
+{\r
+    FILE* stream;\r
+    void* ptr;\r
+    int retVal=1;\r
+    stream=fopen(filename, "rb");\r
+    if (stream==NULL)\r
+        return 0;\r
+\r
+    fseek(stream,0,SEEK_END);\r
+\r
+    *plFileSize=ftell(stream);\r
+    fseek(stream,0,SEEK_SET);\r
+    ptr=malloc((*plFileSize)+1);\r
+    if (ptr==NULL)\r
+        retVal=0;\r
+    else\r
+    {\r
+        if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))\r
+            retVal=0;\r
+    }\r
+    fclose(stream);\r
+    *pFilePtr=ptr;\r
+    return retVal;\r
+}\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+    int BlockSizeCompress=0x8000;\r
+    int BlockSizeUncompress=0x8000;\r
+    int cprLevel=Z_DEFAULT_COMPRESSION ;\r
+    long lFileSize;\r
+    unsigned char* FilePtr;\r
+    long lBufferSizeCpr;\r
+    long lBufferSizeUncpr;\r
+    long lCompressedSize=0;\r
+    unsigned char* CprPtr;\r
+    unsigned char* UncprPtr;\r
+    long lSizeCpr,lSizeUncpr;\r
+    DWORD dwGetTick,dwMsecQP;\r
+    LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;\r
+\r
+    if (argc<=1)\r
+    {\r
+        printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");\r
+        return 0;\r
+    }\r
+\r
+    if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)\r
+    {\r
+        printf("error reading %s\n",argv[1]);\r
+        return 1;\r
+    }\r
+    else printf("file %s read, %u bytes\n",argv[1],lFileSize);\r
+\r
+    if (argc>=3)\r
+        BlockSizeCompress=atol(argv[2]);\r
+\r
+    if (argc>=4)\r
+        BlockSizeUncompress=atol(argv[3]);\r
+\r
+    if (argc>=5)\r
+        cprLevel=(int)atol(argv[4]);\r
+\r
+    lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;\r
+    lBufferSizeUncpr = lBufferSizeCpr;\r
+\r
+    CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);\r
+\r
+    BeginCountPerfCounter(&li_qp,TRUE);\r
+    dwGetTick=GetTickCount();\r
+    BeginCountRdtsc(&li_rdtsc);\r
+    {\r
+        z_stream zcpr;\r
+        int ret=Z_OK;\r
+        long lOrigToDo = lFileSize;\r
+        long lOrigDone = 0;\r
+        int step=0;\r
+        memset(&zcpr,0,sizeof(z_stream));\r
+        deflateInit(&zcpr,cprLevel);\r
+\r
+        zcpr.next_in = FilePtr;\r
+        zcpr.next_out = CprPtr;\r
+\r
+\r
+        do\r
+        {\r
+            long all_read_before = zcpr.total_in;\r
+            zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);\r
+            zcpr.avail_out = BlockSizeCompress;\r
+            ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);\r
+            lOrigDone += (zcpr.total_in-all_read_before);\r
+            lOrigToDo -= (zcpr.total_in-all_read_before);\r
+            step++;\r
+        } while (ret==Z_OK);\r
+\r
+        lSizeCpr=zcpr.total_out;\r
+        deflateEnd(&zcpr);\r
+        dwGetTick=GetTickCount()-dwGetTick;\r
+        dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);\r
+        dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);\r
+        printf("total compress size = %u, in %u step\n",lSizeCpr,step);\r
+        printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);\r
+        printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);\r
+        printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);\r
+    }\r
+\r
+    CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);\r
+    UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);\r
+\r
+    BeginCountPerfCounter(&li_qp,TRUE);\r
+    dwGetTick=GetTickCount();\r
+    BeginCountRdtsc(&li_rdtsc);\r
+    {\r
+        z_stream zcpr;\r
+        int ret=Z_OK;\r
+        long lOrigToDo = lSizeCpr;\r
+        long lOrigDone = 0;\r
+        int step=0;\r
+        memset(&zcpr,0,sizeof(z_stream));\r
+        inflateInit(&zcpr);\r
+\r
+        zcpr.next_in = CprPtr;\r
+        zcpr.next_out = UncprPtr;\r
+\r
+\r
+        do\r
+        {\r
+            long all_read_before = zcpr.total_in;\r
+            zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);\r
+            zcpr.avail_out = BlockSizeUncompress;\r
+            ret=inflate(&zcpr,Z_SYNC_FLUSH);\r
+            lOrigDone += (zcpr.total_in-all_read_before);\r
+            lOrigToDo -= (zcpr.total_in-all_read_before);\r
+            step++;\r
+        } while (ret==Z_OK);\r
+\r
+        lSizeUncpr=zcpr.total_out;\r
+        inflateEnd(&zcpr);\r
+        dwGetTick=GetTickCount()-dwGetTick;\r
+        dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);\r
+        dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);\r
+        printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);\r
+        printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);\r
+        printf("uncpr  time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);\r
+        printf("uncpr  result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);\r
+    }\r
+\r
+    if (lSizeUncpr==lFileSize)\r
+    {\r
+        if (memcmp(FilePtr,UncprPtr,lFileSize)==0)\r
+            printf("compare ok\n");\r
+\r
+    }\r
+\r
+    return 0;\r
+}\r
diff --git a/8.x/zlib/contrib/testzlib/testzlib.txt b/8.x/zlib/contrib/testzlib/testzlib.txt
new file mode 100644 (file)
index 0000000..62258f1
--- /dev/null
@@ -0,0 +1,10 @@
+To build testzLib with Visual Studio 2005:\r
+\r
+copy to a directory file from :\r
+- root of zLib tree\r
+- contrib/testzlib\r
+- contrib/masmx86\r
+- contrib/masmx64\r
+- contrib/vstudio/vc7\r
+\r
+and open testzlib8.sln
\ No newline at end of file
diff --git a/8.x/zlib/contrib/untgz/Makefile b/8.x/zlib/contrib/untgz/Makefile
new file mode 100644 (file)
index 0000000..b54266f
--- /dev/null
@@ -0,0 +1,14 @@
+CC=cc
+CFLAGS=-g
+
+untgz: untgz.o ../../libz.a
+       $(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz
+
+untgz.o: untgz.c ../../zlib.h
+       $(CC) $(CFLAGS) -c -I../.. untgz.c
+
+../../libz.a:
+       cd ../..; ./configure; make
+
+clean:
+       rm -f untgz untgz.o *~
diff --git a/8.x/zlib/contrib/untgz/Makefile.msc b/8.x/zlib/contrib/untgz/Makefile.msc
new file mode 100644 (file)
index 0000000..77b8602
--- /dev/null
@@ -0,0 +1,17 @@
+CC=cl
+CFLAGS=-MD
+
+untgz.exe: untgz.obj ..\..\zlib.lib
+       $(CC) $(CFLAGS) untgz.obj ..\..\zlib.lib
+
+untgz.obj: untgz.c ..\..\zlib.h
+       $(CC) $(CFLAGS) -c -I..\.. untgz.c
+
+..\..\zlib.lib:
+       cd ..\..
+       $(MAKE) -f win32\makefile.msc
+       cd contrib\untgz
+
+clean:
+       -del untgz.obj
+       -del untgz.exe
diff --git a/8.x/zlib/contrib/untgz/untgz.c b/8.x/zlib/contrib/untgz/untgz.c
new file mode 100644 (file)
index 0000000..2c391e5
--- /dev/null
@@ -0,0 +1,674 @@
+/*
+ * untgz.c -- Display contents and extract files from a gzip'd TAR file
+ *
+ * written by Pedro A. Aranda Gutierrez <paag@tid.es>
+ * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
+ * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+#include "zlib.h"
+
+#ifdef unix
+#  include <unistd.h>
+#else
+#  include <direct.h>
+#  include <io.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#  ifndef F_OK
+#    define F_OK  0
+#  endif
+#  define mkdir(dirname,mode)   _mkdir(dirname)
+#  ifdef _MSC_VER
+#    define access(path,mode)   _access(path,mode)
+#    define chmod(path,mode)    _chmod(path,mode)
+#    define strdup(str)         _strdup(str)
+#  endif
+#else
+#  include <utime.h>
+#endif
+
+
+/* values used in typeflag field */
+
+#define REGTYPE  '0'            /* regular file */
+#define AREGTYPE '\0'           /* regular file */
+#define LNKTYPE  '1'            /* link */
+#define SYMTYPE  '2'            /* reserved */
+#define CHRTYPE  '3'            /* character special */
+#define BLKTYPE  '4'            /* block special */
+#define DIRTYPE  '5'            /* directory */
+#define FIFOTYPE '6'            /* FIFO special */
+#define CONTTYPE '7'            /* reserved */
+
+/* GNU tar extensions */
+
+#define GNUTYPE_DUMPDIR  'D'    /* file names from dumped directory */
+#define GNUTYPE_LONGLINK 'K'    /* long link name */
+#define GNUTYPE_LONGNAME 'L'    /* long file name */
+#define GNUTYPE_MULTIVOL 'M'    /* continuation of file from another volume */
+#define GNUTYPE_NAMES    'N'    /* file name that does not fit into main hdr */
+#define GNUTYPE_SPARSE   'S'    /* sparse file */
+#define GNUTYPE_VOLHDR   'V'    /* tape/volume header */
+
+
+/* tar header */
+
+#define BLOCKSIZE     512
+#define SHORTNAMESIZE 100
+
+struct tar_header
+{                               /* byte offset */
+  char name[100];               /*   0 */
+  char mode[8];                 /* 100 */
+  char uid[8];                  /* 108 */
+  char gid[8];                  /* 116 */
+  char size[12];                /* 124 */
+  char mtime[12];               /* 136 */
+  char chksum[8];               /* 148 */
+  char typeflag;                /* 156 */
+  char linkname[100];           /* 157 */
+  char magic[6];                /* 257 */
+  char version[2];              /* 263 */
+  char uname[32];               /* 265 */
+  char gname[32];               /* 297 */
+  char devmajor[8];             /* 329 */
+  char devminor[8];             /* 337 */
+  char prefix[155];             /* 345 */
+                                /* 500 */
+};
+
+union tar_buffer
+{
+  char               buffer[BLOCKSIZE];
+  struct tar_header  header;
+};
+
+struct attr_item
+{
+  struct attr_item  *next;
+  char              *fname;
+  int                mode;
+  time_t             time;
+};
+
+enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };
+
+char *TGZfname          OF((const char *));
+void TGZnotfound        OF((const char *));
+
+int getoct              OF((char *, int));
+char *strtime           OF((time_t *));
+int setfiletime         OF((char *, time_t));
+void push_attr          OF((struct attr_item **, char *, int, time_t));
+void restore_attr       OF((struct attr_item **));
+
+int ExprMatch           OF((char *, char *));
+
+int makedir             OF((char *));
+int matchname           OF((int, int, char **, char *));
+
+void error              OF((const char *));
+int tar                 OF((gzFile, int, int, int, char **));
+
+void help               OF((int));
+int main                OF((int, char **));
+
+char *prog;
+
+const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL };
+
+/* return the file name of the TGZ archive */
+/* or NULL if it does not exist */
+
+char *TGZfname (const char *arcname)
+{
+  static char buffer[1024];
+  int origlen,i;
+
+  strcpy(buffer,arcname);
+  origlen = strlen(buffer);
+
+  for (i=0; TGZsuffix[i]; i++)
+    {
+       strcpy(buffer+origlen,TGZsuffix[i]);
+       if (access(buffer,F_OK) == 0)
+         return buffer;
+    }
+  return NULL;
+}
+
+
+/* error message for the filename */
+
+void TGZnotfound (const char *arcname)
+{
+  int i;
+
+  fprintf(stderr,"%s: Couldn't find ",prog);
+  for (i=0;TGZsuffix[i];i++)
+    fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n",
+            arcname,
+            TGZsuffix[i]);
+  exit(1);
+}
+
+
+/* convert octal digits to int */
+/* on error return -1 */
+
+int getoct (char *p,int width)
+{
+  int result = 0;
+  char c;
+
+  while (width--)
+    {
+      c = *p++;
+      if (c == 0)
+        break;
+      if (c == ' ')
+        continue;
+      if (c < '0' || c > '7')
+        return -1;
+      result = result * 8 + (c - '0');
+    }
+  return result;
+}
+
+
+/* convert time_t to string */
+/* use the "YYYY/MM/DD hh:mm:ss" format */
+
+char *strtime (time_t *t)
+{
+  struct tm   *local;
+  static char result[32];
+
+  local = localtime(t);
+  sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d",
+          local->tm_year+1900, local->tm_mon+1, local->tm_mday,
+          local->tm_hour, local->tm_min, local->tm_sec);
+  return result;
+}
+
+
+/* set file time */
+
+int setfiletime (char *fname,time_t ftime)
+{
+#ifdef WIN32
+  static int isWinNT = -1;
+  SYSTEMTIME st;
+  FILETIME locft, modft;
+  struct tm *loctm;
+  HANDLE hFile;
+  int result;
+
+  loctm = localtime(&ftime);
+  if (loctm == NULL)
+    return -1;
+
+  st.wYear         = (WORD)loctm->tm_year + 1900;
+  st.wMonth        = (WORD)loctm->tm_mon + 1;
+  st.wDayOfWeek    = (WORD)loctm->tm_wday;
+  st.wDay          = (WORD)loctm->tm_mday;
+  st.wHour         = (WORD)loctm->tm_hour;
+  st.wMinute       = (WORD)loctm->tm_min;
+  st.wSecond       = (WORD)loctm->tm_sec;
+  st.wMilliseconds = 0;
+  if (!SystemTimeToFileTime(&st, &locft) ||
+      !LocalFileTimeToFileTime(&locft, &modft))
+    return -1;
+
+  if (isWinNT < 0)
+    isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;
+  hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+                     (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),
+                     NULL);
+  if (hFile == INVALID_HANDLE_VALUE)
+    return -1;
+  result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1;
+  CloseHandle(hFile);
+  return result;
+#else
+  struct utimbuf settime;
+
+  settime.actime = settime.modtime = ftime;
+  return utime(fname,&settime);
+#endif
+}
+
+
+/* push file attributes */
+
+void push_attr(struct attr_item **list,char *fname,int mode,time_t time)
+{
+  struct attr_item *item;
+
+  item = (struct attr_item *)malloc(sizeof(struct attr_item));
+  if (item == NULL)
+    error("Out of memory");
+  item->fname = strdup(fname);
+  item->mode  = mode;
+  item->time  = time;
+  item->next  = *list;
+  *list       = item;
+}
+
+
+/* restore file attributes */
+
+void restore_attr(struct attr_item **list)
+{
+  struct attr_item *item, *prev;
+
+  for (item = *list; item != NULL; )
+    {
+      setfiletime(item->fname,item->time);
+      chmod(item->fname,item->mode);
+      prev = item;
+      item = item->next;
+      free(prev);
+    }
+  *list = NULL;
+}
+
+
+/* match regular expression */
+
+#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
+
+int ExprMatch (char *string,char *expr)
+{
+  while (1)
+    {
+      if (ISSPECIAL(*expr))
+        {
+          if (*expr == '/')
+            {
+              if (*string != '\\' && *string != '/')
+                return 0;
+              string ++; expr++;
+            }
+          else if (*expr == '*')
+            {
+              if (*expr ++ == 0)
+                return 1;
+              while (*++string != *expr)
+                if (*string == 0)
+                  return 0;
+            }
+        }
+      else
+        {
+          if (*string != *expr)
+            return 0;
+          if (*expr++ == 0)
+            return 1;
+          string++;
+        }
+    }
+}
+
+
+/* recursive mkdir */
+/* abort on ENOENT; ignore other errors like "directory already exists" */
+/* return 1 if OK */
+/*        0 on error */
+
+int makedir (char *newdir)
+{
+  char *buffer = strdup(newdir);
+  char *p;
+  int  len = strlen(buffer);
+
+  if (len <= 0) {
+    free(buffer);
+    return 0;
+  }
+  if (buffer[len-1] == '/') {
+    buffer[len-1] = '\0';
+  }
+  if (mkdir(buffer, 0755) == 0)
+    {
+      free(buffer);
+      return 1;
+    }
+
+  p = buffer+1;
+  while (1)
+    {
+      char hold;
+
+      while(*p && *p != '\\' && *p != '/')
+        p++;
+      hold = *p;
+      *p = 0;
+      if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT))
+        {
+          fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer);
+          free(buffer);
+          return 0;
+        }
+      if (hold == 0)
+        break;
+      *p++ = hold;
+    }
+  free(buffer);
+  return 1;
+}
+
+
+int matchname (int arg,int argc,char **argv,char *fname)
+{
+  if (arg == argc)      /* no arguments given (untgz tgzarchive) */
+    return 1;
+
+  while (arg < argc)
+    if (ExprMatch(fname,argv[arg++]))
+      return 1;
+
+  return 0; /* ignore this for the moment being */
+}
+
+
+/* tar file list or extract */
+
+int tar (gzFile in,int action,int arg,int argc,char **argv)
+{
+  union  tar_buffer buffer;
+  int    len;
+  int    err;
+  int    getheader = 1;
+  int    remaining = 0;
+  FILE   *outfile = NULL;
+  char   fname[BLOCKSIZE];
+  int    tarmode;
+  time_t tartime;
+  struct attr_item *attributes = NULL;
+
+  if (action == TGZ_LIST)
+    printf("    date      time     size                       file\n"
+           " ---------- -------- --------- -------------------------------------\n");
+  while (1)
+    {
+      len = gzread(in, &buffer, BLOCKSIZE);
+      if (len < 0)
+        error(gzerror(in, &err));
+      /*
+       * Always expect complete blocks to process
+       * the tar information.
+       */
+      if (len != BLOCKSIZE)
+        {
+          action = TGZ_INVALID; /* force error exit */
+          remaining = 0;        /* force I/O cleanup */
+        }
+
+      /*
+       * If we have to get a tar header
+       */
+      if (getheader >= 1)
+        {
+          /*
+           * if we met the end of the tar
+           * or the end-of-tar block,
+           * we are done
+           */
+          if (len == 0 || buffer.header.name[0] == 0)
+            break;
+
+          tarmode = getoct(buffer.header.mode,8);
+          tartime = (time_t)getoct(buffer.header.mtime,12);
+          if (tarmode == -1 || tartime == (time_t)-1)
+            {
+              buffer.header.name[0] = 0;
+              action = TGZ_INVALID;
+            }
+
+          if (getheader == 1)
+            {
+              strncpy(fname,buffer.header.name,SHORTNAMESIZE);
+              if (fname[SHORTNAMESIZE-1] != 0)
+                  fname[SHORTNAMESIZE] = 0;
+            }
+          else
+            {
+              /*
+               * The file name is longer than SHORTNAMESIZE
+               */
+              if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
+                  error("bad long name");
+              getheader = 1;
+            }
+
+          /*
+           * Act according to the type flag
+           */
+          switch (buffer.header.typeflag)
+            {
+            case DIRTYPE:
+              if (action == TGZ_LIST)
+                printf(" %s     <dir> %s\n",strtime(&tartime),fname);
+              if (action == TGZ_EXTRACT)
+                {
+                  makedir(fname);
+                  push_attr(&attributes,fname,tarmode,tartime);
+                }
+              break;
+            case REGTYPE:
+            case AREGTYPE:
+              remaining = getoct(buffer.header.size,12);
+              if (remaining == -1)
+                {
+                  action = TGZ_INVALID;
+                  break;
+                }
+              if (action == TGZ_LIST)
+                printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
+              else if (action == TGZ_EXTRACT)
+                {
+                  if (matchname(arg,argc,argv,fname))
+                    {
+                      outfile = fopen(fname,"wb");
+                      if (outfile == NULL) {
+                        /* try creating directory */
+                        char *p = strrchr(fname, '/');
+                        if (p != NULL) {
+                          *p = '\0';
+                          makedir(fname);
+                          *p = '/';
+                          outfile = fopen(fname,"wb");
+                        }
+                      }
+                      if (outfile != NULL)
+                        printf("Extracting %s\n",fname);
+                      else
+                        fprintf(stderr, "%s: Couldn't create %s",prog,fname);
+                    }
+                  else
+                    outfile = NULL;
+                }
+              getheader = 0;
+              break;
+            case GNUTYPE_LONGLINK:
+            case GNUTYPE_LONGNAME:
+              remaining = getoct(buffer.header.size,12);
+              if (remaining < 0 || remaining >= BLOCKSIZE)
+                {
+                  action = TGZ_INVALID;
+                  break;
+                }
+              len = gzread(in, fname, BLOCKSIZE);
+              if (len < 0)
+                error(gzerror(in, &err));
+              if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
+                {
+                  action = TGZ_INVALID;
+                  break;
+                }
+              getheader = 2;
+              break;
+            default:
+              if (action == TGZ_LIST)
+                printf(" %s     <---> %s\n",strtime(&tartime),fname);
+              break;
+            }
+        }
+      else
+        {
+          unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
+
+          if (outfile != NULL)
+            {
+              if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
+                {
+                  fprintf(stderr,
+                    "%s: Error writing %s -- skipping\n",prog,fname);
+                  fclose(outfile);
+                  outfile = NULL;
+                  remove(fname);
+                }
+            }
+          remaining -= bytes;
+        }
+
+      if (remaining == 0)
+        {
+          getheader = 1;
+          if (outfile != NULL)
+            {
+              fclose(outfile);
+              outfile = NULL;
+              if (action != TGZ_INVALID)
+                push_attr(&attributes,fname,tarmode,tartime);
+            }
+        }
+
+      /*
+       * Abandon if errors are found
+       */
+      if (action == TGZ_INVALID)
+        {
+          error("broken archive");
+          break;
+        }
+    }
+
+  /*
+   * Restore file modes and time stamps
+   */
+  restore_attr(&attributes);
+
+  if (gzclose(in) != Z_OK)
+    error("failed gzclose");
+
+  return 0;
+}
+
+
+/* ============================================================ */
+
+void help(int exitval)
+{
+  printf("untgz version 0.2.1\n"
+         "  using zlib version %s\n\n",
+         zlibVersion());
+  printf("Usage: untgz file.tgz            extract all files\n"
+         "       untgz file.tgz fname ...  extract selected files\n"
+         "       untgz -l file.tgz         list archive contents\n"
+         "       untgz -h                  display this help\n");
+  exit(exitval);
+}
+
+void error(const char *msg)
+{
+  fprintf(stderr, "%s: %s\n", prog, msg);
+  exit(1);
+}
+
+
+/* ============================================================ */
+
+#if defined(WIN32) && defined(__GNUC__)
+int _CRT_glob = 0;      /* disable argument globbing in MinGW */
+#endif
+
+int main(int argc,char **argv)
+{
+    int         action = TGZ_EXTRACT;
+    int         arg = 1;
+    char        *TGZfile;
+    gzFile      *f;
+
+    prog = strrchr(argv[0],'\\');
+    if (prog == NULL)
+      {
+        prog = strrchr(argv[0],'/');
+        if (prog == NULL)
+          {
+            prog = strrchr(argv[0],':');
+            if (prog == NULL)
+              prog = argv[0];
+            else
+              prog++;
+          }
+        else
+          prog++;
+      }
+    else
+      prog++;
+
+    if (argc == 1)
+      help(0);
+
+    if (strcmp(argv[arg],"-l") == 0)
+      {
+        action = TGZ_LIST;
+        if (argc == ++arg)
+          help(0);
+      }
+    else if (strcmp(argv[arg],"-h") == 0)
+      {
+        help(0);
+      }
+
+    if ((TGZfile = TGZfname(argv[arg])) == NULL)
+      TGZnotfound(argv[arg]);
+
+    ++arg;
+    if ((action == TGZ_LIST) && (arg != argc))
+      help(1);
+
+/*
+ *  Process the TGZ file
+ */
+    switch(action)
+      {
+      case TGZ_LIST:
+      case TGZ_EXTRACT:
+        f = gzopen(TGZfile,"rb");
+        if (f == NULL)
+          {
+            fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile);
+            return 1;
+          }
+        exit(tar(f, action, arg, argc, argv));
+      break;
+
+      default:
+        error("Unknown option");
+        exit(1);
+      }
+
+    return 0;
+}
diff --git a/8.x/zlib/contrib/vstudio/readme.txt b/8.x/zlib/contrib/vstudio/readme.txt
new file mode 100644 (file)
index 0000000..904888b
--- /dev/null
@@ -0,0 +1,60 @@
+Building instructions for the DLL versions of Zlib 1.2.4\r
+========================================================\r
+\r
+This directory contains projects that build zlib and minizip using\r
+Microsoft Visual C++ 9.0/10.0, and Visual C++ .\r
+\r
+You don't need to build these projects yourself. You can download the\r
+binaries from:\r
+  http://www.winimage.com/zLibDll\r
+\r
+More information can be found at this site.\r
+\r
+first compile assembly code by running\r
+bld_ml64.bat in contrib\masmx64\r
+bld_ml32.bat in contrib\masmx86\r
+\r
+\r
+\r
+\r
+Build instructions for Visual Studio 2008 (32 bits or 64 bits)\r
+--------------------------------------------------------------\r
+- Uncompress current zlib, including all contrib/* files\r
+- Open contrib\vstudio\vc9\zlibvc.sln with Microsoft Visual C++ 2008.0\r
+- Or run: vcbuild /rebuild contrib\vstudio\vc9\zlibvc.sln "Release|Win32"\r
+\r
+Build instructions for Visual Studio 2010 (32 bits or 64 bits)\r
+--------------------------------------------------------------\r
+- Uncompress current zlib, including all contrib/* files\r
+- Open contrib\vstudio\vc10\zlibvc.sln with Microsoft Visual C++ 2010.0\r
+\r
+\r
+Important\r
+---------\r
+- To use zlibwapi.dll in your application, you must define the\r
+  macro ZLIB_WINAPI when compiling your application's source files.\r
+\r
+\r
+Additional notes\r
+----------------\r
+- This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built\r
+  by Gilles Vollant from the zlib 1.1.x sources, and distributed at\r
+    http://www.winimage.com/zLibDll\r
+  It uses the WINAPI calling convention for the exported functions, and\r
+  includes the minizip functionality. If your application needs that\r
+  particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll.\r
+\r
+- The new DLL was renamed because there exist several incompatible\r
+  versions of zlib.dll on the Internet.\r
+\r
+- There is also an official DLL build of zlib, named zlib1.dll. This one\r
+  is exporting the functions using the CDECL convention. See the file\r
+  win32\DLL_FAQ.txt found in this zlib distribution.\r
+\r
+- There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol\r
+  has a slightly different effect. To avoid compatibility problems, do\r
+  not define it here.\r
+\r
+\r
+Gilles Vollant\r
+info@winimage.com\r
diff --git a/8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj b/8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj
new file mode 100644 (file)
index 0000000..74e15c9
--- /dev/null
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Itanium">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Itanium">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\minizip\miniunz.c" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="zlibvc.vcxproj">\r
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters b/8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters
new file mode 100644 (file)
index 0000000..0b2a3de
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{048af943-022b-4db6-beeb-a54c34774ee2}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{c1d600d2-888f-4aea-b73e-8b0dd9befa0c}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{0844199a-966b-4f19-81db-1e0125e141b9}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\minizip\miniunz.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj.user b/8.x/zlib/contrib/vstudio/vc10/miniunz.vcxproj.user
new file mode 100644 (file)
index 0000000..695b5c7
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj b/8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj
new file mode 100644 (file)
index 0000000..917e156
--- /dev/null
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Itanium">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Itanium">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\minizip\minizip.c" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="zlibvc.vcxproj">\r
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters b/8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters
new file mode 100644 (file)
index 0000000..dd73cd3
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{c0419b40-bf50-40da-b153-ff74215b79de}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{bb87b070-735b-478e-92ce-7383abb2f36c}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{f46ab6a6-548f-43cb-ae96-681abb5bd5db}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\minizip\minizip.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj.user b/8.x/zlib/contrib/vstudio/vc10/minizip.vcxproj.user
new file mode 100644 (file)
index 0000000..695b5c7
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj b/8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj
new file mode 100644 (file)
index 0000000..9088d17
--- /dev/null
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Itanium">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Itanium">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>\r
+    <RootNamespace>testzlib</RootNamespace>\r
+    <Keyword>Win32Proj</Keyword>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <ClCompile>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">\r
+    <ClCompile>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <ClCompile>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\..\adler32.c" />\r
+    <ClCompile Include="..\..\..\compress.c" />\r
+    <ClCompile Include="..\..\..\crc32.c" />\r
+    <ClCompile Include="..\..\..\deflate.c" />\r
+    <ClCompile Include="..\..\..\infback.c" />\r
+    <ClCompile Include="..\..\masmx64\inffas8664.c">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inffast.c" />\r
+    <ClCompile Include="..\..\..\inflate.c" />\r
+    <ClCompile Include="..\..\..\inftrees.c" />\r
+    <ClCompile Include="..\..\testzlib\testzlib.c" />\r
+    <ClCompile Include="..\..\..\trees.c" />\r
+    <ClCompile Include="..\..\..\uncompr.c" />\r
+    <ClCompile Include="..\..\..\zutil.c" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters b/8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters
new file mode 100644 (file)
index 0000000..249daa8
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{c1f6a2e3-5da5-4955-8653-310d3efe05a9}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{c2aaffdc-2c95-4d6f-8466-4bec5890af2c}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{c274fe07-05f2-461c-964b-f6341e4e7eb5}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\..\adler32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\compress.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\crc32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\deflate.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\infback.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\masmx64\inffas8664.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inffast.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inflate.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inftrees.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\testzlib\testzlib.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\trees.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\uncompr.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\zutil.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj.user b/8.x/zlib/contrib/vstudio/vc10/testzlib.vcxproj.user
new file mode 100644 (file)
index 0000000..695b5c7
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj b/8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
new file mode 100644 (file)
index 0000000..2d62815
--- /dev/null
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Itanium">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Itanium">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <OmitFramePointers>true</OmitFramePointers>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Console</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\testzlib\testzlib.c" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="zlibvc.vcxproj">\r
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters b/8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters
new file mode 100644 (file)
index 0000000..53a8693
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{fa61a89f-93fc-4c89-b29e-36224b7592f4}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{d4b85da0-2ba2-4934-b57f-e2584e3848ee}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{e573e075-00bd-4a7d-bd67-a8cc9bfc5aca}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\testzlib\testzlib.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.user b/8.x/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.user
new file mode 100644 (file)
index 0000000..695b5c7
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlib.rc b/8.x/zlib/contrib/vstudio/vc10/zlib.rc
new file mode 100644 (file)
index 0000000..f822450
--- /dev/null
@@ -0,0 +1,32 @@
+#include <windows.h>\r
+\r
+#define IDR_VERSION1  1\r
+IDR_VERSION1   VERSIONINFO     MOVEABLE IMPURE LOADONCALL DISCARDABLE\r
+  FILEVERSION   1,2,5,0\r
+  PRODUCTVERSION 1,2,5,0\r
+  FILEFLAGSMASK        VS_FFI_FILEFLAGSMASK\r
+  FILEFLAGS    0\r
+  FILEOS       VOS_DOS_WINDOWS32\r
+  FILETYPE     VFT_DLL\r
+  FILESUBTYPE  0       // not used\r
+BEGIN\r
+  BLOCK "StringFileInfo"\r
+  BEGIN\r
+    BLOCK "040904E4"\r
+    //language ID = U.S. English, char set = Windows, Multilingual\r
+\r
+    BEGIN\r
+      VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"\r
+      VALUE "FileVersion",     "1.2.5\0"\r
+      VALUE "InternalName",    "zlib\0"\r
+      VALUE "OriginalFilename",        "zlib.dll\0"\r
+      VALUE "ProductName",     "ZLib.DLL\0"\r
+      VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"\r
+      VALUE "LegalCopyright", "(C) 1995-2010 Jean-loup Gailly & Mark Adler\0"\r
+    END\r
+  END\r
+  BLOCK "VarFileInfo"\r
+  BEGIN\r
+    VALUE "Translation", 0x0409, 1252\r
+  END\r
+END\r
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj b/8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
new file mode 100644 (file)
index 0000000..2682fca
--- /dev/null
@@ -0,0 +1,457 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Itanium">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Itanium">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>StaticLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">\r
+    <Midl>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Lib>\r
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>\r
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </Lib>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\..\adler32.c" />\r
+    <ClCompile Include="..\..\..\compress.c" />\r
+    <ClCompile Include="..\..\..\crc32.c" />\r
+    <ClCompile Include="..\..\..\deflate.c" />\r
+    <ClCompile Include="..\..\..\gzclose.c" />\r
+    <ClCompile Include="..\..\..\gzlib.c" />\r
+    <ClCompile Include="..\..\..\gzread.c" />\r
+    <ClCompile Include="..\..\..\gzwrite.c" />\r
+    <ClCompile Include="..\..\..\infback.c" />\r
+    <ClCompile Include="..\..\masmx64\inffas8664.c">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inffast.c" />\r
+    <ClCompile Include="..\..\..\inflate.c" />\r
+    <ClCompile Include="..\..\..\inftrees.c" />\r
+    <ClCompile Include="..\..\minizip\ioapi.c" />\r
+    <ClCompile Include="..\..\..\trees.c" />\r
+    <ClCompile Include="..\..\..\uncompr.c" />\r
+    <ClCompile Include="..\..\minizip\unzip.c" />\r
+    <ClCompile Include="..\..\minizip\zip.c" />\r
+    <ClCompile Include="..\..\..\zutil.c" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ResourceCompile Include="zlib.rc" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="zlibvc.def" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters b/8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters
new file mode 100644 (file)
index 0000000..c8c7f7e
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{174213f6-7f66-4ae8-a3a8-a1e0a1e6ffdd}</UniqueIdentifier>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\..\adler32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\compress.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\crc32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\deflate.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\gzclose.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\gzlib.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\gzread.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\gzwrite.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\infback.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\masmx64\inffas8664.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inffast.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inflate.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inftrees.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\minizip\ioapi.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\trees.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\uncompr.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\minizip\unzip.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\minizip\zip.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\zutil.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ResourceCompile Include="zlib.rc">\r
+      <Filter>Source Files</Filter>\r
+    </ResourceCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="zlibvc.def">\r
+      <Filter>Source Files</Filter>\r
+    </None>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.user b/8.x/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.user
new file mode 100644 (file)
index 0000000..695b5c7
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlibvc.def b/8.x/zlib/contrib/vstudio/vc10/zlibvc.def
new file mode 100644 (file)
index 0000000..0269ef7
--- /dev/null
@@ -0,0 +1,130 @@
+LIBRARY\r
+; zlib data compression and ZIP file I/O library\r
+\r
+VERSION                1.24\r
+\r
+EXPORTS\r
+        adler32                                  @1\r
+        compress                                 @2\r
+        crc32                                    @3\r
+        deflate                                  @4\r
+        deflateCopy                              @5\r
+        deflateEnd                               @6\r
+        deflateInit2_                            @7\r
+        deflateInit_                             @8\r
+        deflateParams                            @9\r
+        deflateReset                             @10\r
+        deflateSetDictionary                     @11\r
+        gzclose                                  @12\r
+        gzdopen                                  @13\r
+        gzerror                                  @14\r
+        gzflush                                  @15\r
+        gzopen                                   @16\r
+        gzread                                   @17\r
+        gzwrite                                  @18\r
+        inflate                                  @19\r
+        inflateEnd                               @20\r
+        inflateInit2_                            @21\r
+        inflateInit_                             @22\r
+        inflateReset                             @23\r
+        inflateSetDictionary                     @24\r
+        inflateSync                              @25\r
+        uncompress                               @26\r
+        zlibVersion                              @27\r
+        gzprintf                                 @28\r
+        gzputc                                   @29\r
+        gzgetc                                   @30\r
+        gzseek                                   @31\r
+        gzrewind                                 @32\r
+        gztell                                   @33\r
+        gzeof                                    @34\r
+        gzsetparams                              @35\r
+        zError                                   @36\r
+        inflateSyncPoint                         @37\r
+        get_crc_table                            @38\r
+        compress2                                @39\r
+        gzputs                                   @40\r
+        gzgets                                   @41\r
+        inflateCopy                              @42\r
+        inflateBackInit_                         @43\r
+        inflateBack                              @44\r
+        inflateBackEnd                           @45\r
+        compressBound                            @46\r
+        deflateBound                             @47\r
+        gzclearerr                               @48\r
+        gzungetc                                 @49\r
+        zlibCompileFlags                         @50\r
+        deflatePrime                             @51\r
+\r
+        unzOpen                                  @61\r
+        unzClose                                 @62\r
+        unzGetGlobalInfo                         @63\r
+        unzGetCurrentFileInfo                    @64\r
+        unzGoToFirstFile                         @65\r
+        unzGoToNextFile                          @66\r
+        unzOpenCurrentFile                       @67\r
+        unzReadCurrentFile                       @68\r
+        unzOpenCurrentFile3                      @69\r
+        unztell                                  @70\r
+        unzeof                                   @71\r
+        unzCloseCurrentFile                      @72\r
+        unzGetGlobalComment                      @73\r
+        unzStringFileNameCompare                 @74\r
+        unzLocateFile                            @75\r
+        unzGetLocalExtrafield                    @76\r
+        unzOpen2                                 @77\r
+        unzOpenCurrentFile2                      @78\r
+        unzOpenCurrentFilePassword               @79\r
+\r
+        zipOpen                                  @80\r
+        zipOpenNewFileInZip                      @81\r
+        zipWriteInFileInZip                      @82\r
+        zipCloseFileInZip                        @83\r
+        zipClose                                 @84\r
+        zipOpenNewFileInZip2                     @86\r
+        zipCloseFileInZipRaw                     @87\r
+        zipOpen2                                 @88\r
+        zipOpenNewFileInZip3                     @89\r
+\r
+        unzGetFilePos                            @100\r
+        unzGoToFilePos                           @101\r
+\r
+        fill_win32_filefunc                      @110\r
+\r
+; zlibwapi v1.2.4 added:\r
+        fill_win32_filefunc64                   @111\r
+        fill_win32_filefunc64A                  @112\r
+        fill_win32_filefunc64W                  @113\r
+\r
+        unzOpen64                               @120\r
+        unzOpen2_64                             @121\r
+        unzGetGlobalInfo64                      @122\r
+        unzGetCurrentFileInfo64                 @124\r
+        unzGetCurrentFileZStreamPos64           @125\r
+        unztell64                               @126\r
+        unzGetFilePos64                         @127\r
+        unzGoToFilePos64                        @128\r
+\r
+        zipOpen64                               @130\r
+        zipOpen2_64                             @131\r
+        zipOpenNewFileInZip64                   @132\r
+        zipOpenNewFileInZip2_64                 @133\r
+        zipOpenNewFileInZip3_64                 @134\r
+        zipOpenNewFileInZip4_64                 @135\r
+        zipCloseFileInZipRaw64                  @136\r
+\r
+; zlib1 v1.2.4 added:\r
+        adler32_combine                         @140\r
+        crc32_combine                           @142\r
+        deflateSetHeader                        @144\r
+        deflateTune                             @145\r
+        gzbuffer                                @146\r
+        gzclose_r                               @147\r
+        gzclose_w                               @148\r
+        gzdirect                                @149\r
+        gzoffset                                @150\r
+        inflateGetHeader                        @156\r
+        inflateMark                             @157\r
+        inflatePrime                            @158\r
+        inflateReset2                           @159\r
+        inflateUndermine                        @160\r
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlibvc.sln b/8.x/zlib/contrib/vstudio/vc10/zlibvc.sln
new file mode 100644 (file)
index 0000000..6f6ffd5
--- /dev/null
@@ -0,0 +1,135 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Itanium = Debug|Itanium\r
+               Debug|Win32 = Debug|Win32\r
+               Debug|x64 = Debug|x64\r
+               Release|Itanium = Release|Itanium\r
+               Release|Win32 = Release|Win32\r
+               Release|x64 = Release|x64\r
+               ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium\r
+               ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32\r
+               ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj b/8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
new file mode 100644 (file)
index 0000000..9862398
--- /dev/null
@@ -0,0 +1,659 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Itanium">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">\r
+      <Configuration>ReleaseWithoutAsm</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Itanium">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Itanium</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>\r
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>Win32</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\r
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>Win32</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerOutput>All</AssemblerOutput>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>Win32</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerOutput>All</AssemblerOutput>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>\r
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerOutput>All</AssemblerOutput>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerOutput>All</AssemblerOutput>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerOutput>All</AssemblerOutput>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">\r
+    <Midl>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MkTypLibCompatible>true</MkTypLibCompatible>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <TargetEnvironment>Itanium</TargetEnvironment>\r
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <ExceptionHandling>\r
+      </ExceptionHandling>\r
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
+      <BufferSecurityCheck>false</BufferSecurityCheck>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerOutput>All</AssemblerOutput>\r
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>\r
+      <ObjectFileName>$(IntDir)</ObjectFileName>\r
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>\r
+      <BrowseInformation>\r
+      </BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x040c</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>\r
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>\r
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>\r
+      <SubSystem>Windows</SubSystem>\r
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>\r
+      <TargetMachine>MachineIA64</TargetMachine>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\..\adler32.c" />\r
+    <ClCompile Include="..\..\..\compress.c" />\r
+    <ClCompile Include="..\..\..\crc32.c" />\r
+    <ClCompile Include="..\..\..\deflate.c" />\r
+    <ClCompile Include="..\..\..\gzclose.c" />\r
+    <ClCompile Include="..\..\..\gzlib.c" />\r
+    <ClCompile Include="..\..\..\gzread.c" />\r
+    <ClCompile Include="..\..\..\gzwrite.c" />\r
+    <ClCompile Include="..\..\..\infback.c" />\r
+    <ClCompile Include="..\..\masmx64\inffas8664.c">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inffast.c" />\r
+    <ClCompile Include="..\..\..\inflate.c" />\r
+    <ClCompile Include="..\..\..\inftrees.c" />\r
+    <ClCompile Include="..\..\minizip\ioapi.c" />\r
+    <ClCompile Include="..\..\minizip\iowin32.c" />\r
+    <ClCompile Include="..\..\..\trees.c" />\r
+    <ClCompile Include="..\..\..\uncompr.c" />\r
+    <ClCompile Include="..\..\minizip\unzip.c">\r
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\minizip\zip.c">\r
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\zutil.c" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ResourceCompile Include="zlib.rc" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="zlibvc.def" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="..\..\..\deflate.h" />\r
+    <ClInclude Include="..\..\..\infblock.h" />\r
+    <ClInclude Include="..\..\..\infcodes.h" />\r
+    <ClInclude Include="..\..\..\inffast.h" />\r
+    <ClInclude Include="..\..\..\inftrees.h" />\r
+    <ClInclude Include="..\..\..\infutil.h" />\r
+    <ClInclude Include="..\..\..\zconf.h" />\r
+    <ClInclude Include="..\..\..\zlib.h" />\r
+    <ClInclude Include="..\..\..\zutil.h" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters b/8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters
new file mode 100644 (file)
index 0000000..180b71c
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{07934a85-8b61-443d-a0ee-b2eedb74f3cd}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{1d99675b-433d-4a21-9e50-ed4ab8b19762}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;fi;fd</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{431c0958-fa71-44d0-9084-2d19d100c0cc}</UniqueIdentifier>\r
+      <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\..\adler32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\compress.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\crc32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\deflate.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\gzclose.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\gzlib.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\gzread.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\gzwrite.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\infback.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\masmx64\inffas8664.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inffast.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inflate.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\inftrees.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\minizip\ioapi.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\minizip\iowin32.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\trees.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\uncompr.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\minizip\unzip.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\minizip\zip.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\zutil.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ResourceCompile Include="zlib.rc">\r
+      <Filter>Source Files</Filter>\r
+    </ResourceCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="zlibvc.def">\r
+      <Filter>Source Files</Filter>\r
+    </None>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="..\..\..\deflate.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\infblock.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\infcodes.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\inffast.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\inftrees.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\infutil.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\zconf.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\zlib.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\zutil.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.user b/8.x/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.user
new file mode 100644 (file)
index 0000000..695b5c7
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
diff --git a/8.x/zlib/contrib/vstudio/vc9/miniunz.vcproj b/8.x/zlib/contrib/vstudio/vc9/miniunz.vcproj
new file mode 100644 (file)
index 0000000..7da32b9
--- /dev/null
@@ -0,0 +1,565 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9.00"\r
+       Name="miniunz"\r
+       ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694382A}"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+               <Platform\r
+                       Name="x64"\r
+               />\r
+               <Platform\r
+                       Name="Itanium"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="x86\MiniUnzip$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\MiniUnzip$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="1"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/miniunz.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/miniunz.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="x86\MiniUnzip$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\MiniUnzip$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/miniunz.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="x64\MiniUnzip$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\MiniUnzip$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/miniunz.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/miniunz.pdb"\r
+                               SubSystem="1"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Itanium"\r
+                       OutputDirectory="ia64\MiniUnzip$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\MiniUnzip$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/miniunz.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/miniunz.pdb"\r
+                               SubSystem="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|x64"\r
+                       OutputDirectory="x64\MiniUnzip$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\MiniUnzip$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/miniunz.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Itanium"\r
+                       OutputDirectory="ia64\MiniUnzip$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\MiniUnzip$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/miniunz.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\minizip\miniunz.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/zlib/contrib/vstudio/vc9/minizip.vcproj b/8.x/zlib/contrib/vstudio/vc9/minizip.vcproj
new file mode 100644 (file)
index 0000000..e57e07d
--- /dev/null
@@ -0,0 +1,562 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9.00"\r
+       Name="minizip"\r
+       ProjectGUID="{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+               <Platform\r
+                       Name="x64"\r
+               />\r
+               <Platform\r
+                       Name="Itanium"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="x86\MiniZip$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\MiniZip$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="1"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/minizip.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/minizip.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="x86\MiniZip$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\MiniZip$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/minizip.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="x64\$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/minizip.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/minizip.pdb"\r
+                               SubSystem="1"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Itanium"\r
+                       OutputDirectory="ia64\$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/minizip.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/minizip.pdb"\r
+                               SubSystem="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|x64"\r
+                       OutputDirectory="x64\$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/minizip.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Itanium"\r
+                       OutputDirectory="ia64\$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/minizip.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\minizip\minizip.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/zlib/contrib/vstudio/vc9/testzlib.vcproj b/8.x/zlib/contrib/vstudio/vc9/testzlib.vcproj
new file mode 100644 (file)
index 0000000..9cb0bf8
--- /dev/null
@@ -0,0 +1,852 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9,00"\r
+       Name="testzlib"\r
+       ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"\r
+       RootNamespace="testzlib"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+               <Platform\r
+                       Name="x64"\r
+               />\r
+               <Platform\r
+                       Name="Itanium"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="x86\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="1"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerOutput="4"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/testzlib.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="x64\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj"\r
+                               GenerateManifest="false"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Itanium"\r
+                       OutputDirectory="ia64\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerOutput="4"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/testzlib.pdb"\r
+                               SubSystem="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|Win32"\r
+                       OutputDirectory="x86\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       CharacterSet="2"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|x64"\r
+                       OutputDirectory="x64\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies=""\r
+                               GenerateManifest="false"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|Itanium"\r
+                       OutputDirectory="ia64\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       CharacterSet="2"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="x86\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       CharacterSet="2"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|x64"\r
+                       OutputDirectory="x64\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj"\r
+                               GenerateManifest="false"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Itanium"\r
+                       OutputDirectory="ia64\TestZlib$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       CharacterSet="2"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\.."\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\..\adler32.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\compress.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\crc32.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\deflate.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\infback.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\masmx64\inffas8664.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="ReleaseWithoutAsm|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="ReleaseWithoutAsm|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inffast.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inflate.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inftrees.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\testzlib\testzlib.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\trees.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\uncompr.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\zutil.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/zlib/contrib/vstudio/vc9/testzlibdll.vcproj b/8.x/zlib/contrib/vstudio/vc9/testzlibdll.vcproj
new file mode 100644 (file)
index 0000000..b1ddde0
--- /dev/null
@@ -0,0 +1,565 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9.00"\r
+       Name="TestZlibDll"\r
+       ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694366A}"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+               <Platform\r
+                       Name="x64"\r
+               />\r
+               <Platform\r
+                       Name="Itanium"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="x86\TestZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\TestZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="1"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/testzlib.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="x86\TestZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\TestZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="x64\TestZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\TestZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/testzlib.pdb"\r
+                               SubSystem="1"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Itanium"\r
+                       OutputDirectory="ia64\TestZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\TestZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/testzlib.pdb"\r
+                               SubSystem="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|x64"\r
+                       OutputDirectory="x64\TestZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\TestZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Itanium"\r
+                       OutputDirectory="ia64\TestZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\TestZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\minizip"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"\r
+                               StringPooling="true"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               UsePrecompiledHeader="0"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"\r
+                               OutputFile="$(OutDir)/testzlib.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateManifest="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="1"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\testzlib\testzlib.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/zlib/contrib/vstudio/vc9/zlib.rc b/8.x/zlib/contrib/vstudio/vc9/zlib.rc
new file mode 100644 (file)
index 0000000..f822450
--- /dev/null
@@ -0,0 +1,32 @@
+#include <windows.h>\r
+\r
+#define IDR_VERSION1  1\r
+IDR_VERSION1   VERSIONINFO     MOVEABLE IMPURE LOADONCALL DISCARDABLE\r
+  FILEVERSION   1,2,5,0\r
+  PRODUCTVERSION 1,2,5,0\r
+  FILEFLAGSMASK        VS_FFI_FILEFLAGSMASK\r
+  FILEFLAGS    0\r
+  FILEOS       VOS_DOS_WINDOWS32\r
+  FILETYPE     VFT_DLL\r
+  FILESUBTYPE  0       // not used\r
+BEGIN\r
+  BLOCK "StringFileInfo"\r
+  BEGIN\r
+    BLOCK "040904E4"\r
+    //language ID = U.S. English, char set = Windows, Multilingual\r
+\r
+    BEGIN\r
+      VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"\r
+      VALUE "FileVersion",     "1.2.5\0"\r
+      VALUE "InternalName",    "zlib\0"\r
+      VALUE "OriginalFilename",        "zlib.dll\0"\r
+      VALUE "ProductName",     "ZLib.DLL\0"\r
+      VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"\r
+      VALUE "LegalCopyright", "(C) 1995-2010 Jean-loup Gailly & Mark Adler\0"\r
+    END\r
+  END\r
+  BLOCK "VarFileInfo"\r
+  BEGIN\r
+    VALUE "Translation", 0x0409, 1252\r
+  END\r
+END\r
diff --git a/8.x/zlib/contrib/vstudio/vc9/zlibstat.vcproj b/8.x/zlib/contrib/vstudio/vc9/zlibstat.vcproj
new file mode 100644 (file)
index 0000000..61c76c7
--- /dev/null
@@ -0,0 +1,835 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9,00"\r
+       Name="zlibstat"\r
+       ProjectGUID="{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+               <Platform\r
+                       Name="x64"\r
+               />\r
+               <Platform\r
+                       Name="Itanium"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="x86\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="1"\r
+                               BufferSecurityCheck="false"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="x64\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Itanium"\r
+                       OutputDirectory="ia64\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="x86\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"\r
+                               AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj "\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|x64"\r
+                       OutputDirectory="x64\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"\r
+                               AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Itanium"\r
+                       OutputDirectory="ia64\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|Win32"\r
+                       OutputDirectory="x86\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|x64"\r
+                       OutputDirectory="x64\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|Itanium"\r
+                       OutputDirectory="ia64\ZlibStat$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TargetEnvironment="2"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"\r
+                               OutputFile="$(OutDir)\zlibstat.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\..\adler32.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\compress.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\crc32.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\deflate.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzclose.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzguts.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzlib.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzread.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzwrite.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\infback.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\masmx64\inffas8664.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="ReleaseWithoutAsm|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="ReleaseWithoutAsm|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inffast.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inflate.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inftrees.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\minizip\ioapi.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\trees.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\uncompr.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\minizip\unzip.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\minizip\zip.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\zlib.rc"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\zlibvc.def"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\zutil.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/zlib/contrib/vstudio/vc9/zlibvc.def b/8.x/zlib/contrib/vstudio/vc9/zlibvc.def
new file mode 100644 (file)
index 0000000..0269ef7
--- /dev/null
@@ -0,0 +1,130 @@
+LIBRARY\r
+; zlib data compression and ZIP file I/O library\r
+\r
+VERSION                1.24\r
+\r
+EXPORTS\r
+        adler32                                  @1\r
+        compress                                 @2\r
+        crc32                                    @3\r
+        deflate                                  @4\r
+        deflateCopy                              @5\r
+        deflateEnd                               @6\r
+        deflateInit2_                            @7\r
+        deflateInit_                             @8\r
+        deflateParams                            @9\r
+        deflateReset                             @10\r
+        deflateSetDictionary                     @11\r
+        gzclose                                  @12\r
+        gzdopen                                  @13\r
+        gzerror                                  @14\r
+        gzflush                                  @15\r
+        gzopen                                   @16\r
+        gzread                                   @17\r
+        gzwrite                                  @18\r
+        inflate                                  @19\r
+        inflateEnd                               @20\r
+        inflateInit2_                            @21\r
+        inflateInit_                             @22\r
+        inflateReset                             @23\r
+        inflateSetDictionary                     @24\r
+        inflateSync                              @25\r
+        uncompress                               @26\r
+        zlibVersion                              @27\r
+        gzprintf                                 @28\r
+        gzputc                                   @29\r
+        gzgetc                                   @30\r
+        gzseek                                   @31\r
+        gzrewind                                 @32\r
+        gztell                                   @33\r
+        gzeof                                    @34\r
+        gzsetparams                              @35\r
+        zError                                   @36\r
+        inflateSyncPoint                         @37\r
+        get_crc_table                            @38\r
+        compress2                                @39\r
+        gzputs                                   @40\r
+        gzgets                                   @41\r
+        inflateCopy                              @42\r
+        inflateBackInit_                         @43\r
+        inflateBack                              @44\r
+        inflateBackEnd                           @45\r
+        compressBound                            @46\r
+        deflateBound                             @47\r
+        gzclearerr                               @48\r
+        gzungetc                                 @49\r
+        zlibCompileFlags                         @50\r
+        deflatePrime                             @51\r
+\r
+        unzOpen                                  @61\r
+        unzClose                                 @62\r
+        unzGetGlobalInfo                         @63\r
+        unzGetCurrentFileInfo                    @64\r
+        unzGoToFirstFile                         @65\r
+        unzGoToNextFile                          @66\r
+        unzOpenCurrentFile                       @67\r
+        unzReadCurrentFile                       @68\r
+        unzOpenCurrentFile3                      @69\r
+        unztell                                  @70\r
+        unzeof                                   @71\r
+        unzCloseCurrentFile                      @72\r
+        unzGetGlobalComment                      @73\r
+        unzStringFileNameCompare                 @74\r
+        unzLocateFile                            @75\r
+        unzGetLocalExtrafield                    @76\r
+        unzOpen2                                 @77\r
+        unzOpenCurrentFile2                      @78\r
+        unzOpenCurrentFilePassword               @79\r
+\r
+        zipOpen                                  @80\r
+        zipOpenNewFileInZip                      @81\r
+        zipWriteInFileInZip                      @82\r
+        zipCloseFileInZip                        @83\r
+        zipClose                                 @84\r
+        zipOpenNewFileInZip2                     @86\r
+        zipCloseFileInZipRaw                     @87\r
+        zipOpen2                                 @88\r
+        zipOpenNewFileInZip3                     @89\r
+\r
+        unzGetFilePos                            @100\r
+        unzGoToFilePos                           @101\r
+\r
+        fill_win32_filefunc                      @110\r
+\r
+; zlibwapi v1.2.4 added:\r
+        fill_win32_filefunc64                   @111\r
+        fill_win32_filefunc64A                  @112\r
+        fill_win32_filefunc64W                  @113\r
+\r
+        unzOpen64                               @120\r
+        unzOpen2_64                             @121\r
+        unzGetGlobalInfo64                      @122\r
+        unzGetCurrentFileInfo64                 @124\r
+        unzGetCurrentFileZStreamPos64           @125\r
+        unztell64                               @126\r
+        unzGetFilePos64                         @127\r
+        unzGoToFilePos64                        @128\r
+\r
+        zipOpen64                               @130\r
+        zipOpen2_64                             @131\r
+        zipOpenNewFileInZip64                   @132\r
+        zipOpenNewFileInZip2_64                 @133\r
+        zipOpenNewFileInZip3_64                 @134\r
+        zipOpenNewFileInZip4_64                 @135\r
+        zipCloseFileInZipRaw64                  @136\r
+\r
+; zlib1 v1.2.4 added:\r
+        adler32_combine                         @140\r
+        crc32_combine                           @142\r
+        deflateSetHeader                        @144\r
+        deflateTune                             @145\r
+        gzbuffer                                @146\r
+        gzclose_r                               @147\r
+        gzclose_w                               @148\r
+        gzdirect                                @149\r
+        gzoffset                                @150\r
+        inflateGetHeader                        @156\r
+        inflateMark                             @157\r
+        inflatePrime                            @158\r
+        inflateReset2                           @159\r
+        inflateUndermine                        @160\r
diff --git a/8.x/zlib/contrib/vstudio/vc9/zlibvc.sln b/8.x/zlib/contrib/vstudio/vc9/zlibvc.sln
new file mode 100644 (file)
index 0000000..b482967
--- /dev/null
@@ -0,0 +1,144 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 10.00\r
+# Visual Studio 2008\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestZlibDll", "testzlibdll.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}\r
+       EndProjectSection\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}\r
+       EndProjectSection\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}\r
+       EndProjectSection\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Itanium = Debug|Itanium\r
+               Debug|Win32 = Debug|Win32\r
+               Debug|x64 = Debug|x64\r
+               Release|Itanium = Release|Itanium\r
+               Release|Win32 = Release|Win32\r
+               Release|x64 = Release|x64\r
+               ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium\r
+               ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32\r
+               ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\r
+               {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\r
+               {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64\r
+               {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\r
+               {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32\r
+               {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/8.x/zlib/contrib/vstudio/vc9/zlibvc.vcproj b/8.x/zlib/contrib/vstudio/vc9/zlibvc.vcproj
new file mode 100644 (file)
index 0000000..c9a8947
--- /dev/null
@@ -0,0 +1,1156 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9,00"\r
+       Name="zlibvc"\r
+       ProjectGUID="{8FD826F8-3739-44E6-8CC8-997122E53B8D}"\r
+       RootNamespace="zlibvc"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+               <Platform\r
+                       Name="x64"\r
+               />\r
+               <Platform\r
+                       Name="Itanium"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="x86\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="1"\r
+                               BufferSecurityCheck="false"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="x64\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="3"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Debug|Itanium"\r
+                       OutputDirectory="ia64\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="2"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="false"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|Win32"\r
+                       OutputDirectory="x86\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerOutput="2"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               IgnoreAllDefaultLibraries="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               OptimizeForWindows98="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|x64"\r
+                       OutputDirectory="x64\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="3"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerOutput="2"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               IgnoreAllDefaultLibraries="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               OptimizeForWindows98="1"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="ReleaseWithoutAsm|Itanium"\r
+                       OutputDirectory="ia64\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="2"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerOutput="2"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               IgnoreAllDefaultLibraries="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               OptimizeForWindows98="1"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="x86\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="0"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerOutput="2"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj "\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               IgnoreAllDefaultLibraries="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               OptimizeForWindows98="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|x64"\r
+                       OutputDirectory="x64\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="3"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerOutput="2"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               IgnoreAllDefaultLibraries="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               OptimizeForWindows98="1"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Itanium"\r
+                       OutputDirectory="ia64\ZlibDll$(ConfigurationName)"\r
+                       IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="UpgradeFromVC70.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       WholeProgramOptimization="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="2"\r
+                               TypeLibraryName="$(OutDir)/zlibvc.tlb"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\..\..;..\..\masmx86"\r
+                               PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"\r
+                               StringPooling="true"\r
+                               ExceptionHandling="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"\r
+                               AssemblerOutput="2"\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(OutDir)\"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1036"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)\zlibwapi.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateManifest="false"\r
+                               IgnoreAllDefaultLibraries="false"\r
+                               ModuleDefinitionFile=".\zlibvc.def"\r
+                               ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(OutDir)/zlibwapi.map"\r
+                               SubSystem="2"\r
+                               OptimizeForWindows98="1"\r
+                               ImportLibrary="$(OutDir)/zlibwapi.lib"\r
+                               TargetMachine="5"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\..\adler32.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\compress.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\crc32.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\deflate.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzclose.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzguts.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzlib.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzread.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\gzwrite.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\infback.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\masmx64\inffas8664.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="ReleaseWithoutAsm|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="ReleaseWithoutAsm|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Itanium"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inffast.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inflate.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inftrees.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\minizip\ioapi.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\minizip\iowin32.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\trees.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\uncompr.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\minizip\unzip.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                               PreprocessorDefinitions="ZLIB_INTERNAL"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|x64"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                               PreprocessorDefinitions="ZLIB_INTERNAL"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Itanium"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                               PreprocessorDefinitions="ZLIB_INTERNAL"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\minizip\zip.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                               PreprocessorDefinitions="ZLIB_INTERNAL"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|x64"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                               PreprocessorDefinitions="ZLIB_INTERNAL"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Itanium"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                               PreprocessorDefinitions="ZLIB_INTERNAL"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\zlib.rc"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\zlibvc.def"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\zutil.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;fi;fd"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\..\deflate.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\infblock.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\infcodes.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inffast.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\inftrees.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\infutil.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\zconf.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\zlib.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\zutil.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/8.x/zlib/crc32.c b/8.x/zlib/crc32.c
new file mode 100644 (file)
index 0000000..91be372
--- /dev/null
@@ -0,0 +1,442 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+#  ifdef STDC           /* need ANSI C limits.h to determine sizes */
+#    include <limits.h>
+#    define BYFOUR
+#    if (UINT_MAX == 0xffffffffUL)
+       typedef unsigned int u4;
+#    else
+#      if (ULONG_MAX == 0xffffffffUL)
+         typedef unsigned long u4;
+#      else
+#        if (USHRT_MAX == 0xffffffffUL)
+           typedef unsigned short u4;
+#        else
+#          undef BYFOUR     /* can't find a four-byte integer type! */
+#        endif
+#      endif
+#    endif
+#  endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+#  define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
+                (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    unsigned long c;
+    int n, k;
+    unsigned long poly;                 /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static volatile int first = 1;      /* flag to limit concurrent making */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* See if another task is already doing this (not thread-safe, but better
+       than nothing -- significantly reduces duration of vulnerability in
+       case the advice about DYNAMIC_CRC_TABLE is ignored) */
+    if (first) {
+        first = 0;
+
+        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+        poly = 0UL;
+        for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+            poly |= 1UL << (31 - p[n]);
+
+        /* generate a crc for every 8-bit value */
+        for (n = 0; n < 256; n++) {
+            c = (unsigned long)n;
+            for (k = 0; k < 8; k++)
+                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+            crc_table[0][n] = c;
+        }
+
+#ifdef BYFOUR
+        /* generate crc for each value followed by one, two, and three zeros,
+           and then the byte reversal of those as well as the first table */
+        for (n = 0; n < 256; n++) {
+            c = crc_table[0][n];
+            crc_table[4][n] = REV(c);
+            for (k = 1; k < 4; k++) {
+                c = crc_table[0][c & 0xff] ^ (c >> 8);
+                crc_table[k][n] = c;
+                crc_table[k + 4][n] = REV(c);
+            }
+        }
+#endif /* BYFOUR */
+
+        crc_table_empty = 0;
+    }
+    else {      /* not first */
+        /* wait for the other guy to finish (not efficient, but rare) */
+        while (crc_table_empty)
+            ;
+    }
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const unsigned long FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const unsigned long FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        u4 endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = (u4)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = REV((u4)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
+    buf4--;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf4++;
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case (also disallow negative lengths) */
+    if (len2 <= 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/8.x/zlib/crc32.h b/8.x/zlib/crc32.h
new file mode 100644 (file)
index 0000000..8053b61
--- /dev/null
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+  {
+    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+    0x2d02ef8dUL
+#ifdef BYFOUR
+  },
+  {
+    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+    0x9324fd72UL
+  },
+  {
+    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+    0xbe9834edUL
+  },
+  {
+    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+    0xde0506f1UL
+  },
+  {
+    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+    0x8def022dUL
+  },
+  {
+    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+    0x72fd2493UL
+  },
+  {
+    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+    0xed3498beUL
+  },
+  {
+    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+    0xf10605deUL
+#endif
+  }
+};
diff --git a/8.x/zlib/deflate.c b/8.x/zlib/deflate.c
new file mode 100644 (file)
index 0000000..5c4022f
--- /dev/null
@@ -0,0 +1,1834 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle    OF((deflate_state *s, int flush));
+local block_state deflate_huff   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+                         Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int wrap = 1;
+    static const char my_version[] = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+        return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+    if (windowBits < 0) { /* suppress zlib wrapper */
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+#ifdef GZIP
+    else if (windowBits > 15) {
+        wrap = 2;       /* write gzip wrapper instead */
+        windowBits -= 16;
+    }
+#endif
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->wrap = wrap;
+    s->gzhead = Z_NULL;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->high_water = 0;      /* nothing written to s->window yet */
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        s->status = FINISH_STATE;
+        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+        strm->state->wrap == 2 ||
+        (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+        return Z_STREAM_ERROR;
+
+    s = strm->state;
+    if (s->wrap)
+        strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > s->w_size) {
+        length = s->w_size;
+        dictionary += dictLength - length; /* use the tail of the dictionary */
+    }
+    zmemcpy(s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+        INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+        return Z_STREAM_ERROR;
+    }
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->wrap < 0) {
+        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+    }
+    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+    strm->adler =
+#ifdef GZIP
+        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+        adler32(0L, Z_NULL, 0);
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+    z_streamp strm;
+    gz_headerp head;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+    strm->state->gzhead = head;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+    z_streamp strm;
+    int bits;
+    int value;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    strm->state->bi_valid = bits;
+    strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if ((strategy != s->strategy || func != configuration_table[level].func) &&
+        strm->total_in != 0) {
+        /* Flush the last buffer: */
+        err = deflate(strm, Z_BLOCK);
+    }
+    if (s->level != level) {
+        s->level = level;
+        s->max_lazy_match   = configuration_table[level].max_lazy;
+        s->good_match       = configuration_table[level].good_length;
+        s->nice_match       = configuration_table[level].nice_length;
+        s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = good_length;
+    s->max_lazy_match = max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = max_chain;
+    return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well.  The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel.  But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+    z_streamp strm;
+    uLong sourceLen;
+{
+    deflate_state *s;
+    uLong complen, wraplen;
+    Bytef *str;
+
+    /* conservative upper bound for compressed data */
+    complen = sourceLen +
+              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+    /* if can't get parameters, return conservative bound plus zlib wrapper */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return complen + 6;
+
+    /* compute wrapper length */
+    s = strm->state;
+    switch (s->wrap) {
+    case 0:                                 /* raw deflate */
+        wraplen = 0;
+        break;
+    case 1:                                 /* zlib wrapper */
+        wraplen = 6 + (s->strstart ? 4 : 0);
+        break;
+    case 2:                                 /* gzip wrapper */
+        wraplen = 18;
+        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
+            if (s->gzhead->extra != Z_NULL)
+                wraplen += 2 + s->gzhead->extra_len;
+            str = s->gzhead->name;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            str = s->gzhead->comment;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            if (s->gzhead->hcrc)
+                wraplen += 2;
+        }
+        break;
+    default:                                /* for compiler happiness */
+        wraplen = 6;
+    }
+
+    /* if not default parameters, return conservative bound */
+    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+        return complen + wraplen;
+
+    /* default settings: return tight bound for that case */
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len = strm->state->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, strm->state->pending_out, len);
+    strm->next_out  += len;
+    strm->state->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    strm->state->pending -= len;
+    if (strm->state->pending == 0) {
+        strm->state->pending_out = strm->state->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        flush > Z_BLOCK || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+        (s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the header */
+    if (s->status == INIT_STATE) {
+#ifdef GZIP
+        if (s->wrap == 2) {
+            strm->adler = crc32(0L, Z_NULL, 0);
+            put_byte(s, 31);
+            put_byte(s, 139);
+            put_byte(s, 8);
+            if (s->gzhead == Z_NULL) {
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, OS_CODE);
+                s->status = BUSY_STATE;
+            }
+            else {
+                put_byte(s, (s->gzhead->text ? 1 : 0) +
+                            (s->gzhead->hcrc ? 2 : 0) +
+                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
+                            (s->gzhead->name == Z_NULL ? 0 : 8) +
+                            (s->gzhead->comment == Z_NULL ? 0 : 16)
+                        );
+                put_byte(s, (Byte)(s->gzhead->time & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, s->gzhead->os & 0xff);
+                if (s->gzhead->extra != Z_NULL) {
+                    put_byte(s, s->gzhead->extra_len & 0xff);
+                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+                }
+                if (s->gzhead->hcrc)
+                    strm->adler = crc32(strm->adler, s->pending_buf,
+                                        s->pending);
+                s->gzindex = 0;
+                s->status = EXTRA_STATE;
+            }
+        }
+        else
+#endif
+        {
+            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+            uInt level_flags;
+
+            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+                level_flags = 0;
+            else if (s->level < 6)
+                level_flags = 1;
+            else if (s->level == 6)
+                level_flags = 2;
+            else
+                level_flags = 3;
+            header |= (level_flags << 6);
+            if (s->strstart != 0) header |= PRESET_DICT;
+            header += 31 - (header % 31);
+
+            s->status = BUSY_STATE;
+            putShortMSB(s, header);
+
+            /* Save the adler32 of the preset dictionary: */
+            if (s->strstart != 0) {
+                putShortMSB(s, (uInt)(strm->adler >> 16));
+                putShortMSB(s, (uInt)(strm->adler & 0xffff));
+            }
+            strm->adler = adler32(0L, Z_NULL, 0);
+        }
+    }
+#ifdef GZIP
+    if (s->status == EXTRA_STATE) {
+        if (s->gzhead->extra != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+
+            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size)
+                        break;
+                }
+                put_byte(s, s->gzhead->extra[s->gzindex]);
+                s->gzindex++;
+            }
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (s->gzindex == s->gzhead->extra_len) {
+                s->gzindex = 0;
+                s->status = NAME_STATE;
+            }
+        }
+        else
+            s->status = NAME_STATE;
+    }
+    if (s->status == NAME_STATE) {
+        if (s->gzhead->name != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->name[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0) {
+                s->gzindex = 0;
+                s->status = COMMENT_STATE;
+            }
+        }
+        else
+            s->status = COMMENT_STATE;
+    }
+    if (s->status == COMMENT_STATE) {
+        if (s->gzhead->comment != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->comment[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0)
+                s->status = HCRC_STATE;
+        }
+        else
+            s->status = HCRC_STATE;
+    }
+    if (s->status == HCRC_STATE) {
+        if (s->gzhead->hcrc) {
+            if (s->pending + 2 > s->pending_buf_size)
+                flush_pending(strm);
+            if (s->pending + 2 <= s->pending_buf_size) {
+                put_byte(s, (Byte)(strm->adler & 0xff));
+                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+                strm->adler = crc32(0L, Z_NULL, 0);
+                s->status = BUSY_STATE;
+            }
+        }
+        else
+            s->status = BUSY_STATE;
+    }
+#endif
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+            /* Since avail_out is 0, deflate will be called again with
+             * more output space, but possibly with both pending and
+             * avail_in equal to zero. There won't be anything to do,
+             * but this is not an error situation so make sure we
+             * return OK instead of BUF_ERROR at next call of deflate:
+             */
+            s->last_flush = -1;
+            return Z_OK;
+        }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+               flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+        bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+                    (s->strategy == Z_RLE ? deflate_rle(s, flush) :
+                        (*(configuration_table[s->level].func))(s, flush));
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+            if (strm->avail_out == 0) {
+                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+            }
+            return Z_OK;
+            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+             * of deflate should use the same flush parameter to make sure
+             * that the flush is complete. So we don't have to output an
+             * empty block here, this will be done at next call. This also
+             * ensures that for a very small output buffer, we emit at most
+             * one empty block.
+             */
+        }
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                    if (s->lookahead == 0) {
+                        s->strstart = 0;
+                        s->block_start = 0L;
+                    }
+                }
+            }
+            flush_pending(strm);
+            if (strm->avail_out == 0) {
+              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+              return Z_OK;
+            }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->wrap <= 0) return Z_STREAM_END;
+
+    /* Write the trailer */
+#ifdef GZIP
+    if (s->wrap == 2) {
+        put_byte(s, (Byte)(strm->adler & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+        put_byte(s, (Byte)(strm->total_in & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+    }
+    else
+#endif
+    {
+        putShortMSB(s, (uInt)(strm->adler >> 16));
+        putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE &&
+        status != EXTRA_STATE &&
+        status != NAME_STATE &&
+        status != COMMENT_STATE &&
+        status != HCRC_STATE &&
+        status != BUSY_STATE &&
+        status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    zmemcpy(dest, source, sizeof(z_stream));
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    zmemcpy(ds, ss, sizeof(deflate_state));
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, strm->next_in, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, strm->next_in, len);
+    }
+#endif
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2.  Note that the checks below
+         * for insufficient lookahead only occur occasionally for performance
+         * reasons.  Therefore uninitialized memory will be accessed, and
+         * conditional jumps will be made that depend on those values.
+         * However the length of the match is limited to the lookahead, so
+         * the output of deflate is not affected by the uninitialized values.
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+                start, match, length);
+        do {
+            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+        } while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+#ifndef FASTEST
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+    /* If the WIN_INIT bytes after the end of the current data have never been
+     * written, then zero those bytes in order to avoid memory check reports of
+     * the use of uninitialized (or uninitialised as Julian writes) bytes by
+     * the longest match routines.  Update the high water mark for the next
+     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
+     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+     */
+    if (s->high_water < s->window_size) {
+        ulg curr = s->strstart + (ulg)(s->lookahead);
+        ulg init;
+
+        if (s->high_water < curr) {
+            /* Previous high water mark below current data -- zero WIN_INIT
+             * bytes or up to end of window, whichever is less.
+             */
+            init = s->window_size - curr;
+            if (init > WIN_INIT)
+                init = WIN_INIT;
+            zmemzero(s->window + curr, (unsigned)init);
+            s->high_water = curr + init;
+        }
+        else if (s->high_water < (ulg)curr + WIN_INIT) {
+            /* High water mark at or above current data, but below current data
+             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+             * to end of window, whichever is less.
+             */
+            init = (ulg)curr + WIN_INIT - s->high_water;
+            if (init > s->window_size - s->high_water)
+                init = s->window_size - s->high_water;
+            zmemzero(s->window + s->high_water, (unsigned)init);
+            s->high_water += init;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+                (ulg)((long)s->strstart - s->block_start), \
+                (last)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+   FLUSH_BLOCK_ONLY(s, last); \
+   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+                   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+        Assert(s->block_start >= 0L, "block gone");
+
+        s->strstart += s->lookahead;
+        s->lookahead = 0;
+
+        /* Emit a stored block if pending_buf will be full: */
+        max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+            /* strstart == 0 is possible when wraparound on 16-bit machine */
+            s->lookahead = (uInt)(s->strstart - max_start);
+            s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+        }
+        /* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+        }
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;       /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++;
+            } else
+#endif
+            {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;          /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+                || (s->match_length == MIN_MATCH &&
+                    s->strstart - s->match_start > TOO_FAR)
+#endif
+                )) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+                           s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+            if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+    uInt prev;              /* byte at distance one to match */
+    Bytef *scan, *strend;   /* scan goes up to strend for length of run */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the longest encodable run.
+         */
+        if (s->lookahead < MAX_MATCH) {
+            fill_window(s);
+            if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* See how many times the previous byte repeats */
+        s->match_length = 0;
+        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+            scan = s->window + s->strstart - 1;
+            prev = *scan;
+            if (prev == *++scan && prev == *++scan && prev == *++scan) {
+                strend = s->window + s->strstart + MAX_MATCH;
+                do {
+                } while (prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         scan < strend);
+                s->match_length = MAX_MATCH - (int)(strend - scan);
+                if (s->match_length > s->lookahead)
+                    s->match_length = s->lookahead;
+            }
+        }
+
+        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+            s->strstart += s->match_length;
+            s->match_length = 0;
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we have a literal to write. */
+        if (s->lookahead == 0) {
+            fill_window(s);
+            if (s->lookahead == 0) {
+                if (flush == Z_NO_FLUSH)
+                    return need_more;
+                break;      /* flush the current block */
+            }
+        }
+
+        /* Output a literal byte */
+        s->match_length = 0;
+        Tracevv((stderr,"%c", s->window[s->strstart]));
+        _tr_tally_lit (s, s->window[s->strstart], bflush);
+        s->lookahead--;
+        s->strstart++;
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
diff --git a/8.x/zlib/deflate.h b/8.x/zlib/deflate.h
new file mode 100644 (file)
index 0000000..cbf0d1e
--- /dev/null
@@ -0,0 +1,342 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2010 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip encoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define EXTRA_STATE   69
+#define NAME_STATE    73
+#define COMMENT_STATE 91
+#define HCRC_STATE   103
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    uInt   pending;      /* nb of bytes in the pending buffer */
+    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    gz_headerp  gzhead;  /* gzip header information to write */
+    uInt   gzindex;      /* where in extra, name, or comment */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+    ulg high_water;
+    /* High water mark offset in window for initialized bytes -- bytes above
+     * this are set to zero in order to avoid memory check warnings when
+     * longest match routines access bytes past the input.  This is then
+     * updated to the new high water mark.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+   memory checker errors from longest match routines */
+
+        /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch ZLIB_INTERNAL _length_code[];
+  extern uch ZLIB_INTERNAL _dist_code[];
+#else
+  extern const uch ZLIB_INTERNAL _length_code[];
+  extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/8.x/zlib/doc/algorithm.txt b/8.x/zlib/doc/algorithm.txt
new file mode 100644 (file)
index 0000000..34960bd
--- /dev/null
@@ -0,0 +1,209 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data.  The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length).  Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes.  (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The key question is how to represent a Huffman code (or any prefix code) so
+that you can decode fast.  The most important characteristic is that shorter
+codes are much more common than longer codes, so pay attention to decoding the
+short codes fast, and let the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code.  It gets that many bits from the
+stream, and looks it up in the table.  The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table.  If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code.  However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table.  What inflate() does is
+simply to make the number of bits in the first table a variable, and  then
+to set that variable for the maximum speed.
+
+For inflate, which has 286 possible codes for the literal/length tree, the size
+of the first table is nine bits.  Also the distance trees have 30 possible
+values, and the size of the first table is six bits.  Note that for each of
+those cases, the table ended up one bit longer than the ``average'' code
+length, i.e. the code length of an approximately flat code which would be a
+little more than eight bits for 286 symbols and a little less than five bits
+for 30 symbols.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like.  You are correct that it's not a Huffman tree.  It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol.  The
+symbol could be as short as one bit or as long as 15 bits.  If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits.  For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits.  Again, there are duplicated
+entries as needed.  The idea is that most of the time the symbol will be short
+and there will only be one table look up.  (That's whole idea behind data
+compression in the first place.)  For the less frequent long symbols, there
+will be two lookups.  If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient.  For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it contains the translation for the symbol
+and the number of bits to gobble.  Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is?  The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols.  At the
+other extreme, you could make a new table for every bit in the code.  In fact,
+that's essentially a Huffman tree.  But then you spend too much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode as and how many bits that is, i.e. how
+many bits to gobble.  Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed.  That's compared to 64 entries for a single table.  Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table).  Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on.  For inflate, the
+meaning of a particular symbol is often more than just a letter.  It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value.  Or it might be the special end-of-block code.  The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly        Mark Adler
+jloup@gzip.org          madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+http://www.ietf.org/rfc/rfc1951.txt
diff --git a/8.x/zlib/doc/rfc1950.txt b/8.x/zlib/doc/rfc1950.txt
new file mode 100644 (file)
index 0000000..ce6428a
--- /dev/null
@@ -0,0 +1,619 @@
+
+
+
+
+
+
+Network Working Group                                         P. Deutsch
+Request for Comments: 1950                           Aladdin Enterprises
+Category: Informational                                      J-L. Gailly
+                                                                Info-ZIP
+                                                                May 1996
+
+
+         ZLIB Compressed Data Format Specification version 3.3
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  This memo
+   does not specify an Internet standard of any kind.  Distribution of
+   this memo is unlimited.
+
+IESG Note:
+
+   The IESG takes no position on the validity of any Intellectual
+   Property Rights statements contained in this document.
+
+Notices
+
+   Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
+
+   Permission is granted to copy and distribute this document for any
+   purpose and without charge, including translations into other
+   languages and incorporation into compilations, provided that the
+   copyright notice and this notice are preserved, and that any
+   substantive changes or deletions from the original are clearly
+   marked.
+
+   A pointer to the latest version of this and related documentation in
+   HTML format can be found at the URL
+   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+   This specification defines a lossless compressed data format.  The
+   data can be produced or consumed, even for an arbitrarily long
+   sequentially presented input data stream, using only an a priori
+   bounded amount of intermediate storage.  The format presently uses
+   the DEFLATE compression method but can be easily extended to use
+   other compression methods.  It can be implemented readily in a manner
+   not covered by patents.  This specification also defines the ADLER-32
+   checksum (an extension and improvement of the Fletcher checksum),
+   used for detection of data corruption, and provides an algorithm for
+   computing it.
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 1]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+Table of Contents
+
+   1. Introduction ................................................... 2
+      1.1. Purpose ................................................... 2
+      1.2. Intended audience ......................................... 3
+      1.3. Scope ..................................................... 3
+      1.4. Compliance ................................................ 3
+      1.5.  Definitions of terms and conventions used ................ 3
+      1.6. Changes from previous versions ............................ 3
+   2. Detailed specification ......................................... 3
+      2.1. Overall conventions ....................................... 3
+      2.2. Data format ............................................... 4
+      2.3. Compliance ................................................ 7
+   3. References ..................................................... 7
+   4. Source code .................................................... 8
+   5. Security Considerations ........................................ 8
+   6. Acknowledgements ............................................... 8
+   7. Authors' Addresses ............................................. 8
+   8. Appendix: Rationale ............................................ 9
+   9. Appendix: Sample code ..........................................10
+
+1. Introduction
+
+   1.1. Purpose
+
+      The purpose of this specification is to define a lossless
+      compressed data format that:
+
+          * Is independent of CPU type, operating system, file system,
+            and character set, and hence can be used for interchange;
+
+          * Can be produced or consumed, even for an arbitrarily long
+            sequentially presented input data stream, using only an a
+            priori bounded amount of intermediate storage, and hence can
+            be used in data communications or similar structures such as
+            Unix filters;
+
+          * Can use a number of different compression methods;
+
+          * Can be implemented readily in a manner not covered by
+            patents, and hence can be practiced freely.
+
+      The data format defined by this specification does not attempt to
+      allow random access to compressed data.
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 2]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+   1.2. Intended audience
+
+      This specification is intended for use by implementors of software
+      to compress data into zlib format and/or decompress data from zlib
+      format.
+
+      The text of the specification assumes a basic background in
+      programming at the level of bits and other primitive data
+      representations.
+
+   1.3. Scope
+
+      The specification specifies a compressed data format that can be
+      used for in-memory compression of a sequence of arbitrary bytes.
+
+   1.4. Compliance
+
+      Unless otherwise indicated below, a compliant decompressor must be
+      able to accept and decompress any data set that conforms to all
+      the specifications presented here; a compliant compressor must
+      produce data sets that conform to all the specifications presented
+      here.
+
+   1.5.  Definitions of terms and conventions used
+
+      byte: 8 bits stored or transmitted as a unit (same as an octet).
+      (For this specification, a byte is exactly 8 bits, even on
+      machines which store a character on a number of bits different
+      from 8.) See below, for the numbering of bits within a byte.
+
+   1.6. Changes from previous versions
+
+      Version 3.1 was the first public release of this specification.
+      In version 3.2, some terminology was changed and the Adler-32
+      sample code was rewritten for clarity.  In version 3.3, the
+      support for a preset dictionary was introduced, and the
+      specification was converted to RFC style.
+
+2. Detailed specification
+
+   2.1. Overall conventions
+
+      In the diagrams below, a box like this:
+
+         +---+
+         |   | <-- the vertical bars might be missing
+         +---+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 3]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+      represents one byte; a box like this:
+
+         +==============+
+         |              |
+         +==============+
+
+      represents a variable number of bytes.
+
+      Bytes stored within a computer do not have a "bit order", since
+      they are always treated as a unit.  However, a byte considered as
+      an integer between 0 and 255 does have a most- and least-
+      significant bit, and since we write numbers with the most-
+      significant digit on the left, we also write bytes with the most-
+      significant bit on the left.  In the diagrams below, we number the
+      bits of a byte so that bit 0 is the least-significant bit, i.e.,
+      the bits are numbered:
+
+         +--------+
+         |76543210|
+         +--------+
+
+      Within a computer, a number may occupy multiple bytes.  All
+      multi-byte numbers in the format described here are stored with
+      the MOST-significant byte first (at the lower memory address).
+      For example, the decimal number 520 is stored as:
+
+             0     1
+         +--------+--------+
+         |00000010|00001000|
+         +--------+--------+
+          ^        ^
+          |        |
+          |        + less significant byte = 8
+          + more significant byte = 2 x 256
+
+   2.2. Data format
+
+      A zlib stream has the following structure:
+
+           0   1
+         +---+---+
+         |CMF|FLG|   (more-->)
+         +---+---+
+
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 4]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+      (if FLG.FDICT set)
+
+           0   1   2   3
+         +---+---+---+---+
+         |     DICTID    |   (more-->)
+         +---+---+---+---+
+
+         +=====================+---+---+---+---+
+         |...compressed data...|    ADLER32    |
+         +=====================+---+---+---+---+
+
+      Any data which may appear after ADLER32 are not part of the zlib
+      stream.
+
+      CMF (Compression Method and flags)
+         This byte is divided into a 4-bit compression method and a 4-
+         bit information field depending on the compression method.
+
+            bits 0 to 3  CM     Compression method
+            bits 4 to 7  CINFO  Compression info
+
+      CM (Compression method)
+         This identifies the compression method used in the file. CM = 8
+         denotes the "deflate" compression method with a window size up
+         to 32K.  This is the method used by gzip and PNG (see
+         references [1] and [2] in Chapter 3, below, for the reference
+         documents).  CM = 15 is reserved.  It might be used in a future
+         version of this specification to indicate the presence of an
+         extra field before the compressed data.
+
+      CINFO (Compression info)
+         For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
+         size, minus eight (CINFO=7 indicates a 32K window size). Values
+         of CINFO above 7 are not allowed in this version of the
+         specification.  CINFO is not defined in this specification for
+         CM not equal to 8.
+
+      FLG (FLaGs)
+         This flag byte is divided as follows:
+
+            bits 0 to 4  FCHECK  (check bits for CMF and FLG)
+            bit  5       FDICT   (preset dictionary)
+            bits 6 to 7  FLEVEL  (compression level)
+
+         The FCHECK value must be such that CMF and FLG, when viewed as
+         a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
+         is a multiple of 31.
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 5]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+      FDICT (Preset dictionary)
+         If FDICT is set, a DICT dictionary identifier is present
+         immediately after the FLG byte. The dictionary is a sequence of
+         bytes which are initially fed to the compressor without
+         producing any compressed output. DICT is the Adler-32 checksum
+         of this sequence of bytes (see the definition of ADLER32
+         below).  The decompressor can use this identifier to determine
+         which dictionary has been used by the compressor.
+
+      FLEVEL (Compression level)
+         These flags are available for use by specific compression
+         methods.  The "deflate" method (CM = 8) sets these flags as
+         follows:
+
+            0 - compressor used fastest algorithm
+            1 - compressor used fast algorithm
+            2 - compressor used default algorithm
+            3 - compressor used maximum compression, slowest algorithm
+
+         The information in FLEVEL is not needed for decompression; it
+         is there to indicate if recompression might be worthwhile.
+
+      compressed data
+         For compression method 8, the compressed data is stored in the
+         deflate compressed data format as described in the document
+         "DEFLATE Compressed Data Format Specification" by L. Peter
+         Deutsch. (See reference [3] in Chapter 3, below)
+
+         Other compressed data formats are not specified in this version
+         of the zlib specification.
+
+      ADLER32 (Adler-32 checksum)
+         This contains a checksum value of the uncompressed data
+         (excluding any dictionary data) computed according to Adler-32
+         algorithm. This algorithm is a 32-bit extension and improvement
+         of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
+         standard. See references [4] and [5] in Chapter 3, below)
+
+         Adler-32 is composed of two sums accumulated per byte: s1 is
+         the sum of all bytes, s2 is the sum of all s1 values. Both sums
+         are done modulo 65521. s1 is initialized to 1, s2 to zero.  The
+         Adler-32 checksum is stored as s2*65536 + s1 in most-
+         significant-byte first (network) order.
+
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 6]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+   2.3. Compliance
+
+      A compliant compressor must produce streams with correct CMF, FLG
+      and ADLER32, but need not support preset dictionaries.  When the
+      zlib data format is used as part of another standard data format,
+      the compressor may use only preset dictionaries that are specified
+      by this other data format.  If this other format does not use the
+      preset dictionary feature, the compressor must not set the FDICT
+      flag.
+
+      A compliant decompressor must check CMF, FLG, and ADLER32, and
+      provide an error indication if any of these have incorrect values.
+      A compliant decompressor must give an error indication if CM is
+      not one of the values defined in this specification (only the
+      value 8 is permitted in this version), since another value could
+      indicate the presence of new features that would cause subsequent
+      data to be interpreted incorrectly.  A compliant decompressor must
+      give an error indication if FDICT is set and DICTID is not the
+      identifier of a known preset dictionary.  A decompressor may
+      ignore FLEVEL and still be compliant.  When the zlib data format
+      is being used as a part of another standard format, a compliant
+      decompressor must support all the preset dictionaries specified by
+      the other format. When the other format does not use the preset
+      dictionary feature, a compliant decompressor must reject any
+      stream in which the FDICT flag is set.
+
+3. References
+
+   [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
+       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+   [2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
+       available in ftp://ftp.uu.net/graphics/png/documents/
+
+   [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
+       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+   [4] Fletcher, J. G., "An Arithmetic Checksum for Serial
+       Transmissions," IEEE Transactions on Communications, Vol. COM-30,
+       No. 1, January 1982, pp. 247-252.
+
+   [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
+       November, 1993, pp. 144, 145. (Available from
+       gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 7]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+4. Source code
+
+   Source code for a C language implementation of a "zlib" compliant
+   library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
+
+5. Security Considerations
+
+   A decoder that fails to check the ADLER32 checksum value may be
+   subject to undetected data corruption.
+
+6. Acknowledgements
+
+   Trademarks cited in this document are the property of their
+   respective owners.
+
+   Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
+   the related software described in this specification.  Glenn
+   Randers-Pehrson converted this document to RFC and HTML format.
+
+7. Authors' Addresses
+
+   L. Peter Deutsch
+   Aladdin Enterprises
+   203 Santa Margarita Ave.
+   Menlo Park, CA 94025
+
+   Phone: (415) 322-0103 (AM only)
+   FAX:   (415) 322-1734
+   EMail: <ghost@aladdin.com>
+
+
+   Jean-Loup Gailly
+
+   EMail: <gzip@prep.ai.mit.edu>
+
+   Questions about the technical content of this specification can be
+   sent by email to
+
+   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+   Mark Adler <madler@alumni.caltech.edu>
+
+   Editorial comments on this specification can be sent by email to
+
+   L. Peter Deutsch <ghost@aladdin.com> and
+   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 8]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+8. Appendix: Rationale
+
+   8.1. Preset dictionaries
+
+      A preset dictionary is specially useful to compress short input
+      sequences. The compressor can take advantage of the dictionary
+      context to encode the input in a more compact manner. The
+      decompressor can be initialized with the appropriate context by
+      virtually decompressing a compressed version of the dictionary
+      without producing any output. However for certain compression
+      algorithms such as the deflate algorithm this operation can be
+      achieved without actually performing any decompression.
+
+      The compressor and the decompressor must use exactly the same
+      dictionary. The dictionary may be fixed or may be chosen among a
+      certain number of predefined dictionaries, according to the kind
+      of input data. The decompressor can determine which dictionary has
+      been chosen by the compressor by checking the dictionary
+      identifier. This document does not specify the contents of
+      predefined dictionaries, since the optimal dictionaries are
+      application specific. Standard data formats using this feature of
+      the zlib specification must precisely define the allowed
+      dictionaries.
+
+   8.2. The Adler-32 algorithm
+
+      The Adler-32 algorithm is much faster than the CRC32 algorithm yet
+      still provides an extremely low probability of undetected errors.
+
+      The modulo on unsigned long accumulators can be delayed for 5552
+      bytes, so the modulo operation time is negligible.  If the bytes
+      are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
+      and order sensitive, unlike the first sum, which is just a
+      checksum.  That 65521 is prime is important to avoid a possible
+      large class of two-byte errors that leave the check unchanged.
+      (The Fletcher checksum uses 255, which is not prime and which also
+      makes the Fletcher check insensitive to single byte changes 0 <->
+      255.)
+
+      The sum s1 is initialized to 1 instead of zero to make the length
+      of the sequence part of s2, so that the length does not have to be
+      checked separately. (Any sequence of zeroes has a Fletcher
+      checksum of zero.)
+
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 9]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+9. Appendix: Sample code
+
+   The following C code computes the Adler-32 checksum of a data buffer.
+   It is written for clarity, not for speed.  The sample code is in the
+   ANSI C programming language. Non C users may find it easier to read
+   with these hints:
+
+      &      Bitwise AND operator.
+      >>     Bitwise right shift operator. When applied to an
+             unsigned quantity, as here, right shift inserts zero bit(s)
+             at the left.
+      <<     Bitwise left shift operator. Left shift inserts zero
+             bit(s) at the right.
+      ++     "n++" increments the variable n.
+      %      modulo operator: a % b is the remainder of a divided by b.
+
+      #define BASE 65521 /* largest prime smaller than 65536 */
+
+      /*
+         Update a running Adler-32 checksum with the bytes buf[0..len-1]
+       and return the updated checksum. The Adler-32 checksum should be
+       initialized to 1.
+
+       Usage example:
+
+         unsigned long adler = 1L;
+
+         while (read_buffer(buffer, length) != EOF) {
+           adler = update_adler32(adler, buffer, length);
+         }
+         if (adler != original_adler) error();
+      */
+      unsigned long update_adler32(unsigned long adler,
+         unsigned char *buf, int len)
+      {
+        unsigned long s1 = adler & 0xffff;
+        unsigned long s2 = (adler >> 16) & 0xffff;
+        int n;
+
+        for (n = 0; n < len; n++) {
+          s1 = (s1 + buf[n]) % BASE;
+          s2 = (s2 + s1)     % BASE;
+        }
+        return (s2 << 16) + s1;
+      }
+
+      /* Return the adler32 of the bytes buf[0..len-1] */
+
+
+
+
+Deutsch & Gailly             Informational                     [Page 10]
+\f
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+      unsigned long adler32(unsigned char *buf, int len)
+      {
+        return update_adler32(1L, buf, len);
+      }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                     [Page 11]
+\f
diff --git a/8.x/zlib/doc/rfc1951.txt b/8.x/zlib/doc/rfc1951.txt
new file mode 100644 (file)
index 0000000..403c8c7
--- /dev/null
@@ -0,0 +1,955 @@
+
+
+
+
+
+
+Network Working Group                                         P. Deutsch
+Request for Comments: 1951                           Aladdin Enterprises
+Category: Informational                                         May 1996
+
+
+        DEFLATE Compressed Data Format Specification version 1.3
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  This memo
+   does not specify an Internet standard of any kind.  Distribution of
+   this memo is unlimited.
+
+IESG Note:
+
+   The IESG takes no position on the validity of any Intellectual
+   Property Rights statements contained in this document.
+
+Notices
+
+   Copyright (c) 1996 L. Peter Deutsch
+
+   Permission is granted to copy and distribute this document for any
+   purpose and without charge, including translations into other
+   languages and incorporation into compilations, provided that the
+   copyright notice and this notice are preserved, and that any
+   substantive changes or deletions from the original are clearly
+   marked.
+
+   A pointer to the latest version of this and related documentation in
+   HTML format can be found at the URL
+   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+   This specification defines a lossless compressed data format that
+   compresses data using a combination of the LZ77 algorithm and Huffman
+   coding, with efficiency comparable to the best currently available
+   general-purpose compression methods.  The data can be produced or
+   consumed, even for an arbitrarily long sequentially presented input
+   data stream, using only an a priori bounded amount of intermediate
+   storage.  The format can be implemented readily in a manner not
+   covered by patents.
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 1]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+Table of Contents
+
+   1. Introduction ................................................... 2
+      1.1. Purpose ................................................... 2
+      1.2. Intended audience ......................................... 3
+      1.3. Scope ..................................................... 3
+      1.4. Compliance ................................................ 3
+      1.5.  Definitions of terms and conventions used ................ 3
+      1.6. Changes from previous versions ............................ 4
+   2. Compressed representation overview ............................. 4
+   3. Detailed specification ......................................... 5
+      3.1. Overall conventions ....................................... 5
+          3.1.1. Packing into bytes .................................. 5
+      3.2. Compressed block format ................................... 6
+          3.2.1. Synopsis of prefix and Huffman coding ............... 6
+          3.2.2. Use of Huffman coding in the "deflate" format ....... 7
+          3.2.3. Details of block format ............................. 9
+          3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
+          3.2.5. Compressed blocks (length and distance codes) ...... 11
+          3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
+          3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
+      3.3. Compliance ............................................... 14
+   4. Compression algorithm details ................................. 14
+   5. References .................................................... 16
+   6. Security Considerations ....................................... 16
+   7. Source code ................................................... 16
+   8. Acknowledgements .............................................. 16
+   9. Author's Address .............................................. 17
+
+1. Introduction
+
+   1.1. Purpose
+
+      The purpose of this specification is to define a lossless
+      compressed data format that:
+          * Is independent of CPU type, operating system, file system,
+            and character set, and hence can be used for interchange;
+          * Can be produced or consumed, even for an arbitrarily long
+            sequentially presented input data stream, using only an a
+            priori bounded amount of intermediate storage, and hence
+            can be used in data communications or similar structures
+            such as Unix filters;
+          * Compresses data with efficiency comparable to the best
+            currently available general-purpose compression methods,
+            and in particular considerably better than the "compress"
+            program;
+          * Can be implemented readily in a manner not covered by
+            patents, and hence can be practiced freely;
+
+
+
+Deutsch                      Informational                      [Page 2]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+          * Is compatible with the file format produced by the current
+            widely used gzip utility, in that conforming decompressors
+            will be able to read data produced by the existing gzip
+            compressor.
+
+      The data format defined by this specification does not attempt to:
+
+          * Allow random access to compressed data;
+          * Compress specialized data (e.g., raster graphics) as well
+            as the best currently available specialized algorithms.
+
+      A simple counting argument shows that no lossless compression
+      algorithm can compress every possible input data set.  For the
+      format defined here, the worst case expansion is 5 bytes per 32K-
+      byte block, i.e., a size increase of 0.015% for large data sets.
+      English text usually compresses by a factor of 2.5 to 3;
+      executable files usually compress somewhat less; graphical data
+      such as raster images may compress much more.
+
+   1.2. Intended audience
+
+      This specification is intended for use by implementors of software
+      to compress data into "deflate" format and/or decompress data from
+      "deflate" format.
+
+      The text of the specification assumes a basic background in
+      programming at the level of bits and other primitive data
+      representations.  Familiarity with the technique of Huffman coding
+      is helpful but not required.
+
+   1.3. Scope
+
+      The specification specifies a method for representing a sequence
+      of bytes as a (usually shorter) sequence of bits, and a method for
+      packing the latter bit sequence into bytes.
+
+   1.4. Compliance
+
+      Unless otherwise indicated below, a compliant decompressor must be
+      able to accept and decompress any data set that conforms to all
+      the specifications presented here; a compliant compressor must
+      produce data sets that conform to all the specifications presented
+      here.
+
+   1.5.  Definitions of terms and conventions used
+
+      Byte: 8 bits stored or transmitted as a unit (same as an octet).
+      For this specification, a byte is exactly 8 bits, even on machines
+
+
+
+Deutsch                      Informational                      [Page 3]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+      which store a character on a number of bits different from eight.
+      See below, for the numbering of bits within a byte.
+
+      String: a sequence of arbitrary bytes.
+
+   1.6. Changes from previous versions
+
+      There have been no technical changes to the deflate format since
+      version 1.1 of this specification.  In version 1.2, some
+      terminology was changed.  Version 1.3 is a conversion of the
+      specification to RFC style.
+
+2. Compressed representation overview
+
+   A compressed data set consists of a series of blocks, corresponding
+   to successive blocks of input data.  The block sizes are arbitrary,
+   except that non-compressible blocks are limited to 65,535 bytes.
+
+   Each block is compressed using a combination of the LZ77 algorithm
+   and Huffman coding. The Huffman trees for each block are independent
+   of those for previous or subsequent blocks; the LZ77 algorithm may
+   use a reference to a duplicated string occurring in a previous block,
+   up to 32K input bytes before.
+
+   Each block consists of two parts: a pair of Huffman code trees that
+   describe the representation of the compressed data part, and a
+   compressed data part.  (The Huffman trees themselves are compressed
+   using Huffman encoding.)  The compressed data consists of a series of
+   elements of two types: literal bytes (of strings that have not been
+   detected as duplicated within the previous 32K input bytes), and
+   pointers to duplicated strings, where a pointer is represented as a
+   pair <length, backward distance>.  The representation used in the
+   "deflate" format limits distances to 32K bytes and lengths to 258
+   bytes, but does not limit the size of a block, except for
+   uncompressible blocks, which are limited as noted above.
+
+   Each type of value (literals, distances, and lengths) in the
+   compressed data is represented using a Huffman code, using one code
+   tree for literals and lengths and a separate code tree for distances.
+   The code trees for each block appear in a compact form just before
+   the compressed data for that block.
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 4]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+3. Detailed specification
+
+   3.1. Overall conventions In the diagrams below, a box like this:
+
+         +---+
+         |   | <-- the vertical bars might be missing
+         +---+
+
+      represents one byte; a box like this:
+
+         +==============+
+         |              |
+         +==============+
+
+      represents a variable number of bytes.
+
+      Bytes stored within a computer do not have a "bit order", since
+      they are always treated as a unit.  However, a byte considered as
+      an integer between 0 and 255 does have a most- and least-
+      significant bit, and since we write numbers with the most-
+      significant digit on the left, we also write bytes with the most-
+      significant bit on the left.  In the diagrams below, we number the
+      bits of a byte so that bit 0 is the least-significant bit, i.e.,
+      the bits are numbered:
+
+         +--------+
+         |76543210|
+         +--------+
+
+      Within a computer, a number may occupy multiple bytes.  All
+      multi-byte numbers in the format described here are stored with
+      the least-significant byte first (at the lower memory address).
+      For example, the decimal number 520 is stored as:
+
+             0        1
+         +--------+--------+
+         |00001000|00000010|
+         +--------+--------+
+          ^        ^
+          |        |
+          |        + more significant byte = 2 x 256
+          + less significant byte = 8
+
+      3.1.1. Packing into bytes
+
+         This document does not address the issue of the order in which
+         bits of a byte are transmitted on a bit-sequential medium,
+         since the final data format described here is byte- rather than
+
+
+
+Deutsch                      Informational                      [Page 5]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         bit-oriented.  However, we describe the compressed block format
+         in below, as a sequence of data elements of various bit
+         lengths, not a sequence of bytes.  We must therefore specify
+         how to pack these data elements into bytes to form the final
+         compressed byte sequence:
+
+             * Data elements are packed into bytes in order of
+               increasing bit number within the byte, i.e., starting
+               with the least-significant bit of the byte.
+             * Data elements other than Huffman codes are packed
+               starting with the least-significant bit of the data
+               element.
+             * Huffman codes are packed starting with the most-
+               significant bit of the code.
+
+         In other words, if one were to print out the compressed data as
+         a sequence of bytes, starting with the first byte at the
+         *right* margin and proceeding to the *left*, with the most-
+         significant bit of each byte on the left as usual, one would be
+         able to parse the result from right to left, with fixed-width
+         elements in the correct MSB-to-LSB order and Huffman codes in
+         bit-reversed order (i.e., with the first bit of the code in the
+         relative LSB position).
+
+   3.2. Compressed block format
+
+      3.2.1. Synopsis of prefix and Huffman coding
+
+         Prefix coding represents symbols from an a priori known
+         alphabet by bit sequences (codes), one code for each symbol, in
+         a manner such that different symbols may be represented by bit
+         sequences of different lengths, but a parser can always parse
+         an encoded string unambiguously symbol-by-symbol.
+
+         We define a prefix code in terms of a binary tree in which the
+         two edges descending from each non-leaf node are labeled 0 and
+         1 and in which the leaf nodes correspond one-for-one with (are
+         labeled with) the symbols of the alphabet; then the code for a
+         symbol is the sequence of 0's and 1's on the edges leading from
+         the root to the leaf labeled with that symbol.  For example:
+
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 6]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+                          /\              Symbol    Code
+                         0  1             ------    ----
+                        /    \                A      00
+                       /\     B               B       1
+                      0  1                    C     011
+                     /    \                   D     010
+                    A     /\
+                         0  1
+                        /    \
+                       D      C
+
+         A parser can decode the next symbol from an encoded input
+         stream by walking down the tree from the root, at each step
+         choosing the edge corresponding to the next input bit.
+
+         Given an alphabet with known symbol frequencies, the Huffman
+         algorithm allows the construction of an optimal prefix code
+         (one which represents strings with those symbol frequencies
+         using the fewest bits of any possible prefix codes for that
+         alphabet).  Such a code is called a Huffman code.  (See
+         reference [1] in Chapter 5, references for additional
+         information on Huffman codes.)
+
+         Note that in the "deflate" format, the Huffman codes for the
+         various alphabets must not exceed certain maximum code lengths.
+         This constraint complicates the algorithm for computing code
+         lengths from symbol frequencies.  Again, see Chapter 5,
+         references for details.
+
+      3.2.2. Use of Huffman coding in the "deflate" format
+
+         The Huffman codes used for each alphabet in the "deflate"
+         format have two additional rules:
+
+             * All codes of a given bit length have lexicographically
+               consecutive values, in the same order as the symbols
+               they represent;
+
+             * Shorter codes lexicographically precede longer codes.
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 7]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         We could recode the example above to follow this rule as
+         follows, assuming that the order of the alphabet is ABCD:
+
+            Symbol  Code
+            ------  ----
+            A       10
+            B       0
+            C       110
+            D       111
+
+         I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
+         lexicographically consecutive.
+
+         Given this rule, we can define the Huffman code for an alphabet
+         just by giving the bit lengths of the codes for each symbol of
+         the alphabet in order; this is sufficient to determine the
+         actual codes.  In our example, the code is completely defined
+         by the sequence of bit lengths (2, 1, 3, 3).  The following
+         algorithm generates the codes as integers, intended to be read
+         from most- to least-significant bit.  The code lengths are
+         initially in tree[I].Len; the codes are produced in
+         tree[I].Code.
+
+         1)  Count the number of codes for each code length.  Let
+             bl_count[N] be the number of codes of length N, N >= 1.
+
+         2)  Find the numerical value of the smallest code for each
+             code length:
+
+                code = 0;
+                bl_count[0] = 0;
+                for (bits = 1; bits <= MAX_BITS; bits++) {
+                    code = (code + bl_count[bits-1]) << 1;
+                    next_code[bits] = code;
+                }
+
+         3)  Assign numerical values to all codes, using consecutive
+             values for all codes of the same length with the base
+             values determined at step 2. Codes that are never used
+             (which have a bit length of zero) must not be assigned a
+             value.
+
+                for (n = 0;  n <= max_code; n++) {
+                    len = tree[n].Len;
+                    if (len != 0) {
+                        tree[n].Code = next_code[len];
+                        next_code[len]++;
+                    }
+
+
+
+Deutsch                      Informational                      [Page 8]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+                }
+
+         Example:
+
+         Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
+         3, 2, 4, 4).  After step 1, we have:
+
+            N      bl_count[N]
+            -      -----------
+            2      1
+            3      5
+            4      2
+
+         Step 2 computes the following next_code values:
+
+            N      next_code[N]
+            -      ------------
+            1      0
+            2      0
+            3      2
+            4      14
+
+         Step 3 produces the following code values:
+
+            Symbol Length   Code
+            ------ ------   ----
+            A       3        010
+            B       3        011
+            C       3        100
+            D       3        101
+            E       3        110
+            F       2         00
+            G       4       1110
+            H       4       1111
+
+      3.2.3. Details of block format
+
+         Each block of compressed data begins with 3 header bits
+         containing the following data:
+
+            first bit       BFINAL
+            next 2 bits     BTYPE
+
+         Note that the header bits do not necessarily begin on a byte
+         boundary, since a block does not necessarily occupy an integral
+         number of bytes.
+
+
+
+
+
+Deutsch                      Informational                      [Page 9]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         BFINAL is set if and only if this is the last block of the data
+         set.
+
+         BTYPE specifies how the data are compressed, as follows:
+
+            00 - no compression
+            01 - compressed with fixed Huffman codes
+            10 - compressed with dynamic Huffman codes
+            11 - reserved (error)
+
+         The only difference between the two compressed cases is how the
+         Huffman codes for the literal/length and distance alphabets are
+         defined.
+
+         In all cases, the decoding algorithm for the actual data is as
+         follows:
+
+            do
+               read block header from input stream.
+               if stored with no compression
+                  skip any remaining bits in current partially
+                     processed byte
+                  read LEN and NLEN (see next section)
+                  copy LEN bytes of data to output
+               otherwise
+                  if compressed with dynamic Huffman codes
+                     read representation of code trees (see
+                        subsection below)
+                  loop (until end of block code recognized)
+                     decode literal/length value from input stream
+                     if value < 256
+                        copy value (literal byte) to output stream
+                     otherwise
+                        if value = end of block (256)
+                           break from loop
+                        otherwise (value = 257..285)
+                           decode distance from input stream
+
+                           move backwards distance bytes in the output
+                           stream, and copy length bytes from this
+                           position to the output stream.
+                  end loop
+            while not last block
+
+         Note that a duplicated string reference may refer to a string
+         in a previous block; i.e., the backward distance may cross one
+         or more block boundaries.  However a distance cannot refer past
+         the beginning of the output stream.  (An application using a
+
+
+
+Deutsch                      Informational                     [Page 10]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         preset dictionary might discard part of the output stream; a
+         distance can refer to that part of the output stream anyway)
+         Note also that the referenced string may overlap the current
+         position; for example, if the last 2 bytes decoded have values
+         X and Y, a string reference with <length = 5, distance = 2>
+         adds X,Y,X,Y,X to the output stream.
+
+         We now specify each compression method in turn.
+
+      3.2.4. Non-compressed blocks (BTYPE=00)
+
+         Any bits of input up to the next byte boundary are ignored.
+         The rest of the block consists of the following information:
+
+              0   1   2   3   4...
+            +---+---+---+---+================================+
+            |  LEN  | NLEN  |... LEN bytes of literal data...|
+            +---+---+---+---+================================+
+
+         LEN is the number of data bytes in the block.  NLEN is the
+         one's complement of LEN.
+
+      3.2.5. Compressed blocks (length and distance codes)
+
+         As noted above, encoded data blocks in the "deflate" format
+         consist of sequences of symbols drawn from three conceptually
+         distinct alphabets: either literal bytes, from the alphabet of
+         byte values (0..255), or <length, backward distance> pairs,
+         where the length is drawn from (3..258) and the distance is
+         drawn from (1..32,768).  In fact, the literal and length
+         alphabets are merged into a single alphabet (0..285), where
+         values 0..255 represent literal bytes, the value 256 indicates
+         end-of-block, and values 257..285 represent length codes
+         (possibly in conjunction with extra bits following the symbol
+         code) as follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                     [Page 11]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+                 Extra               Extra               Extra
+            Code Bits Length(s) Code Bits Lengths   Code Bits Length(s)
+            ---- ---- ------     ---- ---- -------   ---- ---- -------
+             257   0     3       267   1   15,16     277   4   67-82
+             258   0     4       268   1   17,18     278   4   83-98
+             259   0     5       269   2   19-22     279   4   99-114
+             260   0     6       270   2   23-26     280   4  115-130
+             261   0     7       271   2   27-30     281   5  131-162
+             262   0     8       272   2   31-34     282   5  163-194
+             263   0     9       273   3   35-42     283   5  195-226
+             264   0    10       274   3   43-50     284   5  227-257
+             265   1  11,12      275   3   51-58     285   0    258
+             266   1  13,14      276   3   59-66
+
+         The extra bits should be interpreted as a machine integer
+         stored with the most-significant bit first, e.g., bits 1110
+         represent the value 14.
+
+                  Extra           Extra               Extra
+             Code Bits Dist  Code Bits   Dist     Code Bits Distance
+             ---- ---- ----  ---- ----  ------    ---- ---- --------
+               0   0    1     10   4     33-48    20    9   1025-1536
+               1   0    2     11   4     49-64    21    9   1537-2048
+               2   0    3     12   5     65-96    22   10   2049-3072
+               3   0    4     13   5     97-128   23   10   3073-4096
+               4   1   5,6    14   6    129-192   24   11   4097-6144
+               5   1   7,8    15   6    193-256   25   11   6145-8192
+               6   2   9-12   16   7    257-384   26   12  8193-12288
+               7   2  13-16   17   7    385-512   27   12 12289-16384
+               8   3  17-24   18   8    513-768   28   13 16385-24576
+               9   3  25-32   19   8   769-1024   29   13 24577-32768
+
+      3.2.6. Compression with fixed Huffman codes (BTYPE=01)
+
+         The Huffman codes for the two alphabets are fixed, and are not
+         represented explicitly in the data.  The Huffman code lengths
+         for the literal/length alphabet are:
+
+                   Lit Value    Bits        Codes
+                   ---------    ----        -----
+                     0 - 143     8          00110000 through
+                                            10111111
+                   144 - 255     9          110010000 through
+                                            111111111
+                   256 - 279     7          0000000 through
+                                            0010111
+                   280 - 287     8          11000000 through
+                                            11000111
+
+
+
+Deutsch                      Informational                     [Page 12]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         The code lengths are sufficient to generate the actual codes,
+         as described above; we show the codes in the table for added
+         clarity.  Literal/length values 286-287 will never actually
+         occur in the compressed data, but participate in the code
+         construction.
+
+         Distance codes 0-31 are represented by (fixed-length) 5-bit
+         codes, with possible additional bits as shown in the table
+         shown in Paragraph 3.2.5, above.  Note that distance codes 30-
+         31 will never actually occur in the compressed data.
+
+      3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
+
+         The Huffman codes for the two alphabets appear in the block
+         immediately after the header bits and before the actual
+         compressed data, first the literal/length code and then the
+         distance code.  Each code is defined by a sequence of code
+         lengths, as discussed in Paragraph 3.2.2, above.  For even
+         greater compactness, the code length sequences themselves are
+         compressed using a Huffman code.  The alphabet for code lengths
+         is as follows:
+
+               0 - 15: Represent code lengths of 0 - 15
+                   16: Copy the previous code length 3 - 6 times.
+                       The next 2 bits indicate repeat length
+                             (0 = 3, ... , 3 = 6)
+                          Example:  Codes 8, 16 (+2 bits 11),
+                                    16 (+2 bits 10) will expand to
+                                    12 code lengths of 8 (1 + 6 + 5)
+                   17: Repeat a code length of 0 for 3 - 10 times.
+                       (3 bits of length)
+                   18: Repeat a code length of 0 for 11 - 138 times
+                       (7 bits of length)
+
+         A code length of 0 indicates that the corresponding symbol in
+         the literal/length or distance alphabet will not occur in the
+         block, and should not participate in the Huffman code
+         construction algorithm given earlier.  If only one distance
+         code is used, it is encoded using one bit, not zero bits; in
+         this case there is a single code length of one, with one unused
+         code.  One distance code of zero bits means that there are no
+         distance codes used at all (the data is all literals).
+
+         We can now define the format of the block:
+
+               5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
+               5 Bits: HDIST, # of Distance codes - 1        (1 - 32)
+               4 Bits: HCLEN, # of Code Length codes - 4     (4 - 19)
+
+
+
+Deutsch                      Informational                     [Page 13]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+               (HCLEN + 4) x 3 bits: code lengths for the code length
+                  alphabet given just above, in the order: 16, 17, 18,
+                  0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+
+                  These code lengths are interpreted as 3-bit integers
+                  (0-7); as above, a code length of 0 means the
+                  corresponding symbol (literal/length or distance code
+                  length) is not used.
+
+               HLIT + 257 code lengths for the literal/length alphabet,
+                  encoded using the code length Huffman code
+
+               HDIST + 1 code lengths for the distance alphabet,
+                  encoded using the code length Huffman code
+
+               The actual compressed data of the block,
+                  encoded using the literal/length and distance Huffman
+                  codes
+
+               The literal/length symbol 256 (end of data),
+                  encoded using the literal/length Huffman code
+
+         The code length repeat codes can cross from HLIT + 257 to the
+         HDIST + 1 code lengths.  In other words, all code lengths form
+         a single sequence of HLIT + HDIST + 258 values.
+
+   3.3. Compliance
+
+      A compressor may limit further the ranges of values specified in
+      the previous section and still be compliant; for example, it may
+      limit the range of backward pointers to some value smaller than
+      32K.  Similarly, a compressor may limit the size of blocks so that
+      a compressible block fits in memory.
+
+      A compliant decompressor must accept the full range of possible
+      values defined in the previous section, and must accept blocks of
+      arbitrary size.
+
+4. Compression algorithm details
+
+   While it is the intent of this document to define the "deflate"
+   compressed data format without reference to any particular
+   compression algorithm, the format is related to the compressed
+   formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
+   since many variations of LZ77 are patented, it is strongly
+   recommended that the implementor of a compressor follow the general
+   algorithm presented here, which is known not to be patented per se.
+   The material in this section is not part of the definition of the
+
+
+
+Deutsch                      Informational                     [Page 14]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+   specification per se, and a compressor need not follow it in order to
+   be compliant.
+
+   The compressor terminates a block when it determines that starting a
+   new block with fresh trees would be useful, or when the block size
+   fills up the compressor's block buffer.
+
+   The compressor uses a chained hash table to find duplicated strings,
+   using a hash function that operates on 3-byte sequences.  At any
+   given point during compression, let XYZ be the next 3 input bytes to
+   be examined (not necessarily all different, of course).  First, the
+   compressor examines the hash chain for XYZ.  If the chain is empty,
+   the compressor simply writes out X as a literal byte and advances one
+   byte in the input.  If the hash chain is not empty, indicating that
+   the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
+   same hash function value) has occurred recently, the compressor
+   compares all strings on the XYZ hash chain with the actual input data
+   sequence starting at the current point, and selects the longest
+   match.
+
+   The compressor searches the hash chains starting with the most recent
+   strings, to favor small distances and thus take advantage of the
+   Huffman encoding.  The hash chains are singly linked. There are no
+   deletions from the hash chains; the algorithm simply discards matches
+   that are too old.  To avoid a worst-case situation, very long hash
+   chains are arbitrarily truncated at a certain length, determined by a
+   run-time parameter.
+
+   To improve overall compression, the compressor optionally defers the
+   selection of matches ("lazy matching"): after a match of length N has
+   been found, the compressor searches for a longer match starting at
+   the next input byte.  If it finds a longer match, it truncates the
+   previous match to a length of one (thus producing a single literal
+   byte) and then emits the longer match.  Otherwise, it emits the
+   original match, and, as described above, advances N bytes before
+   continuing.
+
+   Run-time parameters also control this "lazy match" procedure.  If
+   compression ratio is most important, the compressor attempts a
+   complete second search regardless of the length of the first match.
+   In the normal case, if the current match is "long enough", the
+   compressor reduces the search for a longer match, thus speeding up
+   the process.  If speed is most important, the compressor inserts new
+   strings in the hash table only when no match was found, or when the
+   match is not "too long".  This degrades the compression ratio but
+   saves time since there are both fewer insertions and fewer searches.
+
+
+
+
+
+Deutsch                      Informational                     [Page 15]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+5. References
+
+   [1] Huffman, D. A., "A Method for the Construction of Minimum
+       Redundancy Codes", Proceedings of the Institute of Radio
+       Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
+
+   [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
+       Compression", IEEE Transactions on Information Theory, Vol. 23,
+       No. 3, pp. 337-343.
+
+   [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
+       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+   [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
+       available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
+
+   [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
+       encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
+
+   [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
+       Comm. ACM, 33,4, April 1990, pp. 449-459.
+
+6. Security Considerations
+
+   Any data compression method involves the reduction of redundancy in
+   the data.  Consequently, any corruption of the data is likely to have
+   severe effects and be difficult to correct.  Uncompressed text, on
+   the other hand, will probably still be readable despite the presence
+   of some corrupted bytes.
+
+   It is recommended that systems using this data format provide some
+   means of validating the integrity of the compressed data.  See
+   reference [3], for example.
+
+7. Source code
+
+   Source code for a C language implementation of a "deflate" compliant
+   compressor and decompressor is available within the zlib package at
+   ftp://ftp.uu.net/pub/archiving/zip/zlib/.
+
+8. Acknowledgements
+
+   Trademarks cited in this document are the property of their
+   respective owners.
+
+   Phil Katz designed the deflate format.  Jean-Loup Gailly and Mark
+   Adler wrote the related software described in this specification.
+   Glenn Randers-Pehrson converted this document to RFC and HTML format.
+
+
+
+Deutsch                      Informational                     [Page 16]
+\f
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+9. Author's Address
+
+   L. Peter Deutsch
+   Aladdin Enterprises
+   203 Santa Margarita Ave.
+   Menlo Park, CA 94025
+
+   Phone: (415) 322-0103 (AM only)
+   FAX:   (415) 322-1734
+   EMail: <ghost@aladdin.com>
+
+   Questions about the technical content of this specification can be
+   sent by email to:
+
+   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+   Mark Adler <madler@alumni.caltech.edu>
+
+   Editorial comments on this specification can be sent by email to:
+
+   L. Peter Deutsch <ghost@aladdin.com> and
+   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                     [Page 17]
+\f
diff --git a/8.x/zlib/doc/rfc1952.txt b/8.x/zlib/doc/rfc1952.txt
new file mode 100644 (file)
index 0000000..a8e51b4
--- /dev/null
@@ -0,0 +1,675 @@
+
+
+
+
+
+
+Network Working Group                                         P. Deutsch
+Request for Comments: 1952                           Aladdin Enterprises
+Category: Informational                                         May 1996
+
+
+               GZIP file format specification version 4.3
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  This memo
+   does not specify an Internet standard of any kind.  Distribution of
+   this memo is unlimited.
+
+IESG Note:
+
+   The IESG takes no position on the validity of any Intellectual
+   Property Rights statements contained in this document.
+
+Notices
+
+   Copyright (c) 1996 L. Peter Deutsch
+
+   Permission is granted to copy and distribute this document for any
+   purpose and without charge, including translations into other
+   languages and incorporation into compilations, provided that the
+   copyright notice and this notice are preserved, and that any
+   substantive changes or deletions from the original are clearly
+   marked.
+
+   A pointer to the latest version of this and related documentation in
+   HTML format can be found at the URL
+   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+   This specification defines a lossless compressed data format that is
+   compatible with the widely used GZIP utility.  The format includes a
+   cyclic redundancy check value for detecting data corruption.  The
+   format presently uses the DEFLATE method of compression but can be
+   easily extended to use other compression methods.  The format can be
+   implemented readily in a manner not covered by patents.
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 1]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+Table of Contents
+
+   1. Introduction ................................................... 2
+      1.1. Purpose ................................................... 2
+      1.2. Intended audience ......................................... 3
+      1.3. Scope ..................................................... 3
+      1.4. Compliance ................................................ 3
+      1.5. Definitions of terms and conventions used ................. 3
+      1.6. Changes from previous versions ............................ 3
+   2. Detailed specification ......................................... 4
+      2.1. Overall conventions ....................................... 4
+      2.2. File format ............................................... 5
+      2.3. Member format ............................................. 5
+          2.3.1. Member header and trailer ........................... 6
+              2.3.1.1. Extra field ................................... 8
+              2.3.1.2. Compliance .................................... 9
+      3. References .................................................. 9
+      4. Security Considerations .................................... 10
+      5. Acknowledgements ........................................... 10
+      6. Author's Address ........................................... 10
+      7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
+      8. Appendix: Sample CRC Code .................................. 11
+
+1. Introduction
+
+   1.1. Purpose
+
+      The purpose of this specification is to define a lossless
+      compressed data format that:
+
+          * Is independent of CPU type, operating system, file system,
+            and character set, and hence can be used for interchange;
+          * Can compress or decompress a data stream (as opposed to a
+            randomly accessible file) to produce another data stream,
+            using only an a priori bounded amount of intermediate
+            storage, and hence can be used in data communications or
+            similar structures such as Unix filters;
+          * Compresses data with efficiency comparable to the best
+            currently available general-purpose compression methods,
+            and in particular considerably better than the "compress"
+            program;
+          * Can be implemented readily in a manner not covered by
+            patents, and hence can be practiced freely;
+          * Is compatible with the file format produced by the current
+            widely used gzip utility, in that conforming decompressors
+            will be able to read data produced by the existing gzip
+            compressor.
+
+
+
+
+Deutsch                      Informational                      [Page 2]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+      The data format defined by this specification does not attempt to:
+
+          * Provide random access to compressed data;
+          * Compress specialized data (e.g., raster graphics) as well as
+            the best currently available specialized algorithms.
+
+   1.2. Intended audience
+
+      This specification is intended for use by implementors of software
+      to compress data into gzip format and/or decompress data from gzip
+      format.
+
+      The text of the specification assumes a basic background in
+      programming at the level of bits and other primitive data
+      representations.
+
+   1.3. Scope
+
+      The specification specifies a compression method and a file format
+      (the latter assuming only that a file can store a sequence of
+      arbitrary bytes).  It does not specify any particular interface to
+      a file system or anything about character sets or encodings
+      (except for file names and comments, which are optional).
+
+   1.4. Compliance
+
+      Unless otherwise indicated below, a compliant decompressor must be
+      able to accept and decompress any file that conforms to all the
+      specifications presented here; a compliant compressor must produce
+      files that conform to all the specifications presented here.  The
+      material in the appendices is not part of the specification per se
+      and is not relevant to compliance.
+
+   1.5. Definitions of terms and conventions used
+
+      byte: 8 bits stored or transmitted as a unit (same as an octet).
+      (For this specification, a byte is exactly 8 bits, even on
+      machines which store a character on a number of bits different
+      from 8.)  See below for the numbering of bits within a byte.
+
+   1.6. Changes from previous versions
+
+      There have been no technical changes to the gzip format since
+      version 4.1 of this specification.  In version 4.2, some
+      terminology was changed, and the sample CRC code was rewritten for
+      clarity and to eliminate the requirement for the caller to do pre-
+      and post-conditioning.  Version 4.3 is a conversion of the
+      specification to RFC style.
+
+
+
+Deutsch                      Informational                      [Page 3]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+2. Detailed specification
+
+   2.1. Overall conventions
+
+      In the diagrams below, a box like this:
+
+         +---+
+         |   | <-- the vertical bars might be missing
+         +---+
+
+      represents one byte; a box like this:
+
+         +==============+
+         |              |
+         +==============+
+
+      represents a variable number of bytes.
+
+      Bytes stored within a computer do not have a "bit order", since
+      they are always treated as a unit.  However, a byte considered as
+      an integer between 0 and 255 does have a most- and least-
+      significant bit, and since we write numbers with the most-
+      significant digit on the left, we also write bytes with the most-
+      significant bit on the left.  In the diagrams below, we number the
+      bits of a byte so that bit 0 is the least-significant bit, i.e.,
+      the bits are numbered:
+
+         +--------+
+         |76543210|
+         +--------+
+
+      This document does not address the issue of the order in which
+      bits of a byte are transmitted on a bit-sequential medium, since
+      the data format described here is byte- rather than bit-oriented.
+
+      Within a computer, a number may occupy multiple bytes.  All
+      multi-byte numbers in the format described here are stored with
+      the least-significant byte first (at the lower memory address).
+      For example, the decimal number 520 is stored as:
+
+             0        1
+         +--------+--------+
+         |00001000|00000010|
+         +--------+--------+
+          ^        ^
+          |        |
+          |        + more significant byte = 2 x 256
+          + less significant byte = 8
+
+
+
+Deutsch                      Informational                      [Page 4]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+   2.2. File format
+
+      A gzip file consists of a series of "members" (compressed data
+      sets).  The format of each member is specified in the following
+      section.  The members simply appear one after another in the file,
+      with no additional information before, between, or after them.
+
+   2.3. Member format
+
+      Each member has the following structure:
+
+         +---+---+---+---+---+---+---+---+---+---+
+         |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
+         +---+---+---+---+---+---+---+---+---+---+
+
+      (if FLG.FEXTRA set)
+
+         +---+---+=================================+
+         | XLEN  |...XLEN bytes of "extra field"...| (more-->)
+         +---+---+=================================+
+
+      (if FLG.FNAME set)
+
+         +=========================================+
+         |...original file name, zero-terminated...| (more-->)
+         +=========================================+
+
+      (if FLG.FCOMMENT set)
+
+         +===================================+
+         |...file comment, zero-terminated...| (more-->)
+         +===================================+
+
+      (if FLG.FHCRC set)
+
+         +---+---+
+         | CRC16 |
+         +---+---+
+
+         +=======================+
+         |...compressed blocks...| (more-->)
+         +=======================+
+
+           0   1   2   3   4   5   6   7
+         +---+---+---+---+---+---+---+---+
+         |     CRC32     |     ISIZE     |
+         +---+---+---+---+---+---+---+---+
+
+
+
+
+Deutsch                      Informational                      [Page 5]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+      2.3.1. Member header and trailer
+
+         ID1 (IDentification 1)
+         ID2 (IDentification 2)
+            These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
+            (0x8b, \213), to identify the file as being in gzip format.
+
+         CM (Compression Method)
+            This identifies the compression method used in the file.  CM
+            = 0-7 are reserved.  CM = 8 denotes the "deflate"
+            compression method, which is the one customarily used by
+            gzip and which is documented elsewhere.
+
+         FLG (FLaGs)
+            This flag byte is divided into individual bits as follows:
+
+               bit 0   FTEXT
+               bit 1   FHCRC
+               bit 2   FEXTRA
+               bit 3   FNAME
+               bit 4   FCOMMENT
+               bit 5   reserved
+               bit 6   reserved
+               bit 7   reserved
+
+            If FTEXT is set, the file is probably ASCII text.  This is
+            an optional indication, which the compressor may set by
+            checking a small amount of the input data to see whether any
+            non-ASCII characters are present.  In case of doubt, FTEXT
+            is cleared, indicating binary data. For systems which have
+            different file formats for ascii text and binary data, the
+            decompressor can use FTEXT to choose the appropriate format.
+            We deliberately do not specify the algorithm used to set
+            this bit, since a compressor always has the option of
+            leaving it cleared and a decompressor always has the option
+            of ignoring it and letting some other program handle issues
+            of data conversion.
+
+            If FHCRC is set, a CRC16 for the gzip header is present,
+            immediately before the compressed data. The CRC16 consists
+            of the two least significant bytes of the CRC32 for all
+            bytes of the gzip header up to and not including the CRC16.
+            [The FHCRC bit was never set by versions of gzip up to
+            1.2.4, even though it was documented with a different
+            meaning in gzip 1.2.4.]
+
+            If FEXTRA is set, optional extra fields are present, as
+            described in a following section.
+
+
+
+Deutsch                      Informational                      [Page 6]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+            If FNAME is set, an original file name is present,
+            terminated by a zero byte.  The name must consist of ISO
+            8859-1 (LATIN-1) characters; on operating systems using
+            EBCDIC or any other character set for file names, the name
+            must be translated to the ISO LATIN-1 character set.  This
+            is the original name of the file being compressed, with any
+            directory components removed, and, if the file being
+            compressed is on a file system with case insensitive names,
+            forced to lower case. There is no original file name if the
+            data was compressed from a source other than a named file;
+            for example, if the source was stdin on a Unix system, there
+            is no file name.
+
+            If FCOMMENT is set, a zero-terminated file comment is
+            present.  This comment is not interpreted; it is only
+            intended for human consumption.  The comment must consist of
+            ISO 8859-1 (LATIN-1) characters.  Line breaks should be
+            denoted by a single line feed character (10 decimal).
+
+            Reserved FLG bits must be zero.
+
+         MTIME (Modification TIME)
+            This gives the most recent modification time of the original
+            file being compressed.  The time is in Unix format, i.e.,
+            seconds since 00:00:00 GMT, Jan.  1, 1970.  (Note that this
+            may cause problems for MS-DOS and other systems that use
+            local rather than Universal time.)  If the compressed data
+            did not come from a file, MTIME is set to the time at which
+            compression started.  MTIME = 0 means no time stamp is
+            available.
+
+         XFL (eXtra FLags)
+            These flags are available for use by specific compression
+            methods.  The "deflate" method (CM = 8) sets these flags as
+            follows:
+
+               XFL = 2 - compressor used maximum compression,
+                         slowest algorithm
+               XFL = 4 - compressor used fastest algorithm
+
+         OS (Operating System)
+            This identifies the type of file system on which compression
+            took place.  This may be useful in determining end-of-line
+            convention for text files.  The currently defined values are
+            as follows:
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 7]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+                 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
+                 1 - Amiga
+                 2 - VMS (or OpenVMS)
+                 3 - Unix
+                 4 - VM/CMS
+                 5 - Atari TOS
+                 6 - HPFS filesystem (OS/2, NT)
+                 7 - Macintosh
+                 8 - Z-System
+                 9 - CP/M
+                10 - TOPS-20
+                11 - NTFS filesystem (NT)
+                12 - QDOS
+                13 - Acorn RISCOS
+               255 - unknown
+
+         XLEN (eXtra LENgth)
+            If FLG.FEXTRA is set, this gives the length of the optional
+            extra field.  See below for details.
+
+         CRC32 (CRC-32)
+            This contains a Cyclic Redundancy Check value of the
+            uncompressed data computed according to CRC-32 algorithm
+            used in the ISO 3309 standard and in section 8.1.1.6.2 of
+            ITU-T recommendation V.42.  (See http://www.iso.ch for
+            ordering ISO documents. See gopher://info.itu.ch for an
+            online version of ITU-T V.42.)
+
+         ISIZE (Input SIZE)
+            This contains the size of the original (uncompressed) input
+            data modulo 2^32.
+
+      2.3.1.1. Extra field
+
+         If the FLG.FEXTRA bit is set, an "extra field" is present in
+         the header, with total length XLEN bytes.  It consists of a
+         series of subfields, each of the form:
+
+            +---+---+---+---+==================================+
+            |SI1|SI2|  LEN  |... LEN bytes of subfield data ...|
+            +---+---+---+---+==================================+
+
+         SI1 and SI2 provide a subfield ID, typically two ASCII letters
+         with some mnemonic value.  Jean-Loup Gailly
+         <gzip@prep.ai.mit.edu> is maintaining a registry of subfield
+         IDs; please send him any subfield ID you wish to use.  Subfield
+         IDs with SI2 = 0 are reserved for future use.  The following
+         IDs are currently defined:
+
+
+
+Deutsch                      Informational                      [Page 8]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+            SI1         SI2         Data
+            ----------  ----------  ----
+            0x41 ('A')  0x70 ('P')  Apollo file type information
+
+         LEN gives the length of the subfield data, excluding the 4
+         initial bytes.
+
+      2.3.1.2. Compliance
+
+         A compliant compressor must produce files with correct ID1,
+         ID2, CM, CRC32, and ISIZE, but may set all the other fields in
+         the fixed-length part of the header to default values (255 for
+         OS, 0 for all others).  The compressor must set all reserved
+         bits to zero.
+
+         A compliant decompressor must check ID1, ID2, and CM, and
+         provide an error indication if any of these have incorrect
+         values.  It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
+         at least so it can skip over the optional fields if they are
+         present.  It need not examine any other part of the header or
+         trailer; in particular, a decompressor may ignore FTEXT and OS
+         and always produce binary output, and still be compliant.  A
+         compliant decompressor must give an error indication if any
+         reserved bit is non-zero, since such a bit could indicate the
+         presence of a new field that would cause subsequent data to be
+         interpreted incorrectly.
+
+3. References
+
+   [1] "Information Processing - 8-bit single-byte coded graphic
+       character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
+       The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
+       ASCII. Files defining this character set are available as
+       iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
+
+   [2] ISO 3309
+
+   [3] ITU-T recommendation V.42
+
+   [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
+       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+   [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
+       ftp://prep.ai.mit.edu/pub/gnu/
+
+   [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
+       Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
+
+
+
+
+Deutsch                      Informational                      [Page 9]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+   [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
+       pp.118-133.
+
+   [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
+       describing the CRC concept.
+
+4. Security Considerations
+
+   Any data compression method involves the reduction of redundancy in
+   the data.  Consequently, any corruption of the data is likely to have
+   severe effects and be difficult to correct.  Uncompressed text, on
+   the other hand, will probably still be readable despite the presence
+   of some corrupted bytes.
+
+   It is recommended that systems using this data format provide some
+   means of validating the integrity of the compressed data, such as by
+   setting and checking the CRC-32 check value.
+
+5. Acknowledgements
+
+   Trademarks cited in this document are the property of their
+   respective owners.
+
+   Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
+   the related software described in this specification.  Glenn
+   Randers-Pehrson converted this document to RFC and HTML format.
+
+6. Author's Address
+
+   L. Peter Deutsch
+   Aladdin Enterprises
+   203 Santa Margarita Ave.
+   Menlo Park, CA 94025
+
+   Phone: (415) 322-0103 (AM only)
+   FAX:   (415) 322-1734
+   EMail: <ghost@aladdin.com>
+
+   Questions about the technical content of this specification can be
+   sent by email to:
+
+   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+   Mark Adler <madler@alumni.caltech.edu>
+
+   Editorial comments on this specification can be sent by email to:
+
+   L. Peter Deutsch <ghost@aladdin.com> and
+   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+Deutsch                      Informational                     [Page 10]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+7. Appendix: Jean-Loup Gailly's gzip utility
+
+   The most widely used implementation of gzip compression, and the
+   original documentation on which this specification is based, were
+   created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>.  Since this
+   implementation is a de facto standard, we mention some more of its
+   features here.  Again, the material in this section is not part of
+   the specification per se, and implementations need not follow it to
+   be compliant.
+
+   When compressing or decompressing a file, gzip preserves the
+   protection, ownership, and modification time attributes on the local
+   file system, since there is no provision for representing protection
+   attributes in the gzip file format itself.  Since the file format
+   includes a modification time, the gzip decompressor provides a
+   command line switch that assigns the modification time from the file,
+   rather than the local modification time of the compressed input, to
+   the decompressed output.
+
+8. Appendix: Sample CRC Code
+
+   The following sample code represents a practical implementation of
+   the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
+   for a formal specification.)
+
+   The sample code is in the ANSI C programming language. Non C users
+   may find it easier to read with these hints:
+
+      &      Bitwise AND operator.
+      ^      Bitwise exclusive-OR operator.
+      >>     Bitwise right shift operator. When applied to an
+             unsigned quantity, as here, right shift inserts zero
+             bit(s) at the left.
+      !      Logical NOT operator.
+      ++     "n++" increments the variable n.
+      0xNNN  0x introduces a hexadecimal (base 16) constant.
+             Suffix L indicates a long value (at least 32 bits).
+
+      /* Table of CRCs of all 8-bit messages. */
+      unsigned long crc_table[256];
+
+      /* Flag: has the table been computed? Initially false. */
+      int crc_table_computed = 0;
+
+      /* Make the table for a fast CRC. */
+      void make_crc_table(void)
+      {
+        unsigned long c;
+
+
+
+Deutsch                      Informational                     [Page 11]
+\f
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+        int n, k;
+        for (n = 0; n < 256; n++) {
+          c = (unsigned long) n;
+          for (k = 0; k < 8; k++) {
+            if (c & 1) {
+              c = 0xedb88320L ^ (c >> 1);
+            } else {
+              c = c >> 1;
+            }
+          }
+          crc_table[n] = c;
+        }
+        crc_table_computed = 1;
+      }
+
+      /*
+         Update a running crc with the bytes buf[0..len-1] and return
+       the updated crc. The crc should be initialized to zero. Pre- and
+       post-conditioning (one's complement) is performed within this
+       function so it shouldn't be done by the caller. Usage example:
+
+         unsigned long crc = 0L;
+
+         while (read_buffer(buffer, length) != EOF) {
+           crc = update_crc(crc, buffer, length);
+         }
+         if (crc != original_crc) error();
+      */
+      unsigned long update_crc(unsigned long crc,
+                      unsigned char *buf, int len)
+      {
+        unsigned long c = crc ^ 0xffffffffL;
+        int n;
+
+        if (!crc_table_computed)
+          make_crc_table();
+        for (n = 0; n < len; n++) {
+          c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
+        }
+        return c ^ 0xffffffffL;
+      }
+
+      /* Return the CRC of the bytes buf[0..len-1]. */
+      unsigned long crc(unsigned char *buf, int len)
+      {
+        return update_crc(0L, buf, len);
+      }
+
+
+
+
+Deutsch                      Informational                     [Page 12]
+\f
diff --git a/8.x/zlib/doc/txtvsbin.txt b/8.x/zlib/doc/txtvsbin.txt
new file mode 100644 (file)
index 0000000..3d0f063
--- /dev/null
@@ -0,0 +1,107 @@
+A Fast Method for Identifying Plain Text Files
+==============================================
+
+
+Introduction
+------------
+
+Given a file coming from an unknown source, it is sometimes desirable
+to find out whether the format of that file is plain text.  Although
+this may appear like a simple task, a fully accurate detection of the
+file type requires heavy-duty semantic analysis on the file contents.
+It is, however, possible to obtain satisfactory results by employing
+various heuristics.
+
+Previous versions of PKZip and other zip-compatible compression tools
+were using a crude detection scheme: if more than 80% (4/5) of the bytes
+found in a certain buffer are within the range [7..127], the file is
+labeled as plain text, otherwise it is labeled as binary.  A prominent
+limitation of this scheme is the restriction to Latin-based alphabets.
+Other alphabets, like Greek, Cyrillic or Asian, make extensive use of
+the bytes within the range [128..255], and texts using these alphabets
+are most often misidentified by this scheme; in other words, the rate
+of false negatives is sometimes too high, which means that the recall
+is low.  Another weakness of this scheme is a reduced precision, due to
+the false positives that may occur when binary files containing large
+amounts of textual characters are misidentified as plain text.
+
+In this article we propose a new, simple detection scheme that features
+a much increased precision and a near-100% recall.  This scheme is
+designed to work on ASCII, Unicode and other ASCII-derived alphabets,
+and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)
+and variable-sized encodings (ISO-2022, UTF-8, etc.).  Wider encodings
+(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.
+
+
+The Algorithm
+-------------
+
+The algorithm works by dividing the set of bytecodes [0..255] into three
+categories:
+- The white list of textual bytecodes:
+  9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
+- The gray list of tolerated bytecodes:
+  7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
+- The black list of undesired, non-textual bytecodes:
+  0 (NUL) to 6, 14 to 31.
+
+If a file contains at least one byte that belongs to the white list and
+no byte that belongs to the black list, then the file is categorized as
+plain text; otherwise, it is categorized as binary.  (The boundary case,
+when the file is empty, automatically falls into the latter category.)
+
+
+Rationale
+---------
+
+The idea behind this algorithm relies on two observations.
+
+The first observation is that, although the full range of 7-bit codes
+[0..127] is properly specified by the ASCII standard, most control
+characters in the range [0..31] are not used in practice.  The only
+widely-used, almost universally-portable control codes are 9 (TAB),
+10 (LF) and 13 (CR).  There are a few more control codes that are
+recognized on a reduced range of platforms and text viewers/editors:
+7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these
+codes are rarely (if ever) used alone, without being accompanied by
+some printable text.  Even the newer, portable text formats such as
+XML avoid using control characters outside the list mentioned here.
+
+The second observation is that most of the binary files tend to contain
+control characters, especially 0 (NUL).  Even though the older text
+detection schemes observe the presence of non-ASCII codes from the range
+[128..255], the precision rarely has to suffer if this upper range is
+labeled as textual, because the files that are genuinely binary tend to
+contain both control characters and codes from the upper range.  On the
+other hand, the upper range needs to be labeled as textual, because it
+is used by virtually all ASCII extensions.  In particular, this range is
+used for encoding non-Latin scripts.
+
+Since there is no counting involved, other than simply observing the
+presence or the absence of some byte values, the algorithm produces
+consistent results, regardless what alphabet encoding is being used.
+(If counting were involved, it could be possible to obtain different
+results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
+
+There is an extra category of plain text files that are "polluted" with
+one or more black-listed codes, either by mistake or by peculiar design
+considerations.  In such cases, a scheme that tolerates a small fraction
+of black-listed codes would provide an increased recall (i.e. more true
+positives).  This, however, incurs a reduced precision overall, since
+false positives are more likely to appear in binary files that contain
+large chunks of textual data.  Furthermore, "polluted" plain text should
+be regarded as binary by general-purpose text detection schemes, because
+general-purpose text processing algorithms might not be applicable.
+Under this premise, it is safe to say that our detection method provides
+a near-100% recall.
+
+Experiments have been run on many files coming from various platforms
+and applications.  We tried plain text files, system logs, source code,
+formatted office documents, compiled object code, etc.  The results
+confirm the optimistic assumptions about the capabilities of this
+algorithm.
+
+
+--
+Cosmin Truta
+Last updated: 2006-May-28
diff --git a/8.x/zlib/example.c b/8.x/zlib/example.c
new file mode 100644 (file)
index 0000000..604736f
--- /dev/null
@@ -0,0 +1,565 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2006 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+#  define TESTFILE "foo-gz"
+#else
+#  define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+    if (err != Z_OK) { \
+        fprintf(stderr, "%s error: %d\n", msg, err); \
+        exit(1); \
+    } \
+}
+
+const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_compress      OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_gzio          OF((const char *fname,
+                            Byte *uncompr, uLong uncomprLen));
+void test_deflate       OF((Byte *compr, uLong comprLen));
+void test_inflate       OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_flush         OF((Byte *compr, uLong *comprLen));
+void test_sync          OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate  OF((Byte *compr, uLong comprLen));
+void test_dict_inflate  OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+int  main               OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    uLong len = (uLong)strlen(hello)+1;
+
+    err = compress(compr, &comprLen, (const Bytef*)hello, len);
+    CHECK_ERR(err, "compress");
+
+    strcpy((char*)uncompr, "garbage");
+
+    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+    CHECK_ERR(err, "uncompress");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad uncompress\n");
+        exit(1);
+    } else {
+        printf("uncompress(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+    const char *fname; /* compressed file name */
+    Byte *uncompr;
+    uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+    fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+    int err;
+    int len = (int)strlen(hello)+1;
+    gzFile file;
+    z_off_t pos;
+
+    file = gzopen(fname, "wb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    gzputc(file, 'h');
+    if (gzputs(file, "ello") != 4) {
+        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (gzprintf(file, ", %s!", "hello") != 8) {
+        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+    gzclose(file);
+
+    file = gzopen(fname, "rb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    strcpy((char*)uncompr, "garbage");
+
+    if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+        exit(1);
+    } else {
+        printf("gzread(): %s\n", (char*)uncompr);
+    }
+
+    pos = gzseek(file, -8L, SEEK_CUR);
+    if (pos != 6 || gztell(file) != pos) {
+        fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+                (long)pos, (long)gztell(file));
+        exit(1);
+    }
+
+    if (gzgetc(file) != ' ') {
+        fprintf(stderr, "gzgetc error\n");
+        exit(1);
+    }
+
+    if (gzungetc(' ', file) != ' ') {
+        fprintf(stderr, "gzungetc error\n");
+        exit(1);
+    }
+
+    gzgets(file, (char*)uncompr, (int)uncomprLen);
+    if (strlen((char*)uncompr) != 7) { /* " hello!" */
+        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (strcmp((char*)uncompr, hello + 6)) {
+        fprintf(stderr, "bad gzgets after gzseek\n");
+        exit(1);
+    } else {
+        printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+    }
+
+    gzclose(file);
+#endif
+}
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    uLong len = (uLong)strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Bytef*)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = deflate(&c_stream, Z_NO_FLUSH);
+        CHECK_ERR(err, "deflate");
+    }
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = deflate(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "deflate");
+    }
+
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 0;
+    d_stream.next_out = uncompr;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate\n");
+        exit(1);
+    } else {
+        printf("inflate(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_SPEED);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    /* At this point, uncompr is still mostly zeroes, so it should compress
+     * very well:
+     */
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+    if (c_stream.avail_in != 0) {
+        fprintf(stderr, "deflate not greedy\n");
+        exit(1);
+    }
+
+    /* Feed in already compressed data and switch to no compression: */
+    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+    c_stream.next_in = compr;
+    c_stream.avail_in = (uInt)comprLen/2;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    /* Switch back to compressing mode: */
+    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+        exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    for (;;) {
+        d_stream.next_out = uncompr;            /* discard the output */
+        d_stream.avail_out = (uInt)uncomprLen;
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "large inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+        exit(1);
+    } else {
+        printf("large_inflate(): OK\n");
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+    Byte *compr;
+    uLong *comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    uInt len = (uInt)strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Bytef*)hello;
+    c_stream.next_out = compr;
+    c_stream.avail_in = 3;
+    c_stream.avail_out = (uInt)*comprLen;
+    err = deflate(&c_stream, Z_FULL_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    compr[3]++; /* force an error in first compressed block */
+    c_stream.avail_in = len - 3;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        CHECK_ERR(err, "deflate");
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+
+    *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 2; /* just read the zlib header */
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    inflate(&d_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "inflate");
+
+    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
+    err = inflateSync(&d_stream);           /* but skip the damaged part */
+    CHECK_ERR(err, "inflateSync");
+
+    err = inflate(&d_stream, Z_FINISH);
+    if (err != Z_DATA_ERROR) {
+        fprintf(stderr, "inflate should report DATA_ERROR\n");
+        /* Because of incorrect adler32 */
+        exit(1);
+    }
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    err = deflateSetDictionary(&c_stream,
+                               (const Bytef*)dictionary, sizeof(dictionary));
+    CHECK_ERR(err, "deflateSetDictionary");
+
+    dictId = c_stream.adler;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    c_stream.next_in = (Bytef*)hello;
+    c_stream.avail_in = (uInt)strlen(hello)+1;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+        exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    for (;;) {
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        if (err == Z_NEED_DICT) {
+            if (d_stream.adler != dictId) {
+                fprintf(stderr, "unexpected dictionary");
+                exit(1);
+            }
+            err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+                                       sizeof(dictionary));
+        }
+        CHECK_ERR(err, "inflate with dict");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate with dict\n");
+        exit(1);
+    } else {
+        printf("inflate with dictionary: %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Usage:  example [output.gz  [input.gz]]
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    Byte *compr, *uncompr;
+    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+    uLong uncomprLen = comprLen;
+    static const char* myVersion = ZLIB_VERSION;
+
+    if (zlibVersion()[0] != myVersion[0]) {
+        fprintf(stderr, "incompatible zlib version\n");
+        exit(1);
+
+    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+        fprintf(stderr, "warning: different zlib version\n");
+    }
+
+    printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+            ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+    compr    = (Byte*)calloc((uInt)comprLen, 1);
+    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
+    /* compr and uncompr are cleared to avoid reading uninitialized
+     * data and to ensure that uncompr compresses well.
+     */
+    if (compr == Z_NULL || uncompr == Z_NULL) {
+        printf("out of memory\n");
+        exit(1);
+    }
+    test_compress(compr, comprLen, uncompr, uncomprLen);
+
+    test_gzio((argc > 1 ? argv[1] : TESTFILE),
+              uncompr, uncomprLen);
+
+    test_deflate(compr, comprLen);
+    test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_flush(compr, &comprLen);
+    test_sync(compr, comprLen, uncompr, uncomprLen);
+    comprLen = uncomprLen;
+
+    test_dict_deflate(compr, comprLen);
+    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    free(compr);
+    free(uncompr);
+
+    return 0;
+}
diff --git a/8.x/zlib/examples/README.examples b/8.x/zlib/examples/README.examples
new file mode 100644 (file)
index 0000000..56a3171
--- /dev/null
@@ -0,0 +1,49 @@
+This directory contains examples of the use of zlib and other relevant
+programs and documentation.
+
+enough.c
+    calculation and justification of ENOUGH parameter in inftrees.h
+    - calculates the maximum table space used in inflate tree
+      construction over all possible Huffman codes
+
+fitblk.c
+    compress just enough input to nearly fill a requested output size
+    - zlib isn't designed to do this, but fitblk does it anyway
+
+gun.c
+    uncompress a gzip file
+    - illustrates the use of inflateBack() for high speed file-to-file
+      decompression using call-back functions
+    - is approximately twice as fast as gzip -d
+    - also provides Unix uncompress functionality, again twice as fast
+
+gzappend.c
+    append to a gzip file
+    - illustrates the use of the Z_BLOCK flush parameter for inflate()
+    - illustrates the use of deflatePrime() to start at any bit
+
+gzjoin.c
+    join gzip files without recalculating the crc or recompressing
+    - illustrates the use of the Z_BLOCK flush parameter for inflate()
+    - illustrates the use of crc32_combine()
+
+gzlog.c
+gzlog.h
+    efficiently and robustly maintain a message log file in gzip format
+    - illustrates use of raw deflate, Z_PARTIAL_FLUSH, deflatePrime(),
+      and deflateSetDictionary()
+    - illustrates use of a gzip header extra field
+
+zlib_how.html
+    painfully comprehensive description of zpipe.c (see below)
+    - describes in excruciating detail the use of deflate() and inflate()
+
+zpipe.c
+    reads and writes zlib streams from stdin to stdout
+    - illustrates the proper use of deflate() and inflate()
+    - deeply commented in zlib_how.html (see above)
+
+zran.c
+    index a zlib or gzip stream and randomly access it
+    - illustrates the use of Z_BLOCK, inflatePrime(), and
+      inflateSetDictionary() to provide random access
diff --git a/8.x/zlib/examples/enough.c b/8.x/zlib/examples/enough.c
new file mode 100644 (file)
index 0000000..c40410b
--- /dev/null
@@ -0,0 +1,569 @@
+/* enough.c -- determine the maximum size of inflate's Huffman code tables over
+ * all possible valid and complete Huffman codes, subject to a length limit.
+ * Copyright (C) 2007, 2008 Mark Adler
+ * Version 1.3  17 February 2008  Mark Adler
+ */
+
+/* Version history:
+   1.0   3 Jan 2007  First version (derived from codecount.c version 1.4)
+   1.1   4 Jan 2007  Use faster incremental table usage computation
+                     Prune examine() search on previously visited states
+   1.2   5 Jan 2007  Comments clean up
+                     As inflate does, decrease root for short codes
+                     Refuse cases where inflate would increase root
+   1.3  17 Feb 2008  Add argument for initial root table size
+                     Fix bug for initial root table size == max - 1
+                     Use a macro to compute the history index
+ */
+
+/*
+   Examine all possible Huffman codes for a given number of symbols and a
+   maximum code length in bits to determine the maximum table size for zilb's
+   inflate.  Only complete Huffman codes are counted.
+
+   Two codes are considered distinct if the vectors of the number of codes per
+   length are not identical.  So permutations of the symbol assignments result
+   in the same code for the counting, as do permutations of the assignments of
+   the bit values to the codes (i.e. only canonical codes are counted).
+
+   We build a code from shorter to longer lengths, determining how many symbols
+   are coded at each length.  At each step, we have how many symbols remain to
+   be coded, what the last code length used was, and how many bit patterns of
+   that length remain unused. Then we add one to the code length and double the
+   number of unused patterns to graduate to the next code length.  We then
+   assign all portions of the remaining symbols to that code length that
+   preserve the properties of a correct and eventually complete code.  Those
+   properties are: we cannot use more bit patterns than are available; and when
+   all the symbols are used, there are exactly zero possible bit patterns
+   remaining.
+
+   The inflate Huffman decoding algorithm uses two-level lookup tables for
+   speed.  There is a single first-level table to decode codes up to root bits
+   in length (root == 9 in the current inflate implementation).  The table
+   has 1 << root entries and is indexed by the next root bits of input.  Codes
+   shorter than root bits have replicated table entries, so that the correct
+   entry is pointed to regardless of the bits that follow the short code.  If
+   the code is longer than root bits, then the table entry points to a second-
+   level table.  The size of that table is determined by the longest code with
+   that root-bit prefix.  If that longest code has length len, then the table
+   has size 1 << (len - root), to index the remaining bits in that set of
+   codes.  Each subsequent root-bit prefix then has its own sub-table.  The
+   total number of table entries required by the code is calculated
+   incrementally as the number of codes at each bit length is populated.  When
+   all of the codes are shorter than root bits, then root is reduced to the
+   longest code length, resulting in a single, smaller, one-level table.
+
+   The inflate algorithm also provides for small values of root (relative to
+   the log2 of the number of symbols), where the shortest code has more bits
+   than root.  In that case, root is increased to the length of the shortest
+   code.  This program, by design, does not handle that case, so it is verified
+   that the number of symbols is less than 2^(root + 1).
+
+   In order to speed up the examination (by about ten orders of magnitude for
+   the default arguments), the intermediate states in the build-up of a code
+   are remembered and previously visited branches are pruned.  The memory
+   required for this will increase rapidly with the total number of symbols and
+   the maximum code length in bits.  However this is a very small price to pay
+   for the vast speedup.
+
+   First, all of the possible Huffman codes are counted, and reachable
+   intermediate states are noted by a non-zero count in a saved-results array.
+   Second, the intermediate states that lead to (root + 1) bit or longer codes
+   are used to look at all sub-codes from those junctures for their inflate
+   memory usage.  (The amount of memory used is not affected by the number of
+   codes of root bits or less in length.)  Third, the visited states in the
+   construction of those sub-codes and the associated calculation of the table
+   size is recalled in order to avoid recalculating from the same juncture.
+   Beginning the code examination at (root + 1) bit codes, which is enabled by
+   identifying the reachable nodes, accounts for about six of the orders of
+   magnitude of improvement for the default arguments.  About another four
+   orders of magnitude come from not revisiting previous states.  Out of
+   approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes
+   need to be examined to cover all of the possible table memory usage cases
+   for the default arguments of 286 symbols limited to 15-bit codes.
+
+   Note that an unsigned long long type is used for counting.  It is quite easy
+   to exceed the capacity of an eight-byte integer with a large number of
+   symbols and a large maximum code length, so multiple-precision arithmetic
+   would need to replace the unsigned long long arithmetic in that case.  This
+   program will abort if an overflow occurs.  The big_t type identifies where
+   the counting takes place.
+
+   An unsigned long long type is also used for calculating the number of
+   possible codes remaining at the maximum length.  This limits the maximum
+   code length to the number of bits in a long long minus the number of bits
+   needed to represent the symbols in a flat code.  The code_t type identifies
+   where the bit pattern counting takes place.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#define local static
+
+/* special data types */
+typedef unsigned long long big_t;   /* type for code counting */
+typedef unsigned long long code_t;  /* type for bit pattern counting */
+struct tab {                        /* type for been here check */
+    size_t len;         /* length of bit vector in char's */
+    char *vec;          /* allocated bit vector */
+};
+
+/* The array for saving results, num[], is indexed with this triplet:
+
+      syms: number of symbols remaining to code
+      left: number of available bit patterns at length len
+      len: number of bits in the codes currently being assigned
+
+   Those indices are constrained thusly when saving results:
+
+      syms: 3..totsym (totsym == total symbols to code)
+      left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6)
+      len: 1..max - 1 (max == maximum code length in bits)
+
+   syms == 2 is not saved since that immediately leads to a single code.  left
+   must be even, since it represents the number of available bit patterns at
+   the current length, which is double the number at the previous length.
+   left ends at syms-1 since left == syms immediately results in a single code.
+   (left > sym is not allowed since that would result in an incomplete code.)
+   len is less than max, since the code completes immediately when len == max.
+
+   The offset into the array is calculated for the three indices with the
+   first one (syms) being outermost, and the last one (len) being innermost.
+   We build the array with length max-1 lists for the len index, with syms-3
+   of those for each symbol.  There are totsym-2 of those, with each one
+   varying in length as a function of sym.  See the calculation of index in
+   count() for the index, and the calculation of size in main() for the size
+   of the array.
+
+   For the deflate example of 286 symbols limited to 15-bit codes, the array
+   has 284,284 entries, taking up 2.17 MB for an 8-byte big_t.  More than
+   half of the space allocated for saved results is actually used -- not all
+   possible triplets are reached in the generation of valid Huffman codes.
+ */
+
+/* The array for tracking visited states, done[], is itself indexed identically
+   to the num[] array as described above for the (syms, left, len) triplet.
+   Each element in the array is further indexed by the (mem, rem) doublet,
+   where mem is the amount of inflate table space used so far, and rem is the
+   remaining unused entries in the current inflate sub-table.  Each indexed
+   element is simply one bit indicating whether the state has been visited or
+   not.  Since the ranges for mem and rem are not known a priori, each bit
+   vector is of a variable size, and grows as needed to accommodate the visited
+   states.  mem and rem are used to calculate a single index in a triangular
+   array.  Since the range of mem is expected in the default case to be about
+   ten times larger than the range of rem, the array is skewed to reduce the
+   memory usage, with eight times the range for mem than for rem.  See the
+   calculations for offset and bit in beenhere() for the details.
+
+   For the deflate example of 286 symbols limited to 15-bit codes, the bit
+   vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[]
+   array itself.
+ */
+
+/* Globals to avoid propagating constants or constant pointers recursively */
+local int max;          /* maximum allowed bit length for the codes */
+local int root;         /* size of base code table in bits */
+local int large;        /* largest code table so far */
+local size_t size;      /* number of elements in num and done */
+local int *code;        /* number of symbols assigned to each bit length */
+local big_t *num;       /* saved results array for code counting */
+local struct tab *done; /* states already evaluated array */
+
+/* Index function for num[] and done[] */
+#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1)
+
+/* Free allocated space.  Uses globals code, num, and done. */
+local void cleanup(void)
+{
+    size_t n;
+
+    if (done != NULL) {
+        for (n = 0; n < size; n++)
+            if (done[n].len)
+                free(done[n].vec);
+        free(done);
+    }
+    if (num != NULL)
+        free(num);
+    if (code != NULL)
+        free(code);
+}
+
+/* Return the number of possible Huffman codes using bit patterns of lengths
+   len through max inclusive, coding syms symbols, with left bit patterns of
+   length len unused -- return -1 if there is an overflow in the counting.
+   Keep a record of previous results in num to prevent repeating the same
+   calculation.  Uses the globals max and num. */
+local big_t count(int syms, int len, int left)
+{
+    big_t sum;          /* number of possible codes from this juncture */
+    big_t got;          /* value returned from count() */
+    int least;          /* least number of syms to use at this juncture */
+    int most;           /* most number of syms to use at this juncture */
+    int use;            /* number of bit patterns to use in next call */
+    size_t index;       /* index of this case in *num */
+
+    /* see if only one possible code */
+    if (syms == left)
+        return 1;
+
+    /* note and verify the expected state */
+    assert(syms > left && left > 0 && len < max);
+
+    /* see if we've done this one already */
+    index = INDEX(syms, left, len);
+    got = num[index];
+    if (got)
+        return got;         /* we have -- return the saved result */
+
+    /* we need to use at least this many bit patterns so that the code won't be
+       incomplete at the next length (more bit patterns than symbols) */
+    least = (left << 1) - syms;
+    if (least < 0)
+        least = 0;
+
+    /* we can use at most this many bit patterns, lest there not be enough
+       available for the remaining symbols at the maximum length (if there were
+       no limit to the code length, this would become: most = left - 1) */
+    most = (((code_t)left << (max - len)) - syms) /
+            (((code_t)1 << (max - len)) - 1);
+
+    /* count all possible codes from this juncture and add them up */
+    sum = 0;
+    for (use = least; use <= most; use++) {
+        got = count(syms - use, len + 1, (left - use) << 1);
+        sum += got;
+        if (got == -1 || sum < got)         /* overflow */
+            return -1;
+    }
+
+    /* verify that all recursive calls are productive */
+    assert(sum != 0);
+
+    /* save the result and return it */
+    num[index] = sum;
+    return sum;
+}
+
+/* Return true if we've been here before, set to true if not.  Set a bit in a
+   bit vector to indicate visiting this state.  Each (syms,len,left) state
+   has a variable size bit vector indexed by (mem,rem).  The bit vector is
+   lengthened if needed to allow setting the (mem,rem) bit. */
+local int beenhere(int syms, int len, int left, int mem, int rem)
+{
+    size_t index;       /* index for this state's bit vector */
+    size_t offset;      /* offset in this state's bit vector */
+    int bit;            /* mask for this state's bit */
+    size_t length;      /* length of the bit vector in bytes */
+    char *vector;       /* new or enlarged bit vector */
+
+    /* point to vector for (syms,left,len), bit in vector for (mem,rem) */
+    index = INDEX(syms, left, len);
+    mem -= 1 << root;
+    offset = (mem >> 3) + rem;
+    offset = ((offset * (offset + 1)) >> 1) + rem;
+    bit = 1 << (mem & 7);
+
+    /* see if we've been here */
+    length = done[index].len;
+    if (offset < length && (done[index].vec[offset] & bit) != 0)
+        return 1;       /* done this! */
+
+    /* we haven't been here before -- set the bit to show we have now */
+
+    /* see if we need to lengthen the vector in order to set the bit */
+    if (length <= offset) {
+        /* if we have one already, enlarge it, zero out the appended space */
+        if (length) {
+            do {
+                length <<= 1;
+            } while (length <= offset);
+            vector = realloc(done[index].vec, length);
+            if (vector != NULL)
+                memset(vector + done[index].len, 0, length - done[index].len);
+        }
+
+        /* otherwise we need to make a new vector and zero it out */
+        else {
+            length = 1 << (len - root);
+            while (length <= offset)
+                length <<= 1;
+            vector = calloc(length, sizeof(char));
+        }
+
+        /* in either case, bail if we can't get the memory */
+        if (vector == NULL) {
+            fputs("abort: unable to allocate enough memory\n", stderr);
+            cleanup();
+            exit(1);
+        }
+
+        /* install the new vector */
+        done[index].len = length;
+        done[index].vec = vector;
+    }
+
+    /* set the bit */
+    done[index].vec[offset] |= bit;
+    return 0;
+}
+
+/* Examine all possible codes from the given node (syms, len, left).  Compute
+   the amount of memory required to build inflate's decoding tables, where the
+   number of code structures used so far is mem, and the number remaining in
+   the current sub-table is rem.  Uses the globals max, code, root, large, and
+   done. */
+local void examine(int syms, int len, int left, int mem, int rem)
+{
+    int least;          /* least number of syms to use at this juncture */
+    int most;           /* most number of syms to use at this juncture */
+    int use;            /* number of bit patterns to use in next call */
+
+    /* see if we have a complete code */
+    if (syms == left) {
+        /* set the last code entry */
+        code[len] = left;
+
+        /* complete computation of memory used by this code */
+        while (rem < left) {
+            left -= rem;
+            rem = 1 << (len - root);
+            mem += rem;
+        }
+        assert(rem == left);
+
+        /* if this is a new maximum, show the entries used and the sub-code */
+        if (mem > large) {
+            large = mem;
+            printf("max %d: ", mem);
+            for (use = root + 1; use <= max; use++)
+                if (code[use])
+                    printf("%d[%d] ", code[use], use);
+            putchar('\n');
+            fflush(stdout);
+        }
+
+        /* remove entries as we drop back down in the recursion */
+        code[len] = 0;
+        return;
+    }
+
+    /* prune the tree if we can */
+    if (beenhere(syms, len, left, mem, rem))
+        return;
+
+    /* we need to use at least this many bit patterns so that the code won't be
+       incomplete at the next length (more bit patterns than symbols) */
+    least = (left << 1) - syms;
+    if (least < 0)
+        least = 0;
+
+    /* we can use at most this many bit patterns, lest there not be enough
+       available for the remaining symbols at the maximum length (if there were
+       no limit to the code length, this would become: most = left - 1) */
+    most = (((code_t)left << (max - len)) - syms) /
+            (((code_t)1 << (max - len)) - 1);
+
+    /* occupy least table spaces, creating new sub-tables as needed */
+    use = least;
+    while (rem < use) {
+        use -= rem;
+        rem = 1 << (len - root);
+        mem += rem;
+    }
+    rem -= use;
+
+    /* examine codes from here, updating table space as we go */
+    for (use = least; use <= most; use++) {
+        code[len] = use;
+        examine(syms - use, len + 1, (left - use) << 1,
+                mem + (rem ? 1 << (len - root) : 0), rem << 1);
+        if (rem == 0) {
+            rem = 1 << (len - root);
+            mem += rem;
+        }
+        rem--;
+    }
+
+    /* remove entries as we drop back down in the recursion */
+    code[len] = 0;
+}
+
+/* Look at all sub-codes starting with root + 1 bits.  Look at only the valid
+   intermediate code states (syms, left, len).  For each completed code,
+   calculate the amount of memory required by inflate to build the decoding
+   tables. Find the maximum amount of memory required and show the code that
+   requires that maximum.  Uses the globals max, root, and num. */
+local void enough(int syms)
+{
+    int n;              /* number of remaing symbols for this node */
+    int left;           /* number of unused bit patterns at this length */
+    size_t index;       /* index of this case in *num */
+
+    /* clear code */
+    for (n = 0; n <= max; n++)
+        code[n] = 0;
+
+    /* look at all (root + 1) bit and longer codes */
+    large = 1 << root;              /* base table */
+    if (root < max)                 /* otherwise, there's only a base table */
+        for (n = 3; n <= syms; n++)
+            for (left = 2; left < n; left += 2)
+            {
+                /* look at all reachable (root + 1) bit nodes, and the
+                   resulting codes (complete at root + 2 or more) */
+                index = INDEX(n, left, root + 1);
+                if (root + 1 < max && num[index])       /* reachable node */
+                    examine(n, root + 1, left, 1 << root, 0);
+
+                /* also look at root bit codes with completions at root + 1
+                   bits (not saved in num, since complete), just in case */
+                if (num[index - 1] && n <= left << 1)
+                    examine((n - left) << 1, root + 1, (n - left) << 1,
+                            1 << root, 0);
+            }
+
+    /* done */
+    printf("done: maximum of %d table entries\n", large);
+}
+
+/*
+   Examine and show the total number of possible Huffman codes for a given
+   maximum number of symbols, initial root table size, and maximum code length
+   in bits -- those are the command arguments in that order.  The default
+   values are 286, 9, and 15 respectively, for the deflate literal/length code.
+   The possible codes are counted for each number of coded symbols from two to
+   the maximum.  The counts for each of those and the total number of codes are
+   shown.  The maximum number of inflate table entires is then calculated
+   across all possible codes.  Each new maximum number of table entries and the
+   associated sub-code (starting at root + 1 == 10 bits) is shown.
+
+   To count and examine Huffman codes that are not length-limited, provide a
+   maximum length equal to the number of symbols minus one.
+
+   For the deflate literal/length code, use "enough".  For the deflate distance
+   code, use "enough 30 6".
+
+   This uses the %llu printf format to print big_t numbers, which assumes that
+   big_t is an unsigned long long.  If the big_t type is changed (for example
+   to a multiple precision type), the method of printing will also need to be
+   updated.
+ */
+int main(int argc, char **argv)
+{
+    int syms;           /* total number of symbols to code */
+    int n;              /* number of symbols to code for this run */
+    big_t got;          /* return value of count() */
+    big_t sum;          /* accumulated number of codes over n */
+
+    /* set up globals for cleanup() */
+    code = NULL;
+    num = NULL;
+    done = NULL;
+
+    /* get arguments -- default to the deflate literal/length code */
+    syms = 286;
+        root = 9;
+    max = 15;
+    if (argc > 1) {
+        syms = atoi(argv[1]);
+        if (argc > 2) {
+            root = atoi(argv[2]);
+                        if (argc > 3)
+                                max = atoi(argv[3]);
+                }
+    }
+    if (argc > 4 || syms < 2 || root < 1 || max < 1) {
+        fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
+                          stderr);
+        return 1;
+    }
+
+    /* if not restricting the code length, the longest is syms - 1 */
+    if (max > syms - 1)
+        max = syms - 1;
+
+    /* determine the number of bits in a code_t */
+    n = 0;
+    while (((code_t)1 << n) != 0)
+        n++;
+
+    /* make sure that the calculation of most will not overflow */
+    if (max > n || syms - 2 >= (((code_t)0 - 1) >> (max - 1))) {
+        fputs("abort: code length too long for internal types\n", stderr);
+        return 1;
+    }
+
+    /* reject impossible code requests */
+    if (syms - 1 > ((code_t)1 << max) - 1) {
+        fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
+                syms, max);
+        return 1;
+    }
+
+    /* allocate code vector */
+    code = calloc(max + 1, sizeof(int));
+    if (code == NULL) {
+        fputs("abort: unable to allocate enough memory\n", stderr);
+        return 1;
+    }
+
+    /* determine size of saved results array, checking for overflows,
+       allocate and clear the array (set all to zero with calloc()) */
+    if (syms == 2)              /* iff max == 1 */
+        num = NULL;             /* won't be saving any results */
+    else {
+        size = syms >> 1;
+        if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) ||
+                (size *= n, size > ((size_t)0 - 1) / (n = max - 1)) ||
+                (size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) ||
+                (num = calloc(size, sizeof(big_t))) == NULL) {
+            fputs("abort: unable to allocate enough memory\n", stderr);
+            cleanup();
+            return 1;
+        }
+    }
+
+    /* count possible codes for all numbers of symbols, add up counts */
+    sum = 0;
+    for (n = 2; n <= syms; n++) {
+        got = count(n, 1, 2);
+        sum += got;
+        if (got == -1 || sum < got) {       /* overflow */
+            fputs("abort: can't count that high!\n", stderr);
+            cleanup();
+            return 1;
+        }
+        printf("%llu %d-codes\n", got, n);
+    }
+    printf("%llu total codes for 2 to %d symbols", sum, syms);
+    if (max < syms - 1)
+        printf(" (%d-bit length limit)\n", max);
+    else
+        puts(" (no length limit)");
+
+    /* allocate and clear done array for beenhere() */
+    if (syms == 2)
+        done = NULL;
+    else if (size > ((size_t)0 - 1) / sizeof(struct tab) ||
+             (done = calloc(size, sizeof(struct tab))) == NULL) {
+        fputs("abort: unable to allocate enough memory\n", stderr);
+        cleanup();
+        return 1;
+    }
+
+    /* find and show maximum inflate table usage */
+        if (root > max)                 /* reduce root to max length */
+                root = max;
+    if (syms < ((code_t)1 << (root + 1)))
+        enough(syms);
+    else
+        puts("cannot handle minimum code lengths > root");
+
+    /* done */
+    cleanup();
+    return 0;
+}
diff --git a/8.x/zlib/examples/fitblk.c b/8.x/zlib/examples/fitblk.c
new file mode 100644 (file)
index 0000000..c61de5c
--- /dev/null
@@ -0,0 +1,233 @@
+/* fitblk.c: example of fitting compressed output to a specified size
+   Not copyrighted -- provided to the public domain
+   Version 1.1  25 November 2004  Mark Adler */
+
+/* Version history:
+   1.0  24 Nov 2004  First version
+   1.1  25 Nov 2004  Change deflateInit2() to deflateInit()
+                     Use fixed-size, stack-allocated raw buffers
+                     Simplify code moving compression to subroutines
+                     Use assert() for internal errors
+                     Add detailed description of approach
+ */
+
+/* Approach to just fitting a requested compressed size:
+
+   fitblk performs three compression passes on a portion of the input
+   data in order to determine how much of that input will compress to
+   nearly the requested output block size.  The first pass generates
+   enough deflate blocks to produce output to fill the requested
+   output size plus a specfied excess amount (see the EXCESS define
+   below).  The last deflate block may go quite a bit past that, but
+   is discarded.  The second pass decompresses and recompresses just
+   the compressed data that fit in the requested plus excess sized
+   buffer.  The deflate process is terminated after that amount of
+   input, which is less than the amount consumed on the first pass.
+   The last deflate block of the result will be of a comparable size
+   to the final product, so that the header for that deflate block and
+   the compression ratio for that block will be about the same as in
+   the final product.  The third compression pass decompresses the
+   result of the second step, but only the compressed data up to the
+   requested size minus an amount to allow the compressed stream to
+   complete (see the MARGIN define below).  That will result in a
+   final compressed stream whose length is less than or equal to the
+   requested size.  Assuming sufficient input and a requested size
+   greater than a few hundred bytes, the shortfall will typically be
+   less than ten bytes.
+
+   If the input is short enough that the first compression completes
+   before filling the requested output size, then that compressed
+   stream is return with no recompression.
+
+   EXCESS is chosen to be just greater than the shortfall seen in a
+   two pass approach similar to the above.  That shortfall is due to
+   the last deflate block compressing more efficiently with a smaller
+   header on the second pass.  EXCESS is set to be large enough so
+   that there is enough uncompressed data for the second pass to fill
+   out the requested size, and small enough so that the final deflate
+   block of the second pass will be close in size to the final deflate
+   block of the third and final pass.  MARGIN is chosen to be just
+   large enough to assure that the final compression has enough room
+   to complete in all cases.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "zlib.h"
+
+#define local static
+
+/* print nastygram and leave */
+local void quit(char *why)
+{
+    fprintf(stderr, "fitblk abort: %s\n", why);
+    exit(1);
+}
+
+#define RAWLEN 4096    /* intermediate uncompressed buffer size */
+
+/* compress from file to def until provided buffer is full or end of
+   input reached; return last deflate() return value, or Z_ERRNO if
+   there was read error on the file */
+local int partcompress(FILE *in, z_streamp def)
+{
+    int ret, flush;
+    unsigned char raw[RAWLEN];
+
+    flush = Z_NO_FLUSH;
+    do {
+        def->avail_in = fread(raw, 1, RAWLEN, in);
+        if (ferror(in))
+            return Z_ERRNO;
+        def->next_in = raw;
+        if (feof(in))
+            flush = Z_FINISH;
+        ret = deflate(def, flush);
+        assert(ret != Z_STREAM_ERROR);
+    } while (def->avail_out != 0 && flush == Z_NO_FLUSH);
+    return ret;
+}
+
+/* recompress from inf's input to def's output; the input for inf and
+   the output for def are set in those structures before calling;
+   return last deflate() return value, or Z_MEM_ERROR if inflate()
+   was not able to allocate enough memory when it needed to */
+local int recompress(z_streamp inf, z_streamp def)
+{
+    int ret, flush;
+    unsigned char raw[RAWLEN];
+
+    flush = Z_NO_FLUSH;
+    do {
+        /* decompress */
+        inf->avail_out = RAWLEN;
+        inf->next_out = raw;
+        ret = inflate(inf, Z_NO_FLUSH);
+        assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
+               ret != Z_NEED_DICT);
+        if (ret == Z_MEM_ERROR)
+            return ret;
+
+        /* compress what was decompresed until done or no room */
+        def->avail_in = RAWLEN - inf->avail_out;
+        def->next_in = raw;
+        if (inf->avail_out != 0)
+            flush = Z_FINISH;
+        ret = deflate(def, flush);
+        assert(ret != Z_STREAM_ERROR);
+    } while (ret != Z_STREAM_END && def->avail_out != 0);
+    return ret;
+}
+
+#define EXCESS 256      /* empirically determined stream overage */
+#define MARGIN 8        /* amount to back off for completion */
+
+/* compress from stdin to fixed-size block on stdout */
+int main(int argc, char **argv)
+{
+    int ret;                /* return code */
+    unsigned size;          /* requested fixed output block size */
+    unsigned have;          /* bytes written by deflate() call */
+    unsigned char *blk;     /* intermediate and final stream */
+    unsigned char *tmp;     /* close to desired size stream */
+    z_stream def, inf;      /* zlib deflate and inflate states */
+
+    /* get requested output size */
+    if (argc != 2)
+        quit("need one argument: size of output block");
+    ret = strtol(argv[1], argv + 1, 10);
+    if (argv[1][0] != 0)
+        quit("argument must be a number");
+    if (ret < 8)            /* 8 is minimum zlib stream size */
+        quit("need positive size of 8 or greater");
+    size = (unsigned)ret;
+
+    /* allocate memory for buffers and compression engine */
+    blk = malloc(size + EXCESS);
+    def.zalloc = Z_NULL;
+    def.zfree = Z_NULL;
+    def.opaque = Z_NULL;
+    ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
+    if (ret != Z_OK || blk == NULL)
+        quit("out of memory");
+
+    /* compress from stdin until output full, or no more input */
+    def.avail_out = size + EXCESS;
+    def.next_out = blk;
+    ret = partcompress(stdin, &def);
+    if (ret == Z_ERRNO)
+        quit("error reading input");
+
+    /* if it all fit, then size was undersubscribed -- done! */
+    if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
+        /* write block to stdout */
+        have = size + EXCESS - def.avail_out;
+        if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
+            quit("error writing output");
+
+        /* clean up and print results to stderr */
+        ret = deflateEnd(&def);
+        assert(ret != Z_STREAM_ERROR);
+        free(blk);
+        fprintf(stderr,
+                "%u bytes unused out of %u requested (all input)\n",
+                size - have, size);
+        return 0;
+    }
+
+    /* it didn't all fit -- set up for recompression */
+    inf.zalloc = Z_NULL;
+    inf.zfree = Z_NULL;
+    inf.opaque = Z_NULL;
+    inf.avail_in = 0;
+    inf.next_in = Z_NULL;
+    ret = inflateInit(&inf);
+    tmp = malloc(size + EXCESS);
+    if (ret != Z_OK || tmp == NULL)
+        quit("out of memory");
+    ret = deflateReset(&def);
+    assert(ret != Z_STREAM_ERROR);
+
+    /* do first recompression close to the right amount */
+    inf.avail_in = size + EXCESS;
+    inf.next_in = blk;
+    def.avail_out = size + EXCESS;
+    def.next_out = tmp;
+    ret = recompress(&inf, &def);
+    if (ret == Z_MEM_ERROR)
+        quit("out of memory");
+
+    /* set up for next reocmpression */
+    ret = inflateReset(&inf);
+    assert(ret != Z_STREAM_ERROR);
+    ret = deflateReset(&def);
+    assert(ret != Z_STREAM_ERROR);
+
+    /* do second and final recompression (third compression) */
+    inf.avail_in = size - MARGIN;   /* assure stream will complete */
+    inf.next_in = tmp;
+    def.avail_out = size;
+    def.next_out = blk;
+    ret = recompress(&inf, &def);
+    if (ret == Z_MEM_ERROR)
+        quit("out of memory");
+    assert(ret == Z_STREAM_END);    /* otherwise MARGIN too small */
+
+    /* done -- write block to stdout */
+    have = size - def.avail_out;
+    if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
+        quit("error writing output");
+
+    /* clean up and print results to stderr */
+    free(tmp);
+    ret = inflateEnd(&inf);
+    assert(ret != Z_STREAM_ERROR);
+    ret = deflateEnd(&def);
+    assert(ret != Z_STREAM_ERROR);
+    free(blk);
+    fprintf(stderr,
+            "%u bytes unused out of %u requested (%lu input)\n",
+            size - have, size, def.total_in);
+    return 0;
+}
diff --git a/8.x/zlib/examples/gun.c b/8.x/zlib/examples/gun.c
new file mode 100644 (file)
index 0000000..72b0882
--- /dev/null
@@ -0,0 +1,701 @@
+/* gun.c -- simple gunzip to give an example of the use of inflateBack()
+ * Copyright (C) 2003, 2005, 2008, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+   Version 1.6  17 January 2010  Mark Adler */
+
+/* Version history:
+   1.0  16 Feb 2003  First version for testing of inflateBack()
+   1.1  21 Feb 2005  Decompress concatenated gzip streams
+                     Remove use of "this" variable (C++ keyword)
+                     Fix return value for in()
+                     Improve allocation failure checking
+                     Add typecasting for void * structures
+                     Add -h option for command version and usage
+                     Add a bunch of comments
+   1.2  20 Mar 2005  Add Unix compress (LZW) decompression
+                     Copy file attributes from input file to output file
+   1.3  12 Jun 2005  Add casts for error messages [Oberhumer]
+   1.4   8 Dec 2006  LZW decompression speed improvements
+   1.5   9 Feb 2008  Avoid warning in latest version of gcc
+   1.6  17 Jan 2010  Avoid signed/unsigned comparison warnings
+ */
+
+/*
+   gun [ -t ] [ name ... ]
+
+   decompresses the data in the named gzip files.  If no arguments are given,
+   gun will decompress from stdin to stdout.  The names must end in .gz, -gz,
+   .z, -z, _z, or .Z.  The uncompressed data will be written to a file name
+   with the suffix stripped.  On success, the original file is deleted.  On
+   failure, the output file is deleted.  For most failures, the command will
+   continue to process the remaining names on the command line.  A memory
+   allocation failure will abort the command.  If -t is specified, then the
+   listed files or stdin will be tested as gzip files for integrity (without
+   checking for a proper suffix), no output will be written, and no files
+   will be deleted.
+
+   Like gzip, gun allows concatenated gzip streams and will decompress them,
+   writing all of the uncompressed data to the output.  Unlike gzip, gun allows
+   an empty file on input, and will produce no error writing an empty output
+   file.
+
+   gun will also decompress files made by Unix compress, which uses LZW
+   compression.  These files are automatically detected by virtue of their
+   magic header bytes.  Since the end of Unix compress stream is marked by the
+   end-of-file, they cannot be concantenated.  If a Unix compress stream is
+   encountered in an input file, it is the last stream in that file.
+
+   Like gunzip and uncompress, the file attributes of the orignal compressed
+   file are maintained in the final uncompressed file, to the extent that the
+   user permissions allow it.
+
+   On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version
+   1.2.4) is on the same file, when gun is linked with zlib 1.2.2.  Also the
+   LZW decompression provided by gun is about twice as fast as the standard
+   Unix uncompress command.
+ */
+
+/* external functions and related types and constants */
+#include <stdio.h>          /* fprintf() */
+#include <stdlib.h>         /* malloc(), free() */
+#include <string.h>         /* strerror(), strcmp(), strlen(), memcpy() */
+#include <errno.h>          /* errno */
+#include <fcntl.h>          /* open() */
+#include <unistd.h>         /* read(), write(), close(), chown(), unlink() */
+#include <sys/types.h>
+#include <sys/stat.h>       /* stat(), chmod() */
+#include <utime.h>          /* utime() */
+#include "zlib.h"           /* inflateBackInit(), inflateBack(), */
+                            /* inflateBackEnd(), crc32() */
+
+/* function declaration */
+#define local static
+
+/* buffer constants */
+#define SIZE 32768U         /* input and output buffer sizes */
+#define PIECE 16384         /* limits i/o chunks for 16-bit int case */
+
+/* structure for infback() to pass to input function in() -- it maintains the
+   input file and a buffer of size SIZE */
+struct ind {
+    int infile;
+    unsigned char *inbuf;
+};
+
+/* Load input buffer, assumed to be empty, and return bytes loaded and a
+   pointer to them.  read() is called until the buffer is full, or until it
+   returns end-of-file or error.  Return 0 on error. */
+local unsigned in(void *in_desc, unsigned char **buf)
+{
+    int ret;
+    unsigned len;
+    unsigned char *next;
+    struct ind *me = (struct ind *)in_desc;
+
+    next = me->inbuf;
+    *buf = next;
+    len = 0;
+    do {
+        ret = PIECE;
+        if ((unsigned)ret > SIZE - len)
+            ret = (int)(SIZE - len);
+        ret = (int)read(me->infile, next, ret);
+        if (ret == -1) {
+            len = 0;
+            break;
+        }
+        next += ret;
+        len += ret;
+    } while (ret != 0 && len < SIZE);
+    return len;
+}
+
+/* structure for infback() to pass to output function out() -- it maintains the
+   output file, a running CRC-32 check on the output and the total number of
+   bytes output, both for checking against the gzip trailer.  (The length in
+   the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and
+   the output is greater than 4 GB.) */
+struct outd {
+    int outfile;
+    int check;                  /* true if checking crc and total */
+    unsigned long crc;
+    unsigned long total;
+};
+
+/* Write output buffer and update the CRC-32 and total bytes written.  write()
+   is called until all of the output is written or an error is encountered.
+   On success out() returns 0.  For a write failure, out() returns 1.  If the
+   output file descriptor is -1, then nothing is written.
+ */
+local int out(void *out_desc, unsigned char *buf, unsigned len)
+{
+    int ret;
+    struct outd *me = (struct outd *)out_desc;
+
+    if (me->check) {
+        me->crc = crc32(me->crc, buf, len);
+        me->total += len;
+    }
+    if (me->outfile != -1)
+        do {
+            ret = PIECE;
+            if ((unsigned)ret > len)
+                ret = (int)len;
+            ret = (int)write(me->outfile, buf, ret);
+            if (ret == -1)
+                return 1;
+            buf += ret;
+            len -= ret;
+        } while (len != 0);
+    return 0;
+}
+
+/* next input byte macro for use inside lunpipe() and gunpipe() */
+#define NEXT() (have ? 0 : (have = in(indp, &next)), \
+                last = have ? (have--, (int)(*next++)) : -1)
+
+/* memory for gunpipe() and lunpipe() --
+   the first 256 entries of prefix[] and suffix[] are never used, could
+   have offset the index, but it's faster to waste the memory */
+unsigned char inbuf[SIZE];              /* input buffer */
+unsigned char outbuf[SIZE];             /* output buffer */
+unsigned short prefix[65536];           /* index to LZW prefix string */
+unsigned char suffix[65536];            /* one-character LZW suffix */
+unsigned char match[65280 + 2];         /* buffer for reversed match or gzip
+                                           32K sliding window */
+
+/* throw out what's left in the current bits byte buffer (this is a vestigial
+   aspect of the compressed data format derived from an implementation that
+   made use of a special VAX machine instruction!) */
+#define FLUSHCODE() \
+    do { \
+        left = 0; \
+        rem = 0; \
+        if (chunk > have) { \
+            chunk -= have; \
+            have = 0; \
+            if (NEXT() == -1) \
+                break; \
+            chunk--; \
+            if (chunk > have) { \
+                chunk = have = 0; \
+                break; \
+            } \
+        } \
+        have -= chunk; \
+        next += chunk; \
+        chunk = 0; \
+    } while (0)
+
+/* Decompress a compress (LZW) file from indp to outfile.  The compress magic
+   header (two bytes) has already been read and verified.  There are have bytes
+   of buffered input at next.  strm is used for passing error information back
+   to gunpipe().
+
+   lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of
+   file, read error, or write error (a write error indicated by strm->next_in
+   not equal to Z_NULL), or Z_DATA_ERROR for invalid input.
+ */
+local int lunpipe(unsigned have, unsigned char *next, struct ind *indp,
+                  int outfile, z_stream *strm)
+{
+    int last;                   /* last byte read by NEXT(), or -1 if EOF */
+    unsigned chunk;             /* bytes left in current chunk */
+    int left;                   /* bits left in rem */
+    unsigned rem;               /* unused bits from input */
+    int bits;                   /* current bits per code */
+    unsigned code;              /* code, table traversal index */
+    unsigned mask;              /* mask for current bits codes */
+    int max;                    /* maximum bits per code for this stream */
+    unsigned flags;             /* compress flags, then block compress flag */
+    unsigned end;               /* last valid entry in prefix/suffix tables */
+    unsigned temp;              /* current code */
+    unsigned prev;              /* previous code */
+    unsigned final;             /* last character written for previous code */
+    unsigned stack;             /* next position for reversed string */
+    unsigned outcnt;            /* bytes in output buffer */
+    struct outd outd;           /* output structure */
+    unsigned char *p;
+
+    /* set up output */
+    outd.outfile = outfile;
+    outd.check = 0;
+
+    /* process remainder of compress header -- a flags byte */
+    flags = NEXT();
+    if (last == -1)
+        return Z_BUF_ERROR;
+    if (flags & 0x60) {
+        strm->msg = (char *)"unknown lzw flags set";
+        return Z_DATA_ERROR;
+    }
+    max = flags & 0x1f;
+    if (max < 9 || max > 16) {
+        strm->msg = (char *)"lzw bits out of range";
+        return Z_DATA_ERROR;
+    }
+    if (max == 9)                           /* 9 doesn't really mean 9 */
+        max = 10;
+    flags &= 0x80;                          /* true if block compress */
+
+    /* clear table */
+    bits = 9;
+    mask = 0x1ff;
+    end = flags ? 256 : 255;
+
+    /* set up: get first 9-bit code, which is the first decompressed byte, but
+       don't create a table entry until the next code */
+    if (NEXT() == -1)                       /* no compressed data is ok */
+        return Z_OK;
+    final = prev = (unsigned)last;          /* low 8 bits of code */
+    if (NEXT() == -1)                       /* missing a bit */
+        return Z_BUF_ERROR;
+    if (last & 1) {                         /* code must be < 256 */
+        strm->msg = (char *)"invalid lzw code";
+        return Z_DATA_ERROR;
+    }
+    rem = (unsigned)last >> 1;              /* remaining 7 bits */
+    left = 7;
+    chunk = bits - 2;                       /* 7 bytes left in this chunk */
+    outbuf[0] = (unsigned char)final;       /* write first decompressed byte */
+    outcnt = 1;
+
+    /* decode codes */
+    stack = 0;
+    for (;;) {
+        /* if the table will be full after this, increment the code size */
+        if (end >= mask && bits < max) {
+            FLUSHCODE();
+            bits++;
+            mask <<= 1;
+            mask++;
+        }
+
+        /* get a code of length bits */
+        if (chunk == 0)                     /* decrement chunk modulo bits */
+            chunk = bits;
+        code = rem;                         /* low bits of code */
+        if (NEXT() == -1) {                 /* EOF is end of compressed data */
+            /* write remaining buffered output */
+            if (outcnt && out(&outd, outbuf, outcnt)) {
+                strm->next_in = outbuf;     /* signal write error */
+                return Z_BUF_ERROR;
+            }
+            return Z_OK;
+        }
+        code += (unsigned)last << left;     /* middle (or high) bits of code */
+        left += 8;
+        chunk--;
+        if (bits > left) {                  /* need more bits */
+            if (NEXT() == -1)               /* can't end in middle of code */
+                return Z_BUF_ERROR;
+            code += (unsigned)last << left; /* high bits of code */
+            left += 8;
+            chunk--;
+        }
+        code &= mask;                       /* mask to current code length */
+        left -= bits;                       /* number of unused bits */
+        rem = (unsigned)last >> (8 - left); /* unused bits from last byte */
+
+        /* process clear code (256) */
+        if (code == 256 && flags) {
+            FLUSHCODE();
+            bits = 9;                       /* initialize bits and mask */
+            mask = 0x1ff;
+            end = 255;                      /* empty table */
+            continue;                       /* get next code */
+        }
+
+        /* special code to reuse last match */
+        temp = code;                        /* save the current code */
+        if (code > end) {
+            /* Be picky on the allowed code here, and make sure that the code
+               we drop through (prev) will be a valid index so that random
+               input does not cause an exception.  The code != end + 1 check is
+               empirically derived, and not checked in the original uncompress
+               code.  If this ever causes a problem, that check could be safely
+               removed.  Leaving this check in greatly improves gun's ability
+               to detect random or corrupted input after a compress header.
+               In any case, the prev > end check must be retained. */
+            if (code != end + 1 || prev > end) {
+                strm->msg = (char *)"invalid lzw code";
+                return Z_DATA_ERROR;
+            }
+            match[stack++] = (unsigned char)final;
+            code = prev;
+        }
+
+        /* walk through linked list to generate output in reverse order */
+        p = match + stack;
+        while (code >= 256) {
+            *p++ = suffix[code];
+            code = prefix[code];
+        }
+        stack = p - match;
+        match[stack++] = (unsigned char)code;
+        final = code;
+
+        /* link new table entry */
+        if (end < mask) {
+            end++;
+            prefix[end] = (unsigned short)prev;
+            suffix[end] = (unsigned char)final;
+        }
+
+        /* set previous code for next iteration */
+        prev = temp;
+
+        /* write output in forward order */
+        while (stack > SIZE - outcnt) {
+            while (outcnt < SIZE)
+                outbuf[outcnt++] = match[--stack];
+            if (out(&outd, outbuf, outcnt)) {
+                strm->next_in = outbuf; /* signal write error */
+                return Z_BUF_ERROR;
+            }
+            outcnt = 0;
+        }
+        p = match + stack;
+        do {
+            outbuf[outcnt++] = *--p;
+        } while (p > match);
+        stack = 0;
+
+        /* loop for next code with final and prev as the last match, rem and
+           left provide the first 0..7 bits of the next code, end is the last
+           valid table entry */
+    }
+}
+
+/* Decompress a gzip file from infile to outfile.  strm is assumed to have been
+   successfully initialized with inflateBackInit().  The input file may consist
+   of a series of gzip streams, in which case all of them will be decompressed
+   to the output file.  If outfile is -1, then the gzip stream(s) integrity is
+   checked and nothing is written.
+
+   The return value is a zlib error code: Z_MEM_ERROR if out of memory,
+   Z_DATA_ERROR if the header or the compressed data is invalid, or if the
+   trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends
+   prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip
+   stream) follows a valid gzip stream.
+ */
+local int gunpipe(z_stream *strm, int infile, int outfile)
+{
+    int ret, first, last;
+    unsigned have, flags, len;
+    unsigned char *next = NULL;
+    struct ind ind, *indp;
+    struct outd outd;
+
+    /* setup input buffer */
+    ind.infile = infile;
+    ind.inbuf = inbuf;
+    indp = &ind;
+
+    /* decompress concatenated gzip streams */
+    have = 0;                               /* no input data read in yet */
+    first = 1;                              /* looking for first gzip header */
+    strm->next_in = Z_NULL;                 /* so Z_BUF_ERROR means EOF */
+    for (;;) {
+        /* look for the two magic header bytes for a gzip stream */
+        if (NEXT() == -1) {
+            ret = Z_OK;
+            break;                          /* empty gzip stream is ok */
+        }
+        if (last != 31 || (NEXT() != 139 && last != 157)) {
+            strm->msg = (char *)"incorrect header check";
+            ret = first ? Z_DATA_ERROR : Z_ERRNO;
+            break;                          /* not a gzip or compress header */
+        }
+        first = 0;                          /* next non-header is junk */
+
+        /* process a compress (LZW) file -- can't be concatenated after this */
+        if (last == 157) {
+            ret = lunpipe(have, next, indp, outfile, strm);
+            break;
+        }
+
+        /* process remainder of gzip header */
+        ret = Z_BUF_ERROR;
+        if (NEXT() != 8) {                  /* only deflate method allowed */
+            if (last == -1) break;
+            strm->msg = (char *)"unknown compression method";
+            ret = Z_DATA_ERROR;
+            break;
+        }
+        flags = NEXT();                     /* header flags */
+        NEXT();                             /* discard mod time, xflgs, os */
+        NEXT();
+        NEXT();
+        NEXT();
+        NEXT();
+        NEXT();
+        if (last == -1) break;
+        if (flags & 0xe0) {
+            strm->msg = (char *)"unknown header flags set";
+            ret = Z_DATA_ERROR;
+            break;
+        }
+        if (flags & 4) {                    /* extra field */
+            len = NEXT();
+            len += (unsigned)(NEXT()) << 8;
+            if (last == -1) break;
+            while (len > have) {
+                len -= have;
+                have = 0;
+                if (NEXT() == -1) break;
+                len--;
+            }
+            if (last == -1) break;
+            have -= len;
+            next += len;
+        }
+        if (flags & 8)                      /* file name */
+            while (NEXT() != 0 && last != -1)
+                ;
+        if (flags & 16)                     /* comment */
+            while (NEXT() != 0 && last != -1)
+                ;
+        if (flags & 2) {                    /* header crc */
+            NEXT();
+            NEXT();
+        }
+        if (last == -1) break;
+
+        /* set up output */
+        outd.outfile = outfile;
+        outd.check = 1;
+        outd.crc = crc32(0L, Z_NULL, 0);
+        outd.total = 0;
+
+        /* decompress data to output */
+        strm->next_in = next;
+        strm->avail_in = have;
+        ret = inflateBack(strm, in, indp, out, &outd);
+        if (ret != Z_STREAM_END) break;
+        next = strm->next_in;
+        have = strm->avail_in;
+        strm->next_in = Z_NULL;             /* so Z_BUF_ERROR means EOF */
+
+        /* check trailer */
+        ret = Z_BUF_ERROR;
+        if (NEXT() != (int)(outd.crc & 0xff) ||
+            NEXT() != (int)((outd.crc >> 8) & 0xff) ||
+            NEXT() != (int)((outd.crc >> 16) & 0xff) ||
+            NEXT() != (int)((outd.crc >> 24) & 0xff)) {
+            /* crc error */
+            if (last != -1) {
+                strm->msg = (char *)"incorrect data check";
+                ret = Z_DATA_ERROR;
+            }
+            break;
+        }
+        if (NEXT() != (int)(outd.total & 0xff) ||
+            NEXT() != (int)((outd.total >> 8) & 0xff) ||
+            NEXT() != (int)((outd.total >> 16) & 0xff) ||
+            NEXT() != (int)((outd.total >> 24) & 0xff)) {
+            /* length error */
+            if (last != -1) {
+                strm->msg = (char *)"incorrect length check";
+                ret = Z_DATA_ERROR;
+            }
+            break;
+        }
+
+        /* go back and look for another gzip stream */
+    }
+
+    /* clean up and return */
+    return ret;
+}
+
+/* Copy file attributes, from -> to, as best we can.  This is best effort, so
+   no errors are reported.  The mode bits, including suid, sgid, and the sticky
+   bit are copied (if allowed), the owner's user id and group id are copied
+   (again if allowed), and the access and modify times are copied. */
+local void copymeta(char *from, char *to)
+{
+    struct stat was;
+    struct utimbuf when;
+
+    /* get all of from's Unix meta data, return if not a regular file */
+    if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG)
+        return;
+
+    /* set to's mode bits, ignore errors */
+    (void)chmod(to, was.st_mode & 07777);
+
+    /* copy owner's user and group, ignore errors */
+    (void)chown(to, was.st_uid, was.st_gid);
+
+    /* copy access and modify times, ignore errors */
+    when.actime = was.st_atime;
+    when.modtime = was.st_mtime;
+    (void)utime(to, &when);
+}
+
+/* Decompress the file inname to the file outnname, of if test is true, just
+   decompress without writing and check the gzip trailer for integrity.  If
+   inname is NULL or an empty string, read from stdin.  If outname is NULL or
+   an empty string, write to stdout.  strm is a pre-initialized inflateBack
+   structure.  When appropriate, copy the file attributes from inname to
+   outname.
+
+   gunzip() returns 1 if there is an out-of-memory error or an unexpected
+   return code from gunpipe().  Otherwise it returns 0.
+ */
+local int gunzip(z_stream *strm, char *inname, char *outname, int test)
+{
+    int ret;
+    int infile, outfile;
+
+    /* open files */
+    if (inname == NULL || *inname == 0) {
+        inname = "-";
+        infile = 0;     /* stdin */
+    }
+    else {
+        infile = open(inname, O_RDONLY, 0);
+        if (infile == -1) {
+            fprintf(stderr, "gun cannot open %s\n", inname);
+            return 0;
+        }
+    }
+    if (test)
+        outfile = -1;
+    else if (outname == NULL || *outname == 0) {
+        outname = "-";
+        outfile = 1;    /* stdout */
+    }
+    else {
+        outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666);
+        if (outfile == -1) {
+            close(infile);
+            fprintf(stderr, "gun cannot create %s\n", outname);
+            return 0;
+        }
+    }
+    errno = 0;
+
+    /* decompress */
+    ret = gunpipe(strm, infile, outfile);
+    if (outfile > 2) close(outfile);
+    if (infile > 2) close(infile);
+
+    /* interpret result */
+    switch (ret) {
+    case Z_OK:
+    case Z_ERRNO:
+        if (infile > 2 && outfile > 2) {
+            copymeta(inname, outname);          /* copy attributes */
+            unlink(inname);
+        }
+        if (ret == Z_ERRNO)
+            fprintf(stderr, "gun warning: trailing garbage ignored in %s\n",
+                    inname);
+        break;
+    case Z_DATA_ERROR:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg);
+        break;
+    case Z_MEM_ERROR:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun out of memory error--aborting\n");
+        return 1;
+    case Z_BUF_ERROR:
+        if (outfile > 2) unlink(outname);
+        if (strm->next_in != Z_NULL) {
+            fprintf(stderr, "gun write error on %s: %s\n",
+                    outname, strerror(errno));
+        }
+        else if (errno) {
+            fprintf(stderr, "gun read error on %s: %s\n",
+                    inname, strerror(errno));
+        }
+        else {
+            fprintf(stderr, "gun unexpected end of file on %s\n",
+                    inname);
+        }
+        break;
+    default:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun internal error--aborting\n");
+        return 1;
+    }
+    return 0;
+}
+
+/* Process the gun command line arguments.  See the command syntax near the
+   beginning of this source file. */
+int main(int argc, char **argv)
+{
+    int ret, len, test;
+    char *outname;
+    unsigned char *window;
+    z_stream strm;
+
+    /* initialize inflateBack state for repeated use */
+    window = match;                         /* reuse LZW match buffer */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = inflateBackInit(&strm, 15, window);
+    if (ret != Z_OK) {
+        fprintf(stderr, "gun out of memory error--aborting\n");
+        return 1;
+    }
+
+    /* decompress each file to the same name with the suffix removed */
+    argc--;
+    argv++;
+    test = 0;
+    if (argc && strcmp(*argv, "-h") == 0) {
+        fprintf(stderr, "gun 1.6 (17 Jan 2010)\n");
+        fprintf(stderr, "Copyright (C) 2003-2010 Mark Adler\n");
+        fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n");
+        return 0;
+    }
+    if (argc && strcmp(*argv, "-t") == 0) {
+        test = 1;
+        argc--;
+        argv++;
+    }
+    if (argc)
+        do {
+            if (test)
+                outname = NULL;
+            else {
+                len = (int)strlen(*argv);
+                if (strcmp(*argv + len - 3, ".gz") == 0 ||
+                    strcmp(*argv + len - 3, "-gz") == 0)
+                    len -= 3;
+                else if (strcmp(*argv + len - 2, ".z") == 0 ||
+                    strcmp(*argv + len - 2, "-z") == 0 ||
+                    strcmp(*argv + len - 2, "_z") == 0 ||
+                    strcmp(*argv + len - 2, ".Z") == 0)
+                    len -= 2;
+                else {
+                    fprintf(stderr, "gun error: no gz type on %s--skipping\n",
+                            *argv);
+                    continue;
+                }
+                outname = malloc(len + 1);
+                if (outname == NULL) {
+                    fprintf(stderr, "gun out of memory error--aborting\n");
+                    ret = 1;
+                    break;
+                }
+                memcpy(outname, *argv, len);
+                outname[len] = 0;
+            }
+            ret = gunzip(&strm, *argv, outname, test);
+            if (outname != NULL) free(outname);
+            if (ret) break;
+        } while (argv++, --argc);
+    else
+        ret = gunzip(&strm, NULL, NULL, test);
+
+    /* clean up */
+    inflateBackEnd(&strm);
+    return ret;
+}
diff --git a/8.x/zlib/examples/gzappend.c b/8.x/zlib/examples/gzappend.c
new file mode 100644 (file)
index 0000000..e9e878e
--- /dev/null
@@ -0,0 +1,500 @@
+/* gzappend -- command to append to a gzip file
+
+  Copyright (C) 2003 Mark Adler, all rights reserved
+  version 1.1, 4 Nov 2003
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0  19 Oct 2003     - First version
+ * 1.1   4 Nov 2003     - Expand and clarify some comments and notes
+ *                      - Add version and copyright to help
+ *                      - Send help to stdout instead of stderr
+ *                      - Add some preemptive typecasts
+ *                      - Add L to constants in lseek() calls
+ *                      - Remove some debugging information in error messages
+ *                      - Use new data_type definition for zlib 1.2.1
+ *                      - Simplfy and unify file operations
+ *                      - Finish off gzip file in gztack()
+ *                      - Use deflatePrime() instead of adding empty blocks
+ *                      - Keep gzip file clean on appended file read errors
+ *                      - Use in-place rotate instead of auxiliary buffer
+ *                        (Why you ask?  Because it was fun to write!)
+ */
+
+/*
+   gzappend takes a gzip file and appends to it, compressing files from the
+   command line or data from stdin.  The gzip file is written to directly, to
+   avoid copying that file, in case it's large.  Note that this results in the
+   unfriendly behavior that if gzappend fails, the gzip file is corrupted.
+
+   This program was written to illustrate the use of the new Z_BLOCK option of
+   zlib 1.2.x's inflate() function.  This option returns from inflate() at each
+   block boundary to facilitate locating and modifying the last block bit at
+   the start of the final deflate block.  Also whether using Z_BLOCK or not,
+   another required feature of zlib 1.2.x is that inflate() now provides the
+   number of unusued bits in the last input byte used.  gzappend will not work
+   with versions of zlib earlier than 1.2.1.
+
+   gzappend first decompresses the gzip file internally, discarding all but
+   the last 32K of uncompressed data, and noting the location of the last block
+   bit and the number of unused bits in the last byte of the compressed data.
+   The gzip trailer containing the CRC-32 and length of the uncompressed data
+   is verified.  This trailer will be later overwritten.
+
+   Then the last block bit is cleared by seeking back in the file and rewriting
+   the byte that contains it.  Seeking forward, the last byte of the compressed
+   data is saved along with the number of unused bits to initialize deflate.
+
+   A deflate process is initialized, using the last 32K of the uncompressed
+   data from the gzip file to initialize the dictionary.  If the total
+   uncompressed data was less than 32K, then all of it is used to initialize
+   the dictionary.  The deflate output bit buffer is also initialized with the
+   last bits from the original deflate stream.  From here on, the data to
+   append is simply compressed using deflate, and written to the gzip file.
+   When that is complete, the new CRC-32 and uncompressed length are written
+   as the trailer of the gzip file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "zlib.h"
+
+#define local static
+#define LGCHUNK 14
+#define CHUNK (1U << LGCHUNK)
+#define DSIZE 32768U
+
+/* print an error message and terminate with extreme prejudice */
+local void bye(char *msg1, char *msg2)
+{
+    fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2);
+    exit(1);
+}
+
+/* return the greatest common divisor of a and b using Euclid's algorithm,
+   modified to be fast when one argument much greater than the other, and
+   coded to avoid unnecessary swapping */
+local unsigned gcd(unsigned a, unsigned b)
+{
+    unsigned c;
+
+    while (a && b)
+        if (a > b) {
+            c = b;
+            while (a - c >= c)
+                c <<= 1;
+            a -= c;
+        }
+        else {
+            c = a;
+            while (b - c >= c)
+                c <<= 1;
+            b -= c;
+        }
+    return a + b;
+}
+
+/* rotate list[0..len-1] left by rot positions, in place */
+local void rotate(unsigned char *list, unsigned len, unsigned rot)
+{
+    unsigned char tmp;
+    unsigned cycles;
+    unsigned char *start, *last, *to, *from;
+
+    /* normalize rot and handle degenerate cases */
+    if (len < 2) return;
+    if (rot >= len) rot %= len;
+    if (rot == 0) return;
+
+    /* pointer to last entry in list */
+    last = list + (len - 1);
+
+    /* do simple left shift by one */
+    if (rot == 1) {
+        tmp = *list;
+        memcpy(list, list + 1, len - 1);
+        *last = tmp;
+        return;
+    }
+
+    /* do simple right shift by one */
+    if (rot == len - 1) {
+        tmp = *last;
+        memmove(list + 1, list, len - 1);
+        *list = tmp;
+        return;
+    }
+
+    /* otherwise do rotate as a set of cycles in place */
+    cycles = gcd(len, rot);             /* number of cycles */
+    do {
+        start = from = list + cycles;   /* start index is arbitrary */
+        tmp = *from;                    /* save entry to be overwritten */
+        for (;;) {
+            to = from;                  /* next step in cycle */
+            from += rot;                /* go right rot positions */
+            if (from > last) from -= len;   /* (pointer better not wrap) */
+            if (from == start) break;   /* all but one shifted */
+            *to = *from;                /* shift left */
+        }
+        *to = tmp;                      /* complete the circle */
+    } while (--cycles);
+}
+
+/* structure for gzip file read operations */
+typedef struct {
+    int fd;                     /* file descriptor */
+    int size;                   /* 1 << size is bytes in buf */
+    unsigned left;              /* bytes available at next */
+    unsigned char *buf;         /* buffer */
+    unsigned char *next;        /* next byte in buffer */
+    char *name;                 /* file name for error messages */
+} file;
+
+/* reload buffer */
+local int readin(file *in)
+{
+    int len;
+
+    len = read(in->fd, in->buf, 1 << in->size);
+    if (len == -1) bye("error reading ", in->name);
+    in->left = (unsigned)len;
+    in->next = in->buf;
+    return len;
+}
+
+/* read from file in, exit if end-of-file */
+local int readmore(file *in)
+{
+    if (readin(in) == 0) bye("unexpected end of ", in->name);
+    return 0;
+}
+
+#define read1(in) (in->left == 0 ? readmore(in) : 0, \
+                   in->left--, *(in->next)++)
+
+/* skip over n bytes of in */
+local void skip(file *in, unsigned n)
+{
+    unsigned bypass;
+
+    if (n > in->left) {
+        n -= in->left;
+        bypass = n & ~((1U << in->size) - 1);
+        if (bypass) {
+            if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1)
+                bye("seeking ", in->name);
+            n -= bypass;
+        }
+        readmore(in);
+        if (n > in->left)
+            bye("unexpected end of ", in->name);
+    }
+    in->left -= n;
+    in->next += n;
+}
+
+/* read a four-byte unsigned integer, little-endian, from in */
+unsigned long read4(file *in)
+{
+    unsigned long val;
+
+    val = read1(in);
+    val += (unsigned)read1(in) << 8;
+    val += (unsigned long)read1(in) << 16;
+    val += (unsigned long)read1(in) << 24;
+    return val;
+}
+
+/* skip over gzip header */
+local void gzheader(file *in)
+{
+    int flags;
+    unsigned n;
+
+    if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file");
+    if (read1(in) != 8) bye("unknown compression method in", in->name);
+    flags = read1(in);
+    if (flags & 0xe0) bye("unknown header flags set in", in->name);
+    skip(in, 6);
+    if (flags & 4) {
+        n = read1(in);
+        n += (unsigned)(read1(in)) << 8;
+        skip(in, n);
+    }
+    if (flags & 8) while (read1(in) != 0) ;
+    if (flags & 16) while (read1(in) != 0) ;
+    if (flags & 2) skip(in, 2);
+}
+
+/* decompress gzip file "name", return strm with a deflate stream ready to
+   continue compression of the data in the gzip file, and return a file
+   descriptor pointing to where to write the compressed data -- the deflate
+   stream is initialized to compress using level "level" */
+local int gzscan(char *name, z_stream *strm, int level)
+{
+    int ret, lastbit, left, full;
+    unsigned have;
+    unsigned long crc, tot;
+    unsigned char *window;
+    off_t lastoff, end;
+    file gz;
+
+    /* open gzip file */
+    gz.name = name;
+    gz.fd = open(name, O_RDWR, 0);
+    if (gz.fd == -1) bye("cannot open ", name);
+    gz.buf = malloc(CHUNK);
+    if (gz.buf == NULL) bye("out of memory", "");
+    gz.size = LGCHUNK;
+    gz.left = 0;
+
+    /* skip gzip header */
+    gzheader(&gz);
+
+    /* prepare to decompress */
+    window = malloc(DSIZE);
+    if (window == NULL) bye("out of memory", "");
+    strm->zalloc = Z_NULL;
+    strm->zfree = Z_NULL;
+    strm->opaque = Z_NULL;
+    ret = inflateInit2(strm, -15);
+    if (ret != Z_OK) bye("out of memory", " or library mismatch");
+
+    /* decompress the deflate stream, saving append information */
+    lastbit = 0;
+    lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
+    left = 0;
+    strm->avail_in = gz.left;
+    strm->next_in = gz.next;
+    crc = crc32(0L, Z_NULL, 0);
+    have = full = 0;
+    do {
+        /* if needed, get more input */
+        if (strm->avail_in == 0) {
+            readmore(&gz);
+            strm->avail_in = gz.left;
+            strm->next_in = gz.next;
+        }
+
+        /* set up output to next available section of sliding window */
+        strm->avail_out = DSIZE - have;
+        strm->next_out = window + have;
+
+        /* inflate and check for errors */
+        ret = inflate(strm, Z_BLOCK);
+        if (ret == Z_STREAM_ERROR) bye("internal stream error!", "");
+        if (ret == Z_MEM_ERROR) bye("out of memory", "");
+        if (ret == Z_DATA_ERROR)
+            bye("invalid compressed data--format violated in", name);
+
+        /* update crc and sliding window pointer */
+        crc = crc32(crc, window + have, DSIZE - have - strm->avail_out);
+        if (strm->avail_out)
+            have = DSIZE - strm->avail_out;
+        else {
+            have = 0;
+            full = 1;
+        }
+
+        /* process end of block */
+        if (strm->data_type & 128) {
+            if (strm->data_type & 64)
+                left = strm->data_type & 0x1f;
+            else {
+                lastbit = strm->data_type & 0x1f;
+                lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in;
+            }
+        }
+    } while (ret != Z_STREAM_END);
+    inflateEnd(strm);
+    gz.left = strm->avail_in;
+    gz.next = strm->next_in;
+
+    /* save the location of the end of the compressed data */
+    end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
+
+    /* check gzip trailer and save total for deflate */
+    if (crc != read4(&gz))
+        bye("invalid compressed data--crc mismatch in ", name);
+    tot = strm->total_out;
+    if ((tot & 0xffffffffUL) != read4(&gz))
+        bye("invalid compressed data--length mismatch in", name);
+
+    /* if not at end of file, warn */
+    if (gz.left || readin(&gz))
+        fprintf(stderr,
+            "gzappend warning: junk at end of gzip file overwritten\n");
+
+    /* clear last block bit */
+    lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET);
+    if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
+    *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7)));
+    lseek(gz.fd, -1L, SEEK_CUR);
+    if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name);
+
+    /* if window wrapped, build dictionary from window by rotating */
+    if (full) {
+        rotate(window, DSIZE, have);
+        have = DSIZE;
+    }
+
+    /* set up deflate stream with window, crc, total_in, and leftover bits */
+    ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
+    if (ret != Z_OK) bye("out of memory", "");
+    deflateSetDictionary(strm, window, have);
+    strm->adler = crc;
+    strm->total_in = tot;
+    if (left) {
+        lseek(gz.fd, --end, SEEK_SET);
+        if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
+        deflatePrime(strm, 8 - left, *gz.buf);
+    }
+    lseek(gz.fd, end, SEEK_SET);
+
+    /* clean up and return */
+    free(window);
+    free(gz.buf);
+    return gz.fd;
+}
+
+/* append file "name" to gzip file gd using deflate stream strm -- if last
+   is true, then finish off the deflate stream at the end */
+local void gztack(char *name, int gd, z_stream *strm, int last)
+{
+    int fd, len, ret;
+    unsigned left;
+    unsigned char *in, *out;
+
+    /* open file to compress and append */
+    fd = 0;
+    if (name != NULL) {
+        fd = open(name, O_RDONLY, 0);
+        if (fd == -1)
+            fprintf(stderr, "gzappend warning: %s not found, skipping ...\n",
+                    name);
+    }
+
+    /* allocate buffers */
+    in = fd == -1 ? NULL : malloc(CHUNK);
+    out = malloc(CHUNK);
+    if (out == NULL) bye("out of memory", "");
+
+    /* compress input file and append to gzip file */
+    do {
+        /* get more input */
+        len = fd == -1 ? 0 : read(fd, in, CHUNK);
+        if (len == -1) {
+            fprintf(stderr,
+                    "gzappend warning: error reading %s, skipping rest ...\n",
+                    name);
+            len = 0;
+        }
+        strm->avail_in = (unsigned)len;
+        strm->next_in = in;
+        if (len) strm->adler = crc32(strm->adler, in, (unsigned)len);
+
+        /* compress and write all available output */
+        do {
+            strm->avail_out = CHUNK;
+            strm->next_out = out;
+            ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH);
+            left = CHUNK - strm->avail_out;
+            while (left) {
+                len = write(gd, out + CHUNK - strm->avail_out - left, left);
+                if (len == -1) bye("writing gzip file", "");
+                left -= (unsigned)len;
+            }
+        } while (strm->avail_out == 0 && ret != Z_STREAM_END);
+    } while (len != 0);
+
+    /* write trailer after last entry */
+    if (last) {
+        deflateEnd(strm);
+        out[0] = (unsigned char)(strm->adler);
+        out[1] = (unsigned char)(strm->adler >> 8);
+        out[2] = (unsigned char)(strm->adler >> 16);
+        out[3] = (unsigned char)(strm->adler >> 24);
+        out[4] = (unsigned char)(strm->total_in);
+        out[5] = (unsigned char)(strm->total_in >> 8);
+        out[6] = (unsigned char)(strm->total_in >> 16);
+        out[7] = (unsigned char)(strm->total_in >> 24);
+        len = 8;
+        do {
+            ret = write(gd, out + 8 - len, len);
+            if (ret == -1) bye("writing gzip file", "");
+            len -= ret;
+        } while (len);
+        close(gd);
+    }
+
+    /* clean up and return */
+    free(out);
+    if (in != NULL) free(in);
+    if (fd > 0) close(fd);
+}
+
+/* process the compression level option if present, scan the gzip file, and
+   append the specified files, or append the data from stdin if no other file
+   names are provided on the command line -- the gzip file must be writable
+   and seekable */
+int main(int argc, char **argv)
+{
+    int gd, level;
+    z_stream strm;
+
+    /* ignore command name */
+    argv++;
+
+    /* provide usage if no arguments */
+    if (*argv == NULL) {
+        printf("gzappend 1.1 (4 Nov 2003) Copyright (C) 2003 Mark Adler\n");
+        printf(
+            "usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n");
+        return 0;
+    }
+
+    /* set compression level */
+    level = Z_DEFAULT_COMPRESSION;
+    if (argv[0][0] == '-') {
+        if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0)
+            bye("invalid compression level", "");
+        level = argv[0][1] - '0';
+        if (*++argv == NULL) bye("no gzip file name after options", "");
+    }
+
+    /* prepare to append to gzip file */
+    gd = gzscan(*argv++, &strm, level);
+
+    /* append files on command line, or from stdin if none */
+    if (*argv == NULL)
+        gztack(NULL, gd, &strm, 1);
+    else
+        do {
+            gztack(*argv, gd, &strm, argv[1] == NULL);
+        } while (*++argv != NULL);
+    return 0;
+}
diff --git a/8.x/zlib/examples/gzjoin.c b/8.x/zlib/examples/gzjoin.c
new file mode 100644 (file)
index 0000000..129347c
--- /dev/null
@@ -0,0 +1,448 @@
+/* gzjoin -- command to join gzip files into one gzip file
+
+  Copyright (C) 2004 Mark Adler, all rights reserved
+  version 1.0, 11 Dec 2004
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0  11 Dec 2004     - First version
+ * 1.1  12 Jun 2005     - Changed ssize_t to long for portability
+ */
+
+/*
+   gzjoin takes one or more gzip files on the command line and writes out a
+   single gzip file that will uncompress to the concatenation of the
+   uncompressed data from the individual gzip files.  gzjoin does this without
+   having to recompress any of the data and without having to calculate a new
+   crc32 for the concatenated uncompressed data.  gzjoin does however have to
+   decompress all of the input data in order to find the bits in the compressed
+   data that need to be modified to concatenate the streams.
+
+   gzjoin does not do an integrity check on the input gzip files other than
+   checking the gzip header and decompressing the compressed data.  They are
+   otherwise assumed to be complete and correct.
+
+   Each joint between gzip files removes at least 18 bytes of previous trailer
+   and subsequent header, and inserts an average of about three bytes to the
+   compressed data in order to connect the streams.  The output gzip file
+   has a minimal ten-byte gzip header with no file name or modification time.
+
+   This program was written to illustrate the use of the Z_BLOCK option of
+   inflate() and the crc32_combine() function.  gzjoin will not compile with
+   versions of zlib earlier than 1.2.3.
+ */
+
+#include <stdio.h>      /* fputs(), fprintf(), fwrite(), putc() */
+#include <stdlib.h>     /* exit(), malloc(), free() */
+#include <fcntl.h>      /* open() */
+#include <unistd.h>     /* close(), read(), lseek() */
+#include "zlib.h"
+    /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */
+
+#define local static
+
+/* exit with an error (return a value to allow use in an expression) */
+local int bail(char *why1, char *why2)
+{
+    fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2);
+    exit(1);
+    return 0;
+}
+
+/* -- simple buffered file input with access to the buffer -- */
+
+#define CHUNK 32768         /* must be a power of two and fit in unsigned */
+
+/* bin buffered input file type */
+typedef struct {
+    char *name;             /* name of file for error messages */
+    int fd;                 /* file descriptor */
+    unsigned left;          /* bytes remaining at next */
+    unsigned char *next;    /* next byte to read */
+    unsigned char *buf;     /* allocated buffer of length CHUNK */
+} bin;
+
+/* close a buffered file and free allocated memory */
+local void bclose(bin *in)
+{
+    if (in != NULL) {
+        if (in->fd != -1)
+            close(in->fd);
+        if (in->buf != NULL)
+            free(in->buf);
+        free(in);
+    }
+}
+
+/* open a buffered file for input, return a pointer to type bin, or NULL on
+   failure */
+local bin *bopen(char *name)
+{
+    bin *in;
+
+    in = malloc(sizeof(bin));
+    if (in == NULL)
+        return NULL;
+    in->buf = malloc(CHUNK);
+    in->fd = open(name, O_RDONLY, 0);
+    if (in->buf == NULL || in->fd == -1) {
+        bclose(in);
+        return NULL;
+    }
+    in->left = 0;
+    in->next = in->buf;
+    in->name = name;
+    return in;
+}
+
+/* load buffer from file, return -1 on read error, 0 or 1 on success, with
+   1 indicating that end-of-file was reached */
+local int bload(bin *in)
+{
+    long len;
+
+    if (in == NULL)
+        return -1;
+    if (in->left != 0)
+        return 0;
+    in->next = in->buf;
+    do {
+        len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left);
+        if (len < 0)
+            return -1;
+        in->left += (unsigned)len;
+    } while (len != 0 && in->left < CHUNK);
+    return len == 0 ? 1 : 0;
+}
+
+/* get a byte from the file, bail if end of file */
+#define bget(in) (in->left ? 0 : bload(in), \
+                  in->left ? (in->left--, *(in->next)++) : \
+                    bail("unexpected end of file on ", in->name))
+
+/* get a four-byte little-endian unsigned integer from file */
+local unsigned long bget4(bin *in)
+{
+    unsigned long val;
+
+    val = bget(in);
+    val += (unsigned long)(bget(in)) << 8;
+    val += (unsigned long)(bget(in)) << 16;
+    val += (unsigned long)(bget(in)) << 24;
+    return val;
+}
+
+/* skip bytes in file */
+local void bskip(bin *in, unsigned skip)
+{
+    /* check pointer */
+    if (in == NULL)
+        return;
+
+    /* easy case -- skip bytes in buffer */
+    if (skip <= in->left) {
+        in->left -= skip;
+        in->next += skip;
+        return;
+    }
+
+    /* skip what's in buffer, discard buffer contents */
+    skip -= in->left;
+    in->left = 0;
+
+    /* seek past multiples of CHUNK bytes */
+    if (skip > CHUNK) {
+        unsigned left;
+
+        left = skip & (CHUNK - 1);
+        if (left == 0) {
+            /* exact number of chunks: seek all the way minus one byte to check
+               for end-of-file with a read */
+            lseek(in->fd, skip - 1, SEEK_CUR);
+            if (read(in->fd, in->buf, 1) != 1)
+                bail("unexpected end of file on ", in->name);
+            return;
+        }
+
+        /* skip the integral chunks, update skip with remainder */
+        lseek(in->fd, skip - left, SEEK_CUR);
+        skip = left;
+    }
+
+    /* read more input and skip remainder */
+    bload(in);
+    if (skip > in->left)
+        bail("unexpected end of file on ", in->name);
+    in->left -= skip;
+    in->next += skip;
+}
+
+/* -- end of buffered input functions -- */
+
+/* skip the gzip header from file in */
+local void gzhead(bin *in)
+{
+    int flags;
+
+    /* verify gzip magic header and compression method */
+    if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)
+        bail(in->name, " is not a valid gzip file");
+
+    /* get and verify flags */
+    flags = bget(in);
+    if ((flags & 0xe0) != 0)
+        bail("unknown reserved bits set in ", in->name);
+
+    /* skip modification time, extra flags, and os */
+    bskip(in, 6);
+
+    /* skip extra field if present */
+    if (flags & 4) {
+        unsigned len;
+
+        len = bget(in);
+        len += (unsigned)(bget(in)) << 8;
+        bskip(in, len);
+    }
+
+    /* skip file name if present */
+    if (flags & 8)
+        while (bget(in) != 0)
+            ;
+
+    /* skip comment if present */
+    if (flags & 16)
+        while (bget(in) != 0)
+            ;
+
+    /* skip header crc if present */
+    if (flags & 2)
+        bskip(in, 2);
+}
+
+/* write a four-byte little-endian unsigned integer to out */
+local void put4(unsigned long val, FILE *out)
+{
+    putc(val & 0xff, out);
+    putc((val >> 8) & 0xff, out);
+    putc((val >> 16) & 0xff, out);
+    putc((val >> 24) & 0xff, out);
+}
+
+/* Load up zlib stream from buffered input, bail if end of file */
+local void zpull(z_streamp strm, bin *in)
+{
+    if (in->left == 0)
+        bload(in);
+    if (in->left == 0)
+        bail("unexpected end of file on ", in->name);
+    strm->avail_in = in->left;
+    strm->next_in = in->next;
+}
+
+/* Write header for gzip file to out and initialize trailer. */
+local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)
+{
+    fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
+    *crc = crc32(0L, Z_NULL, 0);
+    *tot = 0;
+}
+
+/* Copy the compressed data from name, zeroing the last block bit of the last
+   block if clr is true, and adding empty blocks as needed to get to a byte
+   boundary.  If clr is false, then the last block becomes the last block of
+   the output, and the gzip trailer is written.  crc and tot maintains the
+   crc and length (modulo 2^32) of the output for the trailer.  The resulting
+   gzip file is written to out.  gzinit() must be called before the first call
+   of gzcopy() to write the gzip header and to initialize crc and tot. */
+local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
+                  FILE *out)
+{
+    int ret;                /* return value from zlib functions */
+    int pos;                /* where the "last block" bit is in byte */
+    int last;               /* true if processing the last block */
+    bin *in;                /* buffered input file */
+    unsigned char *start;   /* start of compressed data in buffer */
+    unsigned char *junk;    /* buffer for uncompressed data -- discarded */
+    z_off_t len;            /* length of uncompressed data (support > 4 GB) */
+    z_stream strm;          /* zlib inflate stream */
+
+    /* open gzip file and skip header */
+    in = bopen(name);
+    if (in == NULL)
+        bail("could not open ", name);
+    gzhead(in);
+
+    /* allocate buffer for uncompressed data and initialize raw inflate
+       stream */
+    junk = malloc(CHUNK);
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, -15);
+    if (junk == NULL || ret != Z_OK)
+        bail("out of memory", "");
+
+    /* inflate and copy compressed data, clear last-block bit if requested */
+    len = 0;
+    zpull(&strm, in);
+    start = strm.next_in;
+    last = start[0] & 1;
+    if (last && clr)
+        start[0] &= ~1;
+    strm.avail_out = 0;
+    for (;;) {
+        /* if input used and output done, write used input and get more */
+        if (strm.avail_in == 0 && strm.avail_out != 0) {
+            fwrite(start, 1, strm.next_in - start, out);
+            start = in->buf;
+            in->left = 0;
+            zpull(&strm, in);
+        }
+
+        /* decompress -- return early when end-of-block reached */
+        strm.avail_out = CHUNK;
+        strm.next_out = junk;
+        ret = inflate(&strm, Z_BLOCK);
+        switch (ret) {
+        case Z_MEM_ERROR:
+            bail("out of memory", "");
+        case Z_DATA_ERROR:
+            bail("invalid compressed data in ", in->name);
+        }
+
+        /* update length of uncompressed data */
+        len += CHUNK - strm.avail_out;
+
+        /* check for block boundary (only get this when block copied out) */
+        if (strm.data_type & 128) {
+            /* if that was the last block, then done */
+            if (last)
+                break;
+
+            /* number of unused bits in last byte */
+            pos = strm.data_type & 7;
+
+            /* find the next last-block bit */
+            if (pos != 0) {
+                /* next last-block bit is in last used byte */
+                pos = 0x100 >> pos;
+                last = strm.next_in[-1] & pos;
+                if (last && clr)
+                    strm.next_in[-1] &= ~pos;
+            }
+            else {
+                /* next last-block bit is in next unused byte */
+                if (strm.avail_in == 0) {
+                    /* don't have that byte yet -- get it */
+                    fwrite(start, 1, strm.next_in - start, out);
+                    start = in->buf;
+                    in->left = 0;
+                    zpull(&strm, in);
+                }
+                last = strm.next_in[0] & 1;
+                if (last && clr)
+                    strm.next_in[0] &= ~1;
+            }
+        }
+    }
+
+    /* update buffer with unused input */
+    in->left = strm.avail_in;
+    in->next = strm.next_in;
+
+    /* copy used input, write empty blocks to get to byte boundary */
+    pos = strm.data_type & 7;
+    fwrite(start, 1, in->next - start - 1, out);
+    last = in->next[-1];
+    if (pos == 0 || !clr)
+        /* already at byte boundary, or last file: write last byte */
+        putc(last, out);
+    else {
+        /* append empty blocks to last byte */
+        last &= ((0x100 >> pos) - 1);       /* assure unused bits are zero */
+        if (pos & 1) {
+            /* odd -- append an empty stored block */
+            putc(last, out);
+            if (pos == 1)
+                putc(0, out);               /* two more bits in block header */
+            fwrite("\0\0\xff\xff", 1, 4, out);
+        }
+        else {
+            /* even -- append 1, 2, or 3 empty fixed blocks */
+            switch (pos) {
+            case 6:
+                putc(last | 8, out);
+                last = 0;
+            case 4:
+                putc(last | 0x20, out);
+                last = 0;
+            case 2:
+                putc(last | 0x80, out);
+                putc(0, out);
+            }
+        }
+    }
+
+    /* update crc and tot */
+    *crc = crc32_combine(*crc, bget4(in), len);
+    *tot += (unsigned long)len;
+
+    /* clean up */
+    inflateEnd(&strm);
+    free(junk);
+    bclose(in);
+
+    /* write trailer if this is the last gzip file */
+    if (!clr) {
+        put4(*crc, out);
+        put4(*tot, out);
+    }
+}
+
+/* join the gzip files on the command line, write result to stdout */
+int main(int argc, char **argv)
+{
+    unsigned long crc, tot;     /* running crc and total uncompressed length */
+
+    /* skip command name */
+    argc--;
+    argv++;
+
+    /* show usage if no arguments */
+    if (argc == 0) {
+        fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n",
+              stderr);
+        return 0;
+    }
+
+    /* join gzip files on command line and write to stdout */
+    gzinit(&crc, &tot, stdout);
+    while (argc--)
+        gzcopy(*argv++, argc, &crc, &tot, stdout);
+
+    /* done */
+    return 0;
+}
diff --git a/8.x/zlib/examples/gzlog.c b/8.x/zlib/examples/gzlog.c
new file mode 100644 (file)
index 0000000..d70aaca
--- /dev/null
@@ -0,0 +1,1058 @@
+/*
+ * gzlog.c
+ * Copyright (C) 2004, 2008 Mark Adler, all rights reserved
+ * For conditions of distribution and use, see copyright notice in gzlog.h
+ * version 2.0, 25 Apr 2008
+ */
+
+/*
+   gzlog provides a mechanism for frequently appending short strings to a gzip
+   file that is efficient both in execution time and compression ratio.  The
+   strategy is to write the short strings in an uncompressed form to the end of
+   the gzip file, only compressing when the amount of uncompressed data has
+   reached a given threshold.
+
+   gzlog also provides protection against interruptions in the process due to
+   system crashes.  The status of the operation is recorded in an extra field
+   in the gzip file, and is only updated once the gzip file is brought to a
+   valid state.  The last data to be appended or compressed is saved in an
+   auxiliary file, so that if the operation is interrupted, it can be completed
+   the next time an append operation is attempted.
+
+   gzlog maintains another auxiliary file with the last 32K of data from the
+   compressed portion, which is preloaded for the compression of the subsequent
+   data.  This minimizes the impact to the compression ratio of appending.
+ */
+
+/*
+   Operations Concept:
+
+   Files (log name "foo"):
+   foo.gz -- gzip file with the complete log
+   foo.add -- last message to append or last data to compress
+   foo.dict -- dictionary of the last 32K of data for next compression
+   foo.temp -- temporary dictionary file for compression after this one
+   foo.lock -- lock file for reading and writing the other files
+   foo.repairs -- log file for log file recovery operations (not compressed)
+
+   gzip file structure:
+   - fixed-length (no file name) header with extra field (see below)
+   - compressed data ending initially with empty stored block
+   - uncompressed data filling out originally empty stored block and
+     subsequent stored blocks as needed (16K max each)
+   - gzip trailer
+   - no junk at end (no other gzip streams)
+
+   When appending data, the information in the first three items above plus the
+   foo.add file are sufficient to recover an interrupted append operation.  The
+   extra field has the necessary information to restore the start of the last
+   stored block and determine where to append the data in the foo.add file, as
+   well as the crc and length of the gzip data before the append operation.
+
+   The foo.add file is created before the gzip file is marked for append, and
+   deleted after the gzip file is marked as complete.  So if the append
+   operation is interrupted, the data to add will still be there.  If due to
+   some external force, the foo.add file gets deleted between when the append
+   operation was interrupted and when recovery is attempted, the gzip file will
+   still be restored, but without the appended data.
+
+   When compressing data, the information in the first two items above plus the
+   foo.add file are sufficient to recover an interrupted compress operation.
+   The extra field has the necessary information to find the end of the
+   compressed data, and contains both the crc and length of just the compressed
+   data and of the complete set of data including the contents of the foo.add
+   file.
+
+   Again, the foo.add file is maintained during the compress operation in case
+   of an interruption.  If in the unlikely event the foo.add file with the data
+   to be compressed is missing due to some external force, a gzip file with
+   just the previous compressed data will be reconstructed.  In this case, all
+   of the data that was to be compressed is lost (approximately one megabyte).
+   This will not occur if all that happened was an interruption of the compress
+   operation.
+
+   The third state that is marked is the replacement of the old dictionary with
+   the new dictionary after a compress operation.  Once compression is
+   complete, the gzip file is marked as being in the replace state.  This
+   completes the gzip file, so an interrupt after being so marked does not
+   result in recompression.  Then the dictionary file is replaced, and the gzip
+   file is marked as completed.  This state prevents the possibility of
+   restarting compression with the wrong dictionary file.
+
+   All three operations are wrapped by a lock/unlock procedure.  In order to
+   gain exclusive access to the log files, first a foo.lock file must be
+   exclusively created.  When all operations are complete, the lock is
+   released by deleting the foo.lock file.  If when attempting to create the
+   lock file, it already exists and the modify time of the lock file is more
+   than five minutes old (set by the PATIENCE define below), then the old
+   lock file is considered stale and deleted, and the exclusive creation of
+   the lock file is retried.  To assure that there are no false assessments
+   of the staleness of the lock file, the operations periodically touch the
+   lock file to update the modified date.
+
+   Following is the definition of the extra field with all of the information
+   required to enable the above append and compress operations and their
+   recovery if interrupted.  Multi-byte values are stored little endian
+   (consistent with the gzip format).  File pointers are eight bytes long.
+   The crc's and lengths for the gzip trailer are four bytes long.  (Note that
+   the length at the end of a gzip file is used for error checking only, and
+   for large files is actually the length modulo 2^32.)  The stored block
+   length is two bytes long.  The gzip extra field two-byte identification is
+   "ap" for append.  It is assumed that writing the extra field to the file is
+   an "atomic" operation.  That is, either all of the extra field is written
+   to the file, or none of it is, if the operation is interrupted right at the
+   point of updating the extra field.  This is a reasonable assumption, since
+   the extra field is within the first 52 bytes of the file, which is smaller
+   than any expected block size for a mass storage device (usually 512 bytes or
+   larger).
+
+   Extra field (35 bytes):
+   - Pointer to first stored block length -- this points to the two-byte length
+     of the first stored block, which is followed by the two-byte, one's
+     complement of that length.  The stored block length is preceded by the
+     three-bit header of the stored block, which is the actual start of the
+     stored block in the deflate format.  See the bit offset field below.
+   - Pointer to the last stored block length.  This is the same as above, but
+     for the last stored block of the uncompressed data in the gzip file.
+     Initially this is the same as the first stored block length pointer.
+     When the stored block gets to 16K (see the MAX_STORE define), then a new
+     stored block as added, at which point the last stored block length pointer
+     is different from the first stored block length pointer.  When they are
+     different, the first bit of the last stored block header is eight bits, or
+     one byte back from the block length.
+   - Compressed data crc and length.  This is the crc and length of the data
+     that is in the compressed portion of the deflate stream.  These are used
+     only in the event that the foo.add file containing the data to compress is
+     lost after a compress operation is interrupted.
+   - Total data crc and length.  This is the crc and length of all of the data
+     stored in the gzip file, compressed and uncompressed.  It is used to
+     reconstruct the gzip trailer when compressing, as well as when recovering
+     interrupted operations.
+   - Final stored block length.  This is used to quickly find where to append,
+     and allows the restoration of the original final stored block state when
+     an append operation is interrupted.
+   - First stored block start as the number of bits back from the final stored
+     block first length byte.  This value is in the range of 3..10, and is
+     stored as the low three bits of the final byte of the extra field after
+     subtracting three (0..7).  This allows the last-block bit of the stored
+     block header to be updated when a new stored block is added, for the case
+     when the first stored block and the last stored block are the same.  (When
+     they are different, the numbers of bits back is known to be eight.)  This
+     also allows for new compressed data to be appended to the old compressed
+     data in the compress operation, overwriting the previous first stored
+     block, or for the compressed data to be terminated and a valid gzip file
+     reconstructed on the off chance that a compression operation was
+     interrupted and the data to compress in the foo.add file was deleted.
+   - The operation in process.  This is the next two bits in the last byte (the
+     bits under the mask 0x18).  The are interpreted as 0: nothing in process,
+     1: append in process, 2: compress in process, 3: replace in process.
+   - The top three bits of the last byte in the extra field are reserved and
+     are currently set to zero.
+
+   Main procedure:
+   - Exclusively create the foo.lock file using the O_CREAT and O_EXCL modes of
+     the system open() call.  If the modify time of an existing lock file is
+     more than PATIENCE seconds old, then the lock file is deleted and the
+     exclusive create is retried.
+   - Load the extra field from the foo.gz file, and see if an operation was in
+     progress but not completed.  If so, apply the recovery procedure below.
+   - Perform the append procedure with the provided data.
+   - If the uncompressed data in the foo.gz file is 1MB or more, apply the
+     compress procedure.
+   - Delete the foo.lock file.
+
+   Append procedure:
+   - Put what to append in the foo.add file so that the operation can be
+     restarted if this procedure is interrupted.
+   - Mark the foo.gz extra field with the append operation in progress.
+   + Restore the original last-block bit and stored block length of the last
+     stored block from the information in the extra field, in case a previous
+     append operation was interrupted.
+   - Append the provided data to the last stored block, creating new stored
+     blocks as needed and updating the stored blocks last-block bits and
+     lengths.
+   - Update the crc and length with the new data, and write the gzip trailer.
+   - Write over the extra field (with a single write operation) with the new
+     pointers, lengths, and crc's, and mark the gzip file as not in process.
+     Though there is still a foo.add file, it will be ignored since nothing
+     is in process.  If a foo.add file is leftover from a previously
+     completed operation, it is truncated when writing new data to it.
+   - Delete the foo.add file.
+
+   Compress and replace procedures:
+   - Read all of the uncompressed data in the stored blocks in foo.gz and write
+     it to foo.add.  Also write foo.temp with the last 32K of that data to
+     provide a dictionary for the next invocation of this procedure.
+   - Rewrite the extra field marking foo.gz with a compression in process.
+   * If there is no data provided to compress (due to a missing foo.add file
+     when recovering), reconstruct and truncate the foo.gz file to contain
+     only the previous compressed data and proceed to the step after the next
+     one.  Otherwise ...
+   - Compress the data with the dictionary in foo.dict, and write to the
+     foo.gz file starting at the bit immediately following the last previously
+     compressed block.  If there is no foo.dict, proceed anyway with the
+     compression at slightly reduced efficiency.  (For the foo.dict file to be
+     missing requires some external failure beyond simply the interruption of
+     a compress operation.)  During this process, the foo.lock file is
+     periodically touched to assure that that file is not considered stale by
+     another process before we're done.  The deflation is terminated with a
+     non-last empty static block (10 bits long), that is then located and
+     written over by a last-bit-set empty stored block.
+   - Append the crc and length of the data in the gzip file (previously
+     calculated during the append operations).
+   - Write over the extra field with the updated stored block offsets, bits
+     back, crc's, and lengths, and mark foo.gz as in process for a replacement
+     of the dictionary.
+   @ Delete the foo.add file.
+   - Replace foo.dict with foo.temp.
+   - Write over the extra field, marking foo.gz as complete.
+
+   Recovery procedure:
+   - If not a replace recovery, read in the foo.add file, and provide that data
+     to the appropriate recovery below.  If there is no foo.add file, provide
+     a zero data length to the recovery.  In that case, the append recovery
+     restores the foo.gz to the previous compressed + uncompressed data state.
+     For the the compress recovery, a missing foo.add file results in foo.gz
+     being restored to the previous compressed-only data state.
+   - Append recovery:
+     - Pick up append at + step above
+   - Compress recovery:
+     - Pick up compress at * step above
+   - Replace recovery:
+     - Pick up compress at @ step above
+   - Log the repair with a date stamp in foo.repairs
+ */
+
+#include <sys/types.h>
+#include <stdio.h>      /* rename, fopen, fprintf, fclose */
+#include <stdlib.h>     /* malloc, free */
+#include <string.h>     /* strlen, strrchr, strcpy, strncpy, strcmp */
+#include <fcntl.h>      /* open */
+#include <unistd.h>     /* lseek, read, write, close, unlink, sleep, */
+                        /* ftruncate, fsync */
+#include <errno.h>      /* errno */
+#include <time.h>       /* time, ctime */
+#include <sys/stat.h>   /* stat */
+#include <sys/time.h>   /* utimes */
+#include "zlib.h"       /* crc32 */
+
+#include "gzlog.h"      /* header for external access */
+
+#define local static
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+/* Macro for debugging to deterministically force recovery operations */
+#ifdef DEBUG
+    #include <setjmp.h>         /* longjmp */
+    jmp_buf gzlog_jump;         /* where to go back to */
+    int gzlog_bail = 0;         /* which point to bail at (1..8) */
+    int gzlog_count = -1;       /* number of times through to wait */
+#   define BAIL(n) do { if (n == gzlog_bail && gzlog_count-- == 0) \
+                            longjmp(gzlog_jump, gzlog_bail); } while (0)
+#else
+#   define BAIL(n)
+#endif
+
+/* how old the lock file can be in seconds before considering it stale */
+#define PATIENCE 300
+
+/* maximum stored block size in Kbytes -- must be in 1..63 */
+#define MAX_STORE 16
+
+/* number of stored Kbytes to trigger compression (must be >= 32 to allow
+   dictionary construction, and <= 204 * MAX_STORE, in order for >> 10 to
+   discard the stored block headers contribution of five bytes each) */
+#define TRIGGER 1024
+
+/* size of a deflate dictionary (this cannot be changed) */
+#define DICT 32768U
+
+/* values for the operation (2 bits) */
+#define NO_OP 0
+#define APPEND_OP 1
+#define COMPRESS_OP 2
+#define REPLACE_OP 3
+
+/* macros to extract little-endian integers from an unsigned byte buffer */
+#define PULL2(p) ((p)[0]+((uint)((p)[1])<<8))
+#define PULL4(p) (PULL2(p)+((ulong)PULL2(p+2)<<16))
+#define PULL8(p) (PULL4(p)+((off_t)PULL4(p+4)<<32))
+
+/* macros to store integers into a byte buffer in little-endian order */
+#define PUT2(p,a) do {(p)[0]=a;(p)[1]=(a)>>8;} while(0)
+#define PUT4(p,a) do {PUT2(p,a);PUT2(p+2,a>>16);} while(0)
+#define PUT8(p,a) do {PUT4(p,a);PUT4(p+4,a>>32);} while(0)
+
+/* internal structure for log information */
+#define LOGID "\106\035\172"    /* should be three non-zero characters */
+struct log {
+    char id[4];     /* contains LOGID to detect inadvertent overwrites */
+    int fd;         /* file descriptor for .gz file, opened read/write */
+    char *path;     /* allocated path, e.g. "/var/log/foo" or "foo" */
+    char *end;      /* end of path, for appending suffices such as ".gz" */
+    off_t first;    /* offset of first stored block first length byte */
+    int back;       /* location of first block id in bits back from first */
+    uint stored;    /* bytes currently in last stored block */
+    off_t last;     /* offset of last stored block first length byte */
+    ulong ccrc;     /* crc of compressed data */
+    ulong clen;     /* length (modulo 2^32) of compressed data */
+    ulong tcrc;     /* crc of total data */
+    ulong tlen;     /* length (modulo 2^32) of total data */
+    time_t lock;    /* last modify time of our lock file */
+};
+
+/* gzip header for gzlog */
+local unsigned char log_gzhead[] = {
+    0x1f, 0x8b,                 /* magic gzip id */
+    8,                          /* compression method is deflate */
+    4,                          /* there is an extra field (no file name) */
+    0, 0, 0, 0,                 /* no modification time provided */
+    0, 0xff,                    /* no extra flags, no OS specified */
+    39, 0, 'a', 'p', 35, 0      /* extra field with "ap" subfield */
+                                /* 35 is EXTRA, 39 is EXTRA + 4 */
+};
+
+#define HEAD sizeof(log_gzhead)     /* should be 16 */
+
+/* initial gzip extra field content (52 == HEAD + EXTRA + 1) */
+local unsigned char log_gzext[] = {
+    52, 0, 0, 0, 0, 0, 0, 0,    /* offset of first stored block length */
+    52, 0, 0, 0, 0, 0, 0, 0,    /* offset of last stored block length */
+    0, 0, 0, 0, 0, 0, 0, 0,     /* compressed data crc and length */
+    0, 0, 0, 0, 0, 0, 0, 0,     /* total data crc and length */
+    0, 0,                       /* final stored block data length */
+    5                           /* op is NO_OP, last bit 8 bits back */
+};
+
+#define EXTRA sizeof(log_gzext)     /* should be 35 */
+
+/* initial gzip data and trailer */
+local unsigned char log_gzbody[] = {
+    1, 0, 0, 0xff, 0xff,        /* empty stored block (last) */
+    0, 0, 0, 0,                 /* crc */
+    0, 0, 0, 0                  /* uncompressed length */
+};
+
+#define BODY sizeof(log_gzbody)
+
+/* Exclusively create foo.lock in order to negotiate exclusive access to the
+   foo.* files.  If the modify time of an existing lock file is greater than
+   PATIENCE seconds in the past, then consider the lock file to have been
+   abandoned, delete it, and try the exclusive create again.  Save the lock
+   file modify time for verification of ownership.  Return 0 on success, or -1
+   on failure, usually due to an access restriction or invalid path.  Note that
+   if stat() or unlink() fails, it may be due to another process noticing the
+   abandoned lock file a smidge sooner and deleting it, so those are not
+   flagged as an error. */
+local int log_lock(struct log *log)
+{
+    int fd;
+    struct stat st;
+
+    strcpy(log->end, ".lock");
+    while ((fd = open(log->path, O_CREAT | O_EXCL, 0644)) < 0) {
+        if (errno != EEXIST)
+            return -1;
+        if (stat(log->path, &st) == 0 && time(NULL) - st.st_mtime > PATIENCE) {
+            unlink(log->path);
+            continue;
+        }
+        sleep(2);       /* relinquish the CPU for two seconds while waiting */
+    }
+    close(fd);
+    if (stat(log->path, &st) == 0)
+        log->lock = st.st_mtime;
+    return 0;
+}
+
+/* Update the modify time of the lock file to now, in order to prevent another
+   task from thinking that the lock is stale.  Save the lock file modify time
+   for verification of ownership. */
+local void log_touch(struct log *log)
+{
+    struct stat st;
+
+    strcpy(log->end, ".lock");
+    utimes(log->path, NULL);
+    if (stat(log->path, &st) == 0)
+        log->lock = st.st_mtime;
+}
+
+/* Check the log file modify time against what is expected.  Return true if
+   this is not our lock.  If it is our lock, touch it to keep it. */
+local int log_check(struct log *log)
+{
+    struct stat st;
+
+    strcpy(log->end, ".lock");
+    if (stat(log->path, &st) || st.st_mtime != log->lock)
+        return 1;
+    log_touch(log);
+    return 0;
+}
+
+/* Unlock a previously acquired lock, but only if it's ours. */
+local void log_unlock(struct log *log)
+{
+    if (log_check(log))
+        return;
+    strcpy(log->end, ".lock");
+    unlink(log->path);
+    log->lock = 0;
+}
+
+/* Check the gzip header and read in the extra field, filling in the values in
+   the log structure.  Return op on success or -1 if the gzip header was not as
+   expected.  op is the current operation in progress last written to the extra
+   field.  This assumes that the gzip file has already been opened, with the
+   file descriptor log->fd. */
+local int log_head(struct log *log)
+{
+    int op;
+    unsigned char buf[HEAD + EXTRA];
+
+    if (lseek(log->fd, 0, SEEK_SET) < 0 ||
+        read(log->fd, buf, HEAD + EXTRA) != HEAD + EXTRA ||
+        memcmp(buf, log_gzhead, HEAD)) {
+        return -1;
+    }
+    log->first = PULL8(buf + HEAD);
+    log->last = PULL8(buf + HEAD + 8);
+    log->ccrc = PULL4(buf + HEAD + 16);
+    log->clen = PULL4(buf + HEAD + 20);
+    log->tcrc = PULL4(buf + HEAD + 24);
+    log->tlen = PULL4(buf + HEAD + 28);
+    log->stored = PULL2(buf + HEAD + 32);
+    log->back = 3 + (buf[HEAD + 34] & 7);
+    op = (buf[HEAD + 34] >> 3) & 3;
+    return op;
+}
+
+/* Write over the extra field contents, marking the operation as op.  Use fsync
+   to assure that the device is written to, and in the requested order.  This
+   operation, and only this operation, is assumed to be atomic in order to
+   assure that the log is recoverable in the event of an interruption at any
+   point in the process.  Return -1 if the write to foo.gz failed. */
+local int log_mark(struct log *log, int op)
+{
+    int ret;
+    unsigned char ext[EXTRA];
+
+    PUT8(ext, log->first);
+    PUT8(ext + 8, log->last);
+    PUT4(ext + 16, log->ccrc);
+    PUT4(ext + 20, log->clen);
+    PUT4(ext + 24, log->tcrc);
+    PUT4(ext + 28, log->tlen);
+    PUT2(ext + 32, log->stored);
+    ext[34] = log->back - 3 + (op << 3);
+    fsync(log->fd);
+    ret = lseek(log->fd, HEAD, SEEK_SET) < 0 ||
+          write(log->fd, ext, EXTRA) != EXTRA ? -1 : 0;
+    fsync(log->fd);
+    return ret;
+}
+
+/* Rewrite the last block header bits and subsequent zero bits to get to a byte
+   boundary, setting the last block bit if last is true, and then write the
+   remainder of the stored block header (length and one's complement).  Leave
+   the file pointer after the end of the last stored block data.  Return -1 if
+   there is a read or write failure on the foo.gz file */
+local int log_last(struct log *log, int last)
+{
+    int back, len, mask;
+    unsigned char buf[6];
+
+    /* determine the locations of the bytes and bits to modify */
+    back = log->last == log->first ? log->back : 8;
+    len = back > 8 ? 2 : 1;                 /* bytes back from log->last */
+    mask = 0x80 >> ((back - 1) & 7);        /* mask for block last-bit */
+
+    /* get the byte to modify (one or two back) into buf[0] -- don't need to
+       read the byte if the last-bit is eight bits back, since in that case
+       the entire byte will be modified */
+    buf[0] = 0;
+    if (back != 8 && (lseek(log->fd, log->last - len, SEEK_SET) < 0 ||
+                      read(log->fd, buf, 1) != 1))
+        return -1;
+
+    /* change the last-bit of the last stored block as requested -- note
+       that all bits above the last-bit are set to zero, per the type bits
+       of a stored block being 00 and per the convention that the bits to
+       bring the stream to a byte boundary are also zeros */
+    buf[1] = 0;
+    buf[2 - len] = (*buf & (mask - 1)) + (last ? mask : 0);
+
+    /* write the modified stored block header and lengths, move the file
+       pointer to after the last stored block data */
+    PUT2(buf + 2, log->stored);
+    PUT2(buf + 4, log->stored ^ 0xffff);
+    return lseek(log->fd, log->last - len, SEEK_SET) < 0 ||
+           write(log->fd, buf + 2 - len, len + 4) != len + 4 ||
+           lseek(log->fd, log->stored, SEEK_CUR) < 0 ? -1 : 0;
+}
+
+/* Append len bytes from data to the locked and open log file.  len may be zero
+   if recovering and no .add file was found.  In that case, the previous state
+   of the foo.gz file is restored.  The data is appended uncompressed in
+   deflate stored blocks.  Return -1 if there was an error reading or writing
+   the foo.gz file. */
+local int log_append(struct log *log, unsigned char *data, size_t len)
+{
+    uint put;
+    off_t end;
+    unsigned char buf[8];
+
+    /* set the last block last-bit and length, in case recovering an
+       interrupted append, then position the file pointer to append to the
+       block */
+    if (log_last(log, 1))
+        return -1;
+
+    /* append, adding stored blocks and updating the offset of the last stored
+       block as needed, and update the total crc and length */
+    while (len) {
+        /* append as much as we can to the last block */
+        put = (MAX_STORE << 10) - log->stored;
+        if (put > len)
+            put = (uint)len;
+        if (put) {
+            if (write(log->fd, data, put) != put)
+                return -1;
+            BAIL(1);
+            log->tcrc = crc32(log->tcrc, data, put);
+            log->tlen += put;
+            log->stored += put;
+            data += put;
+            len -= put;
+        }
+
+        /* if we need to, add a new empty stored block */
+        if (len) {
+            /* mark current block as not last */
+            if (log_last(log, 0))
+                return -1;
+
+            /* point to new, empty stored block */
+            log->last += 4 + log->stored + 1;
+            log->stored = 0;
+        }
+
+        /* mark last block as last, update its length */
+        if (log_last(log, 1))
+            return -1;
+        BAIL(2);
+    }
+
+    /* write the new crc and length trailer, and truncate just in case (could
+       be recovering from partial append with a missing foo.add file) */
+    PUT4(buf, log->tcrc);
+    PUT4(buf + 4, log->tlen);
+    if (write(log->fd, buf, 8) != 8 ||
+        (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))
+        return -1;
+
+    /* write the extra field, marking the log file as done, delete .add file */
+    if (log_mark(log, NO_OP))
+        return -1;
+    strcpy(log->end, ".add");
+    unlink(log->path);          /* ignore error, since may not exist */
+    return 0;
+}
+
+/* Replace the foo.dict file with the foo.temp file.  Also delete the foo.add
+   file, since the compress operation may have been interrupted before that was
+   done.  Returns 1 if memory could not be allocated, or -1 if reading or
+   writing foo.gz fails, or if the rename fails for some reason other than
+   foo.temp not existing.  foo.temp not existing is a permitted error, since
+   the replace operation may have been interrupted after the rename is done,
+   but before foo.gz is marked as complete. */
+local int log_replace(struct log *log)
+{
+    int ret;
+    char *dest;
+
+    /* delete foo.add file */
+    strcpy(log->end, ".add");
+    unlink(log->path);         /* ignore error, since may not exist */
+    BAIL(3);
+
+    /* rename foo.name to foo.dict, replacing foo.dict if it exists */
+    strcpy(log->end, ".dict");
+    dest = malloc(strlen(log->path) + 1);
+    if (dest == NULL)
+        return -2;
+    strcpy(dest, log->path);
+    strcpy(log->end, ".temp");
+    ret = rename(log->path, dest);
+    free(dest);
+    if (ret && errno != ENOENT)
+        return -1;
+    BAIL(4);
+
+    /* mark the foo.gz file as done */
+    return log_mark(log, NO_OP);
+}
+
+/* Compress the len bytes at data and append the compressed data to the
+   foo.gz deflate data immediately after the previous compressed data.  This
+   overwrites the previous uncompressed data, which was stored in foo.add
+   and is the data provided in data[0..len-1].  If this operation is
+   interrupted, it picks up at the start of this routine, with the foo.add
+   file read in again.  If there is no data to compress (len == 0), then we
+   simply terminate the foo.gz file after the previously compressed data,
+   appending a final empty stored block and the gzip trailer.  Return -1 if
+   reading or writing the log.gz file failed, or -2 if there was a memory
+   allocation failure. */
+local int log_compress(struct log *log, unsigned char *data, size_t len)
+{
+    int fd;
+    uint got, max;
+    ssize_t dict;
+    off_t end;
+    z_stream strm;
+    unsigned char buf[DICT];
+
+    /* compress and append compressed data */
+    if (len) {
+        /* set up for deflate, allocating memory */
+        strm.zalloc = Z_NULL;
+        strm.zfree = Z_NULL;
+        strm.opaque = Z_NULL;
+        if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8,
+                         Z_DEFAULT_STRATEGY) != Z_OK)
+            return -2;
+
+        /* read in dictionary (last 32K of data that was compressed) */
+        strcpy(log->end, ".dict");
+        fd = open(log->path, O_RDONLY, 0);
+        if (fd >= 0) {
+            dict = read(fd, buf, DICT);
+            close(fd);
+            if (dict < 0) {
+                deflateEnd(&strm);
+                return -1;
+            }
+            if (dict)
+                deflateSetDictionary(&strm, buf, (uint)dict);
+        }
+        log_touch(log);
+
+        /* prime deflate with last bits of previous block, position write
+           pointer to write those bits and overwrite what follows */
+        if (lseek(log->fd, log->first - (log->back > 8 ? 2 : 1),
+                SEEK_SET) < 0 ||
+            read(log->fd, buf, 1) != 1 || lseek(log->fd, -1, SEEK_CUR) < 0) {
+            deflateEnd(&strm);
+            return -1;
+        }
+        deflatePrime(&strm, (8 - log->back) & 7, *buf);
+
+        /* compress, finishing with a partial non-last empty static block */
+        strm.next_in = data;
+        max = (((uint)0 - 1) >> 1) + 1; /* in case int smaller than size_t */
+        do {
+            strm.avail_in = len > max ? max : (uint)len;
+            len -= strm.avail_in;
+            do {
+                strm.avail_out = DICT;
+                strm.next_out = buf;
+                deflate(&strm, len ? Z_NO_FLUSH : Z_PARTIAL_FLUSH);
+                got = DICT - strm.avail_out;
+                if (got && write(log->fd, buf, got) != got) {
+                    deflateEnd(&strm);
+                    return -1;
+                }
+                log_touch(log);
+            } while (strm.avail_out == 0);
+        } while (len);
+        deflateEnd(&strm);
+        BAIL(5);
+
+        /* find start of empty static block -- scanning backwards the first one
+           bit is the second bit of the block, if the last byte is zero, then
+           we know the byte before that has a one in the top bit, since an
+           empty static block is ten bits long */
+        if ((log->first = lseek(log->fd, -1, SEEK_CUR)) < 0 ||
+            read(log->fd, buf, 1) != 1)
+            return -1;
+        log->first++;
+        if (*buf) {
+            log->back = 1;
+            while ((*buf & ((uint)1 << (8 - log->back++))) == 0)
+                ;       /* guaranteed to terminate, since *buf != 0 */
+        }
+        else
+            log->back = 10;
+
+        /* update compressed crc and length */
+        log->ccrc = log->tcrc;
+        log->clen = log->tlen;
+    }
+    else {
+        /* no data to compress -- fix up existing gzip stream */
+        log->tcrc = log->ccrc;
+        log->tlen = log->clen;
+    }
+
+    /* complete and truncate gzip stream */
+    log->last = log->first;
+    log->stored = 0;
+    PUT4(buf, log->tcrc);
+    PUT4(buf + 4, log->tlen);
+    if (log_last(log, 1) || write(log->fd, buf, 8) != 8 ||
+        (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))
+        return -1;
+    BAIL(6);
+
+    /* mark as being in the replace operation */
+    if (log_mark(log, REPLACE_OP))
+        return -1;
+
+    /* execute the replace operation and mark the file as done */
+    return log_replace(log);
+}
+
+/* log a repair record to the .repairs file */
+local void log_log(struct log *log, int op, char *record)
+{
+    time_t now;
+    FILE *rec;
+
+    now = time(NULL);
+    strcpy(log->end, ".repairs");
+    rec = fopen(log->path, "a");
+    if (rec == NULL)
+        return;
+    fprintf(rec, "%.24s %s recovery: %s\n", ctime(&now), op == APPEND_OP ?
+            "append" : (op == COMPRESS_OP ? "compress" : "replace"), record);
+    fclose(rec);
+    return;
+}
+
+/* Recover the interrupted operation op.  First read foo.add for recovering an
+   append or compress operation.  Return -1 if there was an error reading or
+   writing foo.gz or reading an existing foo.add, or -2 if there was a memory
+   allocation failure. */
+local int log_recover(struct log *log, int op)
+{
+    int fd, ret = 0;
+    unsigned char *data = NULL;
+    size_t len = 0;
+    struct stat st;
+
+    /* log recovery */
+    log_log(log, op, "start");
+
+    /* load foo.add file if expected and present */
+    if (op == APPEND_OP || op == COMPRESS_OP) {
+        strcpy(log->end, ".add");
+        if (stat(log->path, &st) == 0 && st.st_size) {
+            len = (size_t)(st.st_size);
+            if (len != st.st_size || (data = malloc(st.st_size)) == NULL) {
+                log_log(log, op, "allocation failure");
+                return -2;
+            }
+            if ((fd = open(log->path, O_RDONLY, 0)) < 0) {
+                log_log(log, op, ".add file read failure");
+                return -1;
+            }
+            ret = read(fd, data, len) != len;
+            close(fd);
+            if (ret) {
+                log_log(log, op, ".add file read failure");
+                return -1;
+            }
+            log_log(log, op, "loaded .add file");
+        }
+        else
+            log_log(log, op, "missing .add file!");
+    }
+
+    /* recover the interrupted operation */
+    switch (op) {
+    case APPEND_OP:
+        ret = log_append(log, data, len);
+        break;
+    case COMPRESS_OP:
+        ret = log_compress(log, data, len);
+        break;
+    case REPLACE_OP:
+        ret = log_replace(log);
+    }
+
+    /* log status */
+    log_log(log, op, ret ? "failure" : "complete");
+
+    /* clean up */
+    if (data != NULL)
+        free(data);
+    return ret;
+}
+
+/* Close the foo.gz file (if open) and release the lock. */
+local void log_close(struct log *log)
+{
+    if (log->fd >= 0)
+        close(log->fd);
+    log->fd = -1;
+    log_unlock(log);
+}
+
+/* Open foo.gz, verify the header, and load the extra field contents, after
+   first creating the foo.lock file to gain exclusive access to the foo.*
+   files.  If foo.gz does not exist or is empty, then write the initial header,
+   extra, and body content of an empty foo.gz log file.  If there is an error
+   creating the lock file due to access restrictions, or an error reading or
+   writing the foo.gz file, or if the foo.gz file is not a proper log file for
+   this object (e.g. not a gzip file or does not contain the expected extra
+   field), then return true.  If there is an error, the lock is released.
+   Otherwise, the lock is left in place. */
+local int log_open(struct log *log)
+{
+    int op;
+
+    /* release open file resource if left over -- can occur if lock lost
+       between gzlog_open() and gzlog_write() */
+    if (log->fd >= 0)
+        close(log->fd);
+    log->fd = -1;
+
+    /* negotiate exclusive access */
+    if (log_lock(log) < 0)
+        return -1;
+
+    /* open the log file, foo.gz */
+    strcpy(log->end, ".gz");
+    log->fd = open(log->path, O_RDWR | O_CREAT, 0644);
+    if (log->fd < 0) {
+        log_close(log);
+        return -1;
+    }
+
+    /* if new, initialize foo.gz with an empty log, delete old dictionary */
+    if (lseek(log->fd, 0, SEEK_END) == 0) {
+        if (write(log->fd, log_gzhead, HEAD) != HEAD ||
+            write(log->fd, log_gzext, EXTRA) != EXTRA ||
+            write(log->fd, log_gzbody, BODY) != BODY) {
+            log_close(log);
+            return -1;
+        }
+        strcpy(log->end, ".dict");
+        unlink(log->path);
+    }
+
+    /* verify log file and load extra field information */
+    if ((op = log_head(log)) < 0) {
+        log_close(log);
+        return -1;
+    }
+
+    /* check for interrupted process and if so, recover */
+    if (op != NO_OP && log_recover(log, op)) {
+        log_close(log);
+        return -1;
+    }
+
+    /* touch the lock file to prevent another process from grabbing it */
+    log_touch(log);
+    return 0;
+}
+
+/* See gzlog.h for the description of the external methods below */
+gzlog *gzlog_open(char *path)
+{
+    size_t n;
+    struct log *log;
+
+    /* check arguments */
+    if (path == NULL || *path == 0)
+        return NULL;
+
+    /* allocate and initialize log structure */
+    log = malloc(sizeof(struct log));
+    if (log == NULL)
+        return NULL;
+    strcpy(log->id, LOGID);
+    log->fd = -1;
+
+    /* save path and end of path for name construction */
+    n = strlen(path);
+    log->path = malloc(n + 9);              /* allow for ".repairs" */
+    if (log->path == NULL) {
+        free(log);
+        return NULL;
+    }
+    strcpy(log->path, path);
+    log->end = log->path + n;
+
+    /* gain exclusive access and verify log file -- may perform a
+       recovery operation if needed */
+    if (log_open(log)) {
+        free(log->path);
+        free(log);
+        return NULL;
+    }
+
+    /* return pointer to log structure */
+    return log;
+}
+
+/* gzlog_compress() return values:
+    0: all good
+   -1: file i/o error (usually access issue)
+   -2: memory allocation failure
+   -3: invalid log pointer argument */
+int gzlog_compress(gzlog *logd)
+{
+    int fd, ret;
+    uint block;
+    size_t len, next;
+    unsigned char *data, buf[5];
+    struct log *log = logd;
+
+    /* check arguments */
+    if (log == NULL || strcmp(log->id, LOGID) || len < 0)
+        return -3;
+
+    /* see if we lost the lock -- if so get it again and reload the extra
+       field information (it probably changed), recover last operation if
+       necessary */
+    if (log_check(log) && log_open(log))
+        return -1;
+
+    /* create space for uncompressed data */
+    len = ((size_t)(log->last - log->first) & ~(((size_t)1 << 10) - 1)) +
+          log->stored;
+    if ((data = malloc(len)) == NULL)
+        return -2;
+
+    /* do statement here is just a cheap trick for error handling */
+    do {
+        /* read in the uncompressed data */
+        if (lseek(log->fd, log->first - 1, SEEK_SET) < 0)
+            break;
+        next = 0;
+        while (next < len) {
+            if (read(log->fd, buf, 5) != 5)
+                break;
+            block = PULL2(buf + 1);
+            if (next + block > len ||
+                read(log->fd, (char *)data + next, block) != block)
+                break;
+            next += block;
+        }
+        if (lseek(log->fd, 0, SEEK_CUR) != log->last + 4 + log->stored)
+            break;
+        log_touch(log);
+
+        /* write the uncompressed data to the .add file */
+        strcpy(log->end, ".add");
+        fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+        if (fd < 0)
+            break;
+        ret = write(fd, data, len) != len;
+        if (ret | close(fd))
+            break;
+        log_touch(log);
+
+        /* write the dictionary for the next compress to the .temp file */
+        strcpy(log->end, ".temp");
+        fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+        if (fd < 0)
+            break;
+        next = DICT > len ? len : DICT;
+        ret = write(fd, (char *)data + len - next, next) != next;
+        if (ret | close(fd))
+            break;
+        log_touch(log);
+
+        /* roll back to compressed data, mark the compress in progress */
+        log->last = log->first;
+        log->stored = 0;
+        if (log_mark(log, COMPRESS_OP))
+            break;
+        BAIL(7);
+
+        /* compress and append the data (clears mark) */
+        ret = log_compress(log, data, len);
+        free(data);
+        return ret;
+    } while (0);
+
+    /* broke out of do above on i/o error */
+    free(data);
+    return -1;
+}
+
+/* gzlog_write() return values:
+    0: all good
+   -1: file i/o error (usually access issue)
+   -2: memory allocation failure
+   -3: invalid log pointer argument */
+int gzlog_write(gzlog *logd, void *data, size_t len)
+{
+    int fd, ret;
+    struct log *log = logd;
+
+    /* check arguments */
+    if (log == NULL || strcmp(log->id, LOGID) || len < 0)
+        return -3;
+    if (data == NULL || len == 0)
+        return 0;
+
+    /* see if we lost the lock -- if so get it again and reload the extra
+       field information (it probably changed), recover last operation if
+       necessary */
+    if (log_check(log) && log_open(log))
+        return -1;
+
+    /* create and write .add file */
+    strcpy(log->end, ".add");
+    fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    if (fd < 0)
+        return -1;
+    ret = write(fd, data, len) != len;
+    if (ret | close(fd))
+        return -1;
+    log_touch(log);
+
+    /* mark log file with append in progress */
+    if (log_mark(log, APPEND_OP))
+        return -1;
+    BAIL(8);
+
+    /* append data (clears mark) */
+    if (log_append(log, data, len))
+        return -1;
+
+    /* check to see if it's time to compress -- if not, then done */
+    if (((log->last - log->first) >> 10) + (log->stored >> 10) < TRIGGER)
+        return 0;
+
+    /* time to compress */
+    return gzlog_compress(log);
+}
+
+/* gzlog_close() return values:
+    0: ok
+   -3: invalid log pointer argument */
+int gzlog_close(gzlog *logd)
+{
+    struct log *log = logd;
+
+    /* check arguments */
+    if (log == NULL || strcmp(log->id, LOGID))
+        return -3;
+
+    /* close the log file and release the lock */
+    log_close(log);
+
+    /* free structure and return */
+    if (log->path != NULL)
+        free(log->path);
+    strcpy(log->id, "bad");
+    free(log);
+    return 0;
+}
diff --git a/8.x/zlib/examples/gzlog.h b/8.x/zlib/examples/gzlog.h
new file mode 100644 (file)
index 0000000..c461426
--- /dev/null
@@ -0,0 +1,89 @@
+/* gzlog.h
+  Copyright (C) 2004, 2008 Mark Adler, all rights reserved
+  version 2.0, 25 Apr 2008
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+/* Version History:
+   1.0  26 Nov 2004  First version
+   2.0  25 Apr 2008  Complete redesign for recovery of interrupted operations
+                     Interface changed slightly in that now path is a prefix
+                     Compression now occurs as needed during gzlog_write()
+                     gzlog_write() now always leaves the log file as valid gzip
+ */
+
+/*
+   The gzlog object allows writing short messages to a gzipped log file,
+   opening the log file locked for small bursts, and then closing it.  The log
+   object works by appending stored (uncompressed) data to the gzip file until
+   1 MB has been accumulated.  At that time, the stored data is compressed, and
+   replaces the uncompressed data in the file.  The log file is truncated to
+   its new size at that time.  After each write operation, the log file is a
+   valid gzip file that can decompressed to recover what was written.
+
+   The gzlog operations can be interupted at any point due to an application or
+   system crash, and the log file will be recovered the next time the log is
+   opened with gzlog_open().
+ */
+
+#ifndef GZLOG_H
+#define GZLOG_H
+
+/* gzlog object type */
+typedef void gzlog;
+
+/* Open a gzlog object, creating the log file if it does not exist.  Return
+   NULL on error.  Note that gzlog_open() could take a while to complete if it
+   has to wait to verify that a lock is stale (possibly for five minutes), or
+   if there is significant contention with other instantiations of this object
+   when locking the resource.  path is the prefix of the file names created by
+   this object.  If path is "foo", then the log file will be "foo.gz", and
+   other auxiliary files will be created and destroyed during the process:
+   "foo.dict" for a compression dictionary, "foo.temp" for a temporary (next)
+   dictionary, "foo.add" for data being added or compressed, "foo.lock" for the
+   lock file, and "foo.repairs" to log recovery operations performed due to
+   interrupted gzlog operations.  A gzlog_open() followed by a gzlog_close()
+   will recover a previously interrupted operation, if any. */
+gzlog *gzlog_open(char *path);
+
+/* Write to a gzlog object.  Return zero on success, -1 if there is a file i/o
+   error on any of the gzlog files (this should not happen if gzlog_open()
+   succeeded, unless the device has run out of space or leftover auxiliary
+   files have permissions or ownership that prevent their use), -2 if there is
+   a memory allocation failure, or -3 if the log argument is invalid (e.g. if
+   it was not created by gzlog_open()).  This function will write data to the
+   file uncompressed, until 1 MB has been accumulated, at which time that data
+   will be compressed.  The log file will be a valid gzip file upon successful
+   return. */
+int gzlog_write(gzlog *log, void *data, size_t len);
+
+/* Force compression of any uncompressed data in the log.  This should be used
+   sparingly, if at all.  The main application would be when a log file will
+   not be appended to again.  If this is used to compress frequently while
+   appending, it will both significantly increase the execution time and
+   reduce the compression ratio.  The return codes are the same as for
+   gzlog_write(). */
+int gzlog_compress(gzlog *log);
+
+/* Close a gzlog object.  Return zero on success, -3 if the log argument is
+   invalid.  The log object is freed, and so cannot be referenced again. */
+int gzlog_close(gzlog *log);
+
+#endif
diff --git a/8.x/zlib/examples/zlib_how.html b/8.x/zlib/examples/zlib_how.html
new file mode 100644 (file)
index 0000000..444ff1c
--- /dev/null
@@ -0,0 +1,545 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+  "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>zlib Usage Example</title>
+<!--  Copyright (c) 2004, 2005 Mark Adler.  -->
+</head>
+<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#00A000">
+<h2 align="center"> zlib Usage Example </h2>
+We often get questions about how the <tt>deflate()</tt> and <tt>inflate()</tt> functions should be used.
+Users wonder when they should provide more input, when they should use more output,
+what to do with a <tt>Z_BUF_ERROR</tt>, how to make sure the process terminates properly, and
+so on.  So for those who have read <tt>zlib.h</tt> (a few times), and
+would like further edification, below is an annotated example in C of simple routines to compress and decompress
+from an input file to an output file using <tt>deflate()</tt> and <tt>inflate()</tt> respectively.  The
+annotations are interspersed between lines of the code.  So please read between the lines.
+We hope this helps explain some of the intricacies of <em>zlib</em>.
+<p>
+Without further adieu, here is the program <a href="zpipe.c"><tt>zpipe.c</tt></a>:
+<pre><b>
+/* zpipe.c: example of proper use of zlib's inflate() and deflate()
+   Not copyrighted -- provided to the public domain
+   Version 1.4  11 December 2005  Mark Adler */
+
+/* Version history:
+   1.0  30 Oct 2004  First version
+   1.1   8 Nov 2004  Add void casting for unused return values
+                     Use switch statement for inflate() return values
+   1.2   9 Nov 2004  Add assertions to document zlib guarantees
+   1.3   6 Apr 2005  Remove incorrect assertion in inf()
+   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions
+                     Avoid some compiler warnings for input and output buffers
+ */
+</b></pre><!-- -->
+We now include the header files for the required definitions.  From
+<tt>stdio.h</tt> we use <tt>fopen()</tt>, <tt>fread()</tt>, <tt>fwrite()</tt>,
+<tt>feof()</tt>, <tt>ferror()</tt>, and <tt>fclose()</tt> for file i/o, and
+<tt>fputs()</tt> for error messages.  From <tt>string.h</tt> we use
+<tt>strcmp()</tt> for command line argument processing.
+From <tt>assert.h</tt> we use the <tt>assert()</tt> macro.
+From <tt>zlib.h</tt>
+we use the basic compression functions <tt>deflateInit()</tt>,
+<tt>deflate()</tt>, and <tt>deflateEnd()</tt>, and the basic decompression
+functions <tt>inflateInit()</tt>, <tt>inflate()</tt>, and
+<tt>inflateEnd()</tt>.
+<pre><b>
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;assert.h&gt;
+#include "zlib.h"
+</b></pre><!-- -->
+This is an ugly hack required to avoid corruption of the input and output data on
+Windows/MS-DOS systems.  Without this, those systems would assume that the input and output
+files are text, and try to convert the end-of-line characters from one standard to
+another.  That would corrupt binary data, and in particular would render the compressed data unusable.
+This sets the input and output to binary which suppresses the end-of-line conversions.
+<tt>SET_BINARY_MODE()</tt> will be used later on <tt>stdin</tt> and <tt>stdout</tt>, at the beginning of <tt>main()</tt>.
+<pre><b>
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include &lt;fcntl.h&gt;
+#  include &lt;io.h&gt;
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+</b></pre><!-- -->
+<tt>CHUNK</tt> is simply the buffer size for feeding data to and pulling data
+from the <em>zlib</em> routines.  Larger buffer sizes would be more efficient,
+especially for <tt>inflate()</tt>.  If the memory is available, buffers sizes
+on the order of 128K or 256K bytes should be used.
+<pre><b>
+#define CHUNK 16384
+</b></pre><!-- -->
+The <tt>def()</tt> routine compresses data from an input file to an output file.  The output data
+will be in the <em>zlib</em> format, which is different from the <em>gzip</em> or <em>zip</em>
+formats.  The <em>zlib</em> format has a very small header of only two bytes to identify it as
+a <em>zlib</em> stream and to provide decoding information, and a four-byte trailer with a fast
+check value to verify the integrity of the uncompressed data after decoding.
+<pre><b>
+/* Compress from file source to file dest until EOF on source.
+   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_STREAM_ERROR if an invalid compression
+   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
+   version of the library linked do not match, or Z_ERRNO if there is
+   an error reading or writing the files. */
+int def(FILE *source, FILE *dest, int level)
+{
+</b></pre>
+Here are the local variables for <tt>def()</tt>.  <tt>ret</tt> will be used for <em>zlib</em>
+return codes.  <tt>flush</tt> will keep track of the current flushing state for <tt>deflate()</tt>,
+which is either no flushing, or flush to completion after the end of the input file is reached.
+<tt>have</tt> is the amount of data returned from <tt>deflate()</tt>.  The <tt>strm</tt> structure
+is used to pass information to and from the <em>zlib</em> routines, and to maintain the
+<tt>deflate()</tt> state.  <tt>in</tt> and <tt>out</tt> are the input and output buffers for
+<tt>deflate()</tt>.
+<pre><b>
+    int ret, flush;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+</b></pre><!-- -->
+The first thing we do is to initialize the <em>zlib</em> state for compression using
+<tt>deflateInit()</tt>.  This must be done before the first use of <tt>deflate()</tt>.
+The <tt>zalloc</tt>, <tt>zfree</tt>, and <tt>opaque</tt> fields in the <tt>strm</tt>
+structure must be initialized before calling <tt>deflateInit()</tt>.  Here they are
+set to the <em>zlib</em> constant <tt>Z_NULL</tt> to request that <em>zlib</em> use
+the default memory allocation routines.  An application may also choose to provide
+custom memory allocation routines here.  <tt>deflateInit()</tt> will allocate on the
+order of 256K bytes for the internal state.
+(See <a href="zlib_tech.html"><em>zlib Technical Details</em></a>.)
+<p>
+<tt>deflateInit()</tt> is called with a pointer to the structure to be initialized and
+the compression level, which is an integer in the range of -1 to 9.  Lower compression
+levels result in faster execution, but less compression.  Higher levels result in
+greater compression, but slower execution.  The <em>zlib</em> constant Z_DEFAULT_COMPRESSION,
+equal to -1,
+provides a good compromise between compression and speed and is equivalent to level 6.
+Level 0 actually does no compression at all, and in fact expands the data slightly to produce
+the <em>zlib</em> format (it is not a byte-for-byte copy of the input).
+More advanced applications of <em>zlib</em>
+may use <tt>deflateInit2()</tt> here instead.  Such an application may want to reduce how
+much memory will be used, at some price in compression.  Or it may need to request a
+<em>gzip</em> header and trailer instead of a <em>zlib</em> header and trailer, or raw
+encoding with no header or trailer at all.
+<p>
+We must check the return value of <tt>deflateInit()</tt> against the <em>zlib</em> constant
+<tt>Z_OK</tt> to make sure that it was able to
+allocate memory for the internal state, and that the provided arguments were valid.
+<tt>deflateInit()</tt> will also check that the version of <em>zlib</em> that the <tt>zlib.h</tt>
+file came from matches the version of <em>zlib</em> actually linked with the program.  This
+is especially important for environments in which <em>zlib</em> is a shared library.
+<p>
+Note that an application can initialize multiple, independent <em>zlib</em> streams, which can
+operate in parallel.  The state information maintained in the structure allows the <em>zlib</em>
+routines to be reentrant.
+<pre><b>
+    /* allocate deflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = deflateInit(&amp;strm, level);
+    if (ret != Z_OK)
+        return ret;
+</b></pre><!-- -->
+With the pleasantries out of the way, now we can get down to business.  The outer <tt>do</tt>-loop
+reads all of the input file and exits at the bottom of the loop once end-of-file is reached.
+This loop contains the only call of <tt>deflate()</tt>.  So we must make sure that all of the
+input data has been processed and that all of the output data has been generated and consumed
+before we fall out of the loop at the bottom.
+<pre><b>
+    /* compress until end of file */
+    do {
+</b></pre>
+We start off by reading data from the input file.  The number of bytes read is put directly
+into <tt>avail_in</tt>, and a pointer to those bytes is put into <tt>next_in</tt>.  We also
+check to see if end-of-file on the input has been reached.  If we are at the end of file, then <tt>flush</tt> is set to the
+<em>zlib</em> constant <tt>Z_FINISH</tt>, which is later passed to <tt>deflate()</tt> to
+indicate that this is the last chunk of input data to compress.  We need to use <tt>feof()</tt>
+to check for end-of-file as opposed to seeing if fewer than <tt>CHUNK</tt> bytes have been read.  The
+reason is that if the input file length is an exact multiple of <tt>CHUNK</tt>, we will miss
+the fact that we got to the end-of-file, and not know to tell <tt>deflate()</tt> to finish
+up the compressed stream.  If we are not yet at the end of the input, then the <em>zlib</em>
+constant <tt>Z_NO_FLUSH</tt> will be passed to <tt>deflate</tt> to indicate that we are still
+in the middle of the uncompressed data.
+<p>
+If there is an error in reading from the input file, the process is aborted with
+<tt>deflateEnd()</tt> being called to free the allocated <em>zlib</em> state before returning
+the error.  We wouldn't want a memory leak, now would we?  <tt>deflateEnd()</tt> can be called
+at any time after the state has been initialized.  Once that's done, <tt>deflateInit()</tt> (or
+<tt>deflateInit2()</tt>) would have to be called to start a new compression process.  There is
+no point here in checking the <tt>deflateEnd()</tt> return code.  The deallocation can't fail.
+<pre><b>
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)deflateEnd(&amp;strm);
+            return Z_ERRNO;
+        }
+        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+        strm.next_in = in;
+</b></pre><!-- -->
+The inner <tt>do</tt>-loop passes our chunk of input data to <tt>deflate()</tt>, and then
+keeps calling <tt>deflate()</tt> until it is done producing output.  Once there is no more
+new output, <tt>deflate()</tt> is guaranteed to have consumed all of the input, i.e.,
+<tt>avail_in</tt> will be zero.
+<pre><b>
+        /* run deflate() on input until output buffer not full, finish
+           compression if all of source has been read in */
+        do {
+</b></pre>
+Output space is provided to <tt>deflate()</tt> by setting <tt>avail_out</tt> to the number
+of available output bytes and <tt>next_out</tt> to a pointer to that space.
+<pre><b>
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+</b></pre>
+Now we call the compression engine itself, <tt>deflate()</tt>.  It takes as many of the
+<tt>avail_in</tt> bytes at <tt>next_in</tt> as it can process, and writes as many as
+<tt>avail_out</tt> bytes to <tt>next_out</tt>.  Those counters and pointers are then
+updated past the input data consumed and the output data written.  It is the amount of
+output space available that may limit how much input is consumed.
+Hence the inner loop to make sure that
+all of the input is consumed by providing more output space each time.  Since <tt>avail_in</tt>
+and <tt>next_in</tt> are updated by <tt>deflate()</tt>, we don't have to mess with those
+between <tt>deflate()</tt> calls until it's all used up.
+<p>
+The parameters to <tt>deflate()</tt> are a pointer to the <tt>strm</tt> structure containing
+the input and output information and the internal compression engine state, and a parameter
+indicating whether and how to flush data to the output.  Normally <tt>deflate</tt> will consume
+several K bytes of input data before producing any output (except for the header), in order
+to accumulate statistics on the data for optimum compression.  It will then put out a burst of
+compressed data, and proceed to consume more input before the next burst.  Eventually,
+<tt>deflate()</tt>
+must be told to terminate the stream, complete the compression with provided input data, and
+write out the trailer check value.  <tt>deflate()</tt> will continue to compress normally as long
+as the flush parameter is <tt>Z_NO_FLUSH</tt>.  Once the <tt>Z_FINISH</tt> parameter is provided,
+<tt>deflate()</tt> will begin to complete the compressed output stream.  However depending on how
+much output space is provided, <tt>deflate()</tt> may have to be called several times until it
+has provided the complete compressed stream, even after it has consumed all of the input.  The flush
+parameter must continue to be <tt>Z_FINISH</tt> for those subsequent calls.
+<p>
+There are other values of the flush parameter that are used in more advanced applications.  You can
+force <tt>deflate()</tt> to produce a burst of output that encodes all of the input data provided
+so far, even if it wouldn't have otherwise, for example to control data latency on a link with
+compressed data.  You can also ask that <tt>deflate()</tt> do that as well as erase any history up to
+that point so that what follows can be decompressed independently, for example for random access
+applications.  Both requests will degrade compression by an amount depending on how often such
+requests are made.
+<p>
+<tt>deflate()</tt> has a return value that can indicate errors, yet we do not check it here.  Why
+not?  Well, it turns out that <tt>deflate()</tt> can do no wrong here.  Let's go through
+<tt>deflate()</tt>'s return values and dispense with them one by one.  The possible values are
+<tt>Z_OK</tt>, <tt>Z_STREAM_END</tt>, <tt>Z_STREAM_ERROR</tt>, or <tt>Z_BUF_ERROR</tt>.  <tt>Z_OK</tt>
+is, well, ok.  <tt>Z_STREAM_END</tt> is also ok and will be returned for the last call of
+<tt>deflate()</tt>.  This is already guaranteed by calling <tt>deflate()</tt> with <tt>Z_FINISH</tt>
+until it has no more output.  <tt>Z_STREAM_ERROR</tt> is only possible if the stream is not
+initialized properly, but we did initialize it properly.  There is no harm in checking for
+<tt>Z_STREAM_ERROR</tt> here, for example to check for the possibility that some
+other part of the application inadvertently clobbered the memory containing the <em>zlib</em> state.
+<tt>Z_BUF_ERROR</tt> will be explained further below, but
+suffice it to say that this is simply an indication that <tt>deflate()</tt> could not consume
+more input or produce more output.  <tt>deflate()</tt> can be called again with more output space
+or more available input, which it will be in this code.
+<pre><b>
+            ret = deflate(&amp;strm, flush);    /* no bad return value */
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+</b></pre>
+Now we compute how much output <tt>deflate()</tt> provided on the last call, which is the
+difference between how much space was provided before the call, and how much output space
+is still available after the call.  Then that data, if any, is written to the output file.
+We can then reuse the output buffer for the next call of <tt>deflate()</tt>.  Again if there
+is a file i/o error, we call <tt>deflateEnd()</tt> before returning to avoid a memory leak.
+<pre><b>
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)deflateEnd(&amp;strm);
+                return Z_ERRNO;
+            }
+</b></pre>
+The inner <tt>do</tt>-loop is repeated until the last <tt>deflate()</tt> call fails to fill the
+provided output buffer.  Then we know that <tt>deflate()</tt> has done as much as it can with
+the provided input, and that all of that input has been consumed.  We can then fall out of this
+loop and reuse the input buffer.
+<p>
+The way we tell that <tt>deflate()</tt> has no more output is by seeing that it did not fill
+the output buffer, leaving <tt>avail_out</tt> greater than zero.  However suppose that
+<tt>deflate()</tt> has no more output, but just so happened to exactly fill the output buffer!
+<tt>avail_out</tt> is zero, and we can't tell that <tt>deflate()</tt> has done all it can.
+As far as we know, <tt>deflate()</tt>
+has more output for us.  So we call it again.  But now <tt>deflate()</tt> produces no output
+at all, and <tt>avail_out</tt> remains unchanged as <tt>CHUNK</tt>.  That <tt>deflate()</tt> call
+wasn't able to do anything, either consume input or produce output, and so it returns
+<tt>Z_BUF_ERROR</tt>.  (See, I told you I'd cover this later.)  However this is not a problem at
+all.  Now we finally have the desired indication that <tt>deflate()</tt> is really done,
+and so we drop out of the inner loop to provide more input to <tt>deflate()</tt>.
+<p>
+With <tt>flush</tt> set to <tt>Z_FINISH</tt>, this final set of <tt>deflate()</tt> calls will
+complete the output stream.  Once that is done, subsequent calls of <tt>deflate()</tt> would return
+<tt>Z_STREAM_ERROR</tt> if the flush parameter is not <tt>Z_FINISH</tt>, and do no more processing
+until the state is reinitialized.
+<p>
+Some applications of <em>zlib</em> have two loops that call <tt>deflate()</tt>
+instead of the single inner loop we have here.  The first loop would call
+without flushing and feed all of the data to <tt>deflate()</tt>.  The second loop would call
+<tt>deflate()</tt> with no more
+data and the <tt>Z_FINISH</tt> parameter to complete the process.  As you can see from this
+example, that can be avoided by simply keeping track of the current flush state.
+<pre><b>
+        } while (strm.avail_out == 0);
+        assert(strm.avail_in == 0);     /* all input will be used */
+</b></pre><!-- -->
+Now we check to see if we have already processed all of the input file.  That information was
+saved in the <tt>flush</tt> variable, so we see if that was set to <tt>Z_FINISH</tt>.  If so,
+then we're done and we fall out of the outer loop.  We're guaranteed to get <tt>Z_STREAM_END</tt>
+from the last <tt>deflate()</tt> call, since we ran it until the last chunk of input was
+consumed and all of the output was generated.
+<pre><b>
+        /* done when last data in file processed */
+    } while (flush != Z_FINISH);
+    assert(ret == Z_STREAM_END);        /* stream will be complete */
+</b></pre><!-- -->
+The process is complete, but we still need to deallocate the state to avoid a memory leak
+(or rather more like a memory hemorrhage if you didn't do this).  Then
+finally we can return with a happy return value.
+<pre><b>
+    /* clean up and return */
+    (void)deflateEnd(&amp;strm);
+    return Z_OK;
+}
+</b></pre><!-- -->
+Now we do the same thing for decompression in the <tt>inf()</tt> routine. <tt>inf()</tt>
+decompresses what is hopefully a valid <em>zlib</em> stream from the input file and writes the
+uncompressed data to the output file.  Much of the discussion above for <tt>def()</tt>
+applies to <tt>inf()</tt> as well, so the discussion here will focus on the differences between
+the two.
+<pre><b>
+/* Decompress from file source to file dest until stream ends or EOF.
+   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_DATA_ERROR if the deflate data is
+   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
+   the version of the library linked do not match, or Z_ERRNO if there
+   is an error reading or writing the files. */
+int inf(FILE *source, FILE *dest)
+{
+</b></pre>
+The local variables have the same functionality as they do for <tt>def()</tt>.  The
+only difference is that there is no <tt>flush</tt> variable, since <tt>inflate()</tt>
+can tell from the <em>zlib</em> stream itself when the stream is complete.
+<pre><b>
+    int ret;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+</b></pre><!-- -->
+The initialization of the state is the same, except that there is no compression level,
+of course, and two more elements of the structure are initialized.  <tt>avail_in</tt>
+and <tt>next_in</tt> must be initialized before calling <tt>inflateInit()</tt>.  This
+is because the application has the option to provide the start of the zlib stream in
+order for <tt>inflateInit()</tt> to have access to information about the compression
+method to aid in memory allocation.  In the current implementation of <em>zlib</em>
+(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of
+<tt>inflate()</tt> anyway.  However those fields must be initialized since later versions
+of <em>zlib</em> that provide more compression methods may take advantage of this interface.
+In any case, no decompression is performed by <tt>inflateInit()</tt>, so the
+<tt>avail_out</tt> and <tt>next_out</tt> fields do not need to be initialized before calling.
+<p>
+Here <tt>avail_in</tt> is set to zero and <tt>next_in</tt> is set to <tt>Z_NULL</tt> to
+indicate that no input data is being provided.
+<pre><b>
+    /* allocate inflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&amp;strm);
+    if (ret != Z_OK)
+        return ret;
+</b></pre><!-- -->
+The outer <tt>do</tt>-loop decompresses input until <tt>inflate()</tt> indicates
+that it has reached the end of the compressed data and has produced all of the uncompressed
+output.  This is in contrast to <tt>def()</tt> which processes all of the input file.
+If end-of-file is reached before the compressed data self-terminates, then the compressed
+data is incomplete and an error is returned.
+<pre><b>
+    /* decompress until deflate stream ends or end of file */
+    do {
+</b></pre>
+We read input data and set the <tt>strm</tt> structure accordingly.  If we've reached the
+end of the input file, then we leave the outer loop and report an error, since the
+compressed data is incomplete.  Note that we may read more data than is eventually consumed
+by <tt>inflate()</tt>, if the input file continues past the <em>zlib</em> stream.
+For applications where <em>zlib</em> streams are embedded in other data, this routine would
+need to be modified to return the unused data, or at least indicate how much of the input
+data was not used, so the application would know where to pick up after the <em>zlib</em> stream.
+<pre><b>
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)inflateEnd(&amp;strm);
+            return Z_ERRNO;
+        }
+        if (strm.avail_in == 0)
+            break;
+        strm.next_in = in;
+</b></pre><!-- -->
+The inner <tt>do</tt>-loop has the same function it did in <tt>def()</tt>, which is to
+keep calling <tt>inflate()</tt> until has generated all of the output it can with the
+provided input.
+<pre><b>
+        /* run inflate() on input until output buffer not full */
+        do {
+</b></pre>
+Just like in <tt>def()</tt>, the same output space is provided for each call of <tt>inflate()</tt>.
+<pre><b>
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+</b></pre>
+Now we run the decompression engine itself.  There is no need to adjust the flush parameter, since
+the <em>zlib</em> format is self-terminating. The main difference here is that there are
+return values that we need to pay attention to.  <tt>Z_DATA_ERROR</tt>
+indicates that <tt>inflate()</tt> detected an error in the <em>zlib</em> compressed data format,
+which means that either the data is not a <em>zlib</em> stream to begin with, or that the data was
+corrupted somewhere along the way since it was compressed.  The other error to be processed is
+<tt>Z_MEM_ERROR</tt>, which can occur since memory allocation is deferred until <tt>inflate()</tt>
+needs it, unlike <tt>deflate()</tt>, whose memory is allocated at the start by <tt>deflateInit()</tt>.
+<p>
+Advanced applications may use
+<tt>deflateSetDictionary()</tt> to prime <tt>deflate()</tt> with a set of likely data to improve the
+first 32K or so of compression.  This is noted in the <em>zlib</em> header, so <tt>inflate()</tt>
+requests that that dictionary be provided before it can start to decompress.  Without the dictionary,
+correct decompression is not possible.  For this routine, we have no idea what the dictionary is,
+so the <tt>Z_NEED_DICT</tt> indication is converted to a <tt>Z_DATA_ERROR</tt>.
+<p>
+<tt>inflate()</tt> can also return <tt>Z_STREAM_ERROR</tt>, which should not be possible here,
+but could be checked for as noted above for <tt>def()</tt>.  <tt>Z_BUF_ERROR</tt> does not need to be
+checked for here, for the same reasons noted for <tt>def()</tt>.  <tt>Z_STREAM_END</tt> will be
+checked for later.
+<pre><b>
+            ret = inflate(&amp;strm, Z_NO_FLUSH);
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            switch (ret) {
+            case Z_NEED_DICT:
+                ret = Z_DATA_ERROR;     /* and fall through */
+            case Z_DATA_ERROR:
+            case Z_MEM_ERROR:
+                (void)inflateEnd(&amp;strm);
+                return ret;
+            }
+</b></pre>
+The output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()</tt>.
+<pre><b>
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)inflateEnd(&amp;strm);
+                return Z_ERRNO;
+            }
+</b></pre>
+The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated
+by not filling the output buffer, just as for <tt>deflate()</tt>.  In this case, we cannot
+assert that <tt>strm.avail_in</tt> will be zero, since the deflate stream may end before the file
+does.
+<pre><b>
+        } while (strm.avail_out == 0);
+</b></pre><!-- -->
+The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the
+end of the input <em>zlib</em> stream, has completed the decompression and integrity
+check, and has provided all of the output.  This is indicated by the <tt>inflate()</tt>
+return value <tt>Z_STREAM_END</tt>.  The inner loop is guaranteed to leave <tt>ret</tt>
+equal to <tt>Z_STREAM_END</tt> if the last chunk of the input file read contained the end
+of the <em>zlib</em> stream.  So if the return value is not <tt>Z_STREAM_END</tt>, the
+loop continues to read more input.
+<pre><b>
+        /* done when inflate() says it's done */
+    } while (ret != Z_STREAM_END);
+</b></pre><!-- -->
+At this point, decompression successfully completed, or we broke out of the loop due to no
+more data being available from the input file.  If the last <tt>inflate()</tt> return value
+is not <tt>Z_STREAM_END</tt>, then the <em>zlib</em> stream was incomplete and a data error
+is returned.  Otherwise, we return with a happy return value.  Of course, <tt>inflateEnd()</tt>
+is called first to avoid a memory leak.
+<pre><b>
+    /* clean up and return */
+    (void)inflateEnd(&amp;strm);
+    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+</b></pre><!-- -->
+That ends the routines that directly use <em>zlib</em>.  The following routines make this
+a command-line program by running data through the above routines from <tt>stdin</tt> to
+<tt>stdout</tt>, and handling any errors reported by <tt>def()</tt> or <tt>inf()</tt>.
+<p>
+<tt>zerr()</tt> is used to interpret the possible error codes from <tt>def()</tt>
+and <tt>inf()</tt>, as detailed in their comments above, and print out an error message.
+Note that these are only a subset of the possible return values from <tt>deflate()</tt>
+and <tt>inflate()</tt>.
+<pre><b>
+/* report a zlib or i/o error */
+void zerr(int ret)
+{
+    fputs("zpipe: ", stderr);
+    switch (ret) {
+    case Z_ERRNO:
+        if (ferror(stdin))
+            fputs("error reading stdin\n", stderr);
+        if (ferror(stdout))
+            fputs("error writing stdout\n", stderr);
+        break;
+    case Z_STREAM_ERROR:
+        fputs("invalid compression level\n", stderr);
+        break;
+    case Z_DATA_ERROR:
+        fputs("invalid or incomplete deflate data\n", stderr);
+        break;
+    case Z_MEM_ERROR:
+        fputs("out of memory\n", stderr);
+        break;
+    case Z_VERSION_ERROR:
+        fputs("zlib version mismatch!\n", stderr);
+    }
+}
+</b></pre><!-- -->
+Here is the <tt>main()</tt> routine used to test <tt>def()</tt> and <tt>inf()</tt>.  The
+<tt>zpipe</tt> command is simply a compression pipe from <tt>stdin</tt> to <tt>stdout</tt>, if
+no arguments are given, or it is a decompression pipe if <tt>zpipe -d</tt> is used.  If any other
+arguments are provided, no compression or decompression is performed.  Instead a usage
+message is displayed.  Examples are <tt>zpipe < foo.txt > foo.txt.z</tt> to compress, and
+<tt>zpipe -d < foo.txt.z > foo.txt</tt> to decompress.
+<pre><b>
+/* compress or decompress from stdin to stdout */
+int main(int argc, char **argv)
+{
+    int ret;
+
+    /* avoid end-of-line conversions */
+    SET_BINARY_MODE(stdin);
+    SET_BINARY_MODE(stdout);
+
+    /* do compression if no arguments */
+    if (argc == 1) {
+        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* do decompression if -d specified */
+    else if (argc == 2 &amp;&amp; strcmp(argv[1], "-d") == 0) {
+        ret = inf(stdin, stdout);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* otherwise, report usage */
+    else {
+        fputs("zpipe usage: zpipe [-d] &lt; source &gt; dest\n", stderr);
+        return 1;
+    }
+}
+</b></pre>
+<hr>
+<i>Copyright (c) 2004, 2005 by Mark Adler<br>Last modified 11 December 2005</i>
+</body>
+</html>
diff --git a/8.x/zlib/examples/zpipe.c b/8.x/zlib/examples/zpipe.c
new file mode 100644 (file)
index 0000000..83535d1
--- /dev/null
@@ -0,0 +1,205 @@
+/* zpipe.c: example of proper use of zlib's inflate() and deflate()
+   Not copyrighted -- provided to the public domain
+   Version 1.4  11 December 2005  Mark Adler */
+
+/* Version history:
+   1.0  30 Oct 2004  First version
+   1.1   8 Nov 2004  Add void casting for unused return values
+                     Use switch statement for inflate() return values
+   1.2   9 Nov 2004  Add assertions to document zlib guarantees
+   1.3   6 Apr 2005  Remove incorrect assertion in inf()
+   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions
+                     Avoid some compiler warnings for input and output buffers
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#define CHUNK 16384
+
+/* Compress from file source to file dest until EOF on source.
+   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_STREAM_ERROR if an invalid compression
+   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
+   version of the library linked do not match, or Z_ERRNO if there is
+   an error reading or writing the files. */
+int def(FILE *source, FILE *dest, int level)
+{
+    int ret, flush;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+    /* allocate deflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = deflateInit(&strm, level);
+    if (ret != Z_OK)
+        return ret;
+
+    /* compress until end of file */
+    do {
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)deflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+        strm.next_in = in;
+
+        /* run deflate() on input until output buffer not full, finish
+           compression if all of source has been read in */
+        do {
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+            ret = deflate(&strm, flush);    /* no bad return value */
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)deflateEnd(&strm);
+                return Z_ERRNO;
+            }
+        } while (strm.avail_out == 0);
+        assert(strm.avail_in == 0);     /* all input will be used */
+
+        /* done when last data in file processed */
+    } while (flush != Z_FINISH);
+    assert(ret == Z_STREAM_END);        /* stream will be complete */
+
+    /* clean up and return */
+    (void)deflateEnd(&strm);
+    return Z_OK;
+}
+
+/* Decompress from file source to file dest until stream ends or EOF.
+   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_DATA_ERROR if the deflate data is
+   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
+   the version of the library linked do not match, or Z_ERRNO if there
+   is an error reading or writing the files. */
+int inf(FILE *source, FILE *dest)
+{
+    int ret;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+    /* allocate inflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);
+    if (ret != Z_OK)
+        return ret;
+
+    /* decompress until deflate stream ends or end of file */
+    do {
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)inflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        if (strm.avail_in == 0)
+            break;
+        strm.next_in = in;
+
+        /* run inflate() on input until output buffer not full */
+        do {
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+            ret = inflate(&strm, Z_NO_FLUSH);
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            switch (ret) {
+            case Z_NEED_DICT:
+                ret = Z_DATA_ERROR;     /* and fall through */
+            case Z_DATA_ERROR:
+            case Z_MEM_ERROR:
+                (void)inflateEnd(&strm);
+                return ret;
+            }
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)inflateEnd(&strm);
+                return Z_ERRNO;
+            }
+        } while (strm.avail_out == 0);
+
+        /* done when inflate() says it's done */
+    } while (ret != Z_STREAM_END);
+
+    /* clean up and return */
+    (void)inflateEnd(&strm);
+    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
+/* report a zlib or i/o error */
+void zerr(int ret)
+{
+    fputs("zpipe: ", stderr);
+    switch (ret) {
+    case Z_ERRNO:
+        if (ferror(stdin))
+            fputs("error reading stdin\n", stderr);
+        if (ferror(stdout))
+            fputs("error writing stdout\n", stderr);
+        break;
+    case Z_STREAM_ERROR:
+        fputs("invalid compression level\n", stderr);
+        break;
+    case Z_DATA_ERROR:
+        fputs("invalid or incomplete deflate data\n", stderr);
+        break;
+    case Z_MEM_ERROR:
+        fputs("out of memory\n", stderr);
+        break;
+    case Z_VERSION_ERROR:
+        fputs("zlib version mismatch!\n", stderr);
+    }
+}
+
+/* compress or decompress from stdin to stdout */
+int main(int argc, char **argv)
+{
+    int ret;
+
+    /* avoid end-of-line conversions */
+    SET_BINARY_MODE(stdin);
+    SET_BINARY_MODE(stdout);
+
+    /* do compression if no arguments */
+    if (argc == 1) {
+        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* do decompression if -d specified */
+    else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
+        ret = inf(stdin, stdout);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* otherwise, report usage */
+    else {
+        fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
+        return 1;
+    }
+}
diff --git a/8.x/zlib/examples/zran.c b/8.x/zlib/examples/zran.c
new file mode 100644 (file)
index 0000000..617a130
--- /dev/null
@@ -0,0 +1,404 @@
+/* zran.c -- example of zlib/gzip stream indexing and random access
+ * Copyright (C) 2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+   Version 1.0  29 May 2005  Mark Adler */
+
+/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary()
+   for random access of a compressed file.  A file containing a zlib or gzip
+   stream is provided on the command line.  The compressed stream is decoded in
+   its entirety, and an index built with access points about every SPAN bytes
+   in the uncompressed output.  The compressed file is left open, and can then
+   be read randomly, having to decompress on the average SPAN/2 uncompressed
+   bytes before getting to the desired block of data.
+
+   An access point can be created at the start of any deflate block, by saving
+   the starting file offset and bit of that block, and the 32K bytes of
+   uncompressed data that precede that block.  Also the uncompressed offset of
+   that block is saved to provide a referece for locating a desired starting
+   point in the uncompressed stream.  build_index() works by decompressing the
+   input zlib or gzip stream a block at a time, and at the end of each block
+   deciding if enough uncompressed data has gone by to justify the creation of
+   a new access point.  If so, that point is saved in a data structure that
+   grows as needed to accommodate the points.
+
+   To use the index, an offset in the uncompressed data is provided, for which
+   the latest accees point at or preceding that offset is located in the index.
+   The input file is positioned to the specified location in the index, and if
+   necessary the first few bits of the compressed data is read from the file.
+   inflate is initialized with those bits and the 32K of uncompressed data, and
+   the decompression then proceeds until the desired offset in the file is
+   reached.  Then the decompression continues to read the desired uncompressed
+   data from the file.
+
+   Another approach would be to generate the index on demand.  In that case,
+   requests for random access reads from the compressed data would try to use
+   the index, but if a read far enough past the end of the index is required,
+   then further index entries would be generated and added.
+
+   There is some fair bit of overhead to starting inflation for the random
+   access, mainly copying the 32K byte dictionary.  So if small pieces of the
+   file are being accessed, it would make sense to implement a cache to hold
+   some lookahead and avoid many calls to extract() for small lengths.
+
+   Another way to build an index would be to use inflateCopy().  That would
+   not be constrained to have access points at block boundaries, but requires
+   more memory per access point, and also cannot be saved to file due to the
+   use of pointers in the state.  The approach here allows for storage of the
+   index in a file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+
+#define local static
+
+#define SPAN 1048576L       /* desired distance between access points */
+#define WINSIZE 32768U      /* sliding window size */
+#define CHUNK 16384         /* file input buffer size */
+
+/* access point entry */
+struct point {
+    off_t out;          /* corresponding offset in uncompressed data */
+    off_t in;           /* offset in input file of first full byte */
+    int bits;           /* number of bits (1-7) from byte at in - 1, or 0 */
+    unsigned char window[WINSIZE];  /* preceding 32K of uncompressed data */
+};
+
+/* access point list */
+struct access {
+    int have;           /* number of list entries filled in */
+    int size;           /* number of list entries allocated */
+    struct point *list; /* allocated list */
+};
+
+/* Deallocate an index built by build_index() */
+local void free_index(struct access *index)
+{
+    if (index != NULL) {
+        free(index->list);
+        free(index);
+    }
+}
+
+/* Add an entry to the access point list.  If out of memory, deallocate the
+   existing list and return NULL. */
+local struct access *addpoint(struct access *index, int bits,
+    off_t in, off_t out, unsigned left, unsigned char *window)
+{
+    struct point *next;
+
+    /* if list is empty, create it (start with eight points) */
+    if (index == NULL) {
+        index = malloc(sizeof(struct access));
+        if (index == NULL) return NULL;
+        index->list = malloc(sizeof(struct point) << 3);
+        if (index->list == NULL) {
+            free(index);
+            return NULL;
+        }
+        index->size = 8;
+        index->have = 0;
+    }
+
+    /* if list is full, make it bigger */
+    else if (index->have == index->size) {
+        index->size <<= 1;
+        next = realloc(index->list, sizeof(struct point) * index->size);
+        if (next == NULL) {
+            free_index(index);
+            return NULL;
+        }
+        index->list = next;
+    }
+
+    /* fill in entry and increment how many we have */
+    next = index->list + index->have;
+    next->bits = bits;
+    next->in = in;
+    next->out = out;
+    if (left)
+        memcpy(next->window, window + WINSIZE - left, left);
+    if (left < WINSIZE)
+        memcpy(next->window + left, window, WINSIZE - left);
+    index->have++;
+
+    /* return list, possibly reallocated */
+    return index;
+}
+
+/* Make one entire pass through the compressed stream and build an index, with
+   access points about every span bytes of uncompressed output -- span is
+   chosen to balance the speed of random access against the memory requirements
+   of the list, about 32K bytes per access point.  Note that data after the end
+   of the first zlib or gzip stream in the file is ignored.  build_index()
+   returns the number of access points on success (>= 1), Z_MEM_ERROR for out
+   of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
+   file read error.  On success, *built points to the resulting index. */
+local int build_index(FILE *in, off_t span, struct access **built)
+{
+    int ret;
+    off_t totin, totout;        /* our own total counters to avoid 4GB limit */
+    off_t last;                 /* totout value of last access point */
+    struct access *index;       /* access points being generated */
+    z_stream strm;
+    unsigned char input[CHUNK];
+    unsigned char window[WINSIZE];
+
+    /* initialize inflate */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, 47);      /* automatic zlib or gzip decoding */
+    if (ret != Z_OK)
+        return ret;
+
+    /* inflate the input, maintain a sliding window, and build an index -- this
+       also validates the integrity of the compressed data using the check
+       information at the end of the gzip or zlib stream */
+    totin = totout = last = 0;
+    index = NULL;               /* will be allocated by first addpoint() */
+    strm.avail_out = 0;
+    do {
+        /* get some compressed data from input file */
+        strm.avail_in = fread(input, 1, CHUNK, in);
+        if (ferror(in)) {
+            ret = Z_ERRNO;
+            goto build_index_error;
+        }
+        if (strm.avail_in == 0) {
+            ret = Z_DATA_ERROR;
+            goto build_index_error;
+        }
+        strm.next_in = input;
+
+        /* process all of that, or until end of stream */
+        do {
+            /* reset sliding window if necessary */
+            if (strm.avail_out == 0) {
+                strm.avail_out = WINSIZE;
+                strm.next_out = window;
+            }
+
+            /* inflate until out of input, output, or at end of block --
+               update the total input and output counters */
+            totin += strm.avail_in;
+            totout += strm.avail_out;
+            ret = inflate(&strm, Z_BLOCK);      /* return at end of block */
+            totin -= strm.avail_in;
+            totout -= strm.avail_out;
+            if (ret == Z_NEED_DICT)
+                ret = Z_DATA_ERROR;
+            if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
+                goto build_index_error;
+            if (ret == Z_STREAM_END)
+                break;
+
+            /* if at end of block, consider adding an index entry (note that if
+               data_type indicates an end-of-block, then all of the
+               uncompressed data from that block has been delivered, and none
+               of the compressed data after that block has been consumed,
+               except for up to seven bits) -- the totout == 0 provides an
+               entry point after the zlib or gzip header, and assures that the
+               index always has at least one access point; we avoid creating an
+               access point after the last block by checking bit 6 of data_type
+             */
+            if ((strm.data_type & 128) && !(strm.data_type & 64) &&
+                (totout == 0 || totout - last > span)) {
+                index = addpoint(index, strm.data_type & 7, totin,
+                                 totout, strm.avail_out, window);
+                if (index == NULL) {
+                    ret = Z_MEM_ERROR;
+                    goto build_index_error;
+                }
+                last = totout;
+            }
+        } while (strm.avail_in != 0);
+    } while (ret != Z_STREAM_END);
+
+    /* clean up and return index (release unused entries in list) */
+    (void)inflateEnd(&strm);
+    index = realloc(index, sizeof(struct point) * index->have);
+    index->size = index->have;
+    *built = index;
+    return index->size;
+
+    /* return error */
+  build_index_error:
+    (void)inflateEnd(&strm);
+    if (index != NULL)
+        free_index(index);
+    return ret;
+}
+
+/* Use the index to read len bytes from offset into buf, return bytes read or
+   negative for error (Z_DATA_ERROR or Z_MEM_ERROR).  If data is requested past
+   the end of the uncompressed data, then extract() will return a value less
+   than len, indicating how much as actually read into buf.  This function
+   should not return a data error unless the file was modified since the index
+   was generated.  extract() may also return Z_ERRNO if there is an error on
+   reading or seeking the input file. */
+local int extract(FILE *in, struct access *index, off_t offset,
+                  unsigned char *buf, int len)
+{
+    int ret, skip;
+    z_stream strm;
+    struct point *here;
+    unsigned char input[CHUNK];
+    unsigned char discard[WINSIZE];
+
+    /* proceed only if something reasonable to do */
+    if (len < 0)
+        return 0;
+
+    /* find where in stream to start */
+    here = index->list;
+    ret = index->have;
+    while (--ret && here[1].out <= offset)
+        here++;
+
+    /* initialize file and inflate state to start there */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, -15);         /* raw inflate */
+    if (ret != Z_OK)
+        return ret;
+    ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
+    if (ret == -1)
+        goto extract_ret;
+    if (here->bits) {
+        ret = getc(in);
+        if (ret == -1) {
+            ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR;
+            goto extract_ret;
+        }
+        (void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits));
+    }
+    (void)inflateSetDictionary(&strm, here->window, WINSIZE);
+
+    /* skip uncompressed bytes until offset reached, then satisfy request */
+    offset -= here->out;
+    strm.avail_in = 0;
+    skip = 1;                               /* while skipping to offset */
+    do {
+        /* define where to put uncompressed data, and how much */
+        if (offset == 0 && skip) {          /* at offset now */
+            strm.avail_out = len;
+            strm.next_out = buf;
+            skip = 0;                       /* only do this once */
+        }
+        if (offset > WINSIZE) {             /* skip WINSIZE bytes */
+            strm.avail_out = WINSIZE;
+            strm.next_out = discard;
+            offset -= WINSIZE;
+        }
+        else if (offset != 0) {             /* last skip */
+            strm.avail_out = (unsigned)offset;
+            strm.next_out = discard;
+            offset = 0;
+        }
+
+        /* uncompress until avail_out filled, or end of stream */
+        do {
+            if (strm.avail_in == 0) {
+                strm.avail_in = fread(input, 1, CHUNK, in);
+                if (ferror(in)) {
+                    ret = Z_ERRNO;
+                    goto extract_ret;
+                }
+                if (strm.avail_in == 0) {
+                    ret = Z_DATA_ERROR;
+                    goto extract_ret;
+                }
+                strm.next_in = input;
+            }
+            ret = inflate(&strm, Z_NO_FLUSH);       /* normal inflate */
+            if (ret == Z_NEED_DICT)
+                ret = Z_DATA_ERROR;
+            if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
+                goto extract_ret;
+            if (ret == Z_STREAM_END)
+                break;
+        } while (strm.avail_out != 0);
+
+        /* if reach end of stream, then don't keep trying to get more */
+        if (ret == Z_STREAM_END)
+            break;
+
+        /* do until offset reached and requested data read, or stream ends */
+    } while (skip);
+
+    /* compute number of uncompressed bytes read after offset */
+    ret = skip ? 0 : len - strm.avail_out;
+
+    /* clean up and return bytes read or error */
+  extract_ret:
+    (void)inflateEnd(&strm);
+    return ret;
+}
+
+/* Demonstrate the use of build_index() and extract() by processing the file
+   provided on the command line, and the extracting 16K from about 2/3rds of
+   the way through the uncompressed output, and writing that to stdout. */
+int main(int argc, char **argv)
+{
+    int len;
+    off_t offset;
+    FILE *in;
+    struct access *index = NULL;
+    unsigned char buf[CHUNK];
+
+    /* open input file */
+    if (argc != 2) {
+        fprintf(stderr, "usage: zran file.gz\n");
+        return 1;
+    }
+    in = fopen(argv[1], "rb");
+    if (in == NULL) {
+        fprintf(stderr, "zran: could not open %s for reading\n", argv[1]);
+        return 1;
+    }
+
+    /* build index */
+    len = build_index(in, SPAN, &index);
+    if (len < 0) {
+        fclose(in);
+        switch (len) {
+        case Z_MEM_ERROR:
+            fprintf(stderr, "zran: out of memory\n");
+            break;
+        case Z_DATA_ERROR:
+            fprintf(stderr, "zran: compressed data error in %s\n", argv[1]);
+            break;
+        case Z_ERRNO:
+            fprintf(stderr, "zran: read error on %s\n", argv[1]);
+            break;
+        default:
+            fprintf(stderr, "zran: error %d while building index\n", len);
+        }
+        return 1;
+    }
+    fprintf(stderr, "zran: built index with %d access points\n", len);
+
+    /* use index by reading some bytes from an arbitrary offset */
+    offset = (index->list[index->have - 1].out << 1) / 3;
+    len = extract(in, index, offset, buf, CHUNK);
+    if (len < 0)
+        fprintf(stderr, "zran: extraction failed: %s error\n",
+                len == Z_MEM_ERROR ? "out of memory" : "input corrupted");
+    else {
+        fwrite(buf, 1, len, stdout);
+        fprintf(stderr, "zran: extracted %d bytes at %llu\n", len, offset);
+    }
+
+    /* clean up and exit */
+    free_index(index);
+    fclose(in);
+    return 0;
+}
diff --git a/8.x/zlib/gzclose.c b/8.x/zlib/gzclose.c
new file mode 100644 (file)
index 0000000..caeb99a
--- /dev/null
@@ -0,0 +1,25 @@
+/* gzclose.c -- zlib gzclose() function
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* gzclose() is in a separate file so that it is linked in only if it is used.
+   That way the other gzclose functions can be used instead to avoid linking in
+   unneeded compression or decompression routines. */
+int ZEXPORT gzclose(file)
+    gzFile file;
+{
+#ifndef NO_GZCOMPRESS
+    gz_statep state;
+
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
+#else
+    return gzclose_r(file);
+#endif
+}
diff --git a/8.x/zlib/gzguts.h b/8.x/zlib/gzguts.h
new file mode 100644 (file)
index 0000000..0f8fb79
--- /dev/null
@@ -0,0 +1,132 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+#  ifndef _LARGEFILE_SOURCE
+#    define _LARGEFILE_SOURCE 1
+#  endif
+#  ifdef _FILE_OFFSET_BITS
+#    undef _FILE_OFFSET_BITS
+#  endif
+#endif
+
+#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#  include <limits.h>
+#endif
+#include <fcntl.h>
+
+#ifdef NO_DEFLATE       /* for compatibility with old definition */
+#  define NO_GZCOMPRESS
+#endif
+
+#ifdef _MSC_VER
+#  include <io.h>
+#  define vsnprintf _vsnprintf
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+  extern voidp  malloc OF((uInt size));
+  extern void   free   OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+#  include <windows.h>
+#  define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+#  ifdef STDC
+#    include <errno.h>
+#    define zstrerror() strerror(errno)
+#  else
+#    define zstrerror() "stdio error (consult errno)"
+#  endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+    ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+    ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+    ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+    ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default i/o buffer size -- double this for output when reading */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1     /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0      /* look for a gzip header */
+#define COPY 1      /* copy input directly */
+#define GZIP 2      /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+        /* used for both reading and writing */
+    int mode;               /* see gzip modes above */
+    int fd;                 /* file descriptor */
+    char *path;             /* path or fd for error messages */
+    z_off64_t pos;          /* current position in uncompressed data */
+    unsigned size;          /* buffer size, zero if not allocated yet */
+    unsigned want;          /* requested buffer size, default is GZBUFSIZE */
+    unsigned char *in;      /* input buffer */
+    unsigned char *out;     /* output buffer (double-sized when reading) */
+    unsigned char *next;    /* next output data to deliver or write */
+        /* just for reading */
+    unsigned have;          /* amount of output data unused at next */
+    int eof;                /* true if end of input file reached */
+    z_off64_t start;        /* where the gzip data started, for rewinding */
+    z_off64_t raw;          /* where the raw data started, for seeking */
+    int how;                /* 0: get header, 1: copy, 2: decompress */
+    int direct;             /* true if last read direct, false if gzip */
+        /* just for writing */
+    int level;              /* compression level */
+    int strategy;           /* compression strategy */
+        /* seek request */
+    z_off64_t skip;         /* amount to skip (already rewound if backwards) */
+    int seek;               /* true if seek request pending */
+        /* error information */
+    int err;                /* error code */
+    char *msg;              /* error message */
+        /* zlib inflate or deflate stream */
+    z_stream strm;          /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+   value -- needed when comparing unsigned to z_off64_t, which is signed
+   (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/8.x/zlib/gzlib.c b/8.x/zlib/gzlib.c
new file mode 100644 (file)
index 0000000..603e60e
--- /dev/null
@@ -0,0 +1,537 @@
+/* gzlib.c -- zlib functions common to reading and writing gzip files
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define LSEEK lseek64
+#else
+#  define LSEEK lseek
+#endif
+
+/* Local functions */
+local void gz_reset OF((gz_statep));
+local gzFile gz_open OF((const char *, int, const char *));
+
+#if defined UNDER_CE
+
+/* Map the Windows error number in ERROR to a locale-dependent error message
+   string and return a pointer to it.  Typically, the values for ERROR come
+   from GetLastError.
+
+   The string pointed to shall not be modified by the application, but may be
+   overwritten by a subsequent call to gz_strwinerror
+
+   The gz_strwinerror function does not change the current setting of
+   GetLastError. */
+char ZLIB_INTERNAL *gz_strwinerror (error)
+     DWORD error;
+{
+    static char buf[1024];
+
+    wchar_t *msgbuf;
+    DWORD lasterr = GetLastError();
+    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+        NULL,
+        error,
+        0, /* Default language */
+        (LPVOID)&msgbuf,
+        0,
+        NULL);
+    if (chars != 0) {
+        /* If there is an \r\n appended, zap it.  */
+        if (chars >= 2
+            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+            chars -= 2;
+            msgbuf[chars] = 0;
+        }
+
+        if (chars > sizeof (buf) - 1) {
+            chars = sizeof (buf) - 1;
+            msgbuf[chars] = 0;
+        }
+
+        wcstombs(buf, msgbuf, chars + 1);
+        LocalFree(msgbuf);
+    }
+    else {
+        sprintf(buf, "unknown win32 error (%ld)", error);
+    }
+
+    SetLastError(lasterr);
+    return buf;
+}
+
+#endif /* UNDER_CE */
+
+/* Reset gzip file state */
+local void gz_reset(state)
+    gz_statep state;
+{
+    if (state->mode == GZ_READ) {   /* for reading ... */
+        state->have = 0;            /* no output data available */
+        state->eof = 0;             /* not at end of file */
+        state->how = LOOK;          /* look for gzip header */
+        state->direct = 1;          /* default for empty file */
+    }
+    state->seek = 0;                /* no seek request pending */
+    gz_error(state, Z_OK, NULL);    /* clear error */
+    state->pos = 0;                 /* no uncompressed data yet */
+    state->strm.avail_in = 0;       /* no input data yet */
+}
+
+/* Open a gzip file either by name or file descriptor. */
+local gzFile gz_open(path, fd, mode)
+    const char *path;
+    int fd;
+    const char *mode;
+{
+    gz_statep state;
+
+    /* allocate gzFile structure to return */
+    state = malloc(sizeof(gz_state));
+    if (state == NULL)
+        return NULL;
+    state->size = 0;            /* no buffers allocated yet */
+    state->want = GZBUFSIZE;    /* requested buffer size */
+    state->msg = NULL;          /* no error message yet */
+
+    /* interpret mode */
+    state->mode = GZ_NONE;
+    state->level = Z_DEFAULT_COMPRESSION;
+    state->strategy = Z_DEFAULT_STRATEGY;
+    while (*mode) {
+        if (*mode >= '0' && *mode <= '9')
+            state->level = *mode - '0';
+        else
+            switch (*mode) {
+            case 'r':
+                state->mode = GZ_READ;
+                break;
+#ifndef NO_GZCOMPRESS
+            case 'w':
+                state->mode = GZ_WRITE;
+                break;
+            case 'a':
+                state->mode = GZ_APPEND;
+                break;
+#endif
+            case '+':       /* can't read and write at the same time */
+                free(state);
+                return NULL;
+            case 'b':       /* ignore -- will request binary anyway */
+                break;
+            case 'f':
+                state->strategy = Z_FILTERED;
+                break;
+            case 'h':
+                state->strategy = Z_HUFFMAN_ONLY;
+                break;
+            case 'R':
+                state->strategy = Z_RLE;
+                break;
+            case 'F':
+                state->strategy = Z_FIXED;
+            default:        /* could consider as an error, but just ignore */
+                ;
+            }
+        mode++;
+    }
+
+    /* must provide an "r", "w", or "a" */
+    if (state->mode == GZ_NONE) {
+        free(state);
+        return NULL;
+    }
+
+    /* save the path name for error messages */
+    state->path = malloc(strlen(path) + 1);
+    if (state->path == NULL) {
+        free(state);
+        return NULL;
+    }
+    strcpy(state->path, path);
+
+    /* open the file with the appropriate mode (or just use fd) */
+    state->fd = fd != -1 ? fd :
+        open(path,
+#ifdef O_LARGEFILE
+            O_LARGEFILE |
+#endif
+#ifdef O_BINARY
+            O_BINARY |
+#endif
+            (state->mode == GZ_READ ?
+                O_RDONLY :
+                (O_WRONLY | O_CREAT | (
+                    state->mode == GZ_WRITE ?
+                        O_TRUNC :
+                        O_APPEND))),
+            0666);
+    if (state->fd == -1) {
+        free(state->path);
+        free(state);
+        return NULL;
+    }
+    if (state->mode == GZ_APPEND)
+        state->mode = GZ_WRITE;         /* simplify later checks */
+
+    /* save the current position for rewinding (only if reading) */
+    if (state->mode == GZ_READ) {
+        state->start = LSEEK(state->fd, 0, SEEK_CUR);
+        if (state->start == -1) state->start = 0;
+    }
+
+    /* initialize stream */
+    gz_reset(state);
+
+    /* return stream */
+    return (gzFile)state;
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen(path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen64(path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzdopen(fd, mode)
+    int fd;
+    const char *mode;
+{
+    char *path;         /* identifier for error messages */
+    gzFile gz;
+
+    if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
+        return NULL;
+    sprintf(path, "<fd:%d>", fd);   /* for debugging */
+    gz = gz_open(path, fd, mode);
+    free(path);
+    return gz;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzbuffer(file, size)
+    gzFile file;
+    unsigned size;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* make sure we haven't already allocated memory */
+    if (state->size != 0)
+        return -1;
+
+    /* check and set requested size */
+    if (size == 0)
+        return -1;
+    state->want = size;
+    return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzrewind(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no error */
+    if (state->mode != GZ_READ || state->err != Z_OK)
+        return -1;
+
+    /* back up and start over */
+    if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
+        return -1;
+    gz_reset(state);
+    return 0;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzseek64(file, offset, whence)
+    gzFile file;
+    z_off64_t offset;
+    int whence;
+{
+    unsigned n;
+    z_off64_t ret;
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* check that there's no error */
+    if (state->err != Z_OK)
+        return -1;
+
+    /* can only seek from start or relative to current position */
+    if (whence != SEEK_SET && whence != SEEK_CUR)
+        return -1;
+
+    /* normalize offset to a SEEK_CUR specification */
+    if (whence == SEEK_SET)
+        offset -= state->pos;
+    else if (state->seek)
+        offset += state->skip;
+    state->seek = 0;
+
+    /* if within raw area while reading, just go there */
+    if (state->mode == GZ_READ && state->how == COPY &&
+        state->pos + offset >= state->raw) {
+        ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
+        if (ret == -1)
+            return -1;
+        state->have = 0;
+        state->eof = 0;
+        state->seek = 0;
+        gz_error(state, Z_OK, NULL);
+        state->strm.avail_in = 0;
+        state->pos += offset;
+        return state->pos;
+    }
+
+    /* calculate skip amount, rewinding if needed for back seek when reading */
+    if (offset < 0) {
+        if (state->mode != GZ_READ)         /* writing -- can't go backwards */
+            return -1;
+        offset += state->pos;
+        if (offset < 0)                     /* before start of file! */
+            return -1;
+        if (gzrewind(file) == -1)           /* rewind, then skip to offset */
+            return -1;
+    }
+
+    /* if reading, skip what's in output buffer (one less gzgetc() check) */
+    if (state->mode == GZ_READ) {
+        n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
+            (unsigned)offset : state->have;
+        state->have -= n;
+        state->next += n;
+        state->pos += n;
+        offset -= n;
+    }
+
+    /* request skip (if not zero) */
+    if (offset) {
+        state->seek = 1;
+        state->skip = offset;
+    }
+    return state->pos + offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzseek(file, offset, whence)
+    gzFile file;
+    z_off_t offset;
+    int whence;
+{
+    z_off64_t ret;
+
+    ret = gzseek64(file, (z_off64_t)offset, whence);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gztell64(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* return position */
+    return state->pos + (state->seek ? state->skip : 0);
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gztell(file)
+    gzFile file;
+{
+    z_off64_t ret;
+
+    ret = gztell64(file);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzoffset64(file)
+    gzFile file;
+{
+    z_off64_t offset;
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* compute and return effective offset in file */
+    offset = LSEEK(state->fd, 0, SEEK_CUR);
+    if (offset == -1)
+        return -1;
+    if (state->mode == GZ_READ)             /* reading */
+        offset -= state->strm.avail_in;     /* don't count buffered input */
+    return offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzoffset(file)
+    gzFile file;
+{
+    z_off64_t ret;
+
+    ret = gzoffset64(file);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzeof(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return 0;
+
+    /* return end-of-file state */
+    return state->mode == GZ_READ ?
+        (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0;
+}
+
+/* -- see zlib.h -- */
+const char * ZEXPORT gzerror(file, errnum)
+    gzFile file;
+    int *errnum;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return NULL;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return NULL;
+
+    /* return error information */
+    if (errnum != NULL)
+        *errnum = state->err;
+    return state->msg == NULL ? "" : state->msg;
+}
+
+/* -- see zlib.h -- */
+void ZEXPORT gzclearerr(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return;
+
+    /* clear error and end-of-file */
+    if (state->mode == GZ_READ)
+        state->eof = 0;
+    gz_error(state, Z_OK, NULL);
+}
+
+/* Create an error message in allocated memory and set state->err and
+   state->msg accordingly.  Free any previous error message already there.  Do
+   not try to free or allocate space if the error is Z_MEM_ERROR (out of
+   memory).  Simply save the error message as a static string.  If there is an
+   allocation failure constructing the error message, then convert the error to
+   out of memory. */
+void ZLIB_INTERNAL gz_error(state, err, msg)
+    gz_statep state;
+    int err;
+    const char *msg;
+{
+    /* free previously allocated message and clear */
+    if (state->msg != NULL) {
+        if (state->err != Z_MEM_ERROR)
+            free(state->msg);
+        state->msg = NULL;
+    }
+
+    /* set error code, and if no message, then done */
+    state->err = err;
+    if (msg == NULL)
+        return;
+
+    /* for an out of memory error, save as static string */
+    if (err == Z_MEM_ERROR) {
+        state->msg = (char *)msg;
+        return;
+    }
+
+    /* construct error message with path */
+    if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
+        state->err = Z_MEM_ERROR;
+        state->msg = (char *)"out of memory";
+        return;
+    }
+    strcpy(state->msg, state->path);
+    strcat(state->msg, ": ");
+    strcat(state->msg, msg);
+    return;
+}
+
+#ifndef INT_MAX
+/* portably return maximum value for an int (when limits.h presumed not
+   available) -- we need to do this to cover cases where 2's complement not
+   used, since C standard permits 1's complement and sign-bit representations,
+   otherwise we could just use ((unsigned)-1) >> 1 */
+unsigned ZLIB_INTERNAL gz_intmax()
+{
+    unsigned p, q;
+
+    p = 1;
+    do {
+        q = p;
+        p <<= 1;
+        p++;
+    } while (p > q);
+    return q >> 1;
+}
+#endif
diff --git a/8.x/zlib/gzread.c b/8.x/zlib/gzread.c
new file mode 100644 (file)
index 0000000..548201a
--- /dev/null
@@ -0,0 +1,653 @@
+/* gzread.c -- zlib functions for reading gzip files
+ * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
+local int gz_avail OF((gz_statep));
+local int gz_next4 OF((gz_statep, unsigned long *));
+local int gz_head OF((gz_statep));
+local int gz_decomp OF((gz_statep));
+local int gz_make OF((gz_statep));
+local int gz_skip OF((gz_statep, z_off64_t));
+
+/* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
+   state->fd, and update state->eof, state->err, and state->msg as appropriate.
+   This function needs to loop on read(), since read() is not guaranteed to
+   read the number of bytes requested, depending on the type of descriptor. */
+local int gz_load(state, buf, len, have)
+    gz_statep state;
+    unsigned char *buf;
+    unsigned len;
+    unsigned *have;
+{
+    int ret;
+
+    *have = 0;
+    do {
+        ret = read(state->fd, buf + *have, len - *have);
+        if (ret <= 0)
+            break;
+        *have += ret;
+    } while (*have < len);
+    if (ret < 0) {
+        gz_error(state, Z_ERRNO, zstrerror());
+        return -1;
+    }
+    if (ret == 0)
+        state->eof = 1;
+    return 0;
+}
+
+/* Load up input buffer and set eof flag if last data loaded -- return -1 on
+   error, 0 otherwise.  Note that the eof flag is set when the end of the input
+   file is reached, even though there may be unused data in the buffer.  Once
+   that data has been used, no more attempts will be made to read the file.
+   gz_avail() assumes that strm->avail_in == 0. */
+local int gz_avail(state)
+    gz_statep state;
+{
+    z_streamp strm = &(state->strm);
+
+    if (state->err != Z_OK)
+        return -1;
+    if (state->eof == 0) {
+        if (gz_load(state, state->in, state->size,
+                (unsigned *)&(strm->avail_in)) == -1)
+            return -1;
+        strm->next_in = state->in;
+    }
+    return 0;
+}
+
+/* Get next byte from input, or -1 if end or error. */
+#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
+                (strm->avail_in == 0 ? -1 : \
+                 (strm->avail_in--, *(strm->next_in)++)))
+
+/* Get a four-byte little-endian integer and return 0 on success and the value
+   in *ret.  Otherwise -1 is returned and *ret is not modified. */
+local int gz_next4(state, ret)
+    gz_statep state;
+    unsigned long *ret;
+{
+    int ch;
+    unsigned long val;
+    z_streamp strm = &(state->strm);
+
+    val = NEXT();
+    val += (unsigned)NEXT() << 8;
+    val += (unsigned long)NEXT() << 16;
+    ch = NEXT();
+    if (ch == -1)
+        return -1;
+    val += (unsigned long)ch << 24;
+    *ret = val;
+    return 0;
+}
+
+/* Look for gzip header, set up for inflate or copy.  state->have must be zero.
+   If this is the first time in, allocate required memory.  state->how will be
+   left unchanged if there is no more input data available, will be set to COPY
+   if there is no gzip header and direct copying will be performed, or it will
+   be set to GZIP for decompression, and the gzip header will be skipped so
+   that the next available input data is the raw deflate stream.  If direct
+   copying, then leftover input data from the input buffer will be copied to
+   the output buffer.  In that case, all further file reads will be directly to
+   either the output buffer or a user buffer.  If decompressing, the inflate
+   state and the check value will be initialized.  gz_head() will return 0 on
+   success or -1 on failure.  Failures may include read errors or gzip header
+   errors.  */
+local int gz_head(state)
+    gz_statep state;
+{
+    z_streamp strm = &(state->strm);
+    int flags;
+    unsigned len;
+
+    /* allocate read buffers and inflate memory */
+    if (state->size == 0) {
+        /* allocate buffers */
+        state->in = malloc(state->want);
+        state->out = malloc(state->want << 1);
+        if (state->in == NULL || state->out == NULL) {
+            if (state->out != NULL)
+                free(state->out);
+            if (state->in != NULL)
+                free(state->in);
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+        state->size = state->want;
+
+        /* allocate inflate memory */
+        state->strm.zalloc = Z_NULL;
+        state->strm.zfree = Z_NULL;
+        state->strm.opaque = Z_NULL;
+        state->strm.avail_in = 0;
+        state->strm.next_in = Z_NULL;
+        if (inflateInit2(&(state->strm), -15) != Z_OK) {    /* raw inflate */
+            free(state->out);
+            free(state->in);
+            state->size = 0;
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+    }
+
+    /* get some data in the input buffer */
+    if (strm->avail_in == 0) {
+        if (gz_avail(state) == -1)
+            return -1;
+        if (strm->avail_in == 0)
+            return 0;
+    }
+
+    /* look for the gzip magic header bytes 31 and 139 */
+    if (strm->next_in[0] == 31) {
+        strm->avail_in--;
+        strm->next_in++;
+        if (strm->avail_in == 0 && gz_avail(state) == -1)
+            return -1;
+        if (strm->avail_in && strm->next_in[0] == 139) {
+            /* we have a gzip header, woo hoo! */
+            strm->avail_in--;
+            strm->next_in++;
+
+            /* skip rest of header */
+            if (NEXT() != 8) {      /* compression method */
+                gz_error(state, Z_DATA_ERROR, "unknown compression method");
+                return -1;
+            }
+            flags = NEXT();
+            if (flags & 0xe0) {     /* reserved flag bits */
+                gz_error(state, Z_DATA_ERROR, "unknown header flags set");
+                return -1;
+            }
+            NEXT();                 /* modification time */
+            NEXT();
+            NEXT();
+            NEXT();
+            NEXT();                 /* extra flags */
+            NEXT();                 /* operating system */
+            if (flags & 4) {        /* extra field */
+                len = (unsigned)NEXT();
+                len += (unsigned)NEXT() << 8;
+                while (len--)
+                    if (NEXT() < 0)
+                        break;
+            }
+            if (flags & 8)          /* file name */
+                while (NEXT() > 0)
+                    ;
+            if (flags & 16)         /* comment */
+                while (NEXT() > 0)
+                    ;
+            if (flags & 2) {        /* header crc */
+                NEXT();
+                NEXT();
+            }
+            /* an unexpected end of file is not checked for here -- it will be
+               noticed on the first request for uncompressed data */
+
+            /* set up for decompression */
+            inflateReset(strm);
+            strm->adler = crc32(0L, Z_NULL, 0);
+            state->how = GZIP;
+            state->direct = 0;
+            return 0;
+        }
+        else {
+            /* not a gzip file -- save first byte (31) and fall to raw i/o */
+            state->out[0] = 31;
+            state->have = 1;
+        }
+    }
+
+    /* doing raw i/o, save start of raw data for seeking, copy any leftover
+       input to output -- this assumes that the output buffer is larger than
+       the input buffer, which also assures space for gzungetc() */
+    state->raw = state->pos;
+    state->next = state->out;
+    if (strm->avail_in) {
+        memcpy(state->next + state->have, strm->next_in, strm->avail_in);
+        state->have += strm->avail_in;
+        strm->avail_in = 0;
+    }
+    state->how = COPY;
+    state->direct = 1;
+    return 0;
+}
+
+/* Decompress from input to the provided next_out and avail_out in the state.
+   If the end of the compressed data is reached, then verify the gzip trailer
+   check value and length (modulo 2^32).  state->have and state->next are set
+   to point to the just decompressed data, and the crc is updated.  If the
+   trailer is verified, state->how is reset to LOOK to look for the next gzip
+   stream or raw data, once state->have is depleted.  Returns 0 on success, -1
+   on failure.  Failures may include invalid compressed data or a failed gzip
+   trailer verification. */
+local int gz_decomp(state)
+    gz_statep state;
+{
+    int ret;
+    unsigned had;
+    unsigned long crc, len;
+    z_streamp strm = &(state->strm);
+
+    /* fill output buffer up to end of deflate stream */
+    had = strm->avail_out;
+    do {
+        /* get more input for inflate() */
+        if (strm->avail_in == 0 && gz_avail(state) == -1)
+            return -1;
+        if (strm->avail_in == 0) {
+            gz_error(state, Z_DATA_ERROR, "unexpected end of file");
+            return -1;
+        }
+
+        /* decompress and handle errors */
+        ret = inflate(strm, Z_NO_FLUSH);
+        if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
+            gz_error(state, Z_STREAM_ERROR,
+                      "internal error: inflate stream corrupt");
+            return -1;
+        }
+        if (ret == Z_MEM_ERROR) {
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+        if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
+            gz_error(state, Z_DATA_ERROR,
+                      strm->msg == NULL ? "compressed data error" : strm->msg);
+            return -1;
+        }
+    } while (strm->avail_out && ret != Z_STREAM_END);
+
+    /* update available output and crc check value */
+    state->have = had - strm->avail_out;
+    state->next = strm->next_out - state->have;
+    strm->adler = crc32(strm->adler, state->next, state->have);
+
+    /* check gzip trailer if at end of deflate stream */
+    if (ret == Z_STREAM_END) {
+        if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
+            gz_error(state, Z_DATA_ERROR, "unexpected end of file");
+            return -1;
+        }
+        if (crc != strm->adler) {
+            gz_error(state, Z_DATA_ERROR, "incorrect data check");
+            return -1;
+        }
+        if (len != (strm->total_out & 0xffffffffL)) {
+            gz_error(state, Z_DATA_ERROR, "incorrect length check");
+            return -1;
+        }
+        state->how = LOOK;      /* ready for next stream, once have is 0 (leave
+                                   state->direct unchanged to remember how) */
+    }
+
+    /* good decompression */
+    return 0;
+}
+
+/* Make data and put in the output buffer.  Assumes that state->have == 0.
+   Data is either copied from the input file or decompressed from the input
+   file depending on state->how.  If state->how is LOOK, then a gzip header is
+   looked for (and skipped if found) to determine wither to copy or decompress.
+   Returns -1 on error, otherwise 0.  gz_make() will leave state->have as COPY
+   or GZIP unless the end of the input file has been reached and all data has
+   been processed.  */
+local int gz_make(state)
+    gz_statep state;
+{
+    z_streamp strm = &(state->strm);
+
+    if (state->how == LOOK) {           /* look for gzip header */
+        if (gz_head(state) == -1)
+            return -1;
+        if (state->have)                /* got some data from gz_head() */
+            return 0;
+    }
+    if (state->how == COPY) {           /* straight copy */
+        if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
+            return -1;
+        state->next = state->out;
+    }
+    else if (state->how == GZIP) {      /* decompress */
+        strm->avail_out = state->size << 1;
+        strm->next_out = state->out;
+        if (gz_decomp(state) == -1)
+            return -1;
+    }
+    return 0;
+}
+
+/* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
+local int gz_skip(state, len)
+    gz_statep state;
+    z_off64_t len;
+{
+    unsigned n;
+
+    /* skip over len bytes or reach end-of-file, whichever comes first */
+    while (len)
+        /* skip over whatever is in output buffer */
+        if (state->have) {
+            n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
+                (unsigned)len : state->have;
+            state->have -= n;
+            state->next += n;
+            state->pos += n;
+            len -= n;
+        }
+
+        /* output buffer empty -- return if we're at the end of the input */
+        else if (state->eof && state->strm.avail_in == 0)
+            break;
+
+        /* need more data to skip -- load up output buffer */
+        else {
+            /* get more output, looking for header if required */
+            if (gz_make(state) == -1)
+                return -1;
+        }
+    return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzread(file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    unsigned got, n;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're reading and that there's no error */
+    if (state->mode != GZ_READ || state->err != Z_OK)
+        return -1;
+
+    /* since an int is returned, make sure len fits in one, otherwise return
+       with an error (this avoids the flaw in the interface) */
+    if ((int)len < 0) {
+        gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
+        return -1;
+    }
+
+    /* if len is zero, avoid unnecessary operations */
+    if (len == 0)
+        return 0;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* get len bytes to buf, or less than len if at the end */
+    got = 0;
+    do {
+        /* first just try copying data from the output buffer */
+        if (state->have) {
+            n = state->have > len ? len : state->have;
+            memcpy(buf, state->next, n);
+            state->next += n;
+            state->have -= n;
+        }
+
+        /* output buffer empty -- return if we're at the end of the input */
+        else if (state->eof && strm->avail_in == 0)
+            break;
+
+        /* need output data -- for small len or new stream load up our output
+           buffer */
+        else if (state->how == LOOK || len < (state->size << 1)) {
+            /* get more output, looking for header if required */
+            if (gz_make(state) == -1)
+                return -1;
+            continue;       /* no progress yet -- go back to memcpy() above */
+            /* the copy above assures that we will leave with space in the
+               output buffer, allowing at least one gzungetc() to succeed */
+        }
+
+        /* large len -- read directly into user buffer */
+        else if (state->how == COPY) {      /* read directly */
+            if (gz_load(state, buf, len, &n) == -1)
+                return -1;
+        }
+
+        /* large len -- decompress directly into user buffer */
+        else {  /* state->how == GZIP */
+            strm->avail_out = len;
+            strm->next_out = buf;
+            if (gz_decomp(state) == -1)
+                return -1;
+            n = state->have;
+            state->have = 0;
+        }
+
+        /* update progress */
+        len -= n;
+        buf = (char *)buf + n;
+        got += n;
+        state->pos += n;
+    } while (len);
+
+    /* return number of bytes read into user buffer (will fit in int) */
+    return (int)got;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzgetc(file)
+    gzFile file;
+{
+    int ret;
+    unsigned char buf[1];
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no error */
+    if (state->mode != GZ_READ || state->err != Z_OK)
+        return -1;
+
+    /* try output buffer (no need to check for skip request) */
+    if (state->have) {
+        state->have--;
+        state->pos++;
+        return *(state->next)++;
+    }
+
+    /* nothing there -- try gzread() */
+    ret = gzread(file, buf, 1);
+    return ret < 1 ? -1 : buf[0];
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzungetc(c, file)
+    int c;
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no error */
+    if (state->mode != GZ_READ || state->err != Z_OK)
+        return -1;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* can't push EOF */
+    if (c < 0)
+        return -1;
+
+    /* if output buffer empty, put byte at end (allows more pushing) */
+    if (state->have == 0) {
+        state->have = 1;
+        state->next = state->out + (state->size << 1) - 1;
+        state->next[0] = c;
+        state->pos--;
+        return c;
+    }
+
+    /* if no room, give up (must have already done a gzungetc()) */
+    if (state->have == (state->size << 1)) {
+        gz_error(state, Z_BUF_ERROR, "out of room to push characters");
+        return -1;
+    }
+
+    /* slide output data if needed and insert byte before existing data */
+    if (state->next == state->out) {
+        unsigned char *src = state->out + state->have;
+        unsigned char *dest = state->out + (state->size << 1);
+        while (src > state->out)
+            *--dest = *--src;
+        state->next = dest;
+    }
+    state->have++;
+    state->next--;
+    state->next[0] = c;
+    state->pos--;
+    return c;
+}
+
+/* -- see zlib.h -- */
+char * ZEXPORT gzgets(file, buf, len)
+    gzFile file;
+    char *buf;
+    int len;
+{
+    unsigned left, n;
+    char *str;
+    unsigned char *eol;
+    gz_statep state;
+
+    /* check parameters and get internal structure */
+    if (file == NULL || buf == NULL || len < 1)
+        return NULL;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no error */
+    if (state->mode != GZ_READ || state->err != Z_OK)
+        return NULL;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return NULL;
+    }
+
+    /* copy output bytes up to new line or len - 1, whichever comes first --
+       append a terminating zero to the string (we don't check for a zero in
+       the contents, let the user worry about that) */
+    str = buf;
+    left = (unsigned)len - 1;
+    if (left) do {
+        /* assure that something is in the output buffer */
+        if (state->have == 0) {
+            if (gz_make(state) == -1)
+                return NULL;            /* error */
+            if (state->have == 0) {     /* end of file */
+                if (buf == str)         /* got bupkus */
+                    return NULL;
+                break;                  /* got something -- return it */
+            }
+        }
+
+        /* look for end-of-line in current output buffer */
+        n = state->have > left ? left : state->have;
+        eol = memchr(state->next, '\n', n);
+        if (eol != NULL)
+            n = (unsigned)(eol - state->next) + 1;
+
+        /* copy through end-of-line, or remainder if not found */
+        memcpy(buf, state->next, n);
+        state->have -= n;
+        state->next += n;
+        state->pos += n;
+        left -= n;
+        buf += n;
+    } while (left && eol == NULL);
+
+    /* found end-of-line or out of space -- terminate string and return it */
+    buf[0] = 0;
+    return str;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzdirect(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+
+    /* check that we're reading */
+    if (state->mode != GZ_READ)
+        return 0;
+
+    /* if the state is not known, but we can find out, then do so (this is
+       mainly for right after a gzopen() or gzdopen()) */
+    if (state->how == LOOK && state->have == 0)
+        (void)gz_head(state);
+
+    /* return 1 if reading direct, 0 if decompressing a gzip stream */
+    return state->direct;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_r(file)
+    gzFile file;
+{
+    int ret;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    /* check that we're reading */
+    if (state->mode != GZ_READ)
+        return Z_STREAM_ERROR;
+
+    /* free memory and close file */
+    if (state->size) {
+        inflateEnd(&(state->strm));
+        free(state->out);
+        free(state->in);
+    }
+    gz_error(state, Z_OK, NULL);
+    free(state->path);
+    ret = close(state->fd);
+    free(state);
+    return ret ? Z_ERRNO : Z_OK;
+}
diff --git a/8.x/zlib/gzwrite.c b/8.x/zlib/gzwrite.c
new file mode 100644 (file)
index 0000000..e8defc6
--- /dev/null
@@ -0,0 +1,531 @@
+/* gzwrite.c -- zlib functions for writing gzip files
+ * Copyright (C) 2004, 2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_init OF((gz_statep));
+local int gz_comp OF((gz_statep, int));
+local int gz_zero OF((gz_statep, z_off64_t));
+
+/* Initialize state for writing a gzip file.  Mark initialization by setting
+   state->size to non-zero.  Return -1 on failure or 0 on success. */
+local int gz_init(state)
+    gz_statep state;
+{
+    int ret;
+    z_streamp strm = &(state->strm);
+
+    /* allocate input and output buffers */
+    state->in = malloc(state->want);
+    state->out = malloc(state->want);
+    if (state->in == NULL || state->out == NULL) {
+        if (state->out != NULL)
+            free(state->out);
+        if (state->in != NULL)
+            free(state->in);
+        gz_error(state, Z_MEM_ERROR, "out of memory");
+        return -1;
+    }
+
+    /* allocate deflate memory, set up for gzip compression */
+    strm->zalloc = Z_NULL;
+    strm->zfree = Z_NULL;
+    strm->opaque = Z_NULL;
+    ret = deflateInit2(strm, state->level, Z_DEFLATED,
+                       15 + 16, 8, state->strategy);
+    if (ret != Z_OK) {
+        free(state->in);
+        gz_error(state, Z_MEM_ERROR, "out of memory");
+        return -1;
+    }
+
+    /* mark state as initialized */
+    state->size = state->want;
+
+    /* initialize write buffer */
+    strm->avail_out = state->size;
+    strm->next_out = state->out;
+    state->next = strm->next_out;
+    return 0;
+}
+
+/* Compress whatever is at avail_in and next_in and write to the output file.
+   Return -1 if there is an error writing to the output file, otherwise 0.
+   flush is assumed to be a valid deflate() flush value.  If flush is Z_FINISH,
+   then the deflate() state is reset to start a new gzip stream. */
+local int gz_comp(state, flush)
+    gz_statep state;
+    int flush;
+{
+    int ret, got;
+    unsigned have;
+    z_streamp strm = &(state->strm);
+
+    /* allocate memory if this is the first time through */
+    if (state->size == 0 && gz_init(state) == -1)
+        return -1;
+
+    /* run deflate() on provided input until it produces no more output */
+    ret = Z_OK;
+    do {
+        /* write out current buffer contents if full, or if flushing, but if
+           doing Z_FINISH then don't write until we get to Z_STREAM_END */
+        if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
+            (flush != Z_FINISH || ret == Z_STREAM_END))) {
+            have = (unsigned)(strm->next_out - state->next);
+            if (have && ((got = write(state->fd, state->next, have)) < 0 ||
+                         (unsigned)got != have)) {
+                gz_error(state, Z_ERRNO, zstrerror());
+                return -1;
+            }
+            if (strm->avail_out == 0) {
+                strm->avail_out = state->size;
+                strm->next_out = state->out;
+            }
+            state->next = strm->next_out;
+        }
+
+        /* compress */
+        have = strm->avail_out;
+        ret = deflate(strm, flush);
+        if (ret == Z_STREAM_ERROR) {
+            gz_error(state, Z_STREAM_ERROR,
+                      "internal error: deflate stream corrupt");
+            return -1;
+        }
+        have -= strm->avail_out;
+    } while (have);
+
+    /* if that completed a deflate stream, allow another to start */
+    if (flush == Z_FINISH)
+        deflateReset(strm);
+
+    /* all done, no errors */
+    return 0;
+}
+
+/* Compress len zeros to output.  Return -1 on error, 0 on success. */
+local int gz_zero(state, len)
+    gz_statep state;
+    z_off64_t len;
+{
+    int first;
+    unsigned n;
+    z_streamp strm = &(state->strm);
+
+    /* consume whatever's left in the input buffer */
+    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+        return -1;
+
+    /* compress len zeros (len guaranteed > 0) */
+    first = 1;
+    while (len) {
+        n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
+            (unsigned)len : state->size;
+        if (first) {
+            memset(state->in, 0, n);
+            first = 0;
+        }
+        strm->avail_in = n;
+        strm->next_in = state->in;
+        state->pos += n;
+        if (gz_comp(state, Z_NO_FLUSH) == -1)
+            return -1;
+        len -= n;
+    }
+    return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzwrite(file, buf, len)
+    gzFile file;
+    voidpc buf;
+    unsigned len;
+{
+    unsigned put = len;
+    unsigned n;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return 0;
+
+    /* since an int is returned, make sure len fits in one, otherwise return
+       with an error (this avoids the flaw in the interface) */
+    if ((int)len < 0) {
+        gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
+        return 0;
+    }
+
+    /* if len is zero, avoid unnecessary operations */
+    if (len == 0)
+        return 0;
+
+    /* allocate memory if this is the first time through */
+    if (state->size == 0 && gz_init(state) == -1)
+        return 0;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return 0;
+    }
+
+    /* for small len, copy to input buffer, otherwise compress directly */
+    if (len < state->size) {
+        /* copy to input buffer, compress when full */
+        do {
+            if (strm->avail_in == 0)
+                strm->next_in = state->in;
+            n = state->size - strm->avail_in;
+            if (n > len)
+                n = len;
+            memcpy(strm->next_in + strm->avail_in, buf, n);
+            strm->avail_in += n;
+            state->pos += n;
+            buf = (char *)buf + n;
+            len -= n;
+            if (len && gz_comp(state, Z_NO_FLUSH) == -1)
+                return 0;
+        } while (len);
+    }
+    else {
+        /* consume whatever's left in the input buffer */
+        if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+            return 0;
+
+        /* directly compress user buffer to file */
+        strm->avail_in = len;
+        strm->next_in = (voidp)buf;
+        state->pos += len;
+        if (gz_comp(state, Z_NO_FLUSH) == -1)
+            return 0;
+    }
+
+    /* input was all buffered or compressed (put will fit in int) */
+    return (int)put;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputc(file, c)
+    gzFile file;
+    int c;
+{
+    unsigned char buf[1];
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return -1;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* try writing to input buffer for speed (state->size == 0 if buffer not
+       initialized) */
+    if (strm->avail_in < state->size) {
+        if (strm->avail_in == 0)
+            strm->next_in = state->in;
+        strm->next_in[strm->avail_in++] = c;
+        state->pos++;
+        return c;
+    }
+
+    /* no room in buffer or not initialized, use gz_write() */
+    buf[0] = c;
+    if (gzwrite(file, buf, 1) != 1)
+        return -1;
+    return c;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputs(file, str)
+    gzFile file;
+    const char *str;
+{
+    int ret;
+    unsigned len;
+
+    /* write string */
+    len = (unsigned)strlen(str);
+    ret = gzwrite(file, str, len);
+    return ret == 0 && len != 0 ? -1 : ret;
+}
+
+#ifdef STDC
+#include <stdarg.h>
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
+{
+    int size, len;
+    gz_statep state;
+    z_streamp strm;
+    va_list va;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return 0;
+
+    /* make sure we have some buffer space */
+    if (state->size == 0 && gz_init(state) == -1)
+        return 0;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return 0;
+    }
+
+    /* consume whatever's left in the input buffer */
+    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+        return 0;
+
+    /* do the printf() into the input buffer, put length in len */
+    size = (int)(state->size);
+    state->in[size - 1] = 0;
+    va_start(va, format);
+#ifdef NO_vsnprintf
+#  ifdef HAS_vsprintf_void
+    (void)vsprintf(state->in, format, va);
+    va_end(va);
+    for (len = 0; len < size; len++)
+        if (state->in[len] == 0) break;
+#  else
+    len = vsprintf(state->in, format, va);
+    va_end(va);
+#  endif
+#else
+#  ifdef HAS_vsnprintf_void
+    (void)vsnprintf(state->in, size, format, va);
+    va_end(va);
+    len = strlen(state->in);
+#  else
+    len = vsnprintf((char *)(state->in), size, format, va);
+    va_end(va);
+#  endif
+#endif
+
+    /* check that printf() results fit in buffer */
+    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+        return 0;
+
+    /* update buffer and position, defer compression until needed */
+    strm->avail_in = (unsigned)len;
+    strm->next_in = state->in;
+    state->pos += len;
+    return len;
+}
+
+#else /* !STDC */
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+    gzFile file;
+    const char *format;
+    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+    int size, len;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return 0;
+
+    /* make sure we have some buffer space */
+    if (state->size == 0 && gz_init(state) == -1)
+        return 0;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return 0;
+    }
+
+    /* consume whatever's left in the input buffer */
+    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+        return 0;
+
+    /* do the printf() into the input buffer, put length in len */
+    size = (int)(state->size);
+    state->in[size - 1] = 0;
+#ifdef NO_snprintf
+#  ifdef HAS_sprintf_void
+    sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
+            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    for (len = 0; len < size; len++)
+        if (state->in[len] == 0) break;
+#  else
+    len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
+                a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#else
+#  ifdef HAS_snprintf_void
+    snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    len = strlen(state->in);
+#  else
+    len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#endif
+
+    /* check that printf() results fit in buffer */
+    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+        return 0;
+
+    /* update buffer and position, defer compression until needed */
+    strm->avail_in = (unsigned)len;
+    strm->next_in = state->in;
+    state->pos += len;
+    return len;
+}
+
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzflush(file, flush)
+    gzFile file;
+    int flush;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return Z_STREAM_ERROR;
+
+    /* check flush parameter */
+    if (flush < 0 || flush > Z_FINISH)
+        return Z_STREAM_ERROR;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* compress remaining data with requested flush */
+    gz_comp(state, flush);
+    return state->err;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzsetparams(file, level, strategy)
+    gzFile file;
+    int level;
+    int strategy;
+{
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return Z_STREAM_ERROR;
+
+    /* if no change is requested, then do nothing */
+    if (level == state->level && strategy == state->strategy)
+        return Z_OK;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* change compression parameters for subsequent input */
+    if (state->size) {
+        /* flush previous input with previous parameters before changing */
+        if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
+            return state->err;
+        deflateParams(strm, level, strategy);
+    }
+    state->level = level;
+    state->strategy = strategy;
+    return Z_OK;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_w(file)
+    gzFile file;
+{
+    int ret = 0;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    /* check that we're writing */
+    if (state->mode != GZ_WRITE)
+        return Z_STREAM_ERROR;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        ret += gz_zero(state, state->skip);
+    }
+
+    /* flush, free memory, and close file */
+    ret += gz_comp(state, Z_FINISH);
+    (void)deflateEnd(&(state->strm));
+    free(state->out);
+    free(state->in);
+    gz_error(state, Z_OK, NULL);
+    free(state->path);
+    ret += close(state->fd);
+    free(state);
+    return ret ? Z_ERRNO : Z_OK;
+}
diff --git a/8.x/zlib/infback.c b/8.x/zlib/infback.c
new file mode 100644 (file)
index 0000000..af3a8c9
--- /dev/null
@@ -0,0 +1,632 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2009 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+   This code is largely copied from inflate.c.  Normally either infback.o or
+   inflate.o would be linked into an application--not both.  The interface
+   with inffast.c is retained so that optimized assembler-coded versions of
+   inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+   strm provides memory allocation functions in zalloc and zfree, or
+   Z_NULL to use the library memory allocation functions.
+
+   windowBits is in the range 8..15, and window is a user-supplied
+   window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL || window == Z_NULL ||
+        windowBits < 8 || windowBits > 15)
+        return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+                                               sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->dmax = 32768U;
+    state->wbits = windowBits;
+    state->wsize = 1U << windowBits;
+    state->window = window;
+    state->wnext = 0;
+    state->whave = 0;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Assure that some input is available.  If input is requested, but denied,
+   then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+    do { \
+        if (have == 0) { \
+            have = in(in_desc, &next); \
+            if (have == 0) { \
+                next = Z_NULL; \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+   with an error if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        PULL(); \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflateBack() with
+   an error. */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Assure that some output space is available, by writing out the window
+   if it's full.  If the write fails, return from inflateBack() with a
+   Z_BUF_ERROR. */
+#define ROOM() \
+    do { \
+        if (left == 0) { \
+            put = state->window; \
+            left = state->wsize; \
+            state->whave = left; \
+            if (out(out_desc, put, left)) { \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/*
+   strm provides the memory allocation functions and window buffer on input,
+   and provides information on the unused input on return.  For Z_DATA_ERROR
+   returns, strm will also provide an error message.
+
+   in() and out() are the call-back input and output functions.  When
+   inflateBack() needs more input, it calls in().  When inflateBack() has
+   filled the window with output, or when it completes with data in the
+   window, it calls out() to write out the data.  The application must not
+   change the provided input until in() is called again or inflateBack()
+   returns.  The application must not change the window/output buffer until
+   inflateBack() returns.
+
+   in() and out() are called with a descriptor parameter provided in the
+   inflateBack() call.  This parameter can be a structure that provides the
+   information required to do the read or write, as well as accumulated
+   information on the input and output such as totals and check values.
+
+   in() should return zero on failure.  out() should return non-zero on
+   failure.  If either in() or out() fails, than inflateBack() returns a
+   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
+   was in() or out() that caused in the error.  Otherwise,  inflateBack()
+   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+   error, or Z_MEM_ERROR if it could not allocate memory for the state.
+   inflateBack() can also return Z_STREAM_ERROR if the input parameters
+   are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    /* Check that the strm exists and that the state was initialized */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* Reset the state */
+    strm->msg = Z_NULL;
+    state->mode = TYPE;
+    state->last = 0;
+    state->whave = 0;
+    next = strm->next_in;
+    have = next != Z_NULL ? strm->avail_in : 0;
+    hold = 0;
+    bits = 0;
+    put = state->window;
+    left = state->wsize;
+
+    /* Inflate until end of block marked as last */
+    for (;;)
+        switch (state->mode) {
+        case TYPE:
+            /* determine and dispatch block type */
+            if (state->last) {
+                BYTEBITS();
+                state->mode = DONE;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+
+        case STORED:
+            /* get and verify stored block length */
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+
+            /* copy stored block from input to output */
+            while (state->length != 0) {
+                copy = state->length;
+                PULL();
+                ROOM();
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+
+        case TABLE:
+            /* get dynamic table entries descriptor */
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+
+            /* get code length code lengths (not a typo) */
+            state->have = 0;
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+
+            /* get length and distance code code lengths */
+            state->have = 0;
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    NEEDBITS(here.bits);
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = (unsigned)(state->lens[state->have - 1]);
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+
+        case LEN:
+            /* use inflate_fast() if we have enough input and output */
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                if (state->whave < state->wsize)
+                    state->whave = state->wsize - left;
+                inflate_fast(strm, state->wsize);
+                LOAD();
+                break;
+            }
+
+            /* get a literal, length, or end-of-block code */
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            state->length = (unsigned)here.val;
+
+            /* process literal */
+            if (here.op == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                ROOM();
+                *put++ = (unsigned char)(state->length);
+                left--;
+                state->mode = LEN;
+                break;
+            }
+
+            /* process end of block */
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+
+            /* invalid code */
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+
+            /* length code -- get extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+
+            /* get distance code */
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+
+            /* get distance extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            if (state->offset > state->wsize - (state->whave < state->wsize ?
+                                                left : 0)) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+
+            /* copy match from window to output */
+            do {
+                ROOM();
+                copy = state->wsize - state->offset;
+                if (copy < left) {
+                    from = put + copy;
+                    copy = left - copy;
+                }
+                else {
+                    from = put - state->offset;
+                    copy = left;
+                }
+                if (copy > state->length) copy = state->length;
+                state->length -= copy;
+                left -= copy;
+                do {
+                    *put++ = *from++;
+                } while (--copy);
+            } while (state->length != 0);
+            break;
+
+        case DONE:
+            /* inflate stream terminated properly -- write leftover output */
+            ret = Z_STREAM_END;
+            if (left < state->wsize) {
+                if (out(out_desc, state->window, state->wsize - left))
+                    ret = Z_BUF_ERROR;
+            }
+            goto inf_leave;
+
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+
+        default:                /* can't happen, but makes compilers happy */
+            ret = Z_STREAM_ERROR;
+            goto inf_leave;
+        }
+
+    /* Return unused input */
+  inf_leave:
+    strm->next_in = next;
+    strm->avail_in = have;
+    return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
diff --git a/8.x/zlib/inffast.c b/8.x/zlib/inffast.c
new file mode 100644 (file)
index 0000000..2f1d60b
--- /dev/null
@@ -0,0 +1,340 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2008, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+   Based on testing to date,
+   Pre-increment preferred for:
+   - PowerPC G3 (Adler)
+   - MIPS R5000 (Randers-Pehrson)
+   Post-increment preferred for:
+   - none
+   No measurable difference:
+   - Pentium III (Anderson)
+   - M68060 (Nikl)
+ */
+#ifdef POSTINC
+#  define OFF 0
+#  define PUP(a) *(a)++
+#else
+#  define OFF 1
+#  define PUP(a) *++(a)
+#endif
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *in;      /* local strm->next_in */
+    unsigned char FAR *last;    /* while in < last, enough input available */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code here;                  /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in - OFF;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out - OFF;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
+    wsize = state->wsize;
+    whave = state->whave;
+    wnext = state->wnext;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+        }
+        here = lcode[hold & lmask];
+      dolen:
+        op = (unsigned)(here.bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(here.op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", here.val));
+            PUP(out) = (unsigned char)(here.val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(here.val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+            }
+            here = dcode[hold & dmask];
+          dodist:
+            op = (unsigned)(here.bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(here.op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(here.val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(PUP(in)) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        if (state->sane) {
+                            strm->msg =
+                                (char *)"invalid distance too far back";
+                            state->mode = BAD;
+                            break;
+                        }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        if (len <= op - whave) {
+                            do {
+                                PUP(out) = 0;
+                            } while (--len);
+                            continue;
+                        }
+                        len -= op - whave;
+                        do {
+                            PUP(out) = 0;
+                        } while (--op > whave);
+                        if (op == 0) {
+                            from = out - dist;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--len);
+                            continue;
+                        }
+#endif
+                    }
+                    from = window - OFF;
+                    if (wnext == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (wnext < op) {      /* wrap around window */
+                        from += wsize + wnext - op;
+                        op -= wnext;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = window - OFF;
+                            if (wnext < len) {  /* some from start of window */
+                                op = wnext;
+                                len -= op;
+                                do {
+                                    PUP(out) = PUP(from);
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += wnext - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    }
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+                else {
+                    from = out - dist;          /* copy direct from output */
+                    do {                        /* minimum length is three */
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    } while (len > 2);
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                here = dcode[here.val + (hold & ((1U << op) - 1))];
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            here = lcode[here.val + (hold & ((1U << op) - 1))];
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in + OFF;
+    strm->next_out = out + OFF;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and wnext == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/8.x/zlib/inffast.h b/8.x/zlib/inffast.h
new file mode 100644 (file)
index 0000000..e5c1aa4
--- /dev/null
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/8.x/zlib/inffixed.h b/8.x/zlib/inffixed.h
new file mode 100644 (file)
index 0000000..75ed4b5
--- /dev/null
@@ -0,0 +1,94 @@
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
+
+    /* WARNING: this file should *not* be used by applications. It
+       is part of the implementation of the compression library and
+       is subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };
diff --git a/8.x/zlib/inflate.c b/8.x/zlib/inflate.c
new file mode 100644 (file)
index 0000000..a8431ab
--- /dev/null
@@ -0,0 +1,1480 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0    24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ *   creation of window when not needed, minimize use of window when it is
+ *   needed, make inffast.c even faster, implement gzip decoding, and to
+ *   improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1    25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2    4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ *   to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3    22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ *   buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4    1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ *   source file infback.c to provide a call-back interface to inflate for
+ *   programs like gzip and unzip -- uses window as output buffer to avoid
+ *   window copying
+ *
+ * 1.2.beta5    1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ *   input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6    4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ *   make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7    27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0        9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ *   for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ *   and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+   void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+                              unsigned len));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    strm->adler = 1;        /* to support ill-conceived Java test suite */
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
+    state->wsize = 0;
+    state->whave = 0;
+    state->wnext = 0;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    state->sane = 1;
+    state->back = -1;
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+    int wrap;
+    struct inflate_state FAR *state;
+
+    /* get the state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* extract wrap request from windowBits parameter */
+    if (windowBits < 0) {
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+        if (windowBits < 48)
+            windowBits &= 15;
+#endif
+    }
+
+    /* set number of window bits, free window if different */
+    if (windowBits && (windowBits < 8 || windowBits > 15))
+        return Z_STREAM_ERROR;
+    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+        ZFREE(strm, state->window);
+        state->window = Z_NULL;
+    }
+
+    /* update state and reset the rest of it */
+    state->wrap = wrap;
+    state->wbits = (unsigned)windowBits;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+    int ret;
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)
+            ZALLOC(strm, 1, sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->window = Z_NULL;
+    ret = inflateReset2(strm, windowBits);
+    if (ret != Z_OK) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+    }
+    return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (bits < 0) {
+        state->hold = 0;
+        state->bits = 0;
+        return Z_OK;
+    }
+    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+    value &= (1L << bits) - 1;
+    state->hold += value << state->bits;
+    state->bits += bits;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
+   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
+   those tables to stdout, which would be piped to inffixed.h.  A small program
+   can simply call makefixed to do this:
+
+    void makefixed(void);
+
+    int main(void)
+    {
+        makefixed();
+        return 0;
+    }
+
+   Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+    a.out > inffixed.h
+ */
+void makefixed()
+{
+    unsigned low, size;
+    struct inflate_state state;
+
+    fixedtables(&state);
+    puts("    /* inffixed.h -- table for decoding fixed codes");
+    puts("     * Generated automatically by makefixed().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 7) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+               state.lencode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+               state.distcode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+    struct inflate_state FAR *state;
+    unsigned copy, dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->wnext = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    copy = out - strm->avail_out;
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+        state->wnext = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->wnext;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, strm->next_out - copy, copy);
+            state->wnext = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->wnext += dist;
+            if (state->wnext == state->wsize) state->wnext = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+    ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
+        break;
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned in, out;           /* save starting available input and output */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            state->flags = 0;           /* expect zlib header */
+            if (state->head != Z_NULL)
+                state->head->done = -1;
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            len = BITS(4) + 8;
+            if (state->wbits == 0)
+                state->wbits = len;
+            else if (len > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            state->dmax = 1U << len;
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+        case TIME:
+            NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
+            if (state->flags & 0x0200) CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+        case OS:
+            NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
+                if (state->flags & 0x0200) CRC2(state->check, hold);
+                INITBITS();
+            }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
+            state->mode = EXTRA;
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL) {
+                        len = state->head->extra_len - state->length;
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
+                    if (state->flags & 0x0200)
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->length = 0;
+            state->mode = NAME;
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
+            state->mode = COMMENT;
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
+            state->mode = HCRC;
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if (hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = REVERSE(hold);
+            INITBITS();
+            state->mode = DICT;
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+        case TYPE:
+            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN_;             /* decode codes */
+                if (flush == Z_TREES) {
+                    DROPBITS(2);
+                    goto inf_leave;
+                }
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+        case STORED:
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+            state->mode = COPY_;
+            if (flush == Z_TREES) goto inf_leave;
+        case COPY_:
+            state->mode = COPY;
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+            state->have = 0;
+            state->mode = LENLENS;
+        case LENLENS:
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+            state->have = 0;
+            state->mode = CODELENS;
+        case CODELENS:
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    NEEDBITS(here.bits);
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = state->lens[state->have - 1];
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN_;
+            if (flush == Z_TREES) goto inf_leave;
+        case LEN_:
+            state->mode = LEN;
+        case LEN:
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                if (state->mode == TYPE)
+                    state->back = -1;
+                break;
+            }
+            state->back = 0;
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            state->length = (unsigned)here.val;
+            if ((int)(here.op) == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                state->mode = LIT;
+                break;
+            }
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->back = -1;
+                state->mode = TYPE;
+                break;
+            }
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = LENEXT;
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->was = state->length;
+            state->mode = DIST;
+        case DIST:
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = DISTEXT;
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->whave) {
+                    if (state->sane) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                    Trace((stderr, "inflate.c too far\n"));
+                    copy -= state->whave;
+                    if (copy > state->length) copy = state->length;
+                    if (copy > left) copy = left;
+                    left -= copy;
+                    state->length -= copy;
+                    do {
+                        *put++ = 0;
+                    } while (--copy);
+                    if (state->length == 0) state->mode = LEN;
+                    break;
+#endif
+                }
+                if (copy > state->wnext) {
+                    copy -= state->wnext;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->wnext - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if (out)
+                    strm->adler = state->check =
+                        UPDATE(state->check, put - out, out);
+                out = left;
+                if ((
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     REVERSE(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if (hold != (state->total & 0xffffffffUL)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+        if (updatewindow(strm, out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if (state->wrap && out)
+        strm->adler = state->check =
+            UPDATE(state->check, strm->next_out - out, out);
+    strm->data_type = state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0) +
+                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) ZFREE(strm, state->window);
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+    struct inflate_state FAR *state;
+    unsigned long id;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->wrap != 0 && state->mode != DICT)
+        return Z_STREAM_ERROR;
+
+    /* check for correct dictionary id */
+    if (state->mode == DICT) {
+        id = adler32(0L, Z_NULL, 0);
+        id = adler32(id, dictionary, dictLength);
+        if (id != state->check)
+            return Z_DATA_ERROR;
+    }
+
+    /* copy dictionary to window */
+    if (updatewindow(strm, strm->avail_out)) {
+        state->mode = MEM;
+        return Z_MEM_ERROR;
+    }
+    if (dictLength > state->wsize) {
+        zmemcpy(state->window, dictionary + dictLength - state->wsize,
+                state->wsize);
+        state->whave = state->wsize;
+    }
+    else {
+        zmemcpy(state->window + state->wsize - dictLength, dictionary,
+                dictLength);
+        state->whave = dictLength;
+    }
+    state->havedict = 1;
+    Tracev((stderr, "inflate:   dictionary set\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+    /* save header structure */
+    state->head = head;
+    head->done = 0;
+    return Z_OK;
+}
+
+/*
+   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
+   or when out of input.  When called, *have is the number of pattern bytes
+   found in order so far, in 0..3.  On return *have is updated to the new
+   state.  If on return *have equals four, then the pattern was found and the
+   return value is how many bytes were read including the last byte of the
+   pattern.  If *have is less than four, then the pattern has not been found
+   yet and the return value is len.  In the latter case, syncsearch() can be
+   called again with more data and the *have state.  *have is initialized to
+   zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+unsigned char FAR *buf;
+unsigned len;
+{
+    unsigned got;
+    unsigned next;
+
+    got = *have;
+    next = 0;
+    while (next < len && got < 4) {
+        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+            got++;
+        else if (buf[next])
+            got = 0;
+        else
+            got = 4 - got;
+        next++;
+    }
+    *have = got;
+    return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+    unsigned len;               /* number of bytes to look at or looked at */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
+    unsigned char buf[4];       /* to restore bit buffer to byte string */
+    struct inflate_state FAR *state;
+
+    /* check parameters */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+    /* if first time, start search in bit buffer */
+    if (state->mode != SYNC) {
+        state->mode = SYNC;
+        state->hold <<= state->bits & 7;
+        state->bits -= state->bits & 7;
+        len = 0;
+        while (state->bits >= 8) {
+            buf[len++] = (unsigned char)(state->hold);
+            state->hold >>= 8;
+            state->bits -= 8;
+        }
+        state->have = 0;
+        syncsearch(&(state->have), buf, len);
+    }
+
+    /* search available input */
+    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+    strm->avail_in -= len;
+    strm->next_in += len;
+    strm->total_in += len;
+
+    /* return no joy or set up to restart inflate() on a new block */
+    if (state->have != 4) return Z_DATA_ERROR;
+    in = strm->total_in;  out = strm->total_out;
+    inflateReset(strm);
+    strm->total_in = in;  strm->total_out = out;
+    state->mode = TYPE;
+    return Z_OK;
+}
+
+/*
+   Returns true if inflate is currently at the end of a block generated by
+   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+   implementation to provide an additional safety check. PPP uses
+   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+   block. When decompressing, PPP checks that at the end of input packet,
+   inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+    struct inflate_state FAR *state;
+    struct inflate_state FAR *copy;
+    unsigned char FAR *window;
+    unsigned wsize;
+
+    /* check input */
+    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)source->state;
+
+    /* allocate space */
+    copy = (struct inflate_state FAR *)
+           ZALLOC(source, 1, sizeof(struct inflate_state));
+    if (copy == Z_NULL) return Z_MEM_ERROR;
+    window = Z_NULL;
+    if (state->window != Z_NULL) {
+        window = (unsigned char FAR *)
+                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+        if (window == Z_NULL) {
+            ZFREE(source, copy);
+            return Z_MEM_ERROR;
+        }
+    }
+
+    /* copy state */
+    zmemcpy(dest, source, sizeof(z_stream));
+    zmemcpy(copy, state, sizeof(struct inflate_state));
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1) {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
+    copy->next = copy->codes + (state->next - state->codes);
+    if (window != Z_NULL) {
+        wsize = 1U << state->wbits;
+        zmemcpy(window, state->window, wsize);
+    }
+    copy->window = window;
+    dest->state = (struct internal_state FAR *)copy;
+    return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    state->sane = !subvert;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+    return Z_OK;
+#else
+    state->sane = 1;
+    return Z_DATA_ERROR;
+#endif
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+    state = (struct inflate_state FAR *)strm->state;
+    return ((long)(state->back) << 16) +
+        (state->mode == COPY ? state->length :
+            (state->mode == MATCH ? state->was - state->length : 0));
+}
diff --git a/8.x/zlib/inflate.h b/8.x/zlib/inflate.h
new file mode 100644 (file)
index 0000000..95f4986
--- /dev/null
@@ -0,0 +1,122 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2009 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD,       /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY_,      /* i/o: same as COPY below, but only first time in */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN_,       /* i: same as LEN below, but only first time in */
+            LEN,        /* i: waiting for length/lit/eob code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib) or (raw)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+                  HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+        (raw) -> TYPEDO
+    Read deflate blocks:
+            TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+            STORED -> COPY_ -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN_
+            LEN_ -> LEN
+    Read deflate codes in fixed or dynamic block:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls.  Approximately 10K bytes. */
+struct inflate_state {
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+    int sane;                   /* if false, allow invalid distance too far */
+    int back;                   /* bits back of last unprocessed length/lit */
+    unsigned was;               /* initial length of match */
+};
diff --git a/8.x/zlib/inftrees.c b/8.x/zlib/inftrees.c
new file mode 100644 (file)
index 0000000..11e9c52
--- /dev/null
@@ -0,0 +1,330 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+   " inflate 1.2.5 Copyright 1995-2010 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code here;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) {                     /* no symbols to code at all */
+        here.op = (unsigned char)64;    /* invalid code marker */
+        here.bits = (unsigned char)1;
+        here.val = (unsigned short)0;
+        *(*table)++ = here;             /* make a table to force an error */
+        *(*table)++ = here;
+        *bits = 1;
+        return 0;     /* no symbols, but wait for decoding to report error */
+    }
+    for (min = 1; min < max; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked for LENS and DIST tables against
+       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+       the initial root table size constants.  See the comments in inftrees.h
+       for more information.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if ((type == LENS && used >= ENOUGH_LENS) ||
+        (type == DISTS && used >= ENOUGH_DISTS))
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        here.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            here.op = (unsigned char)0;
+            here.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            here.op = (unsigned char)(extra[work[sym]]);
+            here.val = base[work[sym]];
+        }
+        else {
+            here.op = (unsigned char)(32 + 64);         /* end of block */
+            here.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = here;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += min;            /* here min is 1 << curr */
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if ((type == LENS && used >= ENOUGH_LENS) ||
+                (type == DISTS && used >= ENOUGH_DISTS))
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /*
+       Fill in rest of table for incomplete codes.  This loop is similar to the
+       loop above in incrementing huff for table indices.  It is assumed that
+       len is equal to curr + drop, so there is no loop needed to increment
+       through high index bits.  When the current sub-table is filled, the loop
+       drops back to the root table to fill in any remaining entries there.
+     */
+    here.op = (unsigned char)64;                /* invalid code marker */
+    here.bits = (unsigned char)(len - drop);
+    here.val = (unsigned short)0;
+    while (huff != 0) {
+        /* when done with sub-table, drop back to root table */
+        if (drop != 0 && (huff & mask) != low) {
+            drop = 0;
+            len = root;
+            next = *table;
+            here.bits = (unsigned char)len;
+        }
+
+        /* put invalid code marker in table */
+        next[huff >> drop] = here;
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
diff --git a/8.x/zlib/inftrees.h b/8.x/zlib/inftrees.h
new file mode 100644 (file)
index 0000000..baa53a0
--- /dev/null
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table.  The maximum number of code structures is
+   1444, which is the sum of 852 for literal/length codes and 592 for distance
+   codes.  These values were found by exhaustive searches using the program
+   examples/enough.c found in the zlib distribtution.  The arguments to that
+   program are the number of symbols, the initial root table size, and the
+   maximum bit length of a code.  "enough 286 9 15" for literal/length codes
+   returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+   The initial root table size (9 or 6) is found in the fifth argument of the
+   inflate_table() calls in inflate.c and infback.c.  If the root table size is
+   changed, then these maximum sizes would be need to be recalculated and
+   updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
diff --git a/8.x/zlib/make_vms.com b/8.x/zlib/make_vms.com
new file mode 100644 (file)
index 0000000..6576490
--- /dev/null
@@ -0,0 +1,804 @@
+$! make libz under VMS written by
+$! Martin P.J. Zinser
+$!
+$! In case of problems with the install you might contact me at
+$! zinser@zinser.no-ip.info(preferred) or
+$! zinser@sysdev.deutsche-boerse.com (work)
+$!
+$! Make procedure history for Zlib
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20060120 First version to receive a number
+$! 0.02 20061008 Adapt to new Makefile.in
+$! 0.03 20091224 Add support for large file check
+$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite
+$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in
+$!
+$ on error then goto err_exit
+$ set proc/parse=ext
+$!
+$ true  = 1
+$ false = 0
+$ tmpnam = "temp_" + f$getjpi("","pid")
+$ tt = tmpnam + ".txt"
+$ tc = tmpnam + ".c"
+$ th = tmpnam + ".h"
+$ define/nolog tconfig 'th'
+$ its_decc = false
+$ its_vaxc = false
+$ its_gnuc = false
+$ s_case   = False
+$!
+$! Setup variables holding "config" information
+$!
+$ Make    = ""
+$ name     = "Zlib"
+$ version  = "?.?.?"
+$ v_string = "ZLIB_VERSION"
+$ v_file   = "zlib.h"
+$ ccopt   = ""
+$ lopts   = ""
+$ dnsrl   = ""
+$ aconf_in_file = "zconf.h.in#zconf.h_in"
+$ conf_check_string = ""
+$ linkonly = false
+$ optfile  = name + ".opt"
+$ libdefs  = ""
+$ axp      = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096
+$!
+$ whoami = f$parse(f$enviornment("Procedure"),,,,"NO_CONCEAL")
+$ mydef  = F$parse(whoami,,,"DEVICE")
+$ mydir  = f$parse(whoami,,,"DIRECTORY") - "]["
+$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type")
+$!
+$! Check for MMK/MMS
+$!
+$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$!
+$!
+$ gosub find_version
+$!
+$  open/write topt tmp.opt
+$  open/write optf 'optfile'
+$!
+$ gosub check_opts
+$!
+$! Look for the compiler used
+$!
+$ gosub check_compiler
+$ close topt
+$!
+$ if its_decc
+$ then
+$   ccopt = "/prefix=all" + ccopt
+$   if f$trnlnm("SYS") .eqs. ""
+$   then
+$     if axp
+$     then
+$       define sys sys$library:
+$     else
+$       ccopt = "/decc" + ccopt
+$       define sys decc$library_include:
+$     endif
+$   endif
+$ endif
+$ if its_vaxc .or. its_gnuc
+$ then
+$    if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ endif
+$!
+$! Build a fake configure input header
+$!
+$ open/write conf_hin config.hin
+$ write conf_hin "#undef _LARGEFILE64_SOURCE"
+$ close conf_hin
+$!
+$!
+$ i = 0
+$FIND_ACONF:
+$ fname = f$element(i,"#",aconf_in_file)
+$ if fname .eqs. "#" then goto AMISS_ERR
+$ if f$search(fname) .eqs. ""
+$ then
+$   i = i + 1
+$   goto find_aconf
+$ endif
+$ open/read/err=aconf_err aconf_in 'fname'
+$ open/write aconf zconf.h
+$ACONF_LOOP:
+$ read/end_of_file=aconf_exit aconf_in line
+$ work = f$edit(line, "compress,trim")
+$ if f$extract(0,6,work) .nes. "#undef"
+$ then
+$   if f$extract(0,12,work) .nes. "#cmakedefine"
+$   then
+$       write aconf line
+$   endif
+$ else
+$   cdef = f$element(1," ",work)
+$   gosub check_config
+$ endif
+$ goto aconf_loop
+$ACONF_EXIT:
+$ write aconf "#define VMS 1"
+$ write aconf "#include <unistd.h>"
+$ write aconf "#include <unixio.h>"
+$ write aconf "#ifdef _LARGEFILE"
+$ write aconf "#define off64_t __off64_t"
+$ write aconf "#define fopen64 fopen"
+$ write aconf "#define fseeko64 fseeko"
+$ write aconf "#define lseek64 lseek"
+$ write aconf "#define ftello64 ftell"
+$ write aconf "#endif"
+$ close aconf_in
+$ close aconf
+$ if f$search("''th'") .nes. "" then delete 'th';*
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Zlib sources ..."
+$ if make.eqs.""
+$  then
+$   dele example.obj;*,minigzip.obj;*
+$   CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
+                adler32.c zlib.h zconf.h
+$   CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
+                compress.c zlib.h zconf.h
+$   CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
+                crc32.c zlib.h zconf.h
+$   CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
+                deflate.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" -
+                gzclose.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" -
+                gzlib.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" -
+                gzread.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" -
+                gzwrite.c zutil.h zlib.h zconf.h
+$   CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
+                infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$   CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
+                inffast.c zutil.h zlib.h zconf.h inffast.h
+$   CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
+                inflate.c zutil.h zlib.h zconf.h infblock.h
+$   CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
+                inftrees.c zutil.h zlib.h zconf.h inftrees.h
+$   CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
+                trees.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
+                uncompr.c zlib.h zconf.h
+$   CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
+                zutil.c zutil.h zlib.h zconf.h
+$   write sys$output "Building Zlib ..."
+$   CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
+$   write sys$output "Building example..."
+$   CALL MAKE example.OBJ "CC ''CCOPT' example" -
+                example.c zlib.h zconf.h
+$   call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
+$   if f$search("x11vms:xvmsutils.olb") .nes. ""
+$   then
+$     write sys$output "Building minigzip..."
+$     CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
+                minigzip.c zlib.h zconf.h
+$     call make minigzip.exe -
+                "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" -
+                minigzip.obj libz.olb
+$   endif
+$  else
+$   gosub crea_mms
+$   write sys$output "Make ''name' ''version' with ''Make' "
+$   'make'
+$  endif
+$!
+$! Alpha gets a shareable image
+$!
+$ If axp
+$ Then
+$   gosub crea_olist
+$   write sys$output "Creating libzshr.exe"
+$   call anal_obj_axp modules.opt _link.opt
+$   if s_case
+$   then
+$      open/append optf modules.opt
+$      write optf "case_sensitive=YES"
+$      close optf
+$   endif
+$   LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,_link.opt/opt
+$ endif
+$ write sys$output "Zlib build completed"
+$ exit
+$CC_ERR:
+$ write sys$output "C compiler required to build ''name'"
+$ goto err_exit
+$ERR_EXIT:
+$ set message/facil/ident/sever/text
+$ close/nolog optf
+$ close/nolog topt
+$ close/nolog conf_hin
+$ close/nolog aconf_in
+$ close/nolog aconf
+$ close/nolog out
+$ close/nolog min
+$ close/nolog mod
+$ close/nolog h_in
+$ write sys$output "Exiting..."
+$ exit 2
+$!
+$!
+$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8  What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$       Argument = P'arg
+$       If Argument .Eqs. "" Then Goto Exit
+$       El=0
+$Loop2:
+$       File = F$Element(El," ",Argument)
+$       If File .Eqs. " " Then Goto Endl
+$       AFile = ""
+$Loop3:
+$       OFile = AFile
+$       AFile = F$Search(File)
+$       If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$       If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$       Goto Loop3
+$NextEL:
+$       El = El + 1
+$       Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Check command line options and set symbols accordingly
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20041206 First version to receive a number
+$! 0.02 20060126 Add new "HELP" target
+$ CHECK_OPTS:
+$ i = 1
+$ OPT_LOOP:
+$ if i .lt. 9
+$ then
+$   cparm = f$edit(p'i',"upcase")
+$!
+$! Check if parameter actually contains something
+$!
+$   if f$edit(cparm,"trim") .nes. ""
+$   then
+$     if cparm .eqs. "DEBUG"
+$     then
+$       ccopt = ccopt + "/noopt/deb"
+$       lopts = lopts + "/deb"
+$     endif
+$     if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
+$     then
+$       start = f$locate("=",cparm) + 1
+$       len   = f$length(cparm) - start
+$       ccopt = ccopt + f$extract(start,len,cparm)
+$       if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
+          then s_case = true
+$     endif
+$     if cparm .eqs. "LINK" then linkonly = true
+$     if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
+$     then
+$       start = f$locate("=",cparm) + 1
+$       len   = f$length(cparm) - start
+$       lopts = lopts + f$extract(start,len,cparm)
+$     endif
+$     if f$locate("CC=",cparm) .lt. f$length(cparm)
+$     then
+$       start  = f$locate("=",cparm) + 1
+$       len    = f$length(cparm) - start
+$       cc_com = f$extract(start,len,cparm)
+        if (cc_com .nes. "DECC") .and. -
+           (cc_com .nes. "VAXC") .and. -
+           (cc_com .nes. "GNUC")
+$       then
+$         write sys$output "Unsupported compiler choice ''cc_com' ignored"
+$         write sys$output "Use DECC, VAXC, or GNUC instead"
+$       else
+$         if cc_com .eqs. "DECC" then its_decc = true
+$         if cc_com .eqs. "VAXC" then its_vaxc = true
+$         if cc_com .eqs. "GNUC" then its_gnuc = true
+$       endif
+$     endif
+$     if f$locate("MAKE=",cparm) .lt. f$length(cparm)
+$     then
+$       start  = f$locate("=",cparm) + 1
+$       len    = f$length(cparm) - start
+$       mmks = f$extract(start,len,cparm)
+$       if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS")
+$       then
+$         make = mmks
+$       else
+$         write sys$output "Unsupported make choice ''mmks' ignored"
+$         write sys$output "Use MMK or MMS instead"
+$       endif
+$     endif
+$     if cparm .eqs. "HELP" then gosub bhelp
+$   endif
+$   i = i + 1
+$   goto opt_loop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Look for the compiler used
+$!
+$! Version history
+$! 0.01 20040223 First version to receive a number
+$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists
+$! 0.03 20060202 Extend handling of GNU C
+$! 0.04 20090402 Compaq -> hp
+$CHECK_COMPILER:
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then
+$   its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
+$   its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "")
+$   its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "")
+$ endif
+$!
+$! Exit if no compiler available
+$!
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then goto CC_ERR
+$ else
+$   if its_decc
+$   then
+$     write sys$output "CC compiler check ... hp C"
+$     if f$trnlnm("decc$no_rooted_search_lists") .nes. ""
+$     then
+$       dnrsl = f$trnlnm("decc$no_rooted_search_lists")
+$     endif
+$     define/nolog decc$no_rooted_search_lists 1
+$   else
+$     if its_vaxc then write sys$output "CC compiler check ... VAX C"
+$     if its_gnuc
+$     then
+$         write sys$output "CC compiler check ... GNU C"
+$         if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib"
+$         if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib"
+$         cc = "gcc"
+$     endif
+$     if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share"
+$     if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share"
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! If MMS/MMK are available dump out the descrip.mms if required
+$!
+$CREA_MMS:
+$ write sys$output "Creating descrip.mms..."
+$ create descrip.mms
+$ open/append out descrip.mms
+$ copy sys$input: out
+$ deck
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser
+# <zinser@zinser.no-ip.info or zinser@sysdev.deutsche-boerse.com>
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\
+       gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\
+       deflate.obj, trees.obj, zutil.obj, inflate.obj, \
+       inftrees.obj, inffast.obj
+
+$ eod
+$ write out "CFLAGS=", ccopt
+$ write out "LOPTS=", lopts
+$ copy sys$input: out
+$ deck
+
+all : example.exe minigzip.exe libz.olb
+        @ write sys$output " Example applications available"
+
+libz.olb : libz.olb($(OBJS))
+       @ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+              link $(LOPTS) example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+              link $(LOPTS) minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+
+clean :
+       delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
+
+
+# Other dependencies.
+adler32.obj  : adler32.c zutil.h zlib.h zconf.h
+compress.obj : compress.c zlib.h zconf.h
+crc32.obj    : crc32.c zutil.h zlib.h zconf.h
+deflate.obj  : deflate.c deflate.h zutil.h zlib.h zconf.h
+example.obj  : example.c zlib.h zconf.h
+gzclose.obj  : gzclose.c zutil.h zlib.h zconf.h
+gzlib.obj    : gzlib.c zutil.h zlib.h zconf.h
+gzread.obj   : gzread.c zutil.h zlib.h zconf.h
+gzwrite.obj  : gzwrite.c zutil.h zlib.h zconf.h
+inffast.obj  : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
+inflate.obj  : inflate.c zutil.h zlib.h zconf.h
+inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
+minigzip.obj : minigzip.c zlib.h zconf.h
+trees.obj    : trees.c deflate.h zutil.h zlib.h zconf.h
+uncompr.obj  : uncompr.c zlib.h zconf.h
+zutil.obj    : zutil.c zutil.h zlib.h zconf.h
+infback.obj  : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ eod
+$ close out
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Read list of core library sources from makefile.in and create options
+$! needed to build shareable image
+$!
+$CREA_OLIST:
+$ open/read min makefile.in
+$ open/write mod modules.opt
+$ src_check = "OBJC ="
+$MRLOOP:
+$ read/end=mrdone min rec
+$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop
+$ rec = rec - src_check
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .eqs. "\") then goto mrdone
+$MRSLOOP:
+$ read/end=mrdone min rec
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop
+$MRDONE:
+$ close min
+$ close mod
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Take record extracted in crea_olist and split it into single filenames
+$!
+$EXTRA_FILNAM:
+$ myrec = f$edit(rec - "\", "trim,compress")
+$ i = 0
+$FELOOP:
+$ srcfil = f$element(i," ", myrec)
+$ if (srcfil .nes. " ")
+$ then
+$   write mod f$parse(srcfil,,,"NAME"), ".obj"
+$   i = i + 1
+$   goto feloop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Find current Zlib version number
+$!
+$FIND_VERSION:
+$ open/read h_in 'v_file'
+$hloop:
+$ read/end=hdone h_in rec
+$ rec = f$edit(rec,"TRIM")
+$ if (f$extract(0,1,rec) .nes. "#") then goto hloop
+$ rec = f$edit(rec - "#", "TRIM")
+$ if f$element(0," ",rec) .nes. "define" then goto hloop
+$ if f$element(1," ",rec) .eqs. v_string
+$ then
+$   version = 'f$element(2," ",rec)'
+$   goto hdone
+$ endif
+$ goto hloop
+$hdone:
+$ close h_in
+$ return
+$!------------------------------------------------------------------------------
+$!
+$CHECK_CONFIG:
+$!
+$ in_ldef = f$locate(cdef,libdefs)
+$ if (in_ldef .lt. f$length(libdefs))
+$ then
+$   write aconf "#define ''cdef' 1"
+$   libdefs = f$extract(0,in_ldef,libdefs) + -
+              f$extract(in_ldef + f$length(cdef) + 1, -
+                        f$length(libdefs) - in_ldef - f$length(cdef) - 1, -
+                        libdefs)
+$ else
+$   if (f$type('cdef') .eqs. "INTEGER")
+$   then
+$     write aconf "#define ''cdef' ", 'cdef'
+$   else
+$     if (f$type('cdef') .eqs. "STRING")
+$     then
+$       write aconf "#define ''cdef' ", """", '''cdef'', """"
+$     else
+$       gosub check_cc_def
+$     endif
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check if this is a define relating to the properties of the C/C++
+$! compiler
+$!
+$ CHECK_CC_DEF:
+$ if (cdef .eqs. "_LARGEFILE64_SOURCE")
+$ then
+$   copy sys$input: 'tc'
+$   deck
+#include "tconfig"
+#define _LARGEFILE
+#include <stdio.h>
+
+int main(){
+FILE *fp;
+  fp = fopen("temp.txt","r");
+  fseeko(fp,1,SEEK_SET);
+  fclose(fp);
+}
+
+$   eod
+$   test_inv = false
+$   comm_h = false
+$   gosub cc_prop_check
+$   return
+$ endif
+$ write aconf "/* ", line, " */"
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler
+$!
+$! Version history
+$! 0.01 20031020 First version to receive a number
+$! 0.02 20031022 Added logic for defines with value
+$! 0.03 20040309 Make sure local config file gets not deleted
+$! 0.04 20041230 Also write include for configure run
+$! 0.05 20050103 Add processing of "comment defines"
+$CC_PROP_CHECK:
+$ cc_prop = true
+$ is_need = false
+$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true)
+$ if f$search(th) .eqs. "" then create 'th'
+$ set message/nofac/noident/nosever/notext
+$ on error then continue
+$ cc 'tmpnam'
+$ if .not. ($status)  then cc_prop = false
+$ on error then continue
+$! The headers might lie about the capabilities of the RTL
+$ link 'tmpnam',tmp.opt/opt
+$ if .not. ($status)  then cc_prop = false
+$ set message/fac/ident/sever/text
+$ on error then goto err_exit
+$ delete/nolog 'tmpnam'.*;*/exclude='th'
+$ if (cc_prop .and. .not. is_need) .or. -
+     (.not. cc_prop .and. is_need)
+$ then
+$   write sys$output "Checking for ''cdef'... yes"
+$   if f$type('cdef_val'_yes) .nes. ""
+$   then
+$     if f$type('cdef_val'_yes) .eqs. "INTEGER" -
+         then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes)
+$     if f$type('cdef_val'_yes) .eqs. "STRING" -
+         then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes)
+$   else
+$     call write_config f$fao("#define !AS 1",cdef)
+$   endif
+$   if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. -
+       (cdef .eqs. "_LARGEFILE64_SOURCE") then -
+      call write_config f$string("#define _LARGEFILE 1")
+$ else
+$   write sys$output "Checking for ''cdef'... no"
+$   if (comm_h)
+$   then
+      call write_config f$fao("/* !AS */",line)
+$   else
+$     if f$type('cdef_val'_no) .nes. ""
+$     then
+$       if f$type('cdef_val'_no) .eqs. "INTEGER" -
+           then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no)
+$       if f$type('cdef_val'_no) .eqs. "STRING" -
+           then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no)
+$     else
+$       call write_config f$fao("#undef !AS",cdef)
+$     endif
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler with multiple result values
+$!
+$! Version history
+$! 0.01 20040127 First version
+$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05
+$CC_MPROP_CHECK:
+$ cc_prop = true
+$ i    = 1
+$ idel = 1
+$ MT_LOOP:
+$ if f$type(result_'i') .eqs. "STRING"
+$ then
+$   set message/nofac/noident/nosever/notext
+$   on error then continue
+$   cc 'tmpnam'_'i'
+$   if .not. ($status)  then cc_prop = false
+$   on error then continue
+$! The headers might lie about the capabilities of the RTL
+$   link 'tmpnam'_'i',tmp.opt/opt
+$   if .not. ($status)  then cc_prop = false
+$   set message/fac/ident/sever/text
+$   on error then goto err_exit
+$   delete/nolog 'tmpnam'_'i'.*;*
+$   if (cc_prop)
+$   then
+$     write sys$output "Checking for ''cdef'... ", mdef_'i'
+$     if f$type(mdef_'i') .eqs. "INTEGER" -
+         then call write_config f$fao("#define !AS !UL",cdef,mdef_'i')
+$     if f$type('cdef_val'_yes) .eqs. "STRING" -
+         then call write_config f$fao("#define !AS !AS",cdef,mdef_'i')
+$     goto msym_clean
+$   else
+$     i = i + 1
+$     goto mt_loop
+$   endif
+$ endif
+$ write sys$output "Checking for ''cdef'... no"
+$ call write_config f$fao("#undef !AS",cdef)
+$ MSYM_CLEAN:
+$ if (idel .le. msym_max)
+$ then
+$   delete/sym mdef_'idel'
+$   idel = idel + 1
+$   goto msym_clean
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Analyze Object files for OpenVMS AXP to extract Procedure and Data
+$! information to build a symbol vector for a shareable image
+$! All the "brains" of this logic was suggested by Hartmut Becker
+$! (Hartmut.Becker@compaq.com). All the bugs were introduced by me
+$! (zinser@zinser.no-ip.info), so if you do have problem reports please do not
+$! bother Hartmut/HP, but get in touch with me
+$!
+$! Version history
+$! 0.01 20040406 Skip over shareable images in option file
+$! 0.02 20041109 Fix option file for shareable images with case_sensitive=YES
+$! 0.03 20050107 Skip over Identification labels in option file
+$! 0.04 20060117 Add uppercase alias to code compiled with /name=as_is
+$!
+$ ANAL_OBJ_AXP: Subroutine
+$ V = 'F$Verify(0)
+$ SAY := "WRITE_ SYS$OUTPUT"
+$
+$ IF F$SEARCH("''P1'") .EQS. ""
+$ THEN
+$    SAY "ANAL_OBJ_AXP-E-NOSUCHFILE:  Error, inputfile ''p1' not available"
+$    goto exit_aa
+$ ENDIF
+$ IF "''P2'" .EQS. ""
+$ THEN
+$    SAY "ANAL_OBJ_AXP:  Error, no output file provided"
+$    goto exit_aa
+$ ENDIF
+$
+$ open/read in 'p1
+$ create a.tmp
+$ open/append atmp a.tmp
+$ loop:
+$ read/end=end_loop in line
+$ if f$locate("/SHARE",f$edit(line,"upcase")) .lt. f$length(line)
+$ then
+$   write sys$output "ANAL_SKP_SHR-i-skipshare, ''line'"
+$   goto loop
+$ endif
+$ if f$locate("IDENTIFICATION=",f$edit(line,"upcase")) .lt. f$length(line)
+$ then
+$   write sys$output "ANAL_OBJ_AXP-i-ident: Identification ", -
+                     f$element(1,"=",line)
+$   goto loop
+$ endif
+$ f= f$search(line)
+$ if f .eqs. ""
+$ then
+$      write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'"
+$      goto loop
+$ endif
+$ define/user sys$output nl:
+$ define/user sys$error nl:
+$ anal/obj/gsd 'f /out=x.tmp
+$ open/read xtmp x.tmp
+$ XLOOP:
+$ read/end=end_xloop xtmp xline
+$ xline = f$edit(xline,"compress")
+$ write atmp xline
+$ goto xloop
+$ END_XLOOP:
+$ close xtmp
+$ goto loop
+$ end_loop:
+$ close in
+$ close atmp
+$ if f$search("a.tmp") .eqs. "" -
+       then $ exit
+$ ! all global definitions
+$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp
+$ ! all procedures
+$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp
+$ search c.tmp "symbol:"/out=d.tmp
+$ define/user sys$output nl:
+$ edito/edt/command=sys$input d.tmp
+sub/symbol: "/symbol_vector=(/whole
+sub/"/=PROCEDURE)/whole
+exit
+$ ! all data
+$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp
+$ search e.tmp "symbol:"/out=f.tmp
+$ define/user sys$output nl:
+$ edito/edt/command=sys$input f.tmp
+sub/symbol: "/symbol_vector=(/whole
+sub/"/=DATA)/whole
+exit
+$ sort/nodupl d.tmp,f.tmp g.tmp
+$ open/read raw_vector g.tmp
+$ open/write case_vector 'p2'
+$ RAWLOOP:
+$ read/end=end_rawloop raw_vector raw_element
+$ write case_vector raw_element
+$ if f$locate("=PROCEDURE)",raw_element) .lt. f$length(raw_element)
+$ then
+$     name = f$element(1,"=",raw_element) - "("
+$     if f$edit(name,"UPCASE") .nes. name then -
+          write case_vector f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)", -
+                                 f$edit(name,"UPCASE"), name)
+$ endif
+$ if f$locate("=DATA)",raw_element) .lt. f$length(raw_element)
+$ then
+$     name = f$element(1,"=",raw_element) - "("
+$     if f$edit(name,"UPCASE") .nes. name then -
+          write case_vector f$fao(" symbol_vector=(!AS/!AS=DATA)", -
+                                 f$edit(name,"UPCASE"), name)
+$ endif
+$ goto rawloop
+$ END_RAWLOOP:
+$ close raw_vector
+$ close case_vector
+$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;*,g.tmp;*
+$ if f$search("x.tmp") .nes. "" -
+       then $ delete x.tmp;*
+$!
+$ EXIT_AA:
+$ if V then set verify
+$ endsubroutine
+$!------------------------------------------------------------------------------
+$!
+$! Write configuration to both permanent and temporary config file
+$!
+$! Version history
+$! 0.01 20031029 First version to receive a number
+$!
+$WRITE_CONFIG: SUBROUTINE
+$  write aconf 'p1'
+$  open/append confh 'th'
+$  write confh 'p1'
+$  close confh
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
diff --git a/8.x/zlib/minigzip.c b/8.x/zlib/minigzip.c
new file mode 100644 (file)
index 0000000..9825ccc
--- /dev/null
@@ -0,0 +1,440 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2006, 2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef USE_MMAP
+#  include <sys/types.h>
+#  include <sys/mman.h>
+#  include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  ifdef UNDER_CE
+#    include <stdlib.h>
+#  endif
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#ifdef VMS
+#  define unlink delete
+#  define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+#  define unlink remove
+#  define GZ_SUFFIX "-gz"
+#  define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#  include <unix.h> /* for fileno */
+#endif
+
+#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+  extern int unlink OF((const char *));
+#endif
+#endif
+
+#if defined(UNDER_CE)
+#  include <windows.h>
+#  define perror(s) pwinerror(s)
+
+/* Map the Windows error number in ERROR to a locale-dependent error
+   message string and return a pointer to it.  Typically, the values
+   for ERROR come from GetLastError.
+
+   The string pointed to shall not be modified by the application,
+   but may be overwritten by a subsequent call to strwinerror
+
+   The strwinerror function does not change the current setting
+   of GetLastError.  */
+
+static char *strwinerror (error)
+     DWORD error;
+{
+    static char buf[1024];
+
+    wchar_t *msgbuf;
+    DWORD lasterr = GetLastError();
+    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+        NULL,
+        error,
+        0, /* Default language */
+        (LPVOID)&msgbuf,
+        0,
+        NULL);
+    if (chars != 0) {
+        /* If there is an \r\n appended, zap it.  */
+        if (chars >= 2
+            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+            chars -= 2;
+            msgbuf[chars] = 0;
+        }
+
+        if (chars > sizeof (buf) - 1) {
+            chars = sizeof (buf) - 1;
+            msgbuf[chars] = 0;
+        }
+
+        wcstombs(buf, msgbuf, chars + 1);
+        LocalFree(msgbuf);
+    }
+    else {
+        sprintf(buf, "unknown win32 error (%ld)", error);
+    }
+
+    SetLastError(lasterr);
+    return buf;
+}
+
+static void pwinerror (s)
+    const char *s;
+{
+    if (s && *s)
+        fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
+    else
+        fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
+}
+
+#endif /* UNDER_CE */
+
+#ifndef GZ_SUFFIX
+#  define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN      16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+#  define local static
+   /* Needed for systems with limitation on stack size. */
+#else
+#  define local
+#endif
+
+char *prog;
+
+void error            OF((const char *msg));
+void gz_compress      OF((FILE   *in, gzFile out));
+#ifdef USE_MMAP
+int  gz_compress_mmap OF((FILE   *in, gzFile out));
+#endif
+void gz_uncompress    OF((gzFile in, FILE   *out));
+void file_compress    OF((char  *file, char *mode));
+void file_uncompress  OF((char  *file));
+int  main             OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+    const char *msg;
+{
+    fprintf(stderr, "%s: %s\n", prog, msg);
+    exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+#ifdef USE_MMAP
+    /* Try first compressing with mmap. If mmap fails (minigzip used in a
+     * pipe), use the normal fread loop.
+     */
+    if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+    for (;;) {
+        len = (int)fread(buf, 1, sizeof(buf), in);
+        if (ferror(in)) {
+            perror("fread");
+            exit(1);
+        }
+        if (len == 0) break;
+
+        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+    }
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    int len;
+    int err;
+    int ifd = fileno(in);
+    caddr_t buf;    /* mmap'ed buffer for the entire input file */
+    off_t buf_len;  /* length of the input file */
+    struct stat sb;
+
+    /* Determine the size of the file, needed for mmap: */
+    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+    buf_len = sb.st_size;
+    if (buf_len <= 0) return Z_ERRNO;
+
+    /* Now do the actual mmap: */
+    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+    if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+    /* Compress the whole file at once: */
+    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+    if (len != (int)buf_len) error(gzerror(out, &err));
+
+    munmap(buf, buf_len);
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+    return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+    gzFile in;
+    FILE   *out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+    for (;;) {
+        len = gzread(in, buf, sizeof(buf));
+        if (len < 0) error (gzerror(in, &err));
+        if (len == 0) break;
+
+        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+            error("failed fwrite");
+        }
+    }
+    if (fclose(out)) error("failed fclose");
+
+    if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+    char  *file;
+    char  *mode;
+{
+    local char outfile[MAX_NAME_LEN];
+    FILE  *in;
+    gzFile out;
+
+    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
+        fprintf(stderr, "%s: filename too long\n", prog);
+        exit(1);
+    }
+
+    strcpy(outfile, file);
+    strcat(outfile, GZ_SUFFIX);
+
+    in = fopen(file, "rb");
+    if (in == NULL) {
+        perror(file);
+        exit(1);
+    }
+    out = gzopen(outfile, mode);
+    if (out == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+        exit(1);
+    }
+    gz_compress(in, out);
+
+    unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+    char  *file;
+{
+    local char buf[MAX_NAME_LEN];
+    char *infile, *outfile;
+    FILE  *out;
+    gzFile in;
+    size_t len = strlen(file);
+
+    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
+        fprintf(stderr, "%s: filename too long\n", prog);
+        exit(1);
+    }
+
+    strcpy(buf, file);
+
+    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+        infile = file;
+        outfile = buf;
+        outfile[len-3] = '\0';
+    } else {
+        outfile = file;
+        infile = buf;
+        strcat(infile, GZ_SUFFIX);
+    }
+    in = gzopen(infile, "rb");
+    if (in == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+        exit(1);
+    }
+    out = fopen(outfile, "wb");
+    if (out == NULL) {
+        perror(file);
+        exit(1);
+    }
+
+    gz_uncompress(in, out);
+
+    unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
+ *   -c : write to standard output
+ *   -d : decompress
+ *   -f : compress with Z_FILTERED
+ *   -h : compress with Z_HUFFMAN_ONLY
+ *   -r : compress with Z_RLE
+ *   -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    int copyout = 0;
+    int uncompr = 0;
+    gzFile file;
+    char *bname, outmode[20];
+
+    strcpy(outmode, "wb6 ");
+
+    prog = argv[0];
+    bname = strrchr(argv[0], '/');
+    if (bname)
+      bname++;
+    else
+      bname = argv[0];
+    argc--, argv++;
+
+    if (!strcmp(bname, "gunzip"))
+      uncompr = 1;
+    else if (!strcmp(bname, "zcat"))
+      copyout = uncompr = 1;
+
+    while (argc > 0) {
+      if (strcmp(*argv, "-c") == 0)
+        copyout = 1;
+      else if (strcmp(*argv, "-d") == 0)
+        uncompr = 1;
+      else if (strcmp(*argv, "-f") == 0)
+        outmode[3] = 'f';
+      else if (strcmp(*argv, "-h") == 0)
+        outmode[3] = 'h';
+      else if (strcmp(*argv, "-r") == 0)
+        outmode[3] = 'R';
+      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+               (*argv)[2] == 0)
+        outmode[2] = (*argv)[1];
+      else
+        break;
+      argc--, argv++;
+    }
+    if (outmode[3] == ' ')
+        outmode[3] = 0;
+    if (argc == 0) {
+        SET_BINARY_MODE(stdin);
+        SET_BINARY_MODE(stdout);
+        if (uncompr) {
+            file = gzdopen(fileno(stdin), "rb");
+            if (file == NULL) error("can't gzdopen stdin");
+            gz_uncompress(file, stdout);
+        } else {
+            file = gzdopen(fileno(stdout), outmode);
+            if (file == NULL) error("can't gzdopen stdout");
+            gz_compress(stdin, file);
+        }
+    } else {
+        if (copyout) {
+            SET_BINARY_MODE(stdout);
+        }
+        do {
+            if (uncompr) {
+                if (copyout) {
+                    file = gzopen(*argv, "rb");
+                    if (file == NULL)
+                        fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
+                    else
+                        gz_uncompress(file, stdout);
+                } else {
+                    file_uncompress(*argv);
+                }
+            } else {
+                if (copyout) {
+                    FILE * in = fopen(*argv, "rb");
+
+                    if (in == NULL) {
+                        perror(*argv);
+                    } else {
+                        file = gzdopen(fileno(stdout), outmode);
+                        if (file == NULL) error("can't gzdopen stdout");
+
+                        gz_compress(in, file);
+                    }
+
+                } else {
+                    file_compress(*argv, outmode);
+                }
+            }
+        } while (argv++, --argc);
+    }
+    return 0;
+}
diff --git a/8.x/zlib/msdos/Makefile.bor b/8.x/zlib/msdos/Makefile.bor
new file mode 100644 (file)
index 0000000..0c1b99c
--- /dev/null
@@ -0,0 +1,115 @@
+# Makefile for zlib
+# Borland C++
+# Last updated: 15-Mar-2003
+
+# To use, do "make -fmakefile.bor"
+# To compile in small model, set below: MODEL=s
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. For example:
+#    -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to the LOC macro below:
+#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------ Turbo C++, Borland C++ ------------
+
+#    Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+#    should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
+#    to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# memory model: one of s, m, c, l (small, medium, compact, large)
+MODEL=l
+
+# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
+CC=bcc
+LD=bcc
+AR=tlib
+
+# compiler flags
+# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0
+CFLAGS=-O2 -Z -m$(MODEL) $(LOC)
+
+LDFLAGS=-m$(MODEL) -f-
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+       $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: example.c zlib.h zconf.h
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+       -del $(ZLIB_LIB)
+       $(AR) $(ZLIB_LIB) $(OBJP1)
+       $(AR) $(ZLIB_LIB) $(OBJP2)
+
+example.exe: example.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+test: example.exe minigzip.exe
+       example
+       echo hello world | minigzip | minigzip -d
+
+clean:
+       -del *.obj
+       -del *.lib
+       -del *.exe
+       -del zlib_*.bak
+       -del foo.gz
diff --git a/8.x/zlib/msdos/Makefile.dj2 b/8.x/zlib/msdos/Makefile.dj2
new file mode 100644 (file)
index 0000000..29b0395
--- /dev/null
@@ -0,0 +1,104 @@
+# Makefile for zlib.  Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+#   make -fmakefile.dj2;  make test -fmakefile.dj2
+#
+# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
+#
+#    make install -fmakefile.dj2
+#
+# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
+# in the sample below if the pattern of the DJGPP distribution is to
+# be followed.  Remember that, while <sp>'es around <=> are ignored in
+# makefiles, they are *not* in batch files or in djgpp.env.
+# - - - - -
+# [make]
+# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
+# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
+# BUTT=-m486
+# - - - - -
+# Alternately, these variables may be defined below, overriding the values
+# in djgpp.env, as
+# INCLUDE_PATH=c:\usr\include
+# LIBRARY_PATH=c:\usr\lib
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DDEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+             -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f."  If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lz
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=libz.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+OBJA =
+# to use the asm code: make OBJA=match.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+check: test
+test: all
+       ./example
+       echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+       $(CC) $(CFLAGS) -c $< -o $@
+
+libz.a: $(OBJS) $(OBJA)
+       $(AR) $@ $(OBJS) $(OBJA)
+
+%.exe : %.o $(LIBS)
+       $(LD) $@ $< $(LDLIBS)
+
+# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
+
+.PHONY : uninstall clean
+
+install: $(INCL) $(LIBS)
+       -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
+       -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
+       $(INSTALL) zlib.h $(INCLUDE_PATH)
+       $(INSTALL) zconf.h $(INCLUDE_PATH)
+       $(INSTALL) libz.a $(LIBRARY_PATH)
+
+uninstall:
+       $(RM) $(INCLUDE_PATH)\zlib.h
+       $(RM) $(INCLUDE_PATH)\zconf.h
+       $(RM) $(LIBRARY_PATH)\libz.a
+
+clean:
+       $(RM) *.d
+       $(RM) *.o
+       $(RM) *.exe
+       $(RM) libz.a
+       $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/8.x/zlib/msdos/Makefile.emx b/8.x/zlib/msdos/Makefile.emx
new file mode 100644 (file)
index 0000000..9c1b57a
--- /dev/null
@@ -0,0 +1,69 @@
+# Makefile for zlib.  Modified for emx 0.9c by Chr. Spieler, 6/17/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+#   make -fmakefile.emx;  make test -fmakefile.emx
+#
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DDEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+             -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f."  If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+       ./example
+       echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+       $(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+       $(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+       $(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+       $(RM) *.d
+       $(RM) *.o
+       $(RM) *.exe
+       $(RM) zlib.a
+       $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/8.x/zlib/msdos/Makefile.msc b/8.x/zlib/msdos/Makefile.msc
new file mode 100644 (file)
index 0000000..cd2816f
--- /dev/null
@@ -0,0 +1,112 @@
+# Makefile for zlib
+# Microsoft C 5.1 or later
+# Last updated: 19-Mar-2003
+
+# To use, do "make makefile.msc"
+# To compile in small model, set below: MODEL=S
+
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to the LOC macro below:
+#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Microsoft C 5.1 and later -------------
+
+#    Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+#    should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
+#    to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# Memory model: one of S, M, C, L (small, medium, compact, large)
+MODEL=L
+
+CC=cl
+CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)
+#-Ox generates bad code with MSC 5.1
+LIB_CFLAGS=-Zl $(CFLAGS)
+
+LD=link
+LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode
+# "/farcall/packcode" are only useful for `large code' memory models
+# but should be a "no-op" for small code models.
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+
+
+# targets
+all:  $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+       $(CC) -c $(LIB_CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: example.c zlib.h zconf.h
+       $(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+       $(CC) -c $(CFLAGS) $*.c
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+       if exist $(ZLIB_LIB) del $(ZLIB_LIB)
+       lib $(ZLIB_LIB) $(OBJ1);
+       lib $(ZLIB_LIB) $(OBJ2);
+
+example.exe: example.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);
+
+test: example.exe minigzip.exe
+       example
+       echo hello world | minigzip | minigzip -d
+
+clean:
+       -del *.obj
+       -del *.lib
+       -del *.exe
+       -del *.map
+       -del zlib_*.bak
+       -del foo.gz
diff --git a/8.x/zlib/msdos/Makefile.tc b/8.x/zlib/msdos/Makefile.tc
new file mode 100644 (file)
index 0000000..bcd0d18
--- /dev/null
@@ -0,0 +1,100 @@
+# Makefile for zlib
+# Turbo C 2.01, Turbo C++ 1.01
+# Last updated: 15-Mar-2003
+
+# To use, do "make -fmakefile.tc"
+# To compile in small model, set below: MODEL=s
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. For example:
+#    -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to CFLAGS below:
+#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------
+MODEL=l
+CC=tcc
+LD=tcc
+AR=tlib
+# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+CFLAGS=-O2 -G -Z -m$(MODEL)
+LDFLAGS=-m$(MODEL) -f-
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+       $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: example.c zlib.h zconf.h
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+       -del $(ZLIB_LIB)
+       $(AR) $(ZLIB_LIB) $(OBJP1)
+       $(AR) $(ZLIB_LIB) $(OBJP2)
+
+example.exe: example.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+test: example.exe minigzip.exe
+       example
+       echo hello world | minigzip | minigzip -d
+
+clean:
+       -del *.obj
+       -del *.lib
+       -del *.exe
+       -del zlib_*.bak
+       -del foo.gz
diff --git a/8.x/zlib/nintendods/Makefile b/8.x/zlib/nintendods/Makefile
new file mode 100644 (file)
index 0000000..21337d0
--- /dev/null
@@ -0,0 +1,126 @@
+#---------------------------------------------------------------------------------
+.SUFFIXES:
+#---------------------------------------------------------------------------------
+
+ifeq ($(strip $(DEVKITARM)),)
+$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
+endif
+
+include $(DEVKITARM)/ds_rules
+
+#---------------------------------------------------------------------------------
+# TARGET is the name of the output
+# BUILD is the directory where object files & intermediate files will be placed
+# SOURCES is a list of directories containing source code
+# DATA is a list of directories containing data files
+# INCLUDES is a list of directories containing header files
+#---------------------------------------------------------------------------------
+TARGET         :=      $(shell basename $(CURDIR))
+BUILD          :=      build
+SOURCES                :=      ../../
+DATA           :=      data
+INCLUDES       :=      include
+
+#---------------------------------------------------------------------------------
+# options for code generation
+#---------------------------------------------------------------------------------
+ARCH   :=      -mthumb -mthumb-interwork
+
+CFLAGS :=      -Wall -O2\
+               -march=armv5te -mtune=arm946e-s \
+               -fomit-frame-pointer -ffast-math \
+               $(ARCH)
+
+CFLAGS +=      $(INCLUDE) -DARM9
+CXXFLAGS       := $(CFLAGS) -fno-rtti -fno-exceptions
+
+ASFLAGS        :=      $(ARCH) -march=armv5te -mtune=arm946e-s
+LDFLAGS        =       -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
+
+#---------------------------------------------------------------------------------
+# list of directories containing libraries, this must be the top level containing
+# include and lib
+#---------------------------------------------------------------------------------
+LIBDIRS        :=      $(LIBNDS)
+
+#---------------------------------------------------------------------------------
+# no real need to edit anything past this point unless you need to add additional
+# rules for different file extensions
+#---------------------------------------------------------------------------------
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+#---------------------------------------------------------------------------------
+
+export OUTPUT  :=      $(CURDIR)/lib/libz.a
+
+export VPATH   :=      $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
+                       $(foreach dir,$(DATA),$(CURDIR)/$(dir))
+
+export DEPSDIR :=      $(CURDIR)/$(BUILD)
+
+CFILES         :=      $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
+CPPFILES       :=      $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES         :=      $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
+BINFILES       :=      $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
+
+#---------------------------------------------------------------------------------
+# use CXX for linking C++ projects, CC for standard C
+#---------------------------------------------------------------------------------
+ifeq ($(strip $(CPPFILES)),)
+#---------------------------------------------------------------------------------
+       export LD       :=      $(CC)
+#---------------------------------------------------------------------------------
+else
+#---------------------------------------------------------------------------------
+       export LD       :=      $(CXX)
+#---------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------
+
+export OFILES  :=      $(addsuffix .o,$(BINFILES)) \
+                       $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
+
+export INCLUDE :=      $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
+                       $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
+                       -I$(CURDIR)/$(BUILD)
+
+.PHONY: $(BUILD) clean all
+
+#---------------------------------------------------------------------------------
+all: $(BUILD)
+       @[ -d $@ ] || mkdir -p include
+       @cp ../../*.h include
+
+lib:
+       @[ -d $@ ] || mkdir -p $@
+       
+$(BUILD): lib
+       @[ -d $@ ] || mkdir -p $@
+       @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+#---------------------------------------------------------------------------------
+clean:
+       @echo clean ...
+       @rm -fr $(BUILD) lib
+
+#---------------------------------------------------------------------------------
+else
+
+DEPENDS        :=      $(OFILES:.o=.d)
+
+#---------------------------------------------------------------------------------
+# main targets
+#---------------------------------------------------------------------------------
+$(OUTPUT)      :       $(OFILES)
+
+#---------------------------------------------------------------------------------
+%.bin.o        :       %.bin
+#---------------------------------------------------------------------------------
+       @echo $(notdir $<)
+       @$(bin2o)
+
+
+-include $(DEPENDS)
+
+#---------------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------------
diff --git a/8.x/zlib/nintendods/README b/8.x/zlib/nintendods/README
new file mode 100644 (file)
index 0000000..ba7a37d
--- /dev/null
@@ -0,0 +1,5 @@
+This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template.
+
+Eduardo Costa <eduardo.m.costa@gmail.com>
+January 3, 2009
+
diff --git a/8.x/zlib/old/Makefile.riscos b/8.x/zlib/old/Makefile.riscos
new file mode 100644 (file)
index 0000000..57e29d3
--- /dev/null
@@ -0,0 +1,151 @@
+# Project:   zlib_1_03
+# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430
+# test works out-of-the-box, installs `somewhere' on demand
+
+# Toolflags:
+CCflags = -c -depend !Depend -IC: -g -throwback  -DRISCOS  -fah
+C++flags = -c -depend !Depend -IC: -throwback
+Linkflags = -aif -c++ -o $@
+ObjAsmflags = -throwback -NoCache -depend !Depend
+CMHGflags =
+LibFileflags = -c -l -o $@
+Squeezeflags = -o $@
+
+# change the line below to where _you_ want the library installed.
+libdest = lib:zlib
+
+# Final targets:
+@.lib:   @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
+        @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
+        @.o.uncompr @.o.zutil
+        LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
+        @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
+        @.o.trees @.o.uncompr @.o.zutil
+test:   @.minigzip @.example @.lib
+       @copy @.lib @.libc  A~C~DF~L~N~P~Q~RS~TV
+       @echo running tests: hang on.
+       @/@.minigzip -f -9 libc
+       @/@.minigzip -d libc-gz
+       @/@.minigzip -f -1 libc
+       @/@.minigzip -d libc-gz
+       @/@.minigzip -h -9 libc
+       @/@.minigzip -d libc-gz
+       @/@.minigzip -h -1 libc
+       @/@.minigzip -d libc-gz
+       @/@.minigzip -9 libc
+       @/@.minigzip -d libc-gz
+       @/@.minigzip -1 libc
+       @/@.minigzip -d libc-gz
+       @diff @.lib @.libc
+       @echo that should have reported '@.lib and @.libc identical' if you have diff.
+       @/@.example @.fred @.fred
+       @echo that will have given lots of hello!'s.
+
+@.minigzip:   @.o.minigzip @.lib C:o.Stubs
+        Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
+@.example:   @.o.example @.lib C:o.Stubs
+        Link $(Linkflags) @.o.example @.lib C:o.Stubs
+
+install: @.lib
+       cdir $(libdest)
+       cdir $(libdest).h
+       @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV
+       @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV
+       @copy @.lib $(libdest).lib  A~C~DF~L~N~P~Q~RS~TV
+       @echo okay, installed zlib in $(libdest)
+
+clean:; remove @.minigzip
+       remove @.example
+       remove @.libc
+       -wipe @.o.* F~r~cV
+       remove @.fred
+
+# User-editable dependencies:
+.c.o:
+        cc $(ccflags) -o $@ $<
+
+# Static dependencies:
+
+# Dynamic dependencies:
+o.example:     c.example
+o.example:     h.zlib
+o.example:     h.zconf
+o.minigzip:    c.minigzip
+o.minigzip:    h.zlib
+o.minigzip:    h.zconf
+o.adler32:     c.adler32
+o.adler32:     h.zlib
+o.adler32:     h.zconf
+o.compress:    c.compress
+o.compress:    h.zlib
+o.compress:    h.zconf
+o.crc32:       c.crc32
+o.crc32:       h.zlib
+o.crc32:       h.zconf
+o.deflate:     c.deflate
+o.deflate:     h.deflate
+o.deflate:     h.zutil
+o.deflate:     h.zlib
+o.deflate:     h.zconf
+o.gzio:        c.gzio
+o.gzio:        h.zutil
+o.gzio:        h.zlib
+o.gzio:        h.zconf
+o.infblock:    c.infblock
+o.infblock:    h.zutil
+o.infblock:    h.zlib
+o.infblock:    h.zconf
+o.infblock:    h.infblock
+o.infblock:    h.inftrees
+o.infblock:    h.infcodes
+o.infblock:    h.infutil
+o.infcodes:    c.infcodes
+o.infcodes:    h.zutil
+o.infcodes:    h.zlib
+o.infcodes:    h.zconf
+o.infcodes:    h.inftrees
+o.infcodes:    h.infblock
+o.infcodes:    h.infcodes
+o.infcodes:    h.infutil
+o.infcodes:    h.inffast
+o.inffast:     c.inffast
+o.inffast:     h.zutil
+o.inffast:     h.zlib
+o.inffast:     h.zconf
+o.inffast:     h.inftrees
+o.inffast:     h.infblock
+o.inffast:     h.infcodes
+o.inffast:     h.infutil
+o.inffast:     h.inffast
+o.inflate:     c.inflate
+o.inflate:     h.zutil
+o.inflate:     h.zlib
+o.inflate:     h.zconf
+o.inflate:     h.infblock
+o.inftrees:    c.inftrees
+o.inftrees:    h.zutil
+o.inftrees:    h.zlib
+o.inftrees:    h.zconf
+o.inftrees:    h.inftrees
+o.inftrees:    h.inffixed
+o.infutil:     c.infutil
+o.infutil:     h.zutil
+o.infutil:     h.zlib
+o.infutil:     h.zconf
+o.infutil:     h.infblock
+o.infutil:     h.inftrees
+o.infutil:     h.infcodes
+o.infutil:     h.infutil
+o.trees:       c.trees
+o.trees:       h.deflate
+o.trees:       h.zutil
+o.trees:       h.zlib
+o.trees:       h.zconf
+o.trees:       h.trees
+o.uncompr:     c.uncompr
+o.uncompr:     h.zlib
+o.uncompr:     h.zconf
+o.zutil:       c.zutil
+o.zutil:       h.zutil
+o.zutil:       h.zlib
+o.zutil:       h.zconf
diff --git a/8.x/zlib/old/README b/8.x/zlib/old/README
new file mode 100644 (file)
index 0000000..800bf07
--- /dev/null
@@ -0,0 +1,3 @@
+This directory contains files that have not been updated for zlib 1.2.x
+
+(Volunteers are encouraged to help clean this up.  Thanks.)
diff --git a/8.x/zlib/old/as400/bndsrc b/8.x/zlib/old/as400/bndsrc
new file mode 100644 (file)
index 0000000..9cf94bb
--- /dev/null
@@ -0,0 +1,132 @@
+STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*   Version 1.1.3 entry points.                                    */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/*   *MODULE      ADLER32      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("adler32")
+
+/********************************************************************/
+/*   *MODULE      COMPRESS     ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("compress")
+  EXPORT SYMBOL("compress2")
+
+/********************************************************************/
+/*   *MODULE      CRC32        ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("crc32")
+  EXPORT SYMBOL("get_crc_table")
+
+/********************************************************************/
+/*   *MODULE      DEFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("deflate")
+  EXPORT SYMBOL("deflateEnd")
+  EXPORT SYMBOL("deflateSetDictionary")
+  EXPORT SYMBOL("deflateCopy")
+  EXPORT SYMBOL("deflateReset")
+  EXPORT SYMBOL("deflateParams")
+  EXPORT SYMBOL("deflatePrime")
+  EXPORT SYMBOL("deflateInit_")
+  EXPORT SYMBOL("deflateInit2_")
+
+/********************************************************************/
+/*   *MODULE      GZIO         ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("gzopen")
+  EXPORT SYMBOL("gzdopen")
+  EXPORT SYMBOL("gzsetparams")
+  EXPORT SYMBOL("gzread")
+  EXPORT SYMBOL("gzwrite")
+  EXPORT SYMBOL("gzprintf")
+  EXPORT SYMBOL("gzputs")
+  EXPORT SYMBOL("gzgets")
+  EXPORT SYMBOL("gzputc")
+  EXPORT SYMBOL("gzgetc")
+  EXPORT SYMBOL("gzflush")
+  EXPORT SYMBOL("gzseek")
+  EXPORT SYMBOL("gzrewind")
+  EXPORT SYMBOL("gztell")
+  EXPORT SYMBOL("gzeof")
+  EXPORT SYMBOL("gzclose")
+  EXPORT SYMBOL("gzerror")
+
+/********************************************************************/
+/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflate")
+  EXPORT SYMBOL("inflateEnd")
+  EXPORT SYMBOL("inflateSetDictionary")
+  EXPORT SYMBOL("inflateSync")
+  EXPORT SYMBOL("inflateReset")
+  EXPORT SYMBOL("inflateInit_")
+  EXPORT SYMBOL("inflateInit2_")
+  EXPORT SYMBOL("inflateSyncPoint")
+
+/********************************************************************/
+/*   *MODULE      UNCOMPR      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("uncompress")
+
+/********************************************************************/
+/*   *MODULE      ZUTIL        ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("zlibVersion")
+  EXPORT SYMBOL("zError")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*   Version 1.2.1 additional entry points.                         */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/*   *MODULE      COMPRESS     ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("compressBound")
+
+/********************************************************************/
+/*   *MODULE      DEFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("deflateBound")
+
+/********************************************************************/
+/*   *MODULE      GZIO         ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("gzungetc")
+  EXPORT SYMBOL("gzclearerr")
+
+/********************************************************************/
+/*   *MODULE      INFBACK      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflateBack")
+  EXPORT SYMBOL("inflateBackEnd")
+  EXPORT SYMBOL("inflateBackInit_")
+
+/********************************************************************/
+/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflateCopy")
+
+/********************************************************************/
+/*   *MODULE      ZUTIL        ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("zlibCompileFlags")
+
+ENDPGMEXP
diff --git a/8.x/zlib/old/as400/compile.clp b/8.x/zlib/old/as400/compile.clp
new file mode 100644 (file)
index 0000000..8554951
--- /dev/null
@@ -0,0 +1,123 @@
+/******************************************************************************/
+/*                                                                            */
+/*  ZLIB                                                                      */
+/*                                                                            */
+/*    Compile sources into modules and link them into a service program.      */
+/*                                                                            */
+/******************************************************************************/
+
+             PGM
+
+/*      Configuration adjustable parameters.                                  */
+
+             DCL        VAR(&SRCLIB) TYPE(*CHAR) LEN(10) +
+                          VALUE('ZLIB')                         /* Source library. */
+             DCL        VAR(&SRCFILE) TYPE(*CHAR) LEN(10) +
+                          VALUE('SOURCES')                      /* Source member file. */
+             DCL        VAR(&CTLFILE) TYPE(*CHAR) LEN(10) +
+                          VALUE('TOOLS')                        /* Control member file. */
+
+             DCL        VAR(&MODLIB) TYPE(*CHAR) LEN(10) +
+                          VALUE('ZLIB')                         /* Module library. */
+
+             DCL        VAR(&SRVLIB) TYPE(*CHAR) LEN(10) +
+                          VALUE('LGPL')                         /* Service program library. */
+
+             DCL        VAR(&CFLAGS) TYPE(*CHAR) +
+                          VALUE('OPTIMIZE(40)')                 /* Compile options. */
+
+
+/*      Working storage.                                                      */
+
+             DCL        VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300)    /* Command length. */
+             DCL        VAR(&CMD) TYPE(*CHAR) LEN(512)
+
+
+/*      Compile sources into modules.                                         */
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/ADLER32)               SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/COMPRESS)              SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/CRC32)                 SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/DEFLATE)               SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/GZIO)                  SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/INFBACK)               SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/INFFAST)               SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/INFLATE)               SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/INFTREES)              SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/TREES)                 SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/UNCOMPR)               SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT  +
+                        '/ZUTIL)                 SRCFILE(' *TCAT               +
+                        &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT                 +
+                        ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+
+/*      Link modules into a service program.                                  */
+
+             CRTSRVPGM  SRVPGM(&SRVLIB/ZLIB) +
+                          MODULE(&MODLIB/ADLER32     &MODLIB/COMPRESS    +
+                                 &MODLIB/CRC32       &MODLIB/DEFLATE     +
+                                 &MODLIB/GZIO        &MODLIB/INFBACK     +
+                                 &MODLIB/INFFAST     &MODLIB/INFLATE     +
+                                 &MODLIB/INFTREES    &MODLIB/TREES       +
+                                 &MODLIB/UNCOMPR     &MODLIB/ZUTIL)      +
+                          SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) +
+                          TEXT('ZLIB 1.2.3') TGTRLS(V4R4M0)
+
+             ENDPGM
diff --git a/8.x/zlib/old/as400/readme.txt b/8.x/zlib/old/as400/readme.txt
new file mode 100644 (file)
index 0000000..beae13f
--- /dev/null
@@ -0,0 +1,111 @@
+        ZLIB version 1.2.3 for AS400 installation instructions
+
+I) From an AS400 *SAVF file:
+
+1)      Unpacking archive to an AS400 save file
+
+On the AS400:
+
+_       Create the ZLIB AS400 library:
+
+        CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library')
+
+_       Create a work save file, for example:
+
+                CRTSAVF FILE(ZLIB/ZLIBSAVF)
+
+On a PC connected to the target AS400:
+
+_       Unpack the save file image to a PC file "ZLIBSAVF"
+_       Upload this file into the save file on the AS400, for example
+                using ftp in BINARY mode.
+
+
+2)      Populating the ZLIB AS400 source library
+
+On the AS400:
+
+_       Extract the saved objects into the ZLIB AS400 library using:
+
+RSTOBJ OBJ(*ALL) SAVLIB(ZLIB) DEV(*SAVF) SAVF(ZLIB/ZLIBSAVF) RSTLIB(ZLIB)
+
+
+3)      Customize installation:
+
+_       Edit CL member ZLIB/TOOLS(COMPILE) and change parameters if needed,
+                according to the comments.
+
+_       Compile this member with:
+
+        CRTCLPGM PGM(ZLIB/COMPILE) SRCFILE(ZLIB/TOOLS) SRCMBR(COMPILE)
+
+
+4)      Compile and generate the service program:
+
+_       This can now be done by executing:
+
+        CALL PGM(ZLIB/COMPILE)
+
+
+
+II) From the original source distribution:
+
+1)      On the AS400, create the source library:
+
+        CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library')
+
+2)      Create the source files:
+
+        CRTSRCPF FILE(ZLIB/SOURCES) RCDLEN(112) TEXT('ZLIB library modules')
+        CRTSRCPF FILE(ZLIB/H)       RCDLEN(112) TEXT('ZLIB library includes')
+        CRTSRCPF FILE(ZLIB/TOOLS)   RCDLEN(112) TEXT('ZLIB library control utilities')
+
+3)      From the machine hosting the distribution files, upload them (with
+                FTP in text mode, for example) according to the following table:
+
+    Original    AS400   AS400    AS400 AS400
+    file        file    member   type  description
+                SOURCES                Original ZLIB C subprogram sources
+    adler32.c           ADLER32  C     ZLIB - Compute the Adler-32 checksum of a dta strm
+    compress.c          COMPRESS C     ZLIB - Compress a memory buffer
+    crc32.c             CRC32    C     ZLIB - Compute the CRC-32 of a data stream
+    deflate.c           DEFLATE  C     ZLIB - Compress data using the deflation algorithm
+    gzio.c              GZIO     C     ZLIB - IO on .gz files
+    infback.c           INFBACK  C     ZLIB - Inflate using a callback interface
+    inffast.c           INFFAST  C     ZLIB - Fast proc. literals & length/distance pairs
+    inflate.c           INFLATE  C     ZLIB - Interface to inflate modules
+    inftrees.c          INFTREES C     ZLIB - Generate Huffman trees for efficient decode
+    trees.c             TREES    C     ZLIB - Output deflated data using Huffman coding
+    uncompr.c           UNCOMPR  C     ZLIB - Decompress a memory buffer
+    zutil.c             ZUTIL    C     ZLIB - Target dependent utility functions
+                H                      Original ZLIB C and ILE/RPG include files
+    crc32.h             CRC32    C     ZLIB - CRC32 tables
+    deflate.h           DEFLATE  C     ZLIB - Internal compression state
+    inffast.h           INFFAST  C     ZLIB - Header to use inffast.c
+    inffixed.h          INFFIXED C     ZLIB - Table for decoding fixed codes
+    inflate.h           INFLATE  C     ZLIB - Internal inflate state definitions
+    inftrees.h          INFTREES C     ZLIB - Header to use inftrees.c
+    trees.h             TREES    C     ZLIB - Created automatically with -DGEN_TREES_H
+    zconf.h             ZCONF    C     ZLIB - Compression library configuration
+    zlib.h              ZLIB     C     ZLIB - Compression library C user interface
+    as400/zlib.inc      ZLIB.INC RPGLE ZLIB - Compression library ILE RPG user interface
+    zutil.h             ZUTIL    C     ZLIB - Internal interface and configuration
+                TOOLS                  Building source software & AS/400 README
+    as400/bndsrc        BNDSRC         Entry point exportation list
+    as400/compile.clp   COMPILE  CLP   Compile sources & generate service program
+    as400/readme.txt    README   TXT   Installation instructions
+
+4)      Continue as in I)3).
+
+
+
+
+Notes:  For AS400 ILE RPG programmers, a /copy member defining the ZLIB
+                API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC).
+                Please read comments in this member for more information.
+
+        Remember that most foreign textual data are ASCII coded: this
+                implementation does not handle conversion from/to ASCII, so
+                text data code conversions must be done explicitely.
+
+        Always open zipped files in binary mode.
diff --git a/8.x/zlib/old/as400/zlib.inc b/8.x/zlib/old/as400/zlib.inc
new file mode 100644 (file)
index 0000000..a9a4f5c
--- /dev/null
@@ -0,0 +1,331 @@
+      *  ZLIB.INC - Interface to the general purpose compression library
+      *
+      *  ILE RPG400 version by Patrick Monnerat, DATASPHERE.
+      *  Version 1.2.3.9
+      *
+      *
+      *  WARNING:
+      *     Procedures inflateInit(), inflateInit2(), deflateInit(),
+      *         deflateInit2() and inflateBackInit() need to be called with
+      *         two additional arguments:
+      *         the package version string and the stream control structure.
+      *         size. This is needed because RPG lacks some macro feature.
+      *         Call these procedures as:
+      *             inflateInit(...: ZLIB_VERSION: %size(z_stream))
+      *
+      /if not defined(ZLIB_H_)
+      /define ZLIB_H_
+      *
+      **************************************************************************
+      *                               Constants
+      **************************************************************************
+      *
+      *  Versioning information.
+      *
+     D ZLIB_VERSION    C                   '1.2.3.9'
+     D ZLIB_VERNUM     C                   X'1239'
+      *
+      *  Other equates.
+      *
+     D Z_NO_FLUSH      C                   0
+     D Z_SYNC_FLUSH    C                   2
+     D Z_FULL_FLUSH    C                   3
+     D Z_FINISH        C                   4
+     D Z_BLOCK         C                   5
+      *
+     D Z_OK            C                   0
+     D Z_STREAM_END    C                   1
+     D Z_NEED_DICT     C                   2
+     D Z_ERRNO         C                   -1
+     D Z_STREAM_ERROR  C                   -2
+     D Z_DATA_ERROR    C                   -3
+     D Z_MEM_ERROR     C                   -4
+     D Z_BUF_ERROR     C                   -5
+     DZ_VERSION_ERROR  C                   -6
+      *
+     D Z_NO_COMPRESSION...
+     D                 C                   0
+     D Z_BEST_SPEED    C                   1
+     D Z_BEST_COMPRESSION...
+     D                 C                   9
+     D Z_DEFAULT_COMPRESSION...
+     D                 C                   -1
+      *
+     D Z_FILTERED      C                   1
+     D Z_HUFFMAN_ONLY  C                   2
+     D Z_RLE           C                   3
+     D Z_DEFAULT_STRATEGY...
+     D                 C                   0
+      *
+     D Z_BINARY        C                   0
+     D Z_ASCII         C                   1
+     D Z_UNKNOWN       C                   2
+      *
+     D Z_DEFLATED      C                   8
+      *
+     D Z_NULL          C                   0
+      *
+      **************************************************************************
+      *                                 Types
+      **************************************************************************
+      *
+     D z_streamp       S               *                                        Stream struct ptr
+     D gzFile          S               *                                        File pointer
+     D z_off_t         S             10i 0                                      Stream offsets
+      *
+      **************************************************************************
+      *                               Structures
+      **************************************************************************
+      *
+      *  The GZIP encode/decode stream support structure.
+      *
+     D z_stream        DS                  align based(z_streamp)
+     D  zs_next_in                     *                                        Next input byte
+     D  zs_avail_in                  10U 0                                      Byte cnt at next_in
+     D  zs_total_in                  10U 0                                      Total bytes read
+     D  zs_next_out                    *                                        Output buffer ptr
+     D  zs_avail_out                 10U 0                                      Room left @ next_out
+     D  zs_total_out                 10U 0                                      Total bytes written
+     D  zs_msg                         *                                        Last errmsg or null
+     D  zs_state                       *                                        Internal state
+     D  zs_zalloc                      *   procptr                              Int. state allocator
+     D  zs_free                        *   procptr                              Int. state dealloc.
+     D  zs_opaque                      *                                        Private alloc. data
+     D  zs_data_type                 10i 0                                      ASC/BIN best guess
+     D  zs_adler                     10u 0                                      Uncompr. adler32 val
+     D                               10U 0                                      Reserved
+     D                               10U 0                                      Ptr. alignment
+      *
+      **************************************************************************
+      *                     Utility function prototypes
+      **************************************************************************
+      *
+     D compress        PR            10I 0 extproc('compress')
+     D  dest                      32767    options(*varsize)                    Destination buffer
+     D  destLen                      10U 0                                      Destination length
+     D  source                    32767    const options(*varsize)              Source buffer
+     D  sourceLen                    10u 0 value                                Source length
+      *
+     D compress2       PR            10I 0 extproc('compress2')
+     D  dest                      32767    options(*varsize)                    Destination buffer
+     D  destLen                      10U 0                                      Destination length
+     D  source                    32767    const options(*varsize)              Source buffer
+     D  sourceLen                    10U 0 value                                Source length
+     D  level                        10I 0 value                                Compression level
+      *
+     D compressBound   PR            10U 0 extproc('compressBound')
+     D  sourceLen                    10U 0 value
+      *
+     D uncompress      PR            10I 0 extproc('uncompress')
+     D  dest                      32767    options(*varsize)                    Destination buffer
+     D  destLen                      10U 0                                      Destination length
+     D  source                    32767    const options(*varsize)              Source buffer
+     D  sourceLen                    10U 0 value                                Source length
+      *
+     D gzopen          PR                  extproc('gzopen')
+     D                                     like(gzFile)
+     D  path                           *   value options(*string)               File pathname
+     D  mode                           *   value options(*string)               Open mode
+      *
+     D gzdopen         PR                  extproc('gzdopen')
+     D                                     like(gzFile)
+     D  fd                           10i 0 value                                File descriptor
+     D  mode                           *   value options(*string)               Open mode
+      *
+     D gzsetparams     PR            10I 0 extproc('gzsetparams')
+     D  file                               value like(gzFile)                   File pointer
+     D  level                        10I 0 value
+     D  strategy                     10i 0 value
+      *
+     D gzread          PR            10I 0 extproc('gzread')
+     D  file                               value like(gzFile)                   File pointer
+     D  buf                       32767    options(*varsize)                    Buffer
+     D  len                          10u 0 value                                Buffer length
+      *
+     D gzwrite         PR            10I 0 extproc('gzwrite')
+     D  file                               value like(gzFile)                   File pointer
+     D  buf                       32767    const options(*varsize)              Buffer
+     D  len                          10u 0 value                                Buffer length
+      *
+     D gzputs          PR            10I 0 extproc('gzputs')
+     D  file                               value like(gzFile)                   File pointer
+     D  s                              *   value options(*string)               String to output
+      *
+     D gzgets          PR              *   extproc('gzgets')
+     D  file                               value like(gzFile)                   File pointer
+     D  buf                       32767    options(*varsize)                    Read buffer
+     D  len                          10i 0 value                                Buffer length
+      *
+     D gzflush         PR            10i 0 extproc('gzflush')
+     D  file                               value like(gzFile)                   File pointer
+     D  flush                        10I 0 value                                Type of flush
+      *
+     D gzseek          PR                  extproc('gzseek')
+     D                                     like(z_off_t)
+     D  file                               value like(gzFile)                   File pointer
+     D  offset                             value like(z_off_t)                  Offset
+     D  whence                       10i 0 value                                Origin
+      *
+     D gzrewind        PR            10i 0 extproc('gzrewind')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gztell          PR                  extproc('gztell')
+     D                                     like(z_off_t)
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzeof           PR            10i 0 extproc('gzeof')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzclose         PR            10i 0 extproc('gzclose')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzerror         PR              *   extproc('gzerror')                   Error string
+     D  file                               value like(gzFile)                   File pointer
+     D  errnum                       10I 0                                      Error code
+      *
+     D gzclearerr      PR                  extproc('gzclearerr')
+     D  file                               value like(gzFile)                   File pointer
+      *
+      **************************************************************************
+      *                        Basic function prototypes
+      **************************************************************************
+      *
+     D zlibVersion     PR              *   extproc('zlibVersion')               Version string
+      *
+     D deflateInit     PR            10I 0 extproc('deflateInit_')              Init. compression
+     D  strm                               like(z_stream)                       Compression stream
+     D  level                        10I 0 value                                Compression level
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D deflate         PR            10I 0 extproc('deflate')                   Compress data
+     D  strm                               like(z_stream)                       Compression stream
+     D  flush                        10I 0 value                                Flush type required
+      *
+     D deflateEnd      PR            10I 0 extproc('deflateEnd')                Termin. compression
+     D  strm                               like(z_stream)                       Compression stream
+      *
+     D inflateInit     PR            10I 0 extproc('inflateInit_')              Init. expansion
+     D  strm                               like(z_stream)                       Expansion stream
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D inflate         PR            10I 0 extproc('inflate')                   Expand data
+     D  strm                               like(z_stream)                       Expansion stream
+     D  flush                        10I 0 value                                Flush type required
+      *
+     D inflateEnd      PR            10I 0 extproc('inflateEnd')                Termin. expansion
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+      **************************************************************************
+      *                        Advanced function prototypes
+      **************************************************************************
+      *
+     D deflateInit2    PR            10I 0 extproc('deflateInit2_')             Init. compression
+     D  strm                               like(z_stream)                       Compression stream
+     D  level                        10I 0 value                                Compression level
+     D  method                       10I 0 value                                Compression method
+     D  windowBits                   10I 0 value                                log2(window size)
+     D  memLevel                     10I 0 value                                Mem/cmpress tradeoff
+     D  strategy                     10I 0 value                                Compression stategy
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D deflateSetDictionary...
+     D                 PR            10I 0 extproc('deflateSetDictionary')      Init. dictionary
+     D  strm                               like(z_stream)                       Compression stream
+     D  dictionary                32767    const options(*varsize)              Dictionary bytes
+     D  dictLength                   10U 0 value                                Dictionary length
+      *
+     D deflateCopy     PR            10I 0 extproc('deflateCopy')               Compress strm 2 strm
+     D  dest                               like(z_stream)                       Destination stream
+     D  source                             like(z_stream)                       Source stream
+      *
+     D deflateReset    PR            10I 0 extproc('deflateReset')              End and init. stream
+     D  strm                               like(z_stream)                       Compression stream
+      *
+     D deflateParams   PR            10I 0 extproc('deflateParams')             Change level & strat
+     D  strm                               like(z_stream)                       Compression stream
+     D  level                        10I 0 value                                Compression level
+     D  strategy                     10I 0 value                                Compression stategy
+      *
+     D deflateBound    PR            10U 0 extproc('deflateBound')              Change level & strat
+     D  strm                               like(z_stream)                       Compression stream
+     D  sourcelen                    10U 0 value                                Compression level
+      *
+     D deflatePrime    PR            10I 0 extproc('deflatePrime')              Change level & strat
+     D  strm                               like(z_stream)                       Compression stream
+     D  bits                         10I 0 value                                Number of bits to insert
+     D  value                        10I 0 value                                Bits to insert
+      *
+     D inflateInit2    PR            10I 0 extproc('inflateInit2_')             Init. expansion
+     D  strm                               like(z_stream)                       Expansion stream
+     D  windowBits                   10I 0 value                                log2(window size)
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D inflateSetDictionary...
+     D                 PR            10I 0 extproc('inflateSetDictionary')      Init. dictionary
+     D  strm                               like(z_stream)                       Expansion stream
+     D  dictionary                32767    const options(*varsize)              Dictionary bytes
+     D  dictLength                   10U 0 value                                Dictionary length
+      *
+     D inflateSync     PR            10I 0 extproc('inflateSync')               Sync. expansion
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D inflateCopy     PR            10I 0 extproc('inflateCopy')
+     D  dest                               like(z_stream)                       Destination stream
+     D  source                             like(z_stream)                       Source stream
+      *
+     D inflateReset    PR            10I 0 extproc('inflateReset')              End and init. stream
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D inflateBackInit...
+     D                 PR            10I 0 extproc('inflateBackInit_')
+     D  strm                               like(z_stream)                       Expansion stream
+     D  windowBits                   10I 0 value                                Log2(buffer size)
+     D  window                    32767    options(*varsize)                    Buffer
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D inflateBack     PR            10I 0 extproc('inflateBack')
+     D  strm                               like(z_stream)                       Expansion stream
+     D  in                             *   value procptr                        Input function
+     D  in_desc                        *   value                                Input descriptor
+     D  out                            *   value procptr                        Output function
+     D  out_desc                       *   value                                Output descriptor
+      *
+     D inflateBackEnd  PR            10I 0 extproc('inflateBackEnd')
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D zlibCompileFlags...
+     D                 PR            10U 0 extproc('zlibCompileFlags')
+      *
+      **************************************************************************
+      *                        Checksum function prototypes
+      **************************************************************************
+      *
+     D adler32         PR            10U 0 extproc('adler32')                   New checksum
+     D  adler                        10U 0 value                                Old checksum
+     D  buf                       32767    const options(*varsize)              Bytes to accumulate
+     D  len                          10U 0 value                                Buffer length
+      *
+     D crc32           PR            10U 0 extproc('crc32')                     New checksum
+     D  crc                          10U 0 value                                Old checksum
+     D  buf                       32767    const options(*varsize)              Bytes to accumulate
+     D  len                          10U 0 value                                Buffer length
+      *
+      **************************************************************************
+      *                     Miscellaneous function prototypes
+      **************************************************************************
+      *
+     D zError          PR              *   extproc('zError')                    Error string
+     D  err                          10I 0 value                                Error code
+      *
+     D inflateSyncPoint...
+     D                 PR            10I 0 extproc('inflateSyncPoint')
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D get_crc_table   PR              *   extproc('get_crc_table')             Ptr to ulongs
+      *
+      /endif
diff --git a/8.x/zlib/old/descrip.mms b/8.x/zlib/old/descrip.mms
new file mode 100644 (file)
index 0000000..7066da5
--- /dev/null
@@ -0,0 +1,48 @@
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser <m.zinser@gsi.de>
+
+cc_defs =
+c_deb =
+
+.ifdef __DECC__
+pref = /prefix=all
+.endif
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
+       deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
+       inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
+
+CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
+
+all : example.exe minigzip.exe
+        @ write sys$output " Example applications available"
+libz.olb : libz.olb($(OBJS))
+       @ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+              link example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+              link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+
+clean :
+       delete *.obj;*,libz.olb;*
+
+
+# Other dependencies.
+adler32.obj : zutil.h zlib.h zconf.h
+compress.obj : zlib.h zconf.h
+crc32.obj : zutil.h zlib.h zconf.h
+deflate.obj : deflate.h zutil.h zlib.h zconf.h
+example.obj : zlib.h zconf.h
+gzio.obj : zutil.h zlib.h zconf.h
+infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
+inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+inflate.obj : zutil.h zlib.h zconf.h infblock.h
+inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
+infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
+minigzip.obj : zlib.h zconf.h
+trees.obj : deflate.h zutil.h zlib.h zconf.h
+uncompr.obj : zlib.h zconf.h
+zutil.obj : zutil.h zlib.h zconf.h
diff --git a/8.x/zlib/old/os2/Makefile.os2 b/8.x/zlib/old/os2/Makefile.os2
new file mode 100644 (file)
index 0000000..a105aaa
--- /dev/null
@@ -0,0 +1,136 @@
+# Makefile for zlib under OS/2 using GCC (PGCC)
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+#   cp Makefile.os2 ..
+#   cd ..
+#   make -f Makefile.os2 test
+
+# This makefile will build a static library z.lib, a shared library
+# z.dll and a import library zdll.lib. You can use either z.lib or
+# zdll.lib by specifying either -lz or -lzdll on gcc's command line
+
+CC=gcc -Zomf -s
+
+CFLAGS=-O6 -Wall
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+#################### BUG WARNING: #####################
+## infcodes.c hits a bug in pgcc-1.0, so you have to use either
+## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)
+## This bug is reportedly fixed in pgcc >1.0, but this was not tested
+CFLAGS+=-fno-force-mem
+
+LDFLAGS=-s -L. -lzdll -Zcrtdll
+LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll
+
+VER=1.1.0
+ZLIB=z.lib
+SHAREDLIB=z.dll
+SHAREDLIBIMP=zdll.lib
+LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
+
+AR=emxomfar cr
+IMPLIB=emximp
+RANLIB=echo
+TAR=tar
+SHELL=bash
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+       zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
+  algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
+  nt/Makefile.nt nt/zlib.dnt  contrib/README.contrib contrib/*.txt \
+  contrib/asm386/*.asm contrib/asm386/*.c \
+  contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
+  contrib/iostream/*.h  contrib/iostream2/*.h contrib/iostream2/*.cpp \
+  contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32
+
+all: example.exe minigzip.exe
+
+test: all
+       @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+       echo hello world | ./minigzip | ./minigzip -d || \
+         echo '                *** minigzip test FAILED ***' ; \
+       if ./example; then \
+         echo '                *** zlib test OK ***'; \
+       else \
+         echo '                *** zlib test FAILED ***'; \
+       fi
+
+$(ZLIB): $(OBJS)
+       $(AR) $@ $(OBJS)
+       -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+$(SHAREDLIB): $(OBJS) os2/z.def
+       $(LDSHARED) -o $@ $^
+
+$(SHAREDLIBIMP): os2/z.def
+       $(IMPLIB) -o $@ $^
+
+example.exe: example.o $(LIBS)
+       $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip.exe: minigzip.o $(LIBS)
+       $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+clean:
+       rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
+
+distclean:     clean
+
+zip:
+       mv Makefile Makefile~; cp -p Makefile.in Makefile
+       rm -f test.c ztest*.c
+       v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+       zip -ul9 zlib$$v $(DISTFILES)
+       mv Makefile~ Makefile
+
+dist:
+       mv Makefile Makefile~; cp -p Makefile.in Makefile
+       rm -f test.c ztest*.c
+       d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+       rm -f $$d.tar.gz; \
+       if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
+       files=""; \
+       for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
+       cd ..; \
+       GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
+       if test ! -d $$d; then rm -f $$d; fi
+       mv Makefile~ Makefile
+
+tags:
+       etags *.[ch]
+
+depend:
+       makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
+infcodes.o: zutil.h zlib.h zconf.h
+infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h
+inffast.o: infblock.h infcodes.h infutil.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h infblock.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/8.x/zlib/old/os2/zlib.def b/8.x/zlib/old/os2/zlib.def
new file mode 100644 (file)
index 0000000..4c753f1
--- /dev/null
@@ -0,0 +1,51 @@
+;
+; Slightly modified version of ../nt/zlib.dnt :-)
+;
+
+LIBRARY                Z
+DESCRIPTION    "Zlib compression library for OS/2"
+CODE           PRELOAD MOVEABLE DISCARDABLE
+DATA           PRELOAD MOVEABLE MULTIPLE
+
+EXPORTS
+    adler32
+    compress
+    crc32
+    deflate
+    deflateCopy
+    deflateEnd
+    deflateInit2_
+    deflateInit_
+    deflateParams
+    deflateReset
+    deflateSetDictionary
+    gzclose
+    gzdopen
+    gzerror
+    gzflush
+    gzopen
+    gzread
+    gzwrite
+    inflate
+    inflateEnd
+    inflateInit2_
+    inflateInit_
+    inflateReset
+    inflateSetDictionary
+    inflateSync
+    uncompress
+    zlibVersion
+    gzprintf
+    gzputc
+    gzgetc
+    gzseek
+    gzrewind
+    gztell
+    gzeof
+    gzsetparams
+    zError
+    inflateSyncPoint
+    get_crc_table
+    compress2
+    gzputs
+    gzgets
diff --git a/8.x/zlib/old/visual-basic.txt b/8.x/zlib/old/visual-basic.txt
new file mode 100644 (file)
index 0000000..57efe58
--- /dev/null
@@ -0,0 +1,160 @@
+See below some functions declarations for Visual Basic.
+
+Frequently Asked Question:
+
+Q: Each time I use the compress function I get the -5 error (not enough
+   room in the output buffer).
+
+A: Make sure that the length of the compressed buffer is passed by
+   reference ("as any"), not by value ("as long"). Also check that
+   before the call of compress this length is equal to the total size of
+   the compressed buffer and not zero.
+
+
+From: "Jon Caruana" <jon-net@usa.net>
+Subject: Re: How to port zlib declares to vb?
+Date: Mon, 28 Oct 1996 18:33:03 -0600
+
+Got the answer! (I haven't had time to check this but it's what I got, and
+looks correct):
+
+He has the following routines working:
+        compress
+        uncompress
+        gzopen
+        gzwrite
+        gzread
+        gzclose
+
+Declares follow: (Quoted from Carlos Rios <c_rios@sonda.cl>, in Vb4 form)
+
+#If Win16 Then   'Use Win16 calls.
+Declare Function compress Lib "ZLIB.DLL" (ByVal compr As
+        String, comprLen As Any, ByVal buf As String, ByVal buflen
+        As Long) As Integer
+Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr
+        As String, uncomprLen As Any, ByVal compr As String, ByVal
+        lcompr As Long) As Integer
+Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As
+        String, ByVal mode As String) As Long
+Declare Function gzread Lib "ZLIB.DLL" (ByVal file As
+        Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
+        As Integer
+Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As
+        Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
+        As Integer
+Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As
+        Long) As Integer
+#Else
+Declare Function compress Lib "ZLIB32.DLL"
+        (ByVal compr As String, comprLen As Any, ByVal buf As
+        String, ByVal buflen As Long) As Integer
+Declare Function uncompress Lib "ZLIB32.DLL"
+        (ByVal uncompr As String, uncomprLen As Any, ByVal compr As
+        String, ByVal lcompr As Long) As Long
+Declare Function gzopen Lib "ZLIB32.DLL"
+        (ByVal file As String, ByVal mode As String) As Long
+Declare Function gzread Lib "ZLIB32.DLL"
+        (ByVal file As Long, ByVal uncompr As String, ByVal
+        uncomprLen As Long) As Long
+Declare Function gzwrite Lib "ZLIB32.DLL"
+        (ByVal file As Long, ByVal uncompr As String, ByVal
+        uncomprLen As Long) As Long
+Declare Function gzclose Lib "ZLIB32.DLL"
+        (ByVal file As Long) As Long
+#End If
+
+-Jon Caruana
+jon-net@usa.net
+Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member
+
+
+Here is another example from Michael <michael_borgsys@hotmail.com> that he
+says conforms to the VB guidelines, and that solves the problem of not
+knowing the uncompressed size by storing it at the end of the file:
+
+'Calling the functions:
+'bracket meaning: <parameter> [optional] {Range of possible values}
+'Call subCompressFile(<path with filename to compress> [, <path with
+filename to write to>, [level of compression {1..9}]])
+'Call subUncompressFile(<path with filename to compress>)
+
+Option Explicit
+Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller'
+Private Const SUCCESS As Long = 0
+Private Const strFilExt As String = ".cpr"
+Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef
+dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long,
+ByVal level As Integer) As Long
+Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef
+dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long)
+As Long
+
+Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal
+strargCprFilPth As String, Optional ByVal intLvl As Integer = 9)
+    Dim strCprPth As String
+    Dim lngOriSiz As Long
+    Dim lngCprSiz As Long
+    Dim bytaryOri() As Byte
+    Dim bytaryCpr() As Byte
+    lngOriSiz = FileLen(strargOriFilPth)
+    ReDim bytaryOri(lngOriSiz - 1)
+    Open strargOriFilPth For Binary Access Read As #1
+        Get #1, , bytaryOri()
+    Close #1
+    strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth)
+'Select file path and name
+    strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) =
+strFilExt, "", strFilExt) 'Add file extension if not exists
+    lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit
+more space then original file size
+    ReDim bytaryCpr(lngCprSiz - 1)
+    If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) =
+SUCCESS Then
+        lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100
+        ReDim Preserve bytaryCpr(lngCprSiz - 1)
+        Open strCprPth For Binary Access Write As #1
+            Put #1, , bytaryCpr()
+            Put #1, , lngOriSiz 'Add the the original size value to the end
+(last 4 bytes)
+        Close #1
+    Else
+        MsgBox "Compression error"
+    End If
+    Erase bytaryCpr
+    Erase bytaryOri
+End Sub
+
+Public Sub subUncompressFile(ByVal strargFilPth As String)
+    Dim bytaryCpr() As Byte
+    Dim bytaryOri() As Byte
+    Dim lngOriSiz As Long
+    Dim lngCprSiz As Long
+    Dim strOriPth As String
+    lngCprSiz = FileLen(strargFilPth)
+    ReDim bytaryCpr(lngCprSiz - 1)
+    Open strargFilPth For Binary Access Read As #1
+        Get #1, , bytaryCpr()
+    Close #1
+    'Read the original file size value:
+    lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _
+              + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _
+              + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _
+              + bytaryCpr(lngCprSiz - 4)
+    ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value
+    ReDim bytaryOri(lngOriSiz - 1)
+    If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS
+Then
+        strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt))
+        Open strOriPth For Binary Access Write As #1
+            Put #1, , bytaryOri()
+        Close #1
+    Else
+        MsgBox "Uncompression error"
+    End If
+    Erase bytaryCpr
+    Erase bytaryOri
+End Sub
+Public Property Get lngPercentSmaller() As Long
+    lngPercentSmaller = lngpvtPcnSml
+End Property
diff --git a/8.x/zlib/old/visualc6/README.txt b/8.x/zlib/old/visualc6/README.txt
new file mode 100644 (file)
index 0000000..d0296c2
--- /dev/null
@@ -0,0 +1,73 @@
+Microsoft Developer Studio Project Files, Format Version 6.00 for zlib.\r
+\r
+Copyright (C) 2000-2004 Simon-Pierre Cadieux.\r
+Copyright (C) 2004 Cosmin Truta.\r
+For conditions of distribution and use, see copyright notice in zlib.h.\r
+\r
+\r
+This project builds the zlib binaries as follows:\r
+\r
+* Win32_DLL_Release\zlib1.dll       DLL build\r
+* Win32_DLL_Debug\zlib1d.dll        DLL build (debug version)\r
+* Win32_DLL_ASM_Release\zlib1.dll   DLL build using ASM code\r
+* Win32_DLL_ASM_Debug\zlib1d.dll    DLL build using ASM code (debug version)\r
+* Win32_LIB_Release\zlib.lib        static build\r
+* Win32_LIB_Debug\zlibd.lib         static build (debug version)\r
+* Win32_LIB_ASM_Release\zlib.lib    static build using ASM code\r
+* Win32_LIB_ASM_Debug\zlibd.lib     static build using ASM code (debug version)\r
+\r
+\r
+For more information regarding the DLL builds, please see the DLL FAQ\r
+in ..\..\win32\DLL_FAQ.txt.\r
+\r
+\r
+To build and test:\r
+\r
+1) On the main menu, select "File | Open Workspace".\r
+   Open "zlib.dsw".\r
+\r
+2) Select "Build | Set Active Configuration".\r
+   Choose the configuration you wish to build.\r
+\r
+3) Select "Build | Clean".\r
+\r
+4) Select "Build | Build ... (F7)".  Ignore warning messages about\r
+   not being able to find certain include files (e.g. alloc.h).\r
+\r
+5) If you built one of the sample programs (example or minigzip),\r
+   select "Build | Execute ... (Ctrl+F5)".\r
+\r
+\r
+To use:\r
+\r
+1) Select "Project | Settings (Alt+F7)".\r
+   Make note of the configuration names used in your project.\r
+   Usually, these names are "Win32 Release" and "Win32 Debug".\r
+\r
+2) In the Workspace window, select the "FileView" tab.\r
+   Right-click on the root item "Workspace '...'".\r
+   Select "Insert Project into Workspace".\r
+   Switch on the checkbox "Dependency of:", and select the name\r
+   of your project.  Open "zlib.dsp".\r
+\r
+3) Select "Build | Configurations".\r
+   For each configuration of your project:\r
+   3.1) Choose the zlib configuration you wish to use.\r
+   3.2) Click on "Add".\r
+   3.3) Set the new zlib configuration name to the name used by\r
+        the configuration from the current iteration.\r
+\r
+4) Select "Build | Set Active Configuration".\r
+   Choose the configuration you wish to build.\r
+\r
+5) Select "Build | Build ... (F7)".\r
+\r
+6) If you built an executable program, select\r
+   "Build | Execute ... (Ctrl+F5)".\r
+\r
+\r
+Note:\r
+\r
+To build the ASM-enabled code, you need Microsoft Assembler\r
+(ML.EXE).  You can get it by downloading and installing the\r
+latest Processor Pack for Visual C++ 6.0.\r
diff --git a/8.x/zlib/old/visualc6/example.dsp b/8.x/zlib/old/visualc6/example.dsp
new file mode 100644 (file)
index 0000000..d358052
--- /dev/null
@@ -0,0 +1,278 @@
+# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=example - Win32 LIB Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE\r
+!MESSAGE NMAKE /f "example.mak".\r
+!MESSAGE\r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE\r
+!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 LIB Debug"\r
+!MESSAGE\r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE\r
+!MESSAGE "example - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "example - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "example - Win32 DLL Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "example - Win32 DLL Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "example - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "example - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "example - Win32 LIB Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "example - Win32 LIB Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE\r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "example - Win32 DLL ASM Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "example___Win32_DLL_ASM_Release"\r
+# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_DLL_ASM_Release"\r
+# PROP Intermediate_Dir "Win32_DLL_ASM_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "example - Win32 DLL ASM Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "example___Win32_DLL_ASM_Debug"\r
+# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_DLL_ASM_Debug"\r
+# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "example - Win32 DLL Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "example___Win32_DLL_Release"\r
+# PROP BASE Intermediate_Dir "example___Win32_DLL_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_DLL_Release"\r
+# PROP Intermediate_Dir "Win32_DLL_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "example - Win32 DLL Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "example___Win32_DLL_Debug"\r
+# PROP BASE Intermediate_Dir "example___Win32_DLL_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_DLL_Debug"\r
+# PROP Intermediate_Dir "Win32_DLL_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "example - Win32 LIB ASM Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "example___Win32_LIB_ASM_Release"\r
+# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_LIB_ASM_Release"\r
+# PROP Intermediate_Dir "Win32_LIB_ASM_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "example - Win32 LIB ASM Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "example___Win32_LIB_ASM_Debug"\r
+# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_LIB_ASM_Debug"\r
+# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "example - Win32 LIB Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "example___Win32_LIB_Release"\r
+# PROP BASE Intermediate_Dir "example___Win32_LIB_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_LIB_Release"\r
+# PROP Intermediate_Dir "Win32_LIB_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "example - Win32 LIB Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "example___Win32_LIB_Debug"\r
+# PROP BASE Intermediate_Dir "example___Win32_LIB_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_LIB_Debug"\r
+# PROP Intermediate_Dir "Win32_LIB_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ENDIF\r
+\r
+# Begin Target\r
+\r
+# Name "example - Win32 DLL ASM Release"\r
+# Name "example - Win32 DLL ASM Debug"\r
+# Name "example - Win32 DLL Release"\r
+# Name "example - Win32 DLL Debug"\r
+# Name "example - Win32 LIB ASM Release"\r
+# Name "example - Win32 LIB ASM Debug"\r
+# Name "example - Win32 LIB Release"\r
+# Name "example - Win32 LIB Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\example.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\zconf.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\zlib.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/8.x/zlib/old/visualc6/minigzip.dsp b/8.x/zlib/old/visualc6/minigzip.dsp
new file mode 100644 (file)
index 0000000..7103468
--- /dev/null
@@ -0,0 +1,278 @@
+# Microsoft Developer Studio Project File - Name="minigzip" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=minigzip - Win32 LIB Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE\r
+!MESSAGE NMAKE /f "minigzip.mak".\r
+!MESSAGE\r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE\r
+!MESSAGE NMAKE /f "minigzip.mak" CFG="minigzip - Win32 LIB Debug"\r
+!MESSAGE\r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE\r
+!MESSAGE "minigzip - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "minigzip - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "minigzip - Win32 DLL Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "minigzip - Win32 DLL Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "minigzip - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "minigzip - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "minigzip - Win32 LIB Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "minigzip - Win32 LIB Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE\r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "minigzip - Win32 DLL ASM Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Release"\r
+# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_DLL_ASM_Release"\r
+# PROP Intermediate_Dir "Win32_DLL_ASM_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "minigzip - Win32 DLL ASM Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Debug"\r
+# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_DLL_ASM_Debug"\r
+# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "minigzip - Win32 DLL Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "minigzip___Win32_DLL_Release"\r
+# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_DLL_Release"\r
+# PROP Intermediate_Dir "Win32_DLL_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "minigzip - Win32 DLL Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "minigzip___Win32_DLL_Debug"\r
+# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_DLL_Debug"\r
+# PROP Intermediate_Dir "Win32_DLL_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "minigzip - Win32 LIB ASM Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Release"\r
+# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_LIB_ASM_Release"\r
+# PROP Intermediate_Dir "Win32_LIB_ASM_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "minigzip - Win32 LIB ASM Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Debug"\r
+# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_LIB_ASM_Debug"\r
+# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "minigzip - Win32 LIB Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "minigzip___Win32_LIB_Release"\r
+# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_LIB_Release"\r
+# PROP Intermediate_Dir "Win32_LIB_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "minigzip - Win32 LIB Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "minigzip___Win32_LIB_Debug"\r
+# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_LIB_Debug"\r
+# PROP Intermediate_Dir "Win32_LIB_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ENDIF\r
+\r
+# Begin Target\r
+\r
+# Name "minigzip - Win32 DLL ASM Release"\r
+# Name "minigzip - Win32 DLL ASM Debug"\r
+# Name "minigzip - Win32 DLL Release"\r
+# Name "minigzip - Win32 DLL Debug"\r
+# Name "minigzip - Win32 LIB ASM Release"\r
+# Name "minigzip - Win32 LIB ASM Debug"\r
+# Name "minigzip - Win32 LIB Release"\r
+# Name "minigzip - Win32 LIB Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\minigzip.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\zconf.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\zlib.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/8.x/zlib/old/visualc6/zlib.dsp b/8.x/zlib/old/visualc6/zlib.dsp
new file mode 100644 (file)
index 0000000..00f54ea
--- /dev/null
@@ -0,0 +1,621 @@
+# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+# TARGTYPE "Win32 (x86) Static Library" 0x0104\r
+\r
+CFG=zlib - Win32 LIB Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE\r
+!MESSAGE NMAKE /f "zlib.mak".\r
+!MESSAGE\r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE\r
+!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 LIB Debug"\r
+!MESSAGE\r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE\r
+!MESSAGE "zlib - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "zlib - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "zlib - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "zlib - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library")\r
+!MESSAGE "zlib - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library")\r
+!MESSAGE "zlib - Win32 LIB Release" (based on "Win32 (x86) Static Library")\r
+!MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library")\r
+!MESSAGE\r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+\r
+!IF  "$(CFG)" == "zlib - Win32 DLL ASM Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Release"\r
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_DLL_ASM_Release"\r
+# PROP Intermediate_Dir "Win32_DLL_ASM_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+CPP=cl.exe\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX /Yc /Yu\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+MTL=midl.exe\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+RSC=rc.exe\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\zlib1.dll"\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL ASM Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Debug"\r
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_DLL_ASM_Debug"\r
+# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+CPP=cl.exe\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX /Yc /Yu\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+MTL=midl.exe\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+RSC=rc.exe\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\zlib1d.dll" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "zlib___Win32_DLL_Release"\r
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_DLL_Release"\r
+# PROP Intermediate_Dir "Win32_DLL_Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+CPP=cl.exe\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX /Yc /Yu\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+MTL=midl.exe\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+RSC=rc.exe\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_Release\zlib1.dll"\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "zlib___Win32_DLL_Debug"\r
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_DLL_Debug"\r
+# PROP Intermediate_Dir "Win32_DLL_Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+CPP=cl.exe\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX /Yc /Yu\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+MTL=midl.exe\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+RSC=rc.exe\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\zlib1d.dll" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Release"\r
+# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_LIB_ASM_Release"\r
+# PROP Intermediate_Dir "Win32_LIB_ASM_Release"\r
+# PROP Target_Dir ""\r
+CPP=cl.exe\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX /Yc /Yu\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+RSC=rc.exe\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo\r
+# ADD LIB32 /nologo\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Debug"\r
+# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_LIB_ASM_Debug"\r
+# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"\r
+# PROP Target_Dir ""\r
+CPP=cl.exe\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX /Yc /Yu\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+RSC=rc.exe\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo\r
+# ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\zlibd.lib"\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "zlib___Win32_LIB_Release"\r
+# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Win32_LIB_Release"\r
+# PROP Intermediate_Dir "Win32_LIB_Release"\r
+# PROP Target_Dir ""\r
+CPP=cl.exe\r
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c\r
+# SUBTRACT BASE CPP /YX /Yc /Yu\r
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+RSC=rc.exe\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo\r
+# ADD LIB32 /nologo\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "zlib___Win32_LIB_Debug"\r
+# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Win32_LIB_Debug"\r
+# PROP Intermediate_Dir "Win32_LIB_Debug"\r
+# PROP Target_Dir ""\r
+CPP=cl.exe\r
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c\r
+# SUBTRACT BASE CPP /YX /Yc /Yu\r
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+RSC=rc.exe\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo\r
+# ADD LIB32 /nologo /out:"Win32_LIB_Debug\zlibd.lib"\r
+\r
+!ENDIF\r
+\r
+# Begin Target\r
+\r
+# Name "zlib - Win32 DLL ASM Release"\r
+# Name "zlib - Win32 DLL ASM Debug"\r
+# Name "zlib - Win32 DLL Release"\r
+# Name "zlib - Win32 DLL Debug"\r
+# Name "zlib - Win32 LIB ASM Release"\r
+# Name "zlib - Win32 LIB ASM Debug"\r
+# Name "zlib - Win32 LIB Release"\r
+# Name "zlib - Win32 LIB Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\adler32.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\compress.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\crc32.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\deflate.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\gzclose.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\gzlib.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\gzread.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\gzwrite.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\infback.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\inffast.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\inflate.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\inftrees.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\trees.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\uncompr.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\win32\zlib.def\r
+\r
+!IF  "$(CFG)" == "zlib - Win32 DLL ASM Release"\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL ASM Debug"\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Release"\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Debug"\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ENDIF\r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\zutil.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\crc32.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\deflate.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\inffast.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\inffixed.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\inflate.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\inftrees.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\trees.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\zconf.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\zlib.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\zutil.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\win32\zlib1.rc\r
+# End Source File\r
+# End Group\r
+# Begin Group "Assembler Files (Unsupported)"\r
+\r
+# PROP Default_Filter "asm;obj;c;cpp;cxx;h;hpp;hxx"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\contrib\masmx86\gvmat32.asm\r
+\r
+!IF  "$(CFG)" == "zlib - Win32 DLL ASM Release"\r
+\r
+# Begin Custom Build - Assembling...\r
+IntDir=.\Win32_DLL_ASM_Release\r
+InputPath=..\..\contrib\masmx86\gvmat32.asm\r
+InputName=gvmat32\r
+\r
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL ASM Debug"\r
+\r
+# Begin Custom Build - Assembling...\r
+IntDir=.\Win32_DLL_ASM_Debug\r
+InputPath=..\..\contrib\masmx86\gvmat32.asm\r
+InputName=gvmat32\r
+\r
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Release"\r
+\r
+# Begin Custom Build - Assembling...\r
+IntDir=.\Win32_LIB_ASM_Release\r
+InputPath=..\..\contrib\masmx86\gvmat32.asm\r
+InputName=gvmat32\r
+\r
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Debug"\r
+\r
+# Begin Custom Build - Assembling...\r
+IntDir=.\Win32_LIB_ASM_Debug\r
+InputPath=..\..\contrib\masmx86\gvmat32.asm\r
+InputName=gvmat32\r
+\r
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ENDIF\r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\contrib\masmx86\gvmat32c.c\r
+\r
+!IF  "$(CFG)" == "zlib - Win32 DLL ASM Release"\r
+\r
+# ADD CPP /I "..\.."\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL ASM Debug"\r
+\r
+# ADD CPP /I "..\.."\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+# ADD CPP /I "..\.."\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+# ADD CPP /I "..\.."\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Release"\r
+\r
+# ADD CPP /I "..\.."\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Debug"\r
+\r
+# ADD CPP /I "..\.."\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+# ADD CPP /I "..\.."\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+# ADD CPP /I "..\.."\r
+\r
+!ENDIF\r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\contrib\masmx86\inffas32.asm\r
+\r
+!IF  "$(CFG)" == "zlib - Win32 DLL ASM Release"\r
+\r
+# Begin Custom Build - Assembling...\r
+IntDir=.\Win32_DLL_ASM_Release\r
+InputPath=..\..\contrib\masmx86\inffas32.asm\r
+InputName=inffas32\r
+\r
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL ASM Debug"\r
+\r
+# Begin Custom Build - Assembling...\r
+IntDir=.\Win32_DLL_ASM_Debug\r
+InputPath=..\..\contrib\masmx86\inffas32.asm\r
+InputName=inffas32\r
+\r
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 DLL Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Release"\r
+\r
+# Begin Custom Build - Assembling...\r
+IntDir=.\Win32_LIB_ASM_Release\r
+InputPath=..\..\contrib\masmx86\inffas32.asm\r
+InputName=inffas32\r
+\r
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB ASM Debug"\r
+\r
+# Begin Custom Build - Assembling...\r
+IntDir=.\Win32_LIB_ASM_Debug\r
+InputPath=..\..\contrib\masmx86\inffas32.asm\r
+InputName=inffas32\r
+\r
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "zlib - Win32 LIB Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ENDIF\r
+\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=.\README.txt\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/8.x/zlib/old/visualc6/zlib.dsw b/8.x/zlib/old/visualc6/zlib.dsw
new file mode 100644 (file)
index 0000000..3a771fc
--- /dev/null
@@ -0,0 +1,59 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "example"=.\example.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name zlib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "minigzip"=.\minigzip.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name zlib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "zlib"=.\zlib.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/8.x/zlib/qnx/package.qpg b/8.x/zlib/qnx/package.qpg
new file mode 100644 (file)
index 0000000..2bc63b2
--- /dev/null
@@ -0,0 +1,141 @@
+<QPG:Generation>
+   <QPG:Options>
+      <QPG:User unattended="no" verbosity="2" listfiles="yes"/>
+      <QPG:Defaults type="qnx_package"/>
+      <QPG:Source></QPG:Source>
+      <QPG:Release number="+"/>
+      <QPG:Build></QPG:Build>
+      <QPG:FileSorting strip="yes"/>
+      <QPG:Package targets="combine"/>
+      <QPG:Repository generate="yes"/>
+      <QPG:FinalDir></QPG:FinalDir>
+      <QPG:Cleanup></QPG:Cleanup>
+   </QPG:Options>
+
+   <QPG:Responsible>
+      <QPG:Company></QPG:Company>
+      <QPG:Department></QPG:Department>
+      <QPG:Group></QPG:Group>
+      <QPG:Team></QPG:Team>
+      <QPG:Employee></QPG:Employee>
+      <QPG:EmailAddress></QPG:EmailAddress>
+   </QPG:Responsible>
+
+   <QPG:Values>
+      <QPG:Files>
+         <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
+         <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
+         <QPG:Add file="../libz.so.1.2.5" install="/opt/lib/" user="root:bin" permission="644"/>
+         <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.5"/>
+         <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.5"/>
+         <QPG:Add file="../libz.so.1.2.5" install="/opt/lib/" component="slib"/>
+      </QPG:Files>
+
+      <QPG:PackageFilter>
+         <QPM:PackageManifest>
+            <QPM:PackageDescription>
+               <QPM:PackageType>Library</QPM:PackageType>
+               <QPM:PackageReleaseNotes></QPM:PackageReleaseNotes>
+               <QPM:PackageReleaseUrgency>Medium</QPM:PackageReleaseUrgency>
+               <QPM:PackageRepository></QPM:PackageRepository>
+               <QPM:FileVersion>2.0</QPM:FileVersion>
+            </QPM:PackageDescription>
+
+            <QPM:ProductDescription>
+               <QPM:ProductName>zlib</QPM:ProductName>
+               <QPM:ProductIdentifier>zlib</QPM:ProductIdentifier>
+               <QPM:ProductEmail>alain.bonnefoy@icbt.com</QPM:ProductEmail>
+               <QPM:VendorName>Public</QPM:VendorName>
+               <QPM:VendorInstallName>public</QPM:VendorInstallName>
+               <QPM:VendorURL>www.gzip.org/zlib</QPM:VendorURL>
+               <QPM:VendorEmbedURL></QPM:VendorEmbedURL>
+               <QPM:VendorEmail></QPM:VendorEmail>
+               <QPM:AuthorName>Jean-Loup Gailly,Mark Adler</QPM:AuthorName>
+               <QPM:AuthorURL>www.gzip.org/zlib</QPM:AuthorURL>
+               <QPM:AuthorEmbedURL></QPM:AuthorEmbedURL>
+               <QPM:AuthorEmail>zlib@gzip.org</QPM:AuthorEmail>
+               <QPM:ProductIconSmall></QPM:ProductIconSmall>
+               <QPM:ProductIconLarge></QPM:ProductIconLarge>
+               <QPM:ProductDescriptionShort>A massively spiffy yet delicately unobtrusive compression library.</QPM:ProductDescriptionShort>
+               <QPM:ProductDescriptionLong>zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system.</QPM:ProductDescriptionLong>
+               <QPM:ProductDescriptionURL>http://www.gzip.org/zlib</QPM:ProductDescriptionURL>
+               <QPM:ProductDescriptionEmbedURL></QPM:ProductDescriptionEmbedURL>
+            </QPM:ProductDescription>
+
+            <QPM:ReleaseDescription>
+               <QPM:ReleaseVersion>1.2.5</QPM:ReleaseVersion>
+               <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
+               <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
+               <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
+               <QPM:ReleaseNoteMajor></QPM:ReleaseNoteMajor>
+               <QPM:ExcludeCountries>
+                  <QPM:Country></QPM:Country>
+               </QPM:ExcludeCountries>
+
+               <QPM:ReleaseCopyright>No License</QPM:ReleaseCopyright>
+            </QPM:ReleaseDescription>
+
+            <QPM:ContentDescription>
+               <QPM:ContentTopic xmlmultiple="true">Software Development/Libraries and Extensions/C Libraries</QPM:ContentTopic>
+               <QPM:ContentKeyword>zlib,compression</QPM:ContentKeyword>
+               <QPM:TargetOS>qnx6</QPM:TargetOS>
+               <QPM:HostOS>qnx6</QPM:HostOS>
+               <QPM:DisplayEnvironment xmlmultiple="true">None</QPM:DisplayEnvironment>
+               <QPM:TargetAudience xmlmultiple="true">Developer</QPM:TargetAudience>
+            </QPM:ContentDescription>
+         </QPM:PackageManifest>
+      </QPG:PackageFilter>
+
+      <QPG:PackageFilter proc="none" target="none">
+         <QPM:PackageManifest>
+            <QPM:ProductInstallationDependencies>
+               <QPM:ProductRequirements></QPM:ProductRequirements>
+            </QPM:ProductInstallationDependencies>
+
+            <QPM:ProductInstallationProcedure>
+               <QPM:Script xmlmultiple="true">
+                  <QPM:ScriptName></QPM:ScriptName>
+                  <QPM:ScriptType>Install</QPM:ScriptType>
+                  <QPM:ScriptTiming>Post</QPM:ScriptTiming>
+                  <QPM:ScriptBlocking>No</QPM:ScriptBlocking>
+                  <QPM:ScriptResult>Ignore</QPM:ScriptResult>
+                  <QPM:ShortDescription></QPM:ShortDescription>
+                  <QPM:UseBinaries>No</QPM:UseBinaries>
+                  <QPM:Priority>Optional</QPM:Priority>
+               </QPM:Script>
+            </QPM:ProductInstallationProcedure>
+         </QPM:PackageManifest>
+
+         <QPM:Launch>
+         </QPM:Launch>
+      </QPG:PackageFilter>
+
+      <QPG:PackageFilter type="core" component="none">
+         <QPM:PackageManifest>
+            <QPM:ProductInstallationProcedure>
+              <QPM:OrderDependency xmlmultiple="true">
+                 <QPM:Order>InstallOver</QPM:Order>
+                 <QPM:Product>zlib</QPM:Product>
+              </QPM:OrderDependency>
+            </QPM:ProductInstallationProcedure>
+         </QPM:PackageManifest>
+
+         <QPM:Launch>
+         </QPM:Launch>
+      </QPG:PackageFilter>
+
+      <QPG:PackageFilter type="core" component="dev">
+         <QPM:PackageManifest>
+            <QPM:ProductInstallationProcedure>
+              <QPM:OrderDependency xmlmultiple="true">
+                 <QPM:Order>InstallOver</QPM:Order>
+                 <QPM:Product>zlib-dev</QPM:Product>
+              </QPM:OrderDependency>
+            </QPM:ProductInstallationProcedure>
+         </QPM:PackageManifest>
+
+         <QPM:Launch>
+         </QPM:Launch>
+      </QPG:PackageFilter>
+   </QPG:Values>
+</QPG:Generation>
diff --git a/8.x/zlib/treebuild.xml b/8.x/zlib/treebuild.xml
new file mode 100644 (file)
index 0000000..6b8f542
--- /dev/null
@@ -0,0 +1,116 @@
+<?xml version="1.0" ?>
+<package name="zlib" version="1.2.5">
+    <library name="zlib" dlversion="1.2.5" dlname="z">
+       <property name="description"> zip compression library </property>
+       <property name="include-target-dir" value="$(@PACKAGE/install-includedir)" />
+
+       <!-- fixme: not implemented yet -->
+       <property name="compiler/c/inline" value="yes" />
+
+       <include-file name="zlib.h" scope="public" mode="644" />
+       <include-file name="zconf.h" scope="public" mode="644" />
+
+       <source name="adler32.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+       </source>
+       <source name="compress.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+       </source>
+       <source name="crc32.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="crc32.h" />
+       </source>
+       <source name="gzclose.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="gzguts.h" />
+       </source>
+       <source name="gzlib.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="gzguts.h" />
+       </source>
+       <source name="gzread.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="gzguts.h" />
+       </source>
+       <source name="gzwrite.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="gzguts.h" />
+       </source>
+       <source name="uncompr.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+       </source>
+       <source name="deflate.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="zutil.h" />
+           <depend name="deflate.h" />
+       </source>
+       <source name="trees.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="zutil.h" />
+           <depend name="deflate.h" />
+           <depend name="trees.h" />
+       </source>
+       <source name="zutil.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="zutil.h" />
+       </source>
+       <source name="inflate.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="zutil.h" />
+           <depend name="inftrees.h" />
+           <depend name="inflate.h" />
+           <depend name="inffast.h" />
+       </source>
+       <source name="infback.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="zutil.h" />
+           <depend name="inftrees.h" />
+           <depend name="inflate.h" />
+           <depend name="inffast.h" />
+       </source>
+       <source name="inftrees.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="zutil.h" />
+           <depend name="inftrees.h" />
+       </source>
+       <source name="inffast.c">
+           <depend name="zlib.h" />
+           <depend name="zconf.h" />
+           <depend name="zutil.h" />
+           <depend name="inftrees.h" />
+           <depend name="inflate.h" />
+           <depend name="inffast.h" />
+       </source>
+    </library>
+</package>
+
+<!--
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+# OBJA =
+# to use the asm code: make OBJA=match.o
+#
+match.o: match.S
+       $(CPP) match.S > _match.s
+       $(CC) -c _match.s
+       mv _match.o match.o
+       rm -f _match.s
+-->
diff --git a/8.x/zlib/trees.c b/8.x/zlib/trees.c
new file mode 100644 (file)
index 0000000..56e9bb1
--- /dev/null
@@ -0,0 +1,1244 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2010 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local int  detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (ush)val << s->bi_valid;\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (ush)(value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+            "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+        fprintf(header, "%2u%s", _dist_code[i],
+                SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header,
+        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+        fprintf(header, "%2u%s", _length_code[i],
+                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+        fprintf(header, "%1u%s", base_length[i],
+                SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "%5u%s", base_dist[i],
+                SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if ((unsigned) tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+                                s->depth[n] : s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */
+#ifdef DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+        s->compressed_len += 10L;
+#endif
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+        /* Check if the file is binary or text */
+        if (s->strm->data_type == Z_UNKNOWN)
+            s->strm->data_type = detect_data_type(s);
+
+        /* Construct the literal and distance trees */
+        build_tree(s, (tree_desc *)(&(s->l_desc)));
+        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+
+        build_tree(s, (tree_desc *)(&(s->d_desc)));
+        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+        /* At this point, opt_len and static_len are the total bit lengths of
+         * the compressed block data, excluding the tree representations.
+         */
+
+        /* Build the bit length tree for the above two trees, and get the index
+         * in bl_order of the last bit length code to send.
+         */
+        max_blindex = build_bl_tree(s);
+
+        /* Determine the best encoding. Compute the block lengths in bytes. */
+        opt_lenb = (s->opt_len+3+7)>>3;
+        static_lenb = (s->static_len+3+7)>>3;
+
+        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+                s->last_lit));
+
+        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+last, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+last, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (last) {
+        bi_windup(s);
+#ifdef DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+               "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ *    a) There are no non-portable control characters belonging to the
+ *       "black list" (0..6, 14..25, 28..31).
+ *    b) There is at least one printable character belonging to the
+ *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ *   "gray list" that is ignored in this detection algorithm:
+ *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+    deflate_state *s;
+{
+    /* black_mask is the bit mask of black-listed bytes
+     * set bits 0..6, 14..25, and 28..31
+     * 0xf3ffc07f = binary 11110011111111111100000001111111
+     */
+    unsigned long black_mask = 0xf3ffc07fUL;
+    int n;
+
+    /* Check for non-textual ("black-listed") bytes. */
+    for (n = 0; n <= 31; n++, black_mask >>= 1)
+        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+            return Z_BINARY;
+
+    /* Check for textual ("white-listed") bytes. */
+    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+            || s->dyn_ltree[13].Freq != 0)
+        return Z_TEXT;
+    for (n = 32; n < LITERALS; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            return Z_TEXT;
+
+    /* There are no "black-listed" or "white-listed" bytes:
+     * this stream either is empty or has tolerated ("gray-listed") bytes only.
+     */
+    return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
diff --git a/8.x/zlib/trees.h b/8.x/zlib/trees.h
new file mode 100644 (file)
index 0000000..d35639d
--- /dev/null
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
diff --git a/8.x/zlib/uncompr.c b/8.x/zlib/uncompr.c
new file mode 100644 (file)
index 0000000..ad98be3
--- /dev/null
@@ -0,0 +1,59 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+            return Z_DATA_ERROR;
+        return err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
diff --git a/8.x/zlib/watcom/watcom_f.mak b/8.x/zlib/watcom/watcom_f.mak
new file mode 100644 (file)
index 0000000..37f4d74
--- /dev/null
@@ -0,0 +1,43 @@
+# Makefile for zlib
+# OpenWatcom flat model
+# Last updated: 28-Dec-2005
+
+# To use, do "wmake -f watcom_f.mak"
+
+C_SOURCE =  adler32.c  compress.c crc32.c   deflate.c    &
+           gzclose.c  gzlib.c    gzread.c  gzwrite.c    &
+            infback.c  inffast.c  inflate.c inftrees.c   &
+            trees.c    uncompr.c  zutil.c
+
+OBJS =      adler32.obj  compress.obj crc32.obj   deflate.obj    &
+           gzclose.obj  gzlib.obj    gzread.obj  gzwrite.obj    &
+            infback.obj  inffast.obj  inflate.obj inftrees.obj   &
+            trees.obj    uncompr.obj  zutil.obj
+
+CC       = wcc386
+LINKER   = wcl386
+CFLAGS   = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx
+ZLIB_LIB = zlib_f.lib
+
+.C.OBJ:
+        $(CC) $(CFLAGS) $[@
+
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+$(ZLIB_LIB): $(OBJS)
+       wlib -b -c $(ZLIB_LIB) -+adler32.obj  -+compress.obj -+crc32.obj
+       wlib -b -c $(ZLIB_LIB) -+gzclose.obj  -+gzlib.obj    -+gzread.obj   -+gzwrite.obj
+        wlib -b -c $(ZLIB_LIB) -+deflate.obj  -+infback.obj
+        wlib -b -c $(ZLIB_LIB) -+inffast.obj  -+inflate.obj  -+inftrees.obj
+        wlib -b -c $(ZLIB_LIB) -+trees.obj    -+uncompr.obj  -+zutil.obj
+
+example.exe: $(ZLIB_LIB) example.obj
+       $(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB)
+
+minigzip.exe: $(ZLIB_LIB) minigzip.obj
+       $(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
+
+clean: .SYMBOLIC
+          del *.obj
+          del $(ZLIB_LIB)
+          @echo Cleaning done
diff --git a/8.x/zlib/watcom/watcom_l.mak b/8.x/zlib/watcom/watcom_l.mak
new file mode 100644 (file)
index 0000000..193eed7
--- /dev/null
@@ -0,0 +1,43 @@
+# Makefile for zlib
+# OpenWatcom large model
+# Last updated: 28-Dec-2005
+
+# To use, do "wmake -f watcom_l.mak"
+
+C_SOURCE =  adler32.c  compress.c crc32.c   deflate.c    &
+           gzclose.c  gzlib.c    gzread.c  gzwrite.c    &
+            infback.c  inffast.c  inflate.c inftrees.c   &
+            trees.c    uncompr.c  zutil.c
+
+OBJS =      adler32.obj  compress.obj crc32.obj   deflate.obj    &
+           gzclose.obj  gzlib.obj    gzread.obj  gzwrite.obj    &
+            infback.obj  inffast.obj  inflate.obj inftrees.obj   &
+            trees.obj    uncompr.obj  zutil.obj
+
+CC       = wcc
+LINKER   = wcl
+CFLAGS   = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx
+ZLIB_LIB = zlib_l.lib
+
+.C.OBJ:
+        $(CC) $(CFLAGS) $[@
+
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+$(ZLIB_LIB): $(OBJS)
+       wlib -b -c $(ZLIB_LIB) -+adler32.obj  -+compress.obj -+crc32.obj
+       wlib -b -c $(ZLIB_LIB) -+gzclose.obj  -+gzlib.obj    -+gzread.obj   -+gzwrite.obj
+        wlib -b -c $(ZLIB_LIB) -+deflate.obj  -+infback.obj
+        wlib -b -c $(ZLIB_LIB) -+inffast.obj  -+inflate.obj  -+inftrees.obj
+        wlib -b -c $(ZLIB_LIB) -+trees.obj    -+uncompr.obj  -+zutil.obj
+
+example.exe: $(ZLIB_LIB) example.obj
+       $(LINKER) -fe=example.exe example.obj $(ZLIB_LIB)
+
+minigzip.exe: $(ZLIB_LIB) minigzip.obj
+       $(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
+
+clean: .SYMBOLIC
+          del *.obj
+          del $(ZLIB_LIB)
+          @echo Cleaning done
diff --git a/8.x/zlib/win32/DLL_FAQ.txt b/8.x/zlib/win32/DLL_FAQ.txt
new file mode 100644 (file)
index 0000000..12c0090
--- /dev/null
@@ -0,0 +1,397 @@
+
+            Frequently Asked Questions about ZLIB1.DLL
+
+
+This document describes the design, the rationale, and the usage
+of the official DLL build of zlib, named ZLIB1.DLL.  If you have
+general questions about zlib, you should see the file "FAQ" found
+in the zlib distribution, or at the following location:
+  http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. What is ZLIB1.DLL, and how can I get it?
+
+  - ZLIB1.DLL is the official build of zlib as a DLL.
+    (Please remark the character '1' in the name.)
+
+    Pointers to a precompiled ZLIB1.DLL can be found in the zlib
+    web site at:
+      http://www.zlib.net/
+
+    Applications that link to ZLIB1.DLL can rely on the following
+    specification:
+
+    * The exported symbols are exclusively defined in the source
+      files "zlib.h" and "zlib.def", found in an official zlib
+      source distribution.
+    * The symbols are exported by name, not by ordinal.
+    * The exported names are undecorated.
+    * The calling convention of functions is "C" (CDECL).
+    * The ZLIB1.DLL binary is linked to MSVCRT.DLL.
+
+    The archive in which ZLIB1.DLL is bundled contains compiled
+    test programs that must run with a valid build of ZLIB1.DLL.
+    It is recommended to download the prebuilt DLL from the zlib
+    web site, instead of building it yourself, to avoid potential
+    incompatibilities that could be introduced by your compiler
+    and build settings.  If you do build the DLL yourself, please
+    make sure that it complies with all the above requirements,
+    and it runs with the precompiled test programs, bundled with
+    the original ZLIB1.DLL distribution.
+
+    If, for any reason, you need to build an incompatible DLL,
+    please use a different file name.
+
+
+ 2. Why did you change the name of the DLL to ZLIB1.DLL?
+    What happened to the old ZLIB.DLL?
+
+  - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
+    compilation settings that were incompatible to those used by
+    a static build.  The DLL settings were supposed to be enabled
+    by defining the macro ZLIB_DLL, before including "zlib.h".
+    Incorrect handling of this macro was silently accepted at
+    build time, resulting in two major problems:
+
+    * ZLIB_DLL was missing from the old makefile.  When building
+      the DLL, not all people added it to the build options.  In
+      consequence, incompatible incarnations of ZLIB.DLL started
+      to circulate around the net.
+
+    * When switching from using the static library to using the
+      DLL, applications had to define the ZLIB_DLL macro and
+      to recompile all the sources that contained calls to zlib
+      functions.  Failure to do so resulted in creating binaries
+      that were unable to run with the official ZLIB.DLL build.
+
+    The only possible solution that we could foresee was to make
+    a binary-incompatible change in the DLL interface, in order to
+    remove the dependency on the ZLIB_DLL macro, and to release
+    the new DLL under a different name.
+
+    We chose the name ZLIB1.DLL, where '1' indicates the major
+    zlib version number.  We hope that we will not have to break
+    the binary compatibility again, at least not as long as the
+    zlib-1.x series will last.
+
+    There is still a ZLIB_DLL macro, that can trigger a more
+    efficient build and use of the DLL, but compatibility no
+    longer dependents on it.
+
+
+ 3. Can I build ZLIB.DLL from the new zlib sources, and replace
+    an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
+
+  - In principle, you can do it by assigning calling convention
+    keywords to the macros ZEXPORT and ZEXPORTVA.  In practice,
+    it depends on what you mean by "an old ZLIB.DLL", because the
+    old DLL exists in several mutually-incompatible versions.
+    You have to find out first what kind of calling convention is
+    being used in your particular ZLIB.DLL build, and to use the
+    same one in the new build.  If you don't know what this is all
+    about, you might be better off if you would just leave the old
+    DLL intact.
+
+
+ 4. Can I compile my application using the new zlib interface, and
+    link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
+    earlier?
+
+  - The official answer is "no"; the real answer depends again on
+    what kind of ZLIB.DLL you have.  Even if you are lucky, this
+    course of action is unreliable.
+
+    If you rebuild your application and you intend to use a newer
+    version of zlib (post- 1.1.4), it is strongly recommended to
+    link it to the new ZLIB1.DLL.
+
+
+ 5. Why are the zlib symbols exported by name, and not by ordinal?
+
+  - Although exporting symbols by ordinal is a little faster, it
+    is risky.  Any single glitch in the maintenance or use of the
+    DEF file that contains the ordinals can result in incompatible
+    builds and frustrating crashes.  Simply put, the benefits of
+    exporting symbols by ordinal do not justify the risks.
+
+    Technically, it should be possible to maintain ordinals in
+    the DEF file, and still export the symbols by name.  Ordinals
+    exist in every DLL, and even if the dynamic linking performed
+    at the DLL startup is searching for names, ordinals serve as
+    hints, for a faster name lookup.  However, if the DEF file
+    contains ordinals, the Microsoft linker automatically builds
+    an implib that will cause the executables linked to it to use
+    those ordinals, and not the names.  It is interesting to
+    notice that the GNU linker for Win32 does not suffer from this
+    problem.
+
+    It is possible to avoid the DEF file if the exported symbols
+    are accompanied by a "__declspec(dllexport)" attribute in the
+    source files.  You can do this in zlib by predefining the
+    ZLIB_DLL macro.
+
+
+ 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
+    convention.  Why not use the STDCALL convention?
+    STDCALL is the standard convention in Win32, and I need it in
+    my Visual Basic project!
+
+    (For readability, we use CDECL to refer to the convention
+     triggered by the "__cdecl" keyword, STDCALL to refer to
+     the convention triggered by "__stdcall", and FASTCALL to
+     refer to the convention triggered by "__fastcall".)
+
+  - Most of the native Windows API functions (without varargs) use
+    indeed the WINAPI convention (which translates to STDCALL in
+    Win32), but the standard C functions use CDECL.  If a user
+    application is intrinsically tied to the Windows API (e.g.
+    it calls native Windows API functions such as CreateFile()),
+    sometimes it makes sense to decorate its own functions with
+    WINAPI.  But if ANSI C or POSIX portability is a goal (e.g.
+    it calls standard C functions such as fopen()), it is not a
+    sound decision to request the inclusion of <windows.h>, or to
+    use non-ANSI constructs, for the sole purpose to make the user
+    functions STDCALL-able.
+
+    The functionality offered by zlib is not in the category of
+    "Windows functionality", but is more like "C functionality".
+
+    Technically, STDCALL is not bad; in fact, it is slightly
+    faster than CDECL, and it works with variable-argument
+    functions, just like CDECL.  It is unfortunate that, in spite
+    of using STDCALL in the Windows API, it is not the default
+    convention used by the C compilers that run under Windows.
+    The roots of the problem reside deep inside the unsafety of
+    the K&R-style function prototypes, where the argument types
+    are not specified; but that is another story for another day.
+
+    The remaining fact is that CDECL is the default convention.
+    Even if an explicit convention is hard-coded into the function
+    prototypes inside C headers, problems may appear.  The
+    necessity to expose the convention in users' callbacks is one
+    of these problems.
+
+    The calling convention issues are also important when using
+    zlib in other programming languages.  Some of them, like Ada
+    (GNAT) and Fortran (GNU G77), have C bindings implemented
+    initially on Unix, and relying on the C calling convention.
+    On the other hand, the pre- .NET versions of Microsoft Visual
+    Basic require STDCALL, while Borland Delphi prefers, although
+    it does not require, FASTCALL.
+
+    In fairness to all possible uses of zlib outside the C
+    programming language, we choose the default "C" convention.
+    Anyone interested in different bindings or conventions is
+    encouraged to maintain specialized projects.  The "contrib/"
+    directory from the zlib distribution already holds a couple
+    of foreign bindings, such as Ada, C++, and Delphi.
+
+
+ 7. I need a DLL for my Visual Basic project.  What can I do?
+
+  - Define the ZLIB_WINAPI macro before including "zlib.h", when
+    building both the DLL and the user application (except that
+    you don't need to define anything when using the DLL in Visual
+    Basic).  The ZLIB_WINAPI macro will switch on the WINAPI
+    (STDCALL) convention.  The name of this DLL must be different
+    than the official ZLIB1.DLL.
+
+    Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
+    with the ZLIB_WINAPI macro turned on, and with the minizip
+    functionality built in.  For more information, please read
+    the notes inside "contrib/vstudio/readme.txt", found in the
+    zlib distribution.
+
+
+ 8. I need to use zlib in my Microsoft .NET project.  What can I
+    do?
+
+  - Henrik Ravn has contributed a .NET wrapper around zlib.  Look
+    into contrib/dotzlib/, inside the zlib distribution.
+
+
+ 9. If my application uses ZLIB1.DLL, should I link it to
+    MSVCRT.DLL?  Why?
+
+  - It is not required, but it is recommended to link your
+    application to MSVCRT.DLL, if it uses ZLIB1.DLL.
+
+    The executables (.EXE, .DLL, etc.) that are involved in the
+    same process and are using the C run-time library (i.e. they
+    are calling standard C functions), must link to the same
+    library.  There are several libraries in the Win32 system:
+    CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
+    Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
+    depend on it should also be linked to MSVCRT.DLL.
+
+
+10. Why are you saying that ZLIB1.DLL and my application should
+    be linked to the same C run-time (CRT) library?  I linked my
+    application and my DLLs to different C libraries (e.g. my
+    application to a static library, and my DLLs to MSVCRT.DLL),
+    and everything works fine.
+
+  - If a user library invokes only pure Win32 API (accessible via
+    <windows.h> and the related headers), its DLL build will work
+    in any context.  But if this library invokes standard C API,
+    things get more complicated.
+
+    There is a single Win32 library in a Win32 system.  Every
+    function in this library resides in a single DLL module, that
+    is safe to call from anywhere.  On the other hand, there are
+    multiple versions of the C library, and each of them has its
+    own separate internal state.  Standalone executables and user
+    DLLs that call standard C functions must link to a C run-time
+    (CRT) library, be it static or shared (DLL).  Intermixing
+    occurs when an executable (not necessarily standalone) and a
+    DLL are linked to different CRTs, and both are running in the
+    same process.
+
+    Intermixing multiple CRTs is possible, as long as their
+    internal states are kept intact.  The Microsoft Knowledge Base
+    articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
+    "HOWTO: Link with the Correct C Run-Time (CRT) Library"
+    mention the potential problems raised by intermixing.
+
+    If intermixing works for you, it's because your application
+    and DLLs are avoiding the corruption of each of the CRTs'
+    internal states, maybe by careful design, or maybe by fortune.
+
+    Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
+    as those provided by Borland, raises similar problems.
+
+
+11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
+
+  - MSVCRT.DLL exists on every Windows 95 with a new service pack
+    installed, or with Microsoft Internet Explorer 4 or later, and
+    on all other Windows 4.x or later (Windows 98, Windows NT 4,
+    or later).  It is freely distributable; if not present in the
+    system, it can be downloaded from Microsoft or from other
+    software provider for free.
+
+    The fact that MSVCRT.DLL does not exist on a virgin Windows 95
+    is not so problematic.  Windows 95 is scarcely found nowadays,
+    Microsoft ended its support a long time ago, and many recent
+    applications from various vendors, including Microsoft, do not
+    even run on it.  Furthermore, no serious user should run
+    Windows 95 without a proper update installed.
+
+
+12. Why are you not linking ZLIB1.DLL to
+    <<my favorite C run-time library>> ?
+
+  - We considered and abandoned the following alternatives:
+
+    * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
+      LIBCMT.LIB) is not a good option.  People are using the DLL
+      mainly to save disk space.  If you are linking your program
+      to a static C library, you may as well consider linking zlib
+      in statically, too.
+
+    * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
+      CRTDLL.DLL is present on every Win32 installation.
+      Unfortunately, it has a series of problems: it does not
+      work properly with Microsoft's C++ libraries, it does not
+      provide support for 64-bit file offsets, (and so on...),
+      and Microsoft discontinued its support a long time ago.
+
+    * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
+      with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
+      raises problems related to the status of ZLIB1.DLL as a
+      system component.  According to the Microsoft Knowledge Base
+      article KB326922 "INFO: Redistribution of the Shared C
+      Runtime Component in Visual C++ .NET", MSVCR70.DLL and
+      MSVCR71.DLL are not supposed to function as system DLLs,
+      because they may clash with MSVCRT.DLL.  Instead, the
+      application's installer is supposed to put these DLLs
+      (if needed) in the application's private directory.
+      If ZLIB1.DLL depends on a non-system runtime, it cannot
+      function as a redistributable system component.
+
+    * Linking ZLIB1.DLL to non-Microsoft runtimes, such as
+      Borland's, or Cygwin's, raises problems related to the
+      reliable presence of these runtimes on Win32 systems.
+      It's easier to let the DLL build of zlib up to the people
+      who distribute these runtimes, and who may proceed as
+      explained in the answer to Question 14.
+
+
+13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
+    how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
+    (Visual Studio .NET) or newer?
+
+  - Due to the problems explained in the Microsoft Knowledge Base
+    article KB326922 (see the previous answer), the C runtime that
+    comes with the VC7 environment is no longer considered a
+    system component.  That is, it should not be assumed that this
+    runtime exists, or may be installed in a system directory.
+    Since ZLIB1.DLL is supposed to be a system component, it may
+    not depend on a non-system component.
+
+    In order to link ZLIB1.DLL and your application to MSVCRT.DLL
+    in VC7, you need the library of Visual C++ 6.0 or older.  If
+    you don't have this library at hand, it's probably best not to
+    use ZLIB1.DLL.
+
+    We are hoping that, in the future, Microsoft will provide a
+    way to build applications linked to a proper system runtime,
+    from the Visual C++ environment.  Until then, you have a
+    couple of alternatives, such as linking zlib in statically.
+    If your application requires dynamic linking, you may proceed
+    as explained in the answer to Question 14.
+
+
+14. I need to link my own DLL build to a CRT different than
+    MSVCRT.DLL.  What can I do?
+
+  - Feel free to rebuild the DLL from the zlib sources, and link
+    it the way you want.  You should, however, clearly state that
+    your build is unofficial.  You should give it a different file
+    name, and/or install it in a private directory that can be
+    accessed by your application only, and is not visible to the
+    others (i.e. it's neither in the PATH, nor in the SYSTEM or
+    SYSTEM32 directories).  Otherwise, your build may clash with
+    applications that link to the official build.
+
+    For example, in Cygwin, zlib is linked to the Cygwin runtime
+    CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
+
+
+15. May I include additional pieces of code that I find useful,
+    link them in ZLIB1.DLL, and export them?
+
+  - No.  A legitimate build of ZLIB1.DLL must not include code
+    that does not originate from the official zlib source code.
+    But you can make your own private DLL build, under a different
+    file name, as suggested in the previous answer.
+
+    For example, zlib is a part of the VCL library, distributed
+    with Borland Delphi and C++ Builder.  The DLL build of VCL
+    is a redistributable file, named VCLxx.DLL.
+
+
+16. May I remove some functionality out of ZLIB1.DLL, by enabling
+    macros like NO_GZCOMPRESS or NO_GZIP at compile time?
+
+  - No.  A legitimate build of ZLIB1.DLL must provide the complete
+    zlib functionality, as implemented in the official zlib source
+    code.  But you can make your own private DLL build, under a
+    different file name, as suggested in the previous answer.
+
+
+17. I made my own ZLIB1.DLL build.  Can I test it for compliance?
+
+  - We prefer that you download the official DLL from the zlib
+    web site.  If you need something peculiar from this DLL, you
+    can send your suggestion to the zlib mailing list.
+
+    However, in case you do rebuild the DLL yourself, you can run
+    it with the test programs found in the DLL distribution.
+    Running these test programs is not a guarantee of compliance,
+    but a failure can imply a detected problem.
+
+**
+
+This document is written and maintained by
+Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/8.x/zlib/win32/Makefile.bor b/8.x/zlib/win32/Makefile.bor
new file mode 100644 (file)
index 0000000..3981d42
--- /dev/null
@@ -0,0 +1,110 @@
+# Makefile for zlib
+# Borland C++ for Win32
+#
+# Usage:
+#  make -f win32/Makefile.bor
+#  make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
+
+# ------------ Borland C++ ------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
+# added to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+CC = bcc32
+AS = bcc32
+LD = bcc32
+AR = tlib
+CFLAGS  = -a -d -k- -O2 $(LOC)
+ASFLAGS = $(LOC)
+LDFLAGS = $(LOC)
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+#OBJA =
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+#OBJPA=
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+       $(CC) -c $(CFLAGS) $<
+
+.asm.obj:
+       $(AS) -c $(ASFLAGS) $<
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: example.c zlib.h zconf.h
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
+       -del $(ZLIB_LIB)
+       $(AR) $(ZLIB_LIB) $(OBJP1)
+       $(AR) $(ZLIB_LIB) $(OBJP2)
+       $(AR) $(ZLIB_LIB) $(OBJPA)
+
+
+# testing
+test: example.exe minigzip.exe
+       example
+       echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+       $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+       -del $(ZLIB_LIB)
+       -del *.obj
+       -del *.exe
+       -del *.tds
+       -del zlib.bak
+       -del foo.gz
diff --git a/8.x/zlib/win32/Makefile.emx b/8.x/zlib/win32/Makefile.emx
new file mode 100644 (file)
index 0000000..4d6ab0e
--- /dev/null
@@ -0,0 +1,69 @@
+# Makefile for zlib.  Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+#   make -fmakefile.emx;  make test -fmakefile.emx
+#
+
+CC=gcc -Zwin32
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DDEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+             -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f."  If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+       gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+       ./example
+       echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+       $(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+       $(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+       $(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+       $(RM) *.d
+       $(RM) *.o
+       $(RM) *.exe
+       $(RM) zlib.a
+       $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/8.x/zlib/win32/Makefile.gcc b/8.x/zlib/win32/Makefile.gcc
new file mode 100644 (file)
index 0000000..0a33bf6
--- /dev/null
@@ -0,0 +1,164 @@
+# Makefile for zlib, derived from Makefile.dj2.
+# Modified for mingw32 by C. Spieler, 6/16/98.
+# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
+# Last updated: 1-Aug-2003.
+# Tested under Cygwin and MinGW.
+
+# Copyright (C) 1995-2003 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+#   make -fmakefile.gcc;  make test testdll -fmakefile.gcc
+#
+# To use the asm code, type:
+#   cp contrib/asm?86/match.S ./match.S
+#   make LOC=-DASMV OBJA=match.o -fmakefile.gcc
+#
+# To install libz.a, zconf.h and zlib.h in the system directories, type:
+#
+#   make install -fmakefile.gcc
+
+# Note:
+# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
+# the DLL name should be changed from "zlib1.dll".
+
+STATICLIB = libz.a
+SHAREDLIB = zlib1.dll
+IMPLIB    = libzdll.a
+
+#
+# Set to 1 if shared object needs to be installed
+#
+SHARED_MODE=0
+
+#LOC = -DASMV
+#LOC = -DDEBUG -g
+
+PREFIX =
+CC = $(PREFIX)gcc
+CFLAGS = $(LOC) -O3 -Wall
+EXTRA_CFLAGS = -DNO_VIZ
+
+AS = $(CC)
+ASFLAGS = $(LOC) -Wall
+
+LD = $(CC)
+LDFLAGS = $(LOC)
+
+AR = $(PREFIX)ar
+ARFLAGS = rcs
+
+RC = $(PREFIX)windres
+RCFLAGS = --define GCC_WINDRES
+
+STRIP = $(PREFIX)strip
+
+CP = cp -fp
+# If GNU install is available, replace $(CP) with install.
+INSTALL = $(CP)
+RM = rm -f
+
+prefix = /usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+       gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+OBJA =
+
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+test: example.exe minigzip.exe
+       ./example
+       echo hello world | ./minigzip | ./minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+       ./example_d
+       echo hello world | ./minigzip_d | ./minigzip_d -d
+
+.c.o:
+       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+
+.S.o:
+       $(AS) $(ASFLAGS) -c -o $@ $<
+
+$(STATICLIB): $(OBJS) $(OBJA)
+       $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+       $(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \
+       -o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+       $(STRIP) $@
+
+example.exe: example.o $(STATICLIB)
+       $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
+       $(STRIP) $@
+
+minigzip.exe: minigzip.o $(STATICLIB)
+       $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
+       $(STRIP) $@
+
+example_d.exe: example.o $(IMPLIB)
+       $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
+       $(STRIP) $@
+
+minigzip_d.exe: minigzip.o $(IMPLIB)
+       $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
+       $(STRIP) $@
+
+zlibrc.o: win32/zlib1.rc
+       $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
+
+
+# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
+
+.PHONY: install uninstall clean
+
+install: zlib.h zconf.h $(STATICLIB) $(IMPLIB)
+       -@mkdir -p $(INCLUDE_PATH)
+       -@mkdir -p $(LIBRARY_PATH)
+       -if [ "$(SHARED_MODE)" = "1" ]; then \
+               mkdir -p $(BINARY_PATH); \
+               $(INSTALL) $(SHAREDLIB) $(BINARY_PATH); \
+               $(INSTALL) $(IMPLIB) $(LIBRARY_PATH); \
+       fi
+       -$(INSTALL) zlib.h $(INCLUDE_PATH)
+       -$(INSTALL) zconf.h $(INCLUDE_PATH)
+       -$(INSTALL) $(STATICLIB) $(LIBRARY_PATH)
+
+uninstall:
+       -if [ "$(SHARED_MODE)" = "1" ]; then \
+               $(RM) $(BINARY_PATH)/$(SHAREDLIB); \
+               $(RM) $(LIBRARY_PATH)/$(IMPLIB); \
+       fi
+       -$(RM) $(INCLUDE_PATH)/zlib.h
+       -$(RM) $(INCLUDE_PATH)/zconf.h
+       -$(RM) $(LIBRARY_PATH)/$(STATICLIB)
+
+clean:
+       -$(RM) $(STATICLIB)
+       -$(RM) $(SHAREDLIB)
+       -$(RM) $(IMPLIB)
+       -$(RM) *.o
+       -$(RM) *.exe
+       -$(RM) foo.gz
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/8.x/zlib/win32/Makefile.msc b/8.x/zlib/win32/Makefile.msc
new file mode 100644 (file)
index 0000000..fa10a1a
--- /dev/null
@@ -0,0 +1,157 @@
+# Makefile for zlib using Microsoft (Visual) C
+# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler
+#
+# Usage:
+#   nmake -f win32/Makefile.msc                          (standard build)
+#   nmake -f win32/Makefile.msc LOC=-DFOO                (nonstandard build)
+#   nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
+#         OBJA="inffas32.obj match686.obj"               (use ASM code, x86)
+#   nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF" \
+#         OBJA="inffasx64.obj gvmat64.obj inffas8664.c"  (use ASM code, x64)
+
+# optional build flags
+LOC =
+
+# variables
+STATICLIB = zlib.lib
+SHAREDLIB = zlib1.dll
+IMPLIB    = zdll.lib
+
+CC = cl
+AS = ml
+LD = link
+AR = lib
+RC = rc
+CFLAGS  = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC)
+WFLAGS  = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
+ASFLAGS = -coff -Zi $(LOC)
+LDFLAGS = -nologo -debug -incremental:no -opt:ref
+ARFLAGS = -nologo
+RCFLAGS = /dWIN32 /r
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \
+       gzwrite.obj infback.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJA =
+
+
+# targets
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
+     example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+$(STATICLIB): $(OBJS) $(OBJA)
+       $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlib1.res
+       $(LD) $(LDFLAGS) -def:win32/zlib.def -dll -implib:$(IMPLIB) \
+         -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res
+       if exist $@.manifest \
+         mt -nologo -manifest $@.manifest -outputresource:$@;2
+
+example.exe: example.obj $(STATICLIB)
+       $(LD) $(LDFLAGS) example.obj $(STATICLIB)
+       if exist $@.manifest \
+         mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+minigzip.exe: minigzip.obj $(STATICLIB)
+       $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
+       if exist $@.manifest \
+         mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+example_d.exe: example.obj $(IMPLIB)
+       $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
+       if exist $@.manifest \
+         mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+minigzip_d.exe: minigzip.obj $(IMPLIB)
+       $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
+       if exist $@.manifest \
+         mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+.c.obj:
+       $(CC) -c $(WFLAGS) $(CFLAGS) $<
+
+{contrib/masmx64}.c.obj:
+       $(CC) -c $(WFLAGS) $(CFLAGS) $<
+
+{contrib/masmx64}.asm.obj:
+       $(AS) -c $(ASFLAGS) $<
+
+{contrib/masmx86}.asm.obj:
+       $(AS) -c $(ASFLAGS) $<
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+             inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+             inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+             inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+gvmat64.obj: contrib\masmx64\gvmat64.asm
+
+inffasx64.obj: contrib\masmx64\inffasx64.asm
+
+inffas8664.obj: contrib\masmx64\inffas8664.c zutil.h zlib.h zconf.h \
+               inftrees.h inflate.h inffast.h
+
+inffas32.obj: contrib\masmx86\inffas32.asm
+
+match686.obj: contrib\masmx86\match686.asm
+
+example.obj: example.c zlib.h zconf.h
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+
+zlib1.res: win32/zlib1.rc
+       $(RC) $(RCFLAGS) /fo$@ win32/zlib1.rc
+
+
+# testing
+test: example.exe minigzip.exe
+       example
+       echo hello world | minigzip | minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+       example_d
+       echo hello world | minigzip_d | minigzip_d -d
+
+
+# cleanup
+clean:
+       -del $(STATICLIB)
+       -del $(SHAREDLIB)
+       -del $(IMPLIB)
+       -del *.obj
+       -del *.res
+       -del *.exp
+       -del *.exe
+       -del *.pdb
+       -del *.manifest
+       -del foo.gz
diff --git a/8.x/zlib/win32/README-WIN32.txt b/8.x/zlib/win32/README-WIN32.txt
new file mode 100644 (file)
index 0000000..1e4c093
--- /dev/null
@@ -0,0 +1,103 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.4 is a general purpose data compression library.  All the code is
+thread safe.  The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org).  Two compiled
+examples are distributed in this package, example and minigzip.  The example_d
+and minigzip_d flavors validate that the zlib1.dll file is working correctly.
+
+Questions about zlib should be sent to <zlib@gzip.org>.  The zlib home page
+is http://zlib.net/ .  Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html
+before asking for help.
+
+
+Manifest:
+
+The package zlib-1.2.4-win32-x86.zip contains the following files:
+
+  README-WIN32.txt This document
+  ChangeLog        Changes since previous zlib packages
+  DLL_FAQ.txt      Frequently asked questions about zlib1.dll
+  zlib.3.pdf       Documentation of this library in Adobe Acrobat format
+
+  example.exe      A statically-bound example (using zlib.lib, not the dll)
+  example.pdb      Symbolic information for debugging example.exe
+
+  example_d.exe    A zlib1.dll bound example (using zdll.lib)
+  example_d.pdb    Symbolic information for debugging example_d.exe
+
+  minigzip.exe     A statically-bound test program (using zlib.lib, not the dll)
+  minigzip.pdb     Symbolic information for debugging minigzip.exe
+
+  minigzip_d.exe   A zlib1.dll bound test program (using zdll.lib)
+  minigzip_d.pdb   Symbolic information for debugging minigzip_d.exe
+
+  zlib.h           Install these files into the compilers' INCLUDE path to
+  zconf.h          compile programs which use zlib.lib or zdll.lib
+
+  zdll.lib         Install these files into the compilers' LIB path if linking
+  zdll.exp         a compiled program to the zlib1.dll binary
+
+  zlib.lib         Install these files into the compilers' LIB path to link zlib
+  zlib.pdb         into compiled programs, without zlib1.dll runtime dependency
+                   (zlib.pdb provides debugging info to the compile time linker)
+
+  zlib1.dll        Install this binary shared library into the system PATH, or
+                   the program's runtime directory (where the .exe resides)
+  zlib1.pdb        Install in the same directory as zlib1.dll, in order to debug
+                   an application crash using WinDbg or similar tools.
+
+All .pdb files above are entirely optional, but are very useful to a developer
+attempting to diagnose program misbehavior or a crash.  Many additional
+important files for developers can be found in the zlib124.zip source package
+available from http://zlib.net/ - review that package's README file for details.
+
+
+Acknowledgments:
+
+The deflate format used by zlib was defined by Phil Katz.  The deflate and
+zlib specifications were written by L.  Peter Deutsch.  Thanks to all the
+people who reported problems and suggested various improvements in zlib; they
+are too numerous to cite here.
+
+
+Copyright notice:
+
+  (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign.  The sources are provided for free but without
+warranty of any kind.  The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes.  Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/8.x/zlib/win32/VisualC.txt b/8.x/zlib/win32/VisualC.txt
new file mode 100644 (file)
index 0000000..579a5fc
--- /dev/null
@@ -0,0 +1,3 @@
+
+To build zlib using the Microsoft Visual C++ environment,
+use the appropriate project from the projects/ directory.
diff --git a/8.x/zlib/win32/zlib.def b/8.x/zlib/win32/zlib.def
new file mode 100644 (file)
index 0000000..03df8bf
--- /dev/null
@@ -0,0 +1,74 @@
+LIBRARY
+; zlib data compression library
+
+EXPORTS
+; basic functions
+    zlibVersion
+    deflate
+    deflateEnd
+    inflate
+    inflateEnd
+; advanced functions
+    deflateSetDictionary
+    deflateCopy
+    deflateReset
+    deflateParams
+    deflateTune
+    deflateBound
+    deflatePrime
+    deflateSetHeader
+    inflateSetDictionary
+    inflateSync
+    inflateCopy
+    inflateReset
+    inflateReset2
+    inflatePrime
+    inflateMark
+    inflateGetHeader
+    inflateBack
+    inflateBackEnd
+    zlibCompileFlags
+; utility functions
+    compress
+    compress2
+    compressBound
+    uncompress
+    gzopen
+    gzdopen
+    gzbuffer
+    gzsetparams
+    gzread
+    gzwrite
+    gzprintf
+    gzputs
+    gzgets
+    gzputc
+    gzgetc
+    gzungetc
+    gzflush
+    gzseek
+    gzrewind
+    gztell
+    gzoffset
+    gzeof
+    gzdirect
+    gzclose
+    gzclose_r
+    gzclose_w
+    gzerror
+    gzclearerr
+; checksum functions
+    adler32
+    crc32
+    adler32_combine
+    crc32_combine
+; various hacks, don't look :)
+    deflateInit_
+    deflateInit2_
+    inflateInit_
+    inflateInit2_
+    inflateBackInit_
+    zError
+    inflateSyncPoint
+    get_crc_table
+    inflateUndermine
diff --git a/8.x/zlib/win32/zlib1.rc b/8.x/zlib/win32/zlib1.rc
new file mode 100644 (file)
index 0000000..0d1d7ff
--- /dev/null
@@ -0,0 +1,40 @@
+#include <winver.h>
+#include "../zlib.h"
+
+#ifdef GCC_WINDRES
+VS_VERSION_INFO                VERSIONINFO
+#else
+VS_VERSION_INFO                VERSIONINFO     MOVEABLE IMPURE LOADONCALL DISCARDABLE
+#endif
+  FILEVERSION          ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
+  PRODUCTVERSION       ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
+  FILEFLAGSMASK                VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+  FILEFLAGS            1
+#else
+  FILEFLAGS            0
+#endif
+  FILEOS               VOS__WINDOWS32
+  FILETYPE             VFT_DLL
+  FILESUBTYPE          0       // not used
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    //language ID = U.S. English, char set = Windows, Multilingual
+    BEGIN
+      VALUE "FileDescription", "zlib data compression library\0"
+      VALUE "FileVersion",     ZLIB_VERSION "\0"
+      VALUE "InternalName",    "zlib1.dll\0"
+      VALUE "LegalCopyright",  "(C) 1995-2006 Jean-loup Gailly & Mark Adler\0"
+      VALUE "OriginalFilename",        "zlib1.dll\0"
+      VALUE "ProductName",     "zlib\0"
+      VALUE "ProductVersion",  ZLIB_VERSION "\0"
+      VALUE "Comments",                "For more information visit http://www.zlib.net/\0"
+    END
+  END
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x0409, 1252
+  END
+END
diff --git a/8.x/zlib/zconf.h b/8.x/zlib/zconf.h
new file mode 100644 (file)
index 0000000..02ce56c
--- /dev/null
@@ -0,0 +1,428 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  define gz_error              z_gz_error
+#  define gz_intmax             z_gz_intmax
+#  define gz_strwinerror        z_gz_strwinerror
+#  define gzbuffer              z_gzbuffer
+#  define gzclearerr            z_gzclearerr
+#  define gzclose               z_gzclose
+#  define gzclose_r             z_gzclose_r
+#  define gzclose_w             z_gzclose_w
+#  define gzdirect              z_gzdirect
+#  define gzdopen               z_gzdopen
+#  define gzeof                 z_gzeof
+#  define gzerror               z_gzerror
+#  define gzflush               z_gzflush
+#  define gzgetc                z_gzgetc
+#  define gzgets                z_gzgets
+#  define gzoffset              z_gzoffset
+#  define gzoffset64            z_gzoffset64
+#  define gzopen                z_gzopen
+#  define gzopen64              z_gzopen64
+#  define gzprintf              z_gzprintf
+#  define gzputc                z_gzputc
+#  define gzputs                z_gzputs
+#  define gzread                z_gzread
+#  define gzrewind              z_gzrewind
+#  define gzseek                z_gzseek
+#  define gzseek64              z_gzseek64
+#  define gzsetparams           z_gzsetparams
+#  define gztell                z_gztell
+#  define gztell64              z_gztell64
+#  define gzungetc              z_gzungetc
+#  define gzwrite               z_gzwrite
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  define uncompress            z_uncompress
+#  define zError                z_zError
+#  define zcalloc               z_zcalloc
+#  define zcfree                z_zcfree
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  define gzFile                z_gzFile
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef STDC
+#  include <sys/types.h>    /* for off_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#  include <unistd.h>       /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>     /* for off_t */
+#  endif
+#  ifndef z_off_t
+#    define z_off_t off_t
+#  endif
+#endif
+
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define z_off64_t off64_t
+#else
+#  define z_off64_t z_off_t
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/8.x/zlib/zconf.h.cmakein b/8.x/zlib/zconf.h.cmakein
new file mode 100644 (file)
index 0000000..a2f71b1
--- /dev/null
@@ -0,0 +1,430 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+#cmakedefine Z_PREFIX
+#cmakedefine Z_HAVE_UNISTD_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  define gz_error              z_gz_error
+#  define gz_intmax             z_gz_intmax
+#  define gz_strwinerror        z_gz_strwinerror
+#  define gzbuffer              z_gzbuffer
+#  define gzclearerr            z_gzclearerr
+#  define gzclose               z_gzclose
+#  define gzclose_r             z_gzclose_r
+#  define gzclose_w             z_gzclose_w
+#  define gzdirect              z_gzdirect
+#  define gzdopen               z_gzdopen
+#  define gzeof                 z_gzeof
+#  define gzerror               z_gzerror
+#  define gzflush               z_gzflush
+#  define gzgetc                z_gzgetc
+#  define gzgets                z_gzgets
+#  define gzoffset              z_gzoffset
+#  define gzoffset64            z_gzoffset64
+#  define gzopen                z_gzopen
+#  define gzopen64              z_gzopen64
+#  define gzprintf              z_gzprintf
+#  define gzputc                z_gzputc
+#  define gzputs                z_gzputs
+#  define gzread                z_gzread
+#  define gzrewind              z_gzrewind
+#  define gzseek                z_gzseek
+#  define gzseek64              z_gzseek64
+#  define gzsetparams           z_gzsetparams
+#  define gztell                z_gztell
+#  define gztell64              z_gztell64
+#  define gzungetc              z_gzungetc
+#  define gzwrite               z_gzwrite
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  define uncompress            z_uncompress
+#  define zError                z_zError
+#  define zcalloc               z_zcalloc
+#  define zcfree                z_zcfree
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  define gzFile                z_gzFile
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef STDC
+#  include <sys/types.h>    /* for off_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#  include <unistd.h>       /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>     /* for off_t */
+#  endif
+#  ifndef z_off_t
+#    define z_off_t off_t
+#  endif
+#endif
+
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define z_off64_t off64_t
+#else
+#  define z_off64_t z_off_t
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/8.x/zlib/zconf.h.in b/8.x/zlib/zconf.h.in
new file mode 100644 (file)
index 0000000..02ce56c
--- /dev/null
@@ -0,0 +1,428 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  define gz_error              z_gz_error
+#  define gz_intmax             z_gz_intmax
+#  define gz_strwinerror        z_gz_strwinerror
+#  define gzbuffer              z_gzbuffer
+#  define gzclearerr            z_gzclearerr
+#  define gzclose               z_gzclose
+#  define gzclose_r             z_gzclose_r
+#  define gzclose_w             z_gzclose_w
+#  define gzdirect              z_gzdirect
+#  define gzdopen               z_gzdopen
+#  define gzeof                 z_gzeof
+#  define gzerror               z_gzerror
+#  define gzflush               z_gzflush
+#  define gzgetc                z_gzgetc
+#  define gzgets                z_gzgets
+#  define gzoffset              z_gzoffset
+#  define gzoffset64            z_gzoffset64
+#  define gzopen                z_gzopen
+#  define gzopen64              z_gzopen64
+#  define gzprintf              z_gzprintf
+#  define gzputc                z_gzputc
+#  define gzputs                z_gzputs
+#  define gzread                z_gzread
+#  define gzrewind              z_gzrewind
+#  define gzseek                z_gzseek
+#  define gzseek64              z_gzseek64
+#  define gzsetparams           z_gzsetparams
+#  define gztell                z_gztell
+#  define gztell64              z_gztell64
+#  define gzungetc              z_gzungetc
+#  define gzwrite               z_gzwrite
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  define uncompress            z_uncompress
+#  define zError                z_zError
+#  define zcalloc               z_zcalloc
+#  define zcfree                z_zcfree
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  define gzFile                z_gzFile
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef STDC
+#  include <sys/types.h>    /* for off_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#  include <unistd.h>       /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>     /* for off_t */
+#  endif
+#  ifndef z_off_t
+#    define z_off_t off_t
+#  endif
+#endif
+
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define z_off64_t off64_t
+#else
+#  define z_off64_t z_off_t
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/8.x/zlib/zlib.3 b/8.x/zlib/zlib.3
new file mode 100644 (file)
index 0000000..27adc4c
--- /dev/null
@@ -0,0 +1,151 @@
+.TH ZLIB 3 "19 Apr 2010"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe, assuming that the standard library functions
+used are thread safe, such as memory allocation routines.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms may be added later
+with the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in the case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I example.c
+and
+.IR minigzip.c,
+as well as other examples in the
+.IR examples/
+directory.
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source.
+.LP
+.I zlib
+is available in Java using the java.util.zip package:
+.IP
+http://java.sun.com/developer/technicalArticles/Programming/compression/
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmqs@cpan.org),
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+including:
+.IP
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/
+.LP
+A Python interface to
+.IR zlib ,
+written by A.M. Kuchling (amk@magnet.com),
+is available in Python 1.5 and later versions:
+.IP
+http://www.python.org/doc/lib/module-zlib.html
+.LP
+.I zlib
+is built into
+.IR tcl:
+.IP
+http://wiki.tcl.tk/4610
+.LP
+An experimental package to read and write files in .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info@winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/minizip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+source distribution.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at:
+.IP
+http://zlib.net/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://www.ietf.org/rfc/rfc1950.txt (for the zlib header and trailer format)
+.br
+http://www.ietf.org/rfc/rfc1951.txt (for the deflate compressed data format)
+.br
+http://www.ietf.org/rfc/rfc1952.txt (for the gzip header and trailer format)
+.LP
+Mark Nelson wrote an article about
+.I zlib
+for the Jan. 1997 issue of  Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://marknelson.us/1997/01/01/zlib-engine/
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://zlib.net/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib@gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
+.SH AUTHORS
+Version 1.2.5
+Copyright (C) 1995-2010 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/8.x/zlib/zlib.3.pdf b/8.x/zlib/zlib.3.pdf
new file mode 100644 (file)
index 0000000..9f8a2c3
Binary files /dev/null and b/8.x/zlib/zlib.3.pdf differ
diff --git a/8.x/zlib/zlib.h b/8.x/zlib/zlib.h
new file mode 100644 (file)
index 0000000..bfbba83
--- /dev/null
@@ -0,0 +1,1613 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.5, April 19th, 2010
+
+  Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.5"
+#define ZLIB_VERNUM 0x1250
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 5
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+    The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed data.
+  This version of the library supports only one compression method (deflation)
+  but other algorithms will be added later and will have the same stream
+  interface.
+
+    Compression can be done in a single step if the buffers are large enough,
+  or can be done by repeated calls of the compression function.  In the latter
+  case, the application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+    The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+    The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+    This library can optionally read and write gzip streams in memory as well.
+
+    The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+    The library does not install any signal handler.  The decoder checks
+  the consistency of the compressed data, so the library should never crash
+  even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+     The application must update next_in and avail_in when avail_in has dropped
+   to zero.  It must update next_out and avail_out when avail_out has dropped
+   to zero.  The application must initialize zalloc, zfree and opaque before
+   calling the init function.  All other fields are set by the compression
+   library and must not be updated by the application.
+
+     The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree.  This can be useful for custom
+   memory management.  The compression library attaches no meaning to the
+   opaque value.
+
+     zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+     On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this if
+   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers
+   returned by zalloc for objects of exactly 65536 bytes *must* have their
+   offset normalized to zero.  The default allocation function provided by this
+   library ensures this (see zutil.c).  To reduce memory requirements and avoid
+   any allocation of 64K objects, at the expense of compression ratio, compile
+   the library with -DMAX_WBITS=14 (see zconf.h).
+
+     The fields total_in and total_out can be used for statistics or progress
+   reports.  After compression, total_in holds the total size of the
+   uncompressed data and may be saved for use in the decompressor (particularly
+   if the decompressor wants to decompress everything in a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+#define Z_TREES         6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is not
+   compatible with the zlib.h header file used by the application.  This check
+   is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression.  The fields
+   zalloc, zfree and opaque must be initialized before by the caller.  If
+   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+   allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at all
+   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION
+   requests a default compromise between speed and compression (currently
+   equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if level is not a valid compression level, or
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null
+   if there is no error message.  deflateInit does not perform any compression:
+   this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows.  deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).  Some
+    output may be provided even if flush is not set.
+
+    Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating avail_in or avail_out accordingly; avail_out should
+  never be zero before the call.  The application can consume the compressed
+  output when it wants, for example when the output buffer is full (avail_out
+  == 0), or after each call of deflate().  If deflate returns Z_OK and with
+  zero avail_out, it must be called again after making room in the output
+  buffer because there might be more output pending.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumulate before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far.  (In
+  particular avail_in is zero after the call if enough output space has been
+  provided before the call.) Flushing may degrade compression for some
+  compression algorithms and so it should be used only when necessary.  This
+  completes the current deflate block and follows it with an empty stored block
+  that is three bits plus filler bits to the next byte, followed by four bytes
+  (00 00 ff ff).
+
+    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+  output buffer, but the output is not aligned to a byte boundary.  All of the
+  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+  This completes the current deflate block and follows it with an empty fixed
+  codes block that is 10 bits long.  This assures that enough bytes are output
+  in order for the decompressor to finish the block before the empty fixed code
+  block.
+
+    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+  seven bits of the current block are held to be written as the next byte after
+  the next deflate block is completed.  In this case, the decompressor may not
+  be provided enough bits at this point in order to complete decompression of
+  the data provided so far to the compressor.  It may need to wait for the next
+  block to be emitted.  This is for advanced applications that need to control
+  the emission of deflate blocks.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there was
+  enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error.  After
+  deflate has returned Z_STREAM_END, the only possible operations on the stream
+  are deflateReset or deflateEnd.
+
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step.  In this case, avail_out must be at least the
+  value returned by deflateBound (see below).  If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT).  In doubt, the data is considered
+  binary.  This field is only for information purposes and does not affect the
+  compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not
+  fatal, and deflate() can be called again with more input and more output
+  space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded).  In the error case, msg
+   may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression.  The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller.  If next_in is not Z_NULL and avail_in is large enough (the
+   exact value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit() does not process any header information -- that is deferred
+   until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows.  inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing will
+    resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there is
+    no more input data or no more space in the output buffer (see below about
+    the flush parameter).
+
+    Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating the next_* and avail_* values accordingly.  The
+  application can consume the uncompressed output when it wants, for example
+  when the output buffer is full (avail_out == 0), or after each call of
+  inflate().  If inflate returns Z_OK and with zero avail_out, it must be
+  called again after making room in the output buffer because there might be
+  more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer.  Z_BLOCK requests that inflate()
+  stop if and when it gets to the next deflate block boundary.  When decoding
+  the zlib or gzip format, this will cause inflate() to return immediately
+  after the header and before the first block.  When doing a raw inflate,
+  inflate() will go ahead and process the first block, and will return when it
+  gets to the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  Also to assist in this, on return inflate() will set strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64 if
+  inflate() is currently decoding the last block in the deflate stream, plus
+  128 if inflate() returned immediately after decoding an end-of-block code or
+  decoding the complete header up to just before the first byte of the deflate
+  stream.  The end-of-block will not be indicated until all of the uncompressed
+  data from that block has been written to strm->next_out.  The number of
+  unused bits may in general be greater than seven, except when bit 7 of
+  data_type is set, in which case the number of unused bits will be less than
+  eight.  data_type is set as noted here every time inflate() returns for all
+  flush options, and so can be used to determine the amount of currently
+  consumed input in bits.
+
+    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+  end of each deflate block header is reached, before any actual data in that
+  block is decoded.  This allows the caller to determine the length of the
+  deflate block header for later use in random access within a deflate block.
+  256 is added to the value of strm->data_type when inflate() returns
+  immediately after reaching the end of the deflate block header.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error.  However if all decompression is to be performed in a single step (a
+  single call of inflate), the parameter flush should be set to Z_FINISH.  In
+  this case all pending input is processed and all pending output is flushed;
+  avail_out must be large enough to hold all the uncompressed data.  (The size
+  of the uncompressed data may have been saved by the compressor for this
+  purpose.) The next operation on this stream must be inflateEnd to deallocate
+  the decompression state.  The use of Z_FINISH is never required, but can be
+  used to inform inflate that a faster approach may be used for the single
+  inflate() call.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call.  So the only effect of the flush parameter in this implementation
+  is on the return value of inflate(), as noted below, or when it returns early
+  because Z_BLOCK or Z_TREES is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the adler32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the adler32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below.  At the end of the stream, inflate() checks that its computed adler32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically, if requested when
+  initializing with inflateInit2().  Any information contained in the gzip
+  header is not retained, so applications that need that information should
+  instead use raw inflate, see inflateInit2() below, or inflateBack() and
+  perform their own processing of the gzip header and trailer.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+  output buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing.  If Z_DATA_ERROR is returned, the application may
+  then call inflateSync() to look for a good compression block if a partial
+  recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent.  In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options.  The
+   fields next_in, zalloc, zfree and opaque must be initialized before by the
+   caller.
+
+     The method parameter is the compression method.  It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library.  Larger values of this parameter result in better
+   compression at the expense of memory usage.  The default value is 15 if
+   deflateInit is used instead.
+
+     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits
+   determines the window size.  deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute an adler32 check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding.  Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper.  The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero), no
+   header crc, and the operating system will be set to 255 (unknown).  If a
+   gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state.  memLevel=1 uses minimum memory but is
+   slow and reduces compression ratio; memLevel=9 uses maximum memory for
+   optimal speed.  The default value is 8.  See zconf.h for total memory usage
+   as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm.  Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding).  Filtered data consists mostly of small values with a somewhat
+   random distribution.  In this case, the compression algorithm is tuned to
+   compress them better.  The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as
+   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The
+   strategy parameter only affects the compression ratio but not the
+   correctness of the compressed output even if it is not set appropriately.
+   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+   decoder for special applications.
+
+     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is
+   set to null if there is no error message.  deflateInit2 does not perform any
+   compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output.  This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any call
+   of deflate.  The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary.  Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size
+   provided in deflateInit or deflateInit2.  Thus the strings most likely to be
+   useful should be put at the end of the dictionary, not at the front.  In
+   addition, the current implementation of deflate will use at most the window
+   size minus 262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor.  (The adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   adler32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort).  deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter.  The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and can
+   consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.  The
+   stream will keep the same compression level and any other attributes that
+   may have been set by deflateInit2.
+
+     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different strategy.
+   If the compression level is changed, the input available so far is
+   compressed with the old level (and may be flushed); the new level will take
+   effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to be
+   compressed and flushed.  In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+   strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit() or
+   deflateInit2(), and after deflateSetHeader(), if used.  This would be used
+   to allocate an output buffer for deflation in a single pass, and so would be
+   called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+   is that this function is used to start off the deflate output with the bits
+   leftover from a previous deflate stream when appending to it.  As such, this
+   function can only be used for raw deflate, and must be used before the first
+   deflate() call after a deflateInit2() or deflateReset().  bits must be less
+   than or equal to 16, and that many of the least significant bits of value
+   will be inserted in the output.
+
+     deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+     If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter.  The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library.  The default value is 15 if inflateInit is used
+   instead.  windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used.  If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be zero to request that inflate use the window size in
+   the zlib header of the compressed stream.
+
+     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits
+   determines the window size.  inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream.  This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values.  If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an adler32 or a crc32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is.  Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding.  Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a
+   crc32 instead of an adler32.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit2 does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit2() does not process any header information -- that is
+   deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence.  This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called
+   immediately after inflateInit2() or inflateReset() and before any call of
+   inflate() to set the dictionary.  The application must insure that the
+   dictionary that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect adler32 value).  inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+     Skips invalid compressed data until a full flush point (see above the
+   description of deflate with Z_FULL_FLUSH) can be found, or until all
+   available input is skipped.  No output is provided.
+
+     inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+   if no more input was provided, Z_DATA_ERROR if no flush point has been
+   found, or Z_STREAM_ERROR if the stream structure was inconsistent.  In the
+   success case, the application may save the current current value of total_in
+   which indicates where valid compressed data was found.  In the error case,
+   the application may repeatedly call inflateSync, providing more input each
+   time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.  The
+   stream will keep attributes that may have been set by inflateInit2.
+
+     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+                                      int windowBits));
+/*
+     This function is the same as inflateReset, but it also permits changing
+   the wrap and window size requests.  The windowBits parameter is interpreted
+   the same as it is for inflateInit2.
+
+     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+   the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+   that this function is used to start inflating at a bit position in the
+   middle of a byte.  The provided bits will be used before any bytes are used
+   from next_in.  This function should only be used with raw inflate, and
+   should be used before the first inflate() call after inflateInit2() or
+   inflateReset().  bits must be less than or equal to 16, and that many of the
+   least significant bits of value will be inserted in the input.
+
+     If bits is negative, then the input stream bit buffer is emptied.  Then
+   inflatePrime() can be called again to put bits in the buffer.  This is used
+   to clear out bits leftover after feeding inflate a block description prior
+   to feeding inflate codes.
+
+     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+     This function returns two values, one in the lower 16 bits of the return
+   value, and the other in the remaining upper bits, obtained by shifting the
+   return value down 16 bits.  If the upper value is -1 and the lower value is
+   zero, then inflate() is currently decoding information outside of a block.
+   If the upper value is -1 and the lower value is non-zero, then inflate is in
+   the middle of a stored block, with the lower value equaling the number of
+   bytes from the input remaining to copy.  If the upper value is not -1, then
+   it is the number of bits back from the current bit position in the input of
+   the code (literal or length/distance pair) currently being processed.  In
+   that case the lower value is the number of bytes already emitted for that
+   code.
+
+     A code is being processed if inflate is waiting for more input to complete
+   decoding of the code, or if it has completed decoding but is waiting for
+   more output space to write the literal or match data.
+
+     inflateMark() is used to mark locations in the input data for random
+   access, which may be at bit positions, and to note those cases where the
+   output of a code may span boundaries of random access blocks.  The current
+   location in the input stream can be determined from avail_in and data_type
+   as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+     inflateMark returns the value noted above or -1 << 16 if the provided
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be
+   used to force inflate() to return immediately after header processing is
+   complete and before any actual data is decompressed.
+
+     The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When any
+   of extra, name, or comment are not Z_NULL and the respective field is not
+   present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+     If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
+   allocated, or Z_VERSION_ERROR if the version of the library does not match
+   the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is more efficient than inflate() for
+   file i/o applications in that it avoids copying between the output and the
+   sliding window by simply making the window itself the output buffer.  This
+   function trusts the application to not change the output buffer passed by
+   the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free the
+   allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects only
+   the raw deflate stream to decompress.  This is different from the normal
+   behavior of inflate(), which expects either a zlib or gzip header and
+   trailer around the deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero--buf is ignored in that
+   case--and inflateBack() will return a buffer error.  inflateBack() will call
+   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
+   should return zero on success, or non-zero on failure.  If out() returns
+   non-zero, inflateBack() will return with an error.  Neither in() nor out()
+   are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+   in the deflate stream (in which case strm->msg is set to indicate the nature
+   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+   In the case of Z_BUF_ERROR, an input or output error can be distinguished
+   using strm->next_in which will be Z_NULL only if in() returned an error.  If
+   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+   non-zero.  (in() will always be called before out(), so strm->next_in is
+   assured to be defined if out() returns non-zero.) Note that inflateBack()
+   cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the basic
+   stream-oriented functions.  To simplify the interface, some default options
+   are assumed (compression level and memory usage, standard memory allocation
+   functions).  The source code of these utility functions can be modified if
+   you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer.  The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer.  Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before a
+   compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be large enough to hold the entire
+   uncompressed data.  (The size of the uncompressed data must have been saved
+   previously by the compressor and transmitted to the decompressor by some
+   mechanism outside the scope of this compression library.) Upon exit, destLen
+   is the actual size of the uncompressed buffer.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+                        /* gzip file access functions */
+
+/*
+     This library supports reading and writing files in gzip (.gz) format with
+   an interface similar to that of stdio, using the functions that start with
+   "gz".  The gzip format is different from the zlib format.  gzip is a gzip
+   wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef voidp gzFile;       /* opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+     Opens a gzip (.gz) file for reading or writing.  The mode parameter is as
+   in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+   a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+   compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+   for fixed code compression as in "wb9F".  (See the description of
+   deflateInit2 for more information about the strategy parameter.) Also "a"
+   can be used instead of "w" to request that the gzip stream that will be
+   written be appended to the file.  "+" will result in an error, since reading
+   and writing to the same gzip file is not supported.
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened, if there was
+   insufficient memory to allocate the gzFile state, or if an invalid mode was
+   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+   errno can be checked to determine if the reason gzopen failed was that the
+   file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+     gzdopen associates a gzFile with the file descriptor fd.  File descriptors
+   are obtained from calls like open, dup, creat, pipe or fileno (if the file
+   has been previously opened with fopen).  The mode parameter is as in gzopen.
+
+     The next call of gzclose on the returned gzFile will also close the file
+   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+   mode);.  The duplicated descriptor should be saved to avoid a leak, since
+   gzdopen does not close fd if it fails.
+
+     gzdopen returns NULL if there was insufficient memory to allocate the
+   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+   provided, or '+' was provided), or if fd is -1.  The file descriptor is not
+   used until the next gz* read, write, seek, or close operation, so gzdopen
+   will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+     Set the internal buffer size used by this library's functions.  The
+   default buffer size is 8192 bytes.  This function must be called after
+   gzopen() or gzdopen(), and before any other calls that read or write the
+   file.  The buffer memory allocation is always deferred to the first read or
+   write.  Two buffers are allocated, either both of the specified size when
+   writing, or one of the specified size and the other twice that size when
+   reading.  A larger buffer size of, for example, 64K or 128K bytes will
+   noticeably increase the speed of decompression (reading).
+
+     The new buffer size also affects the maximum length for gzprintf().
+
+     gzbuffer() returns 0 on success, or -1 on failure, such as being called
+   too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy.  See the description
+   of deflateInit2 for the meaning of these parameters.
+
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.  If
+   the input file was not in gzip format, gzread copies the given number of
+   bytes into the buffer.
+
+     After reaching the end of a gzip stream in the input, gzread will continue
+   to read, looking for another gzip stream, or failing that, reading the rest
+   of the input file directly without decompression.  The entire input file
+   will be read if gzread is called until it returns less than the requested
+   len.
+
+     gzread returns the number of uncompressed bytes actually read, less than
+   len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+                                voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes written or 0 in case of
+   error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the arguments to the compressed file under
+   control of the format string, as in fprintf.  gzprintf returns the number of
+   uncompressed bytes actually written, or 0 in case of error.  The number of
+   uncompressed bytes written is limited to 8191, or one less than the buffer
+   size given to gzbuffer().  The caller should assure that this limit is not
+   exceeded.  If it is exceeded, then gzprintf() will return an error (0) with
+   nothing written.  In this case, there may also be a buffer overflow with
+   unpredictable consequences, which is possible only if zlib was compiled with
+   the insecure functions sprintf() or vsprintf() because the secure snprintf()
+   or vsnprintf() functions were not available.  This can be determined using
+   zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+     Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+
+     gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+     Reads bytes from the compressed file until len-1 characters are read, or a
+   newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  If any characters are read or if len == 1, the
+   string is terminated with a null character.  If no characters are read due
+   to an end-of-file or len < 1, then the buffer is left untouched.
+
+     gzgets returns buf which is a null-terminated string, or it returns NULL
+   for end-of-file or in case of error.  If there was an error, the contents at
+   buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+     Writes c, converted to an unsigned char, into the compressed file.  gzputc
+   returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+     Reads one byte from the compressed file.  gzgetc returns this byte or -1
+   in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+     Push one character back onto the stream to be read as the first character
+   on the next read.  At least one character of push-back is allowed.
+   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will
+   fail if c is -1, and may fail if a character has been pushed but not read
+   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the
+   output buffer size of pushed characters is allowed.  (See gzbuffer above.)
+   The pushed character will be discarded if the stream is repositioned with
+   gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file.  The parameter flush
+   is as in the deflate() function.  The return value is the zlib error number
+   (see function gzerror below).  gzflush is only permitted when writing.
+
+     If the flush parameter is Z_FINISH, the remaining data is written and the
+   gzip stream is completed in the output.  If gzwrite() is called again, a new
+   gzip stream will be started in the output.  gzread() is able to read such
+   concatented gzip streams.
+
+     gzflush should be called only when strictly necessary because it will
+   degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+                                   z_off_t offset, int whence));
+
+     Sets the starting position for the next gzread or gzwrite on the given
+   compressed file.  The offset represents a number of bytes in the
+   uncompressed data stream.  The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow.  If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+     gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+
+     Returns the starting position for the next gzread or gzwrite on the given
+   compressed file.  This position represents a number of bytes in the
+   uncompressed data stream, and is zero when starting, even if appending or
+   reading a gzip stream from the middle of a file using gzdopen().
+
+     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+     Returns the current offset in the file being read or written.  This offset
+   includes the count of bytes that precede the gzip stream, for example when
+   appending or when using gzdopen() for reading.  When reading, the offset
+   does not include as yet unused buffered input.  This information can be used
+   for a progress indicator.  On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns true (1) if the end-of-file indicator has been set while reading,
+   false (0) otherwise.  Note that the end-of-file indicator is set only if the
+   read tried to go past the end of the input, but came up short.  Therefore,
+   just like feof(), gzeof() may return false even if there is no more data to
+   read, in the event that the last read request was for the exact number of
+   bytes remaining in the input file.  This will happen if the input file size
+   is an exact multiple of the buffer size.
+
+     If gzeof() returns true, then the read functions will return no more data,
+   unless the end-of-file indicator is reset by gzclearerr() and the input file
+   has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns true (1) if file is being copied directly while reading, or false
+   (0) if file is a gzip stream being decompressed.  This state can change from
+   false to true while reading the input file if the end of a gzip stream is
+   reached, but is followed by data that is not another gzip stream.
+
+     If the input file is empty, gzdirect() will return true, since the input
+   does not contain a gzip stream.
+
+     If gzdirect() is used immediately after gzopen() or gzdopen() it will
+   cause buffers to be allocated to allow reading the file to determine if it
+   is a gzip file.  Therefore if gzbuffer() is used, it should be called before
+   gzdirect().
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file and
+   deallocates the (de)compression state.  Note that once file is closed, you
+   cannot call gzerror with file, since its structures have been deallocated.
+   gzclose must not be called more than once on the same file, just as free
+   must not be called more than once on the same allocation.
+
+     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+   file operation error, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+     Same as gzclose(), but gzclose_r() is only for use when reading, and
+   gzclose_w() is only for use when writing or appending.  The advantage to
+   using these instead of gzclose() is that they avoid linking in zlib
+   compression or decompression code that is not used when only reading or only
+   writing respectively.  If gzclose() is used, then both compression and
+   decompression code will be included the application when linking to a static
+   zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the given
+   compressed file.  errnum is set to zlib error number.  If an error occurred
+   in the file system and not in the compression library, errnum is set to
+   Z_ERRNO and the application may consult errno to get the exact error code.
+
+     The application must not modify the returned string.  Future calls to
+   this function may invalidate the previously returned string.  If file is
+   closed, then the string previously returned by gzerror will no longer be
+   available.
+
+     gzerror() should be used to distinguish errors from end-of-file for those
+   functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file.  This is analogous to the
+   clearerr() function in stdio.  This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the compression
+   library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum.  If buf is Z_NULL, this function returns the
+   required initial value for the checksum.
+
+     An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster.
+
+   Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32.  If buf is Z_NULL, this function returns the required
+   initial value for the for the crc.  Pre- and post-conditioning (one's
+   complement) is performed within this function so it shouldn't be done by the
+   application.
+
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+        inflateBackInit_((strm), (windowBits), (window), \
+                                            ZLIB_VERSION, sizeof(z_stream))
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
+#  define gzopen gzopen64
+#  define gzseek gzseek64
+#  define gztell gztell64
+#  define gzoffset gzoffset64
+#  define adler32_combine adler32_combine64
+#  define crc32_combine crc32_combine64
+#  ifdef _LARGEFILE64_SOURCE
+     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#  endif
+#else
+   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
+ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/8.x/zlib/zlib.map b/8.x/zlib/zlib.map
new file mode 100644 (file)
index 0000000..f282d36
--- /dev/null
@@ -0,0 +1,68 @@
+ZLIB_1.2.0 {
+  global:
+    compressBound;
+    deflateBound;
+    inflateBack;
+    inflateBackEnd;
+    inflateBackInit_;
+    inflateCopy;
+  local:
+    deflate_copyright;
+    inflate_copyright;
+    inflate_fast;
+    inflate_table;
+    zcalloc;
+    zcfree;
+    z_errmsg;
+    gz_error;
+    gz_intmax;
+    _*;
+};
+
+ZLIB_1.2.0.2 {
+    gzclearerr;
+    gzungetc;
+    zlibCompileFlags;
+} ZLIB_1.2.0;
+
+ZLIB_1.2.0.8 {
+    deflatePrime;
+} ZLIB_1.2.0.2;
+
+ZLIB_1.2.2 {
+    adler32_combine;
+    crc32_combine;
+    deflateSetHeader;
+    inflateGetHeader;
+} ZLIB_1.2.0.8;
+
+ZLIB_1.2.2.3 {
+    deflateTune;
+    gzdirect;
+} ZLIB_1.2.2;
+
+ZLIB_1.2.2.4 {
+    inflatePrime;
+} ZLIB_1.2.2.3;
+
+ZLIB_1.2.3.3 {
+    adler32_combine64;
+    crc32_combine64;
+    gzopen64;
+    gzseek64;
+    gztell64;
+    inflateUndermine;
+} ZLIB_1.2.2.4;
+
+ZLIB_1.2.3.4 {
+    inflateReset2;
+    inflateMark;
+} ZLIB_1.2.3.3;
+
+ZLIB_1.2.3.5 {
+    gzbuffer;
+    gzoffset;
+    gzoffset64;
+    gzclose_r;
+    gzclose_w;
+} ZLIB_1.2.3.4;
diff --git a/8.x/zlib/zlib.pc.in b/8.x/zlib/zlib.pc.in
new file mode 100644 (file)
index 0000000..7e5acf9
--- /dev/null
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+sharedlibdir=@sharedlibdir@
+includedir=@includedir@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/8.x/zlib/zlib2ansi b/8.x/zlib/zlib2ansi
new file mode 100755 (executable)
index 0000000..15e3e16
--- /dev/null
@@ -0,0 +1,152 @@
+#!/usr/bin/perl
+
+# Transform K&R C function definitions into ANSI equivalent.
+#
+# Author: Paul Marquess
+# Version: 1.0
+# Date: 3 October 2006
+
+# TODO
+#
+# Asumes no function pointer parameters. unless they are typedefed.
+# Assumes no literal strings that look like function definitions
+# Assumes functions start at the beginning of a line
+
+use strict;
+use warnings;
+
+local $/;
+$_ = <>;
+
+my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments
+
+my $d1    = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ;
+my $decl  = qr{ $sp (?: \w+ $sp )+ $d1 }xo ;
+my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;
+
+
+while (s/^
+            (                  # Start $1
+                (              #   Start $2
+                    .*?        #     Minimal eat content
+                    ( ^ \w [\w\s\*]+ )    #     $3 -- function name
+                    \s*        #     optional whitespace
+                )              # $2 - Matched up to before parameter list
+
+                \( \s*         # Literal "(" + optional whitespace
+                ( [^\)]+ )     # $4 - one or more anythings except ")"
+                \s* \)         # optional whitespace surrounding a Literal ")"
+
+                ( (?: $dList )+ ) # $5
+
+                $sp ^ {        # literal "{" at start of line
+            )                  # Remember to $1
+        //xsom
+      )
+{
+    my $all = $1 ;
+    my $prefix = $2;
+    my $param_list = $4 ;
+    my $params = $5;
+
+    StripComments($params);
+    StripComments($param_list);
+    $param_list =~ s/^\s+//;
+    $param_list =~ s/\s+$//;
+
+    my $i = 0 ;
+    my %pList = map { $_ => $i++ }
+                split /\s*,\s*/, $param_list;
+    my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ;
+
+    my @params = split /\s*;\s*/, $params;
+    my @outParams = ();
+    foreach my $p (@params)
+    {
+        if ($p =~ /,/)
+        {
+            my @bits = split /\s*,\s*/, $p;
+            my $first = shift @bits;
+            $first =~ s/^\s*//;
+            push @outParams, $first;
+            $first =~ /^(\w+\s*)/;
+            my $type = $1 ;
+            push @outParams, map { $type . $_ } @bits;
+        }
+        else
+        {
+            $p =~ s/^\s+//;
+            push @outParams, $p;
+        }
+    }
+
+
+    my %tmp = map { /$pMatch/;  $_ => $pList{$1}  }
+              @outParams ;
+
+    @outParams = map  { "    $_" }
+                 sort { $tmp{$a} <=> $tmp{$b} }
+                 @outParams ;
+
+    print $prefix ;
+    print "(\n" . join(",\n", @outParams) . ")\n";
+    print "{" ;
+
+}
+
+# Output any trailing code.
+print ;
+exit 0;
+
+
+sub StripComments
+{
+
+  no warnings;
+
+  # Strip C & C++ coments
+  # From the perlfaq
+  $_[0] =~
+
+    s{
+       /\*         ##  Start of /* ... */ comment
+       [^*]*\*+    ##  Non-* followed by 1-or-more *'s
+       (
+         [^/*][^*]*\*+
+       )*          ##  0-or-more things which don't start with /
+                   ##    but do end with '*'
+       /           ##  End of /* ... */ comment
+
+     |         ##     OR  C++ Comment
+       //          ## Start of C++ comment //
+       [^\n]*      ## followed by 0-or-more non end of line characters
+
+     |         ##     OR  various things which aren't comments:
+
+       (
+         "           ##  Start of " ... " string
+         (
+           \\.           ##  Escaped char
+         |               ##    OR
+           [^"\\]        ##  Non "\
+         )*
+         "           ##  End of " ... " string
+
+       |         ##     OR
+
+         '           ##  Start of ' ... ' string
+         (
+           \\.           ##  Escaped char
+         |               ##    OR
+           [^'\\]        ##  Non '\
+         )*
+         '           ##  End of ' ... ' string
+
+       |         ##     OR
+
+         .           ##  Anything other char
+         [^/"'\\]*   ##  Chars which doesn't start a comment, string or escape
+       )
+     }{$2}gxs;
+
+}
diff --git a/8.x/zlib/zutil.c b/8.x/zlib/zutil.c
new file mode 100644 (file)
index 0000000..898ed34
--- /dev/null
@@ -0,0 +1,318 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005, 2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch ((int)(sizeof(uInt))) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch ((int)(sizeof(uLong))) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch ((int)(sizeof(voidpf))) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch ((int)(sizeof(z_off_t))) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef DEBUG
+    flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1L << 20;
+#endif
+#ifdef FASTEST
+    flags += 1L << 21;
+#endif
+#ifdef STDC
+#  ifdef NO_vsnprintf
+        flags += 1L << 25;
+#    ifdef HAS_vsprintf_void
+        flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+        flags += 1L << 26;
+#    endif
+#  endif
+#else
+        flags += 1L << 24;
+#  ifdef NO_snprintf
+        flags += 1L << 25;
+#    ifdef HAS_sprintf_void
+        flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+        flags += 1L << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+    /* The Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/8.x/zlib/zutil.h b/8.x/zlib/zutil.h
new file mode 100644 (file)
index 0000000..258fa88
--- /dev/null
@@ -0,0 +1,274 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#ifdef STDC
+#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+#    include <stddef.h>
+#  endif
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+#  define OS_CODE  0x00
+#  if defined(__TURBOC__) || defined(__BORLANDC__)
+#    if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+       /* Allow compilation with ANSI keywords only enabled */
+       void _Cdecl farfree( void *block );
+       void *_Cdecl farmalloc( unsigned long nbytes );
+#    else
+#      include <alloc.h>
+#    endif
+#  else /* MSC or DJGPP */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#  ifdef M_I86
+#    include <malloc.h>
+#  endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#    include <unix.h> /* for fdopen */
+#  else
+#    ifndef fdopen
+#      define fdopen(fd,mode) NULL /* No fdopen() */
+#    endif
+#  endif
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#ifdef WIN32
+#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
+#    define OS_CODE  0x0b
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#    ifndef _PTRDIFF_T_DEFINED
+       typedef int ptrdiff_t;
+#      define _PTRDIFF_T_DEFINED
+#    endif
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
+#endif
+
+#if defined(__BORLANDC__)
+  #pragma warn -8004
+  #pragma warn -8008
+  #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+        /* common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+#if defined(__CYGWIN__)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+#ifndef HAVE_VSNPRINTF
+#  ifdef MSDOS
+     /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+        but for now we just assume it doesn't. */
+#    define NO_vsnprintf
+#  endif
+#  ifdef __TURBOC__
+#    define NO_vsnprintf
+#  endif
+#  ifdef WIN32
+     /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
+#      if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+#         define vsnprintf _vsnprintf
+#      endif
+#    endif
+#  endif
+#  ifdef __SASC
+#    define NO_vsnprintf
+#  endif
+#endif
+#ifdef VMS
+#  define NO_vsnprintf
+#endif
+
+#if defined(pyr)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int ZLIB_INTERNAL z_verbose;
+   extern void ZLIB_INTERNAL z_error OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+                        unsigned size));
+void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */
index 8a4302c04ccad9d9a13969b01e14530cdcd83d6b..8bacf2dabdab44853bb2ef9573c0d1860479a21c 100644 (file)
@@ -97,7 +97,8 @@ build/vqtcl: build/tcl
 
 build/zlib: build/tcl
        cp -R ../../8.x/zlib/. $@
-       cd $@ && $(MAKE) install prefix=.. CC="$(CC)" CFLAGS="-O $(CFLAGS)"
+       cd $@ && sh configure && \
+       $(MAKE) install prefix=..
 
 base: build/tcl build/tk
        ls -l build/bin